Skip to content

Commit 4b31156

Browse files
author
Cristian Levcovici
committed
Add ResourceTimeRange.
1 parent 4c8247b commit 4b31156

File tree

4 files changed

+736
-1
lines changed

4 files changed

+736
-1
lines changed

src/Microsoft.Performance.SDK/Processing/Projection/ClipTimeToVisibleDomainProjection.cs

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,36 @@ public static IProjection<int, TimeRange> Create(IProjection<int, TimeRange> tim
7373
return (IProjection<int, TimeRange>)instance;
7474
}
7575

76+
/// <summary>
77+
/// Create a <see cref="ResourceTimeRange"/> projection that is clipped to a
78+
/// <see cref="VisibleDomainRegionContainer"/>.
79+
/// See also <seealso cref="IVisibleDomainSensitiveProjection"/>.
80+
/// </summary>
81+
/// <param name="resourceTimeRangeProjection">
82+
/// Original projection.
83+
/// </param>
84+
/// <returns>
85+
/// A visible domain sensitive projection.
86+
/// </returns>
87+
public static IProjection<int, ResourceTimeRange> Create(IProjection<int, ResourceTimeRange> resourceTimeRangeProjection)
88+
{
89+
Guard.NotNull(resourceTimeRangeProjection, nameof(resourceTimeRangeProjection));
90+
91+
var typeArgs = new[]
92+
{
93+
resourceTimeRangeProjection.GetType(),
94+
};
95+
96+
var constructorArgs = new object[]
97+
{
98+
resourceTimeRangeProjection,
99+
};
100+
101+
var type = typeof(ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator<>).MakeGenericType(typeArgs);
102+
var instance = Activator.CreateInstance(type, constructorArgs);
103+
return (IProjection<int, ResourceTimeRange>)instance;
104+
}
105+
76106
/// <summary>
77107
/// Creates a new percent projection that is defined by the current viewport.
78108
/// </summary>
@@ -101,6 +131,34 @@ public static IProjection<int, TimeRange> CreatePercent(IProjection<int, TimeRan
101131
return (IProjection<int, TimeRange>)instance;
102132
}
103133

134+
/// <summary>
135+
/// Creates a new percent projection that is defined by the current viewport.
136+
/// </summary>
137+
/// <param name="resourceTimeRangeColumn">
138+
/// Original projection.
139+
/// </param>
140+
/// <returns>
141+
/// A viewport sensitive projection.
142+
/// </returns>
143+
public static IProjection<int, ResourceTimeRange> CreatePercent(IProjection<int, ResourceTimeRange> resourceTimeRangeColumn)
144+
{
145+
Guard.NotNull(resourceTimeRangeColumn, nameof(resourceTimeRangeColumn));
146+
147+
var typeArgs = new[]
148+
{
149+
resourceTimeRangeColumn.GetType(),
150+
};
151+
152+
var constructorArgs = new object[]
153+
{
154+
resourceTimeRangeColumn,
155+
};
156+
157+
var type = typeof(ClipTimeToVisibleResourceTimeRangePercentColumnGenerator<>).MakeGenericType(typeArgs);
158+
var instance = Activator.CreateInstance(type, constructorArgs);
159+
return (IProjection<int, ResourceTimeRange>)instance;
160+
}
161+
104162
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
105163
private struct ClipTimeToVisibleTimestampDomainColumnGenerator<TGenerator>
106164
: IProjection<int, Timestamp>,
@@ -228,6 +286,72 @@ public bool NotifyVisibleDomainChanged(IVisibleDomainRegion visibleDomain)
228286
public bool DependsOnVisibleDomain => true;
229287
}
230288

289+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
290+
private struct ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator<TGenerator>
291+
: IProjection<int, ResourceTimeRange>,
292+
IVisibleDomainSensitiveProjection
293+
where TGenerator : IProjection<int, ResourceTimeRange>
294+
{
295+
internal TGenerator Generator { get; }
296+
297+
internal VisibleDomainRegionContainer VisibleDomainContainer { get; }
298+
299+
public ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator(TGenerator resourceTimeRangeGenerator)
300+
{
301+
this.Generator = resourceTimeRangeGenerator;
302+
this.VisibleDomainContainer = new VisibleDomainRegionContainer();
303+
}
304+
305+
// IProjection<int, Timestamp>
306+
public ResourceTimeRange this[int value]
307+
{
308+
get
309+
{
310+
TimeRange visibleDomain = this.VisibleDomainContainer.VisibleDomain;
311+
312+
ResourceTimeRange resourceTimeRange = this.Generator[value];
313+
314+
resourceTimeRange.StartTime = ClipTimestampToVisibleDomain(resourceTimeRange.StartTime, visibleDomain);
315+
resourceTimeRange.EndTime = ClipTimestampToVisibleDomain(resourceTimeRange.EndTime, visibleDomain);
316+
317+
return resourceTimeRange;
318+
}
319+
}
320+
321+
public Type SourceType
322+
{
323+
get
324+
{
325+
return typeof(int);
326+
}
327+
}
328+
329+
public Type ResultType
330+
{
331+
get
332+
{
333+
return typeof(ResourceTimeRange);
334+
}
335+
}
336+
337+
public object Clone()
338+
{
339+
var result = new ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator<TGenerator>(
340+
VisibleDomainSensitiveProjection.CloneIfVisibleDomainSensitive(this.Generator));
341+
return result;
342+
}
343+
344+
345+
public bool NotifyVisibleDomainChanged(IVisibleDomainRegion visibleDomain)
346+
{
347+
this.VisibleDomainContainer.VisibleDomainRegion = visibleDomain;
348+
VisibleDomainSensitiveProjection.NotifyVisibleDomainChanged(this.Generator, visibleDomain);
349+
return true;
350+
}
351+
352+
public bool DependsOnVisibleDomain => true;
353+
}
354+
231355
private struct ClipTimeToVisibleTimeRangePercentColumnGenerator<TGenerator>
232356
: IProjection<int, TimeRange>,
233357
IVisibleDomainSensitiveProjection,
@@ -319,6 +443,98 @@ public string Format(string format, object arg, IFormatProvider formatProvider)
319443
}
320444
}
321445
}
446+
447+
private struct ClipTimeToVisibleResourceTimeRangePercentColumnGenerator<TGenerator>
448+
: IProjection<int, ResourceTimeRange>,
449+
IVisibleDomainSensitiveProjection,
450+
IFormatProvider
451+
where TGenerator : IProjection<int, ResourceTimeRange>
452+
{
453+
private readonly ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator<TGenerator> resourceTimeRangeColumnGenerator;
454+
455+
// IFormatProvider returns an object - cannot return 'this' struct.
456+
// So implement ICustomFormatter in a private class and return that object.
457+
//
458+
private readonly ClipTimeToVisibleResourceTimeRangePercentFormatProvider customFormatter;
459+
460+
public ClipTimeToVisibleResourceTimeRangePercentColumnGenerator(TGenerator timeRangeGenerator)
461+
{
462+
var internalGenerator = new ClipTimeToVisibleResourceTimeRangeDomainColumnGenerator<TGenerator>(timeRangeGenerator);
463+
this.resourceTimeRangeColumnGenerator = internalGenerator;
464+
465+
this.customFormatter =
466+
new ClipTimeToVisibleResourceTimeRangePercentFormatProvider(() => internalGenerator.VisibleDomainContainer.VisibleDomain.Duration);
467+
}
468+
469+
public ResourceTimeRange this[int value] => this.resourceTimeRangeColumnGenerator[value];
470+
471+
public Type SourceType => typeof(int);
472+
473+
public Type ResultType => typeof(ResourceTimeRange);
474+
475+
public bool DependsOnVisibleDomain => true;
476+
477+
public object GetFormat(Type formatType)
478+
{
479+
return (formatType == typeof(ResourceTimeRange) ||
480+
formatType == typeof(TimestampDelta)) ? this.customFormatter : null;
481+
}
482+
483+
public object Clone()
484+
{
485+
var result = new ClipTimeToVisibleResourceTimeRangePercentColumnGenerator<TGenerator>(
486+
VisibleDomainSensitiveProjection.CloneIfVisibleDomainSensitive(this.resourceTimeRangeColumnGenerator.Generator));
487+
return result;
488+
}
489+
490+
public bool NotifyVisibleDomainChanged(IVisibleDomainRegion visibleDomain)
491+
{
492+
this.resourceTimeRangeColumnGenerator.NotifyVisibleDomainChanged(visibleDomain);
493+
return true;
494+
}
495+
496+
private class ClipTimeToVisibleResourceTimeRangePercentFormatProvider
497+
: ICustomFormatter
498+
{
499+
private readonly Func<TimestampDelta> getVisibleDomainDuration;
500+
501+
public ClipTimeToVisibleResourceTimeRangePercentFormatProvider(Func<TimestampDelta> getVisibleDomainDuration)
502+
{
503+
Guard.NotNull(getVisibleDomainDuration, nameof(getVisibleDomainDuration));
504+
505+
this.getVisibleDomainDuration = getVisibleDomainDuration;
506+
}
507+
508+
public string Format(string format, object arg, IFormatProvider formatProvider)
509+
{
510+
if (arg == null)
511+
{
512+
return string.Empty;
513+
}
514+
515+
TimestampDelta numerator;
516+
if (arg is ResourceTimeRange)
517+
{
518+
numerator = ((ResourceTimeRange)arg).Duration;
519+
}
520+
else if (arg is TimestampDelta)
521+
{
522+
numerator = (TimestampDelta)arg;
523+
}
524+
else
525+
{
526+
throw new FormatException();
527+
}
528+
529+
TimestampDelta visibleDomainDuration = getVisibleDomainDuration();
530+
double percent = (visibleDomainDuration != TimestampDelta.Zero) ?
531+
(100.0 * ((double)numerator.ToNanoseconds) / (visibleDomainDuration.ToNanoseconds)) :
532+
100.0;
533+
534+
return percent.ToString(format, formatProvider);
535+
}
536+
}
537+
}
322538
}
323539
}
324540
}

0 commit comments

Comments
 (0)