Skip to content

Commit 1d665df

Browse files
committed
Implemented resample method
1 parent e8f0bbd commit 1d665df

File tree

11 files changed

+106
-70
lines changed

11 files changed

+106
-70
lines changed

ManagedCode.TimeSeries.Tests/TimeSeriesTests.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public async Task AccumulatorLimit()
6969
series.AddNewData(i);
7070
}
7171

72-
series.SamplesCount.Should().Be(10);
72+
series.Samples.Count.Should().Be(10);
7373
}
7474

7575
[Fact]
@@ -119,12 +119,12 @@ public async Task AccumulatorMerge()
119119

120120
await Task.WhenAll(seriesA, seriesB);
121121

122-
seriesA.Result.SamplesCount.Should().Be(10);
123-
seriesB.Result.SamplesCount.Should().Be(10);
122+
seriesA.Result.Samples.Count.Should().Be(10);
123+
seriesB.Result.Samples.Count.Should().Be(10);
124124

125125
seriesA.Result.Merge(seriesB.Result);
126126

127-
seriesA.Result.SamplesCount.Should().Be(10);
127+
seriesA.Result.Samples.Count.Should().Be(10);
128128

129129
var seriesList = new List<IntTimeSeriesAccumulator>();
130130
seriesList.Add(await FillFunc());
@@ -145,7 +145,7 @@ public async Task AccumulatorMerge()
145145
}
146146
}
147147

148-
onlineExpertsPerHourTimeSeries.SamplesCount.Should().Be(10);
148+
onlineExpertsPerHourTimeSeries.Samples.Count.Should().Be(10);
149149
}
150150

151151
[Fact]
@@ -247,6 +247,38 @@ public async Task SummerMerge()
247247
seriesA.Result.Samples.Select(s => s.Value).Sum().Should().Be(200);
248248
}
249249

250+
[Fact]
251+
public async Task Resample()
252+
{
253+
var seriesFeature = new IntTimeSeriesAccumulator(TimeSpan.FromMilliseconds(2), 100);
254+
255+
for (var i = 0; i < 100; i++)
256+
{
257+
seriesFeature.AddNewData(i);
258+
259+
await Task.Delay(1);
260+
}
261+
262+
seriesFeature.Resample(TimeSpan.FromMilliseconds(4), 100);
263+
var sad = seriesFeature;
264+
}
265+
266+
[Fact]
267+
public async Task ResampleSummer()
268+
{
269+
var seriesFeature = new IntTimeSeriesSummer(TimeSpan.FromMilliseconds(2), 100);
270+
271+
for (var i = 0; i < 100; i++)
272+
{
273+
seriesFeature.AddNewData(i);
274+
275+
await Task.Delay(1);
276+
}
277+
278+
seriesFeature.Resample(TimeSpan.FromMilliseconds(4), 100);
279+
}
280+
281+
250282
[Fact]
251283
public void MarkupAllSamples()
252284
{

ManagedCode.TimeSeries/Abstractions/BaseTimeSeries.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,39 @@ namespace ManagedCode.TimeSeries.Abstractions;
66
public abstract class BaseTimeSeries<T, TSample, TSelf> : ITimeSeries<T, TSample, TSelf> where TSelf : ITimeSeries<T, TSample, TSelf>
77
{
88
private const int DefaultSampleCount = 100;
9-
private readonly int _samplesCount;
109
protected object _sync = new();
1110

12-
protected BaseTimeSeries(TimeSpan sampleInterval, int samplesCount)
11+
protected BaseTimeSeries(TimeSpan sampleInterval, int maxSamplesCount)
1312
{
14-
_samplesCount = samplesCount;
13+
MaxSamplesCount = maxSamplesCount;
1514
SampleInterval = sampleInterval;
1615
Start = DateTimeOffset.UtcNow.Round(SampleInterval);
1716
End = Start;
1817
}
1918

20-
protected BaseTimeSeries(TimeSpan sampleInterval, int samplesCount, DateTimeOffset start, DateTimeOffset end, DateTimeOffset lastDate)
19+
protected BaseTimeSeries(TimeSpan sampleInterval, int maxSamplesCount, DateTimeOffset start, DateTimeOffset end, DateTimeOffset lastDate)
2120
{
22-
_samplesCount = samplesCount;
21+
MaxSamplesCount = maxSamplesCount;
2322
SampleInterval = sampleInterval;
2423
Start = start.Round(SampleInterval);
2524
End = end.Round(SampleInterval);
2625
LastDate = lastDate;
2726
}
2827

29-
public Dictionary<DateTimeOffset, TSample> Samples { get; } = new();
28+
public Dictionary<DateTimeOffset, TSample> Samples { get; protected set; } = new();
3029
public DateTimeOffset Start { get; }
3130
public DateTimeOffset End { get; protected set; }
32-
public TimeSpan SampleInterval { get; }
31+
32+
public TimeSpan SampleInterval { get; protected set; }
33+
public int MaxSamplesCount { get; protected set; }
3334

3435
public DateTimeOffset LastDate { get; protected set; }
3536

36-
public int SamplesCount => Samples.Count;
3737
public ulong DataCount { get; protected set; }
3838

39-
public bool IsFull => Samples.Count >= _samplesCount;
39+
public bool IsFull => Samples.Count >= MaxSamplesCount;
4040
public bool IsEmpty => Samples.Count == 0;
41-
public bool IsOverflow => Samples.Count > _samplesCount;
41+
public bool IsOverflow => Samples.Count > MaxSamplesCount;
4242

4343
public void AddNewData(T data)
4444
{
@@ -67,7 +67,7 @@ protected void CheckSamplesSize()
6767
{
6868
lock (_sync)
6969
{
70-
if (_samplesCount <= 0)
70+
if (MaxSamplesCount <= 0)
7171
{
7272
return;
7373
}
@@ -81,7 +81,7 @@ protected void CheckSamplesSize()
8181

8282
public void MarkupAllSamples(MarkupDirection direction = MarkupDirection.Past)
8383
{
84-
var samples = _samplesCount > 0 ? _samplesCount : DefaultSampleCount;
84+
var samples = MaxSamplesCount > 0 ? MaxSamplesCount : DefaultSampleCount;
8585

8686
if (direction is MarkupDirection.Past or MarkupDirection.Feature)
8787
{
@@ -126,7 +126,7 @@ public void MarkupAllSamples(MarkupDirection direction = MarkupDirection.Past)
126126
public void DeleteOverdueSamples()
127127
{
128128
var dateTime = DateTimeOffset.UtcNow.Round(SampleInterval);
129-
for (int i = 0; i < _samplesCount; i++)
129+
for (int i = 0; i < MaxSamplesCount; i++)
130130
{
131131
dateTime = dateTime.Subtract(SampleInterval);
132132
}
@@ -145,8 +145,7 @@ public void DeleteOverdueSamples()
145145

146146
public TSelf PureMerge(IEnumerable<TSelf> accumulators)
147147
{
148-
var empty = Activator.CreateInstance<TSelf>();
149-
empty.Resample(SampleInterval, SamplesCount);
148+
var empty = (TSelf) Activator.CreateInstance(typeof(TSelf), SampleInterval, MaxSamplesCount)!;
150149

151150
foreach (var accumulator in accumulators)
152151
{
@@ -166,8 +165,7 @@ public void Merge(IEnumerable<TSelf> accumulators)
166165

167166
public TSelf PureMerge(TSelf accumulator)
168167
{
169-
var empty = Activator.CreateInstance<TSelf>();
170-
empty.Resample(SampleInterval, SamplesCount);
168+
var empty = (TSelf) Activator.CreateInstance(typeof(TSelf), SampleInterval, MaxSamplesCount)!;
171169
empty.Merge(accumulator);
172170

173171
return empty;
@@ -180,10 +178,4 @@ public TSelf PureMerge(TSelf accumulator)
180178

181179
[MethodImpl(MethodImplOptions.AggressiveInlining)]
182180
public abstract void Merge(TSelf accumulator);
183-
184-
185-
public virtual void Dispose()
186-
{
187-
//skip
188-
}
189181
}

ManagedCode.TimeSeries/Abstractions/BaseTimeSeriesAccumulator.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
using ManagedCode.TimeSeries.Extensions;
2+
13
namespace ManagedCode.TimeSeries.Abstractions;
24

35
public abstract class BaseTimeSeriesAccumulator<T, TSelf> : BaseTimeSeries<T, Queue<T>, TSelf> where TSelf : ITimeSeries<T, Queue<T>, TSelf>
46
{
5-
protected BaseTimeSeriesAccumulator(TimeSpan sampleInterval, int samplesCount) : base(sampleInterval, samplesCount)
7+
protected BaseTimeSeriesAccumulator(TimeSpan sampleInterval, int maxSamplesCount) : base(sampleInterval, maxSamplesCount)
68
{
79
}
810

9-
protected BaseTimeSeriesAccumulator(TimeSpan sampleInterval, int samplesCount, DateTimeOffset start, DateTimeOffset end, DateTimeOffset lastDate)
10-
: base(sampleInterval, samplesCount, start, end, lastDate)
11+
protected BaseTimeSeriesAccumulator(TimeSpan sampleInterval, int maxSamplesCount, DateTimeOffset start, DateTimeOffset end,
12+
DateTimeOffset lastDate)
13+
: base(sampleInterval, maxSamplesCount, start, end, lastDate)
1114
{
1215
}
1316

@@ -77,6 +80,24 @@ public override void Merge(TSelf accumulator)
7780

7881
public override void Resample(TimeSpan sampleInterval, int samplesCount)
7982
{
80-
// throw new NotImplementedException();
83+
if (sampleInterval <= SampleInterval)
84+
{
85+
throw new InvalidOperationException();
86+
}
87+
88+
SampleInterval = sampleInterval;
89+
MaxSamplesCount = samplesCount;
90+
91+
var samples = Samples;
92+
93+
Samples = new Dictionary<DateTimeOffset, Queue<T>>();
94+
95+
foreach (var (key, value) in samples)
96+
{
97+
foreach (var v in value)
98+
{
99+
AddNewData(key, v);
100+
}
101+
}
81102
}
82103
}

ManagedCode.TimeSeries/Abstractions/BaseTimeSeriesSummer.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public abstract class BaseTimeSeriesSummer<TNumber, TSelf> : BaseTimeSeries<TNum
1616
{
1717
private readonly Strategy _strategy;
1818

19-
protected BaseTimeSeriesSummer(TimeSpan sampleInterval, int samplesCount, Strategy strategy) : base(sampleInterval, samplesCount)
19+
protected BaseTimeSeriesSummer(TimeSpan sampleInterval, int maxSamplesCount, Strategy strategy) : base(sampleInterval, maxSamplesCount)
2020
{
2121
_strategy = strategy;
2222
}
@@ -51,7 +51,22 @@ public override void Merge(TSelf accumulator)
5151

5252
public override void Resample(TimeSpan sampleInterval, int samplesCount)
5353
{
54-
// throw new NotImplementedException();
54+
if (sampleInterval <= SampleInterval)
55+
{
56+
throw new InvalidOperationException();
57+
}
58+
59+
SampleInterval = sampleInterval;
60+
MaxSamplesCount = samplesCount;
61+
62+
var samples = Samples;
63+
64+
Samples = new Dictionary<DateTimeOffset, TNumber>();
65+
66+
foreach (var (key, value) in samples)
67+
{
68+
AddNewData(key, value);
69+
}
5570
}
5671

5772
private TNumber Update(TNumber left, TNumber right)

ManagedCode.TimeSeries/Abstractions/ITimeSeries.cs

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public interface ITimeSeries<in T, TSample, TSelf> : ITimeSeries<TSample>
66
where TSelf : ITimeSeries<T, TSample, TSelf>
77
{
88
void Resample(TimeSpan sampleInterval, int samplesCount);
9-
9+
1010
void AddNewData(T data);
1111

1212
void Merge(TSelf accumulator);
@@ -18,40 +18,16 @@ public interface ITimeSeries<in T, TSample, TSelf> : ITimeSeries<TSample>
1818

1919
[Pure]
2020
TSelf PureMerge(TSelf accumulator);
21-
22-
23-
[Pure]
24-
static virtual TSelf operator +(TSelf series, TSelf right)
25-
{
26-
return series.PureMerge(right);
27-
}
28-
29-
static virtual TSelf operator checked +(TSelf series, TSelf right)
30-
{
31-
return series + right;
32-
}
33-
34-
// static virtual ITimeSeries<T, TSample> operator +(ITimeSeries<T, TSample> series, T value)
35-
// {
36-
// series.AddNewData(value);
37-
//
38-
// return series;
39-
// }
40-
41-
// static virtual ITimeSeries<T, TSample> operator checked +(ITimeSeries<T, TSample> series, T value)
42-
// {
43-
// return series + value;
44-
// }
4521
}
4622

47-
public interface ITimeSeries<TSample> : IDisposable
23+
public interface ITimeSeries<TSample>
4824
{
4925
public Dictionary<DateTimeOffset, TSample> Samples { get; }
5026
public DateTimeOffset Start { get; }
5127
public DateTimeOffset End { get; }
5228
public DateTimeOffset LastDate { get; }
5329
public TimeSpan SampleInterval { get; }
54-
public int SamplesCount { get; }
30+
public int MaxSamplesCount { get; }
5531
public ulong DataCount { get; }
5632
public bool IsFull { get; }
5733
public bool IsEmpty { get; }

ManagedCode.TimeSeries/Accumulators/DoubleTimeSeriesAccumulator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ManagedCode.TimeSeries.Accumulators;
44

55
public class DoubleTimeSeriesAccumulator : BaseTimeSeriesAccumulator<double, DoubleTimeSeriesAccumulator>
66
{
7-
public DoubleTimeSeriesAccumulator(TimeSpan sampleInterval, int samplesCount = 0) : base(sampleInterval, samplesCount)
7+
public DoubleTimeSeriesAccumulator(TimeSpan sampleInterval, int maxSamplesCount = 0) : base(sampleInterval, maxSamplesCount)
88
{
99
}
1010
}

ManagedCode.TimeSeries/Accumulators/FloatTimeSeriesAccumulator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ManagedCode.TimeSeries.Accumulators;
44

55
public class FloatTimeSeriesAccumulator : BaseTimeSeriesAccumulator<float, FloatTimeSeriesAccumulator>
66
{
7-
public FloatTimeSeriesAccumulator(TimeSpan sampleInterval, int samplesCount = 0) : base(sampleInterval, samplesCount)
7+
public FloatTimeSeriesAccumulator(TimeSpan sampleInterval, int maxSamplesCount = 0) : base(sampleInterval, maxSamplesCount)
88
{
99
}
1010
}

ManagedCode.TimeSeries/Accumulators/IntTimeSeriesAccumulator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ManagedCode.TimeSeries.Accumulators;
44

55
public class IntTimeSeriesAccumulator : BaseTimeSeriesAccumulator<int, IntTimeSeriesAccumulator>
66
{
7-
public IntTimeSeriesAccumulator(TimeSpan sampleInterval, int samplesCount = 0) : base(sampleInterval, samplesCount)
7+
public IntTimeSeriesAccumulator(TimeSpan sampleInterval, int maxSamplesCount = 0) : base(sampleInterval, maxSamplesCount)
88
{
99
}
1010
}

ManagedCode.TimeSeries/Summers/DoubleTimeSeriesSummer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ namespace ManagedCode.TimeSeries.Summers;
44

55
public class DoubleTimeSeriesSummer : BaseTimeSeriesSummer<double, DoubleTimeSeriesSummer>
66
{
7-
public DoubleTimeSeriesSummer(TimeSpan sampleInterval, int samplesCount, Strategy strategy) : base(sampleInterval, samplesCount, strategy)
7+
public DoubleTimeSeriesSummer(TimeSpan sampleInterval, int maxSamplesCount, Strategy strategy) : base(sampleInterval, maxSamplesCount, strategy)
88
{
99
}
1010

11-
public DoubleTimeSeriesSummer(TimeSpan sampleInterval, int samplesCount) : base(sampleInterval, samplesCount, Strategy.Sum)
11+
public DoubleTimeSeriesSummer(TimeSpan sampleInterval, int maxSamplesCount) : base(sampleInterval, maxSamplesCount, Strategy.Sum)
1212
{
1313
}
1414

ManagedCode.TimeSeries/Summers/FloatTimeSeriesSummer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ namespace ManagedCode.TimeSeries.Summers;
44

55
public class FloatTimeSeriesSummer : BaseTimeSeriesSummer<float, FloatTimeSeriesSummer>
66
{
7-
public FloatTimeSeriesSummer(TimeSpan sampleInterval, int samplesCount, Strategy strategy) : base(sampleInterval, samplesCount, strategy)
7+
public FloatTimeSeriesSummer(TimeSpan sampleInterval, int maxSamplesCount, Strategy strategy) : base(sampleInterval, maxSamplesCount, strategy)
88
{
99
}
1010

11-
public FloatTimeSeriesSummer(TimeSpan sampleInterval, int samplesCount) : base(sampleInterval, samplesCount, Strategy.Sum)
11+
public FloatTimeSeriesSummer(TimeSpan sampleInterval, int maxSamplesCount) : base(sampleInterval, maxSamplesCount, Strategy.Sum)
1212
{
1313
}
1414

0 commit comments

Comments
 (0)