@@ -124,47 +124,73 @@ public sealed partial class HotKeysResult
124124 /// <summary>
125125 /// The key slots active for this profiling session.
126126 /// </summary>
127- public SlotRange [ ] SelectedSlots { get ; } = [ ] ;
127+ public ReadOnlySpan < SlotRange > SelectedSlots => _selectedSlots ;
128+
129+ private readonly SlotRange [ ] ? _selectedSlots ;
128130
129131 /// <summary>
130132 /// The total CPU measured for all commands in all slots.
131133 /// </summary>
132- public TimeSpan TotalCpuTime => TimeSpan . FromMilliseconds ( TotalCpuTimeMilliseconds ) ;
134+ public TimeSpan TotalCpuTime => NonNegativeMicroseconds ( TotalCpuTimeMicroseconds ) ;
135+
136+ private static TimeSpan NonNegativeMilliseconds ( long ms )
137+ => TimeSpan . FromMilliseconds ( Math . Max ( ms , 0 ) ) ;
133138
134- private long TotalCpuTimeMilliseconds { get ; }
139+ private static TimeSpan NonNegativeMicroseconds ( long us )
140+ {
141+ const long TICKS_PER_MICROSECOND = TimeSpan . TicksPerMillisecond / 1000 ; // 10, but: clearer
142+ return TimeSpan . FromTicks ( Math . Max ( us , 0 ) / TICKS_PER_MICROSECOND ) ;
143+ }
144+
145+ /// <summary>
146+ /// The total CPU measured for all commands in all slots.
147+ /// </summary>
148+ public long TotalCpuTimeMicroseconds { get ; } = - 1 ;
135149
136150 /// <summary>
137151 /// The total network usage measured for all commands in all slots.
138152 /// </summary>
139153 public long TotalNetworkBytes { get ; }
140154
141- private long CollectionStartTimeUnixMilliseconds { get ; }
155+ /// <summary>
156+ /// The start time of the capture.
157+ /// </summary>
158+ public long CollectionStartTimeUnixMilliseconds { get ; } = - 1 ;
142159
143160 /// <summary>
144161 /// The start time of the capture.
145162 /// </summary>
146- public DateTime CollectionStartTime => RedisBase . UnixEpoch . AddMilliseconds ( CollectionStartTimeUnixMilliseconds ) ;
163+ public DateTime CollectionStartTime => RedisBase . UnixEpoch . AddMilliseconds ( Math . Max ( CollectionStartTimeUnixMilliseconds , 0 ) ) ;
147164
148- private long CollectionDurationMilliseconds { get ; }
165+ /// <summary>
166+ /// The duration of the capture.
167+ /// </summary>
168+ public long CollectionDurationMilliseconds { get ; }
149169
150170 /// <summary>
151171 /// The duration of the capture.
152172 /// </summary>
153- public TimeSpan CollectionDuration => TimeSpan . FromMilliseconds ( CollectionDurationMilliseconds ) ;
173+ public TimeSpan CollectionDuration => NonNegativeMilliseconds ( CollectionDurationMilliseconds ) ;
154174
155- private long TotalCpuTimeUserMilliseconds { get ; }
175+ /// <summary>
176+ /// The total user CPU time measured.
177+ /// </summary>
178+ public long TotalCpuTimeUserMilliseconds { get ; } = - 1 ;
156179
157180 /// <summary>
158181 /// The total user CPU time measured.
159182 /// </summary>
160- public TimeSpan TotalCpuTimeUser => TimeSpan . FromMilliseconds ( TotalCpuTimeUserMilliseconds ) ;
183+ public TimeSpan TotalCpuTimeUser => NonNegativeMilliseconds ( TotalCpuTimeUserMilliseconds ) ;
161184
162- private long TotalCpuTimeSystemMilliseconds { get ; }
185+ /// <summary>
186+ /// The total system CPU measured.
187+ /// </summary>
188+ public long TotalCpuTimeSystemMilliseconds { get ; } = - 1 ;
163189
164190 /// <summary>
165191 /// The total system CPU measured.
166192 /// </summary>
167- public TimeSpan TotalCpuTimeSystem => TimeSpan . FromMilliseconds ( TotalCpuTimeSystemMilliseconds ) ;
193+ public TimeSpan TotalCpuTimeSystem => NonNegativeMilliseconds ( TotalCpuTimeSystemMilliseconds ) ;
168194
169195 /// <summary>
170196 /// The total network data measured.
@@ -178,21 +204,23 @@ public sealed partial class HotKeysResult
178204 /// <summary>
179205 /// Hot keys, as measured by CPU activity.
180206 /// </summary>
181- public MetricKeyCpu [ ] CpuByKey { get ; } = [ ] ;
207+ public ReadOnlySpan < MetricKeyCpu > CpuByKey => _cpuByKey ;
208+
209+ private readonly MetricKeyCpu [ ] ? _cpuByKey ;
182210
183211 /// <summary>
184212 /// Hot keys, as measured by network activity.
185213 /// </summary>
186- public MetricKeyBytes [ ] NetworkBytesByKey { get ; } = [ ] ;
214+ public ReadOnlySpan < MetricKeyBytes > NetworkBytesByKey => _networkBytesByKey ;
187215
188- private const long TicksPerMicroSeconds = TimeSpan . TicksPerMillisecond / 1000 ; // 10, but: clearer
216+ private readonly MetricKeyBytes [ ] ? _networkBytesByKey ;
189217
190218 /// <summary>
191219 /// A hot key, as measured by CPU activity.
192220 /// </summary>
193221 /// <param name="key">The key observed.</param>
194- /// <param name="microSeconds ">The time taken, in microseconds.</param>
195- public readonly struct MetricKeyCpu ( in RedisKey key , long microSeconds )
222+ /// <param name="durationMicroseconds ">The time taken, in microseconds.</param>
223+ public readonly struct MetricKeyCpu ( in RedisKey key , long durationMicroseconds )
196224 {
197225 private readonly RedisKey _key = key ;
198226
@@ -204,22 +232,22 @@ public readonly struct MetricKeyCpu(in RedisKey key, long microSeconds)
204232 /// <summary>
205233 /// The time taken, in microseconds.
206234 /// </summary>
207- public long MicroSeconds => microSeconds ;
235+ public long DurationMicroseconds => durationMicroseconds ;
208236
209237 /// <summary>
210238 /// The time taken.
211239 /// </summary>
212- public TimeSpan Duration => TimeSpan . FromTicks ( microSeconds / TicksPerMicroSeconds ) ;
240+ public TimeSpan Duration => NonNegativeMicroseconds ( durationMicroseconds ) ;
213241
214242 /// <inheritdoc/>
215243 public override string ToString ( ) => $ "{ _key } : { Duration } ";
216244
217245 /// <inheritdoc/>
218- public override int GetHashCode ( ) => _key . GetHashCode ( ) ^ microSeconds . GetHashCode ( ) ;
246+ public override int GetHashCode ( ) => _key . GetHashCode ( ) ^ durationMicroseconds . GetHashCode ( ) ;
219247
220248 /// <inheritdoc/>
221249 public override bool Equals ( object ? obj )
222- => obj is MetricKeyCpu other && _key . Equals ( other . Key ) && MicroSeconds == other . MicroSeconds ;
250+ => obj is MetricKeyCpu other && _key . Equals ( other . Key ) && durationMicroseconds == DurationMicroseconds ;
223251 }
224252
225253 /// <summary>
0 commit comments