• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bitfaster / BitFaster.Caching / 24384053764

14 Apr 2026 06:15AM UTC coverage: 97.527% (-1.5%) from 99.004%
24384053764

Pull #745

github

web-flow
Merge 99d4cd92f into 0f4775249
Pull Request #745: Bump coverlet.msbuild from 6.0.4 to 8.0.1

1218 of 1256 branches covered (96.97%)

Branch coverage included in aggregate %.

5290 of 5417 relevant lines covered (97.66%)

13706774.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.69
/BitFaster.Caching/Duration.cs
1
using System;
2
using System.Diagnostics;
3
using System.Runtime.CompilerServices;
4
using System.Runtime.InteropServices;
5
using BitFaster.Caching.Lru;
6

7
namespace BitFaster.Caching
8
{
9
    /// <summary>
10
    /// Represents a fixed length of time.
11
    /// </summary>
12
    /// <remarks>
13
    /// This struct is used to abstract away the use of different time sources with different precision. 
14
    /// This enables use of native time values (which may be ticks or millisecs), only converting 
15
    /// to TimeSpan for non perf critical user code. Using long without a mul/div makes cache lookups 
16
    /// about 30% faster on .NET6.
17
    /// </remarks>
18
    [DebuggerDisplay("{ToTimeSpan()}")]
19
    public readonly struct Duration
20
    {
21
        internal readonly long raw;
22

23
        // MacOS Stopwatch adjustment factor is 100, giving lowest maximum TTL on mac platform - use same upper limit on all platforms for consistency
24
        // this also avoids overflow when multipling long.MaxValue by 1.0
25
        internal static readonly TimeSpan MaxRepresentable = TimeSpan.FromTicks((long)(long.MaxValue / 100.0d));
1✔
26

27
        internal static readonly Duration Zero = new Duration(0);
1✔
28

29
#if NETCOREAPP3_0_OR_GREATER
30
        private static readonly bool IsMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
1✔
31
#else
32
        private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
33

34
        [DllImport("kernel32")]
35
        internal static extern long GetTickCount64();
36
#endif
37

38
        internal Duration(long raw)
39
        {
411,150,309✔
40
            this.raw = raw;
411,150,309✔
41
        }
411,150,309✔
42

43
        /// <summary>
44
        /// Gets the time since the system epoch.
45
        /// </summary>
46
        /// <returns>A duration</returns>
47
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
48
        public static Duration SinceEpoch()
49
        {
407,118,429✔
50
#if NETCOREAPP3_0_OR_GREATER
51
            if (IsMacOS)
407,118,429!
52
            {
×
53
                return new Duration(Stopwatch.GetTimestamp());
×
54
            }
55
            else
56
            {
407,118,429✔
57
                return new Duration(Environment.TickCount64);
407,118,429✔
58
            }
59
#else
60
            if (IsWindows)
61
            {
62
                return new Duration(GetTickCount64());
63
            }
64
            else
65
            {
66
                return new Duration(Stopwatch.GetTimestamp());
67
            }
68
#endif
69
        }
407,118,429✔
70

71
        /// <summary>
72
        /// Converts the duration to a TimeSpan.
73
        /// </summary>
74
        /// <returns></returns>
75
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
76
        public TimeSpan ToTimeSpan()
77
        {
47✔
78
#if NETCOREAPP3_0_OR_GREATER
79
            if (IsMacOS)
47!
80
            {
×
81
                return StopwatchTickConverter.FromTicks(raw);
×
82
            }
83
            else
84
            {
47✔
85
                return TimeSpan.FromMilliseconds(raw);
47✔
86
            }
87
#else
88
            if (IsWindows)
89
            {
90
                return TimeSpan.FromMilliseconds(raw);
91
            }
92
            else
93
            {
94
                return StopwatchTickConverter.FromTicks(raw);
95
            }
96
#endif
97
        }
47✔
98

99
        /// <summary>
100
        /// Returns a Duration that represents a specified TimeSpan.
101
        /// </summary>
102
        /// <param name="timeSpan">The TimeSpan to convert.</param>
103
        /// <returns>A duration.</returns>
104
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
105
        public static Duration FromTimeSpan(TimeSpan timeSpan)
106
        {
436✔
107
#if NETCOREAPP3_0_OR_GREATER
108
            if (IsMacOS)
436!
109
            {
×
110
                return new Duration(StopwatchTickConverter.ToTicks(timeSpan));
×
111
            }
112
            else
113
            {
436✔
114
                return new Duration((long)timeSpan.TotalMilliseconds);
436✔
115
            }
116
#else
117
            if (IsWindows)
118
            {
119
                return new Duration((long)timeSpan.TotalMilliseconds);
120
            }
121
            else
122
            {
123
                return new Duration(StopwatchTickConverter.ToTicks(timeSpan));
124
            }
125
#endif
126
        }
436✔
127

128
        /// <summary>
129
        /// Returns a Duration that represents a specified number of milliseconds.
130
        /// </summary>
131
        /// <param name="value">A number of milliseconds</param>
132
        /// <returns></returns>
133
        public static Duration FromMilliseconds(double value)
134
        {
30✔
135
            return FromTimeSpan(TimeSpan.FromMilliseconds(value));
30✔
136
        }
30✔
137

138
        /// <summary>
139
        /// Returns a Duration that represents a specified number of seconds.
140
        /// </summary>
141
        /// <param name="value">A number of seconds</param>
142
        /// <returns></returns>
143
        public static Duration FromSeconds(double value)
144
        {
152✔
145
            return FromTimeSpan(TimeSpan.FromSeconds(value));
152✔
146
        }
152✔
147

148
        /// <summary>
149
        /// Returns a Duration that represents a specified number of minutes.
150
        /// </summary>
151
        /// <param name="value">A number of minutes</param>
152
        /// <returns></returns>
153
        public static Duration FromMinutes(double value)
154
        {
41✔
155
            return FromTimeSpan(TimeSpan.FromMinutes(value));
41✔
156
        }
41✔
157

158
        /// <summary>
159
        /// Returns a Duration that represents a specified number of hours.
160
        /// </summary>
161
        /// <param name="value">A number of hours</param>
162
        /// <returns></returns>
163
        public static Duration FromHours(double value)
164
        {
1✔
165
            return FromTimeSpan(TimeSpan.FromHours(value));
1✔
166
        }
1✔
167

168
        /// <summary>
169
        /// Returns a Duration that represents a specified number of days.
170
        /// </summary>
171
        /// <param name="value">A number of days</param>
172
        /// <returns></returns>
173
        public static Duration FromDays(double value)
174
        {
9✔
175
            return FromTimeSpan(TimeSpan.FromDays(value));
9✔
176
        }
9✔
177

178
        /// <summary>
179
        /// Adds two specified Duration instances.
180
        /// </summary>
181
        /// <param name="a">The first duration to add.</param>
182
        /// <param name="b">The second duration to add.</param>
183
        /// <returns>An duration whose value is the sum of the values of a and b.</returns>
184
        public static Duration operator +(Duration a, Duration b) => new Duration(a.raw + b.raw);
4,000,641✔
185

186
        /// <summary>
187
        /// Subtracts a specified Duration from another specified Duration.
188
        /// </summary>
189
        /// <param name="a">The minuend.</param>
190
        /// <param name="b">The subtrahend.</param>
191
        /// <returns>An duration whose value is the result of the value of a minus the value of b.</returns>
192
        public static Duration operator -(Duration a, Duration b) => new Duration(a.raw - b.raw);
24,598✔
193

194
        /// <summary>
195
        /// Returns a value that indicates whether a specified Duration is greater than another specified Duration.    
196
        /// </summary>
197
        /// <param name="a">The first duration to compare.</param>
198
        /// <param name="b">The second duration to compare.</param>
199
        /// <returns>true if the value of a is greater than the value of b; otherwise, false.</returns>
200
        public static bool operator >(Duration a, Duration b) => a.raw > b.raw;
30✔
201

202
        /// <summary>
203
        /// Returns a value that indicates whether a specified Duration is less than another specified Duration.    
204
        /// </summary>
205
        /// <param name="a">The first duration to compare.</param>
206
        /// <param name="b">The second duration to compare.</param>
207
        /// <returns>true if the value of a is less than the value of b; otherwise, false.</returns>
208
        public static bool operator <(Duration a, Duration b) => a.raw < b.raw;
25,602✔
209
    }
210
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc