Skip to content

Commit b725b9e

Browse files
authored
Adding LATEST arg support for TS.MRANGE (#236)
* Adding LATEST arg for TS.MRANGE Removing null check that was already being performed by helper method. Fixed LATEST argument not working in TS.MRANGE command calls. * Adding test for MRange latest args * Using var instead of collection index
1 parent cbbfaae commit b725b9e

File tree

2 files changed

+67
-35
lines changed

2 files changed

+67
-35
lines changed

src/NRedisStack/TimeSeries/TimeSeriesAux.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,9 @@ public static List<object> BuildRangeArgs(string key,
300300
TsBucketTimestamps? bt,
301301
bool empty)
302302
{
303-
var args = new List<object>()
304-
{key, fromTimeStamp.Value, toTimeStamp.Value};
303+
var args = new List<object>() { key, fromTimeStamp.Value, toTimeStamp.Value };
305304
args.AddLatest(latest);
306-
if (filterByTs != null) args.AddFilterByTs(filterByTs);
305+
args.AddFilterByTs(filterByTs);
307306
args.AddFilterByValue(filterByValue);
308307
args.AddCount(count);
309308
args.AddAggregation(align, aggregation, timeBucket, bt, empty);
@@ -328,6 +327,7 @@ public static List<object> BuildMultiRangeArgs(TimeStamp fromTimeStamp,
328327
(string, TsReduce)? groupbyTuple)
329328
{
330329
var args = new List<object>() { fromTimeStamp.Value, toTimeStamp.Value };
330+
args.AddLatest(latest);
331331
args.AddFilterByTs(filterByTs);
332332
args.AddFilterByValue(filterByValue);
333333
args.AddWithLabels(withLabels, selectLabels);
@@ -338,4 +338,4 @@ public static List<object> BuildMultiRangeArgs(TimeStamp fromTimeStamp,
338338
return args;
339339
}
340340
}
341-
}
341+
}

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestMRange.cs

+63-31
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ namespace NRedisStack.Tests.TimeSeries.TestAPI
88
{
99
public class TestMRange : AbstractNRedisStackTest, IDisposable
1010
{
11-
private readonly string[] keys = { "MRANGE_TESTS_1", "MRANGE_TESTS_2" };
11+
private readonly string[] _keys = { "MRANGE_TESTS_1", "MRANGE_TESTS_2" };
1212

1313
public TestMRange(RedisFixture redisFixture) : base(redisFixture) { }
1414

15-
private List<TimeSeriesTuple> CreateData(ITimeSeriesCommands ts, int timeBucket)
15+
private List<TimeSeriesTuple> CreateData(ITimeSeriesCommands ts, int timeBucket, string[]? keys = null)
1616
{
17+
keys ??= _keys;
1718
var tuples = new List<TimeSeriesTuple>();
1819

1920
for (int i = 0; i < 10; i++)
@@ -36,17 +37,17 @@ public void TestSimpleMRange()
3637
var ts = db.TS();
3738
TimeSeriesLabel label = new TimeSeriesLabel("MRANGEkey", "MRANGEvalue");
3839
var labels = new List<TimeSeriesLabel> { label };
39-
foreach (string key in keys)
40+
foreach (string key in _keys)
4041
{
4142
ts.Create(key, labels: labels);
4243
}
4344

4445
var tuples = CreateData(ts, 50);
4546
var results = ts.MRange("-", "+", new List<string> { "MRANGEkey=MRANGEvalue" });
46-
Assert.Equal(keys.Length, results.Count);
47+
Assert.Equal(_keys.Length, results.Count);
4748
for (int i = 0; i < results.Count; i++)
4849
{
49-
Assert.Equal(keys[i], results[i].key);
50+
Assert.Equal(_keys[i], results[i].key);
5051
Assert.Equal(0, results[i].labels.Count);
5152
Assert.Equal(tuples, results[i].values);
5253
}
@@ -59,17 +60,17 @@ public void TestMRangeWithLabels()
5960
var ts = db.TS();
6061
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeWithLabels");
6162
var labels = new List<TimeSeriesLabel> { label };
62-
foreach (string key in keys)
63+
foreach (string key in _keys)
6364
{
6465
ts.Create(key, labels: labels);
6566
}
6667

6768
var tuples = CreateData(ts, 50);
6869
var results = ts.MRange("-", "+", new List<string> { "key=MRangeWithLabels" }, withLabels: true);
69-
Assert.Equal(keys.Length, results.Count);
70+
Assert.Equal(_keys.Length, results.Count);
7071
for (int i = 0; i < results.Count; i++)
7172
{
72-
Assert.Equal(keys[i], results[i].key);
73+
Assert.Equal(_keys[i], results[i].key);
7374
Assert.Equal(labels, results[i].labels);
7475
Assert.Equal(tuples, results[i].values);
7576
}
@@ -83,9 +84,9 @@ public void TestMRangeSelectLabels()
8384
var ts = db.TS();
8485
TimeSeriesLabel label1 = new TimeSeriesLabel("key", "MRangeSelectLabels");
8586
TimeSeriesLabel[] labels = new TimeSeriesLabel[] { new TimeSeriesLabel("team", "CTO"), new TimeSeriesLabel("team", "AUT") };
86-
for (int i = 0; i < keys.Length; i++)
87+
for (int i = 0; i < _keys.Length; i++)
8788
{
88-
ts.Create(keys[i], labels: new List<TimeSeriesLabel> { label1, labels[i] });
89+
ts.Create(_keys[i], labels: new List<TimeSeriesLabel> { label1, labels[i] });
8990
}
9091

9192
var tuples = CreateData(ts, 50);
@@ -95,10 +96,10 @@ public void TestMRangeSelectLabels()
9596
Assert.Equal("withLabels and selectLabels cannot be specified together.", ex.Message);
9697

9798
var results = ts.MRange("-", "+", new List<string> { "key=MRangeSelectLabels" }, selectLabels: new List<string> { "team" });
98-
Assert.Equal(keys.Length, results.Count);
99+
Assert.Equal(_keys.Length, results.Count);
99100
for (int i = 0; i < results.Count; i++)
100101
{
101-
Assert.Equal(keys[i], results[i].key);
102+
Assert.Equal(_keys[i], results[i].key);
102103
Assert.Equal(labels[i], results[i].labels[0]);
103104
Assert.Equal(tuples, results[i].values);
104105
}
@@ -112,11 +113,11 @@ public void TestMRangeFilter()
112113
var ts = db.TS();
113114
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeFilter");
114115
var labels = new List<TimeSeriesLabel> { label };
115-
ts.Create(keys[0], labels: labels);
116+
ts.Create(_keys[0], labels: labels);
116117
var tuples = CreateData(ts, 50);
117118
var results = ts.MRange("-", "+", new List<string> { "key=MRangeFilter" });
118119
Assert.Equal(1, results.Count);
119-
Assert.Equal(keys[0], results[0].key);
120+
Assert.Equal(_keys[0], results[0].key);
120121
Assert.Equal(0, results[0].labels.Count);
121122
Assert.Equal(tuples, results[0].values);
122123
}
@@ -129,18 +130,18 @@ public void TestMRangeCount()
129130
var ts = db.TS();
130131
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeCount");
131132
var labels = new List<TimeSeriesLabel> { label };
132-
foreach (string key in keys)
133+
foreach (string key in _keys)
133134
{
134135
ts.Create(key, labels: labels);
135136
}
136137

137138
var tuples = CreateData(ts, 50);
138139
long count = 5;
139140
var results = ts.MRange("-", "+", new List<string> { "key=MRangeCount" }, count: count);
140-
Assert.Equal(keys.Length, results.Count);
141+
Assert.Equal(_keys.Length, results.Count);
141142
for (int i = 0; i < results.Count; i++)
142143
{
143-
Assert.Equal(keys[i], results[i].key);
144+
Assert.Equal(_keys[i], results[i].key);
144145
Assert.Equal(0, results[i].labels.Count);
145146
Assert.Equal(tuples.GetRange(0, (int)count), results[i].values);
146147
}
@@ -154,17 +155,17 @@ public void TestMRangeAggregation()
154155
var ts = db.TS();
155156
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeAggregation");
156157
var labels = new List<TimeSeriesLabel> { label };
157-
foreach (string key in keys)
158+
foreach (string key in _keys)
158159
{
159160
ts.Create(key, labels: labels);
160161
}
161162

162163
var tuples = CreateData(ts, 50);
163164
var results = ts.MRange("-", "+", new List<string> { "key=MRangeAggregation" }, aggregation: TsAggregation.Min, timeBucket: 50);
164-
Assert.Equal(keys.Length, results.Count);
165+
Assert.Equal(_keys.Length, results.Count);
165166
for (int i = 0; i < results.Count; i++)
166167
{
167-
Assert.Equal(keys[i], results[i].key);
168+
Assert.Equal(_keys[i], results[i].key);
168169
Assert.Equal(0, results[i].labels.Count);
169170
Assert.Equal(tuples, results[i].values);
170171
}
@@ -178,7 +179,7 @@ public void TestMRangeAlign()
178179
var ts = db.TS();
179180
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeAlign");
180181
var labels = new List<TimeSeriesLabel> { label };
181-
ts.Create(keys[0], labels: labels);
182+
ts.Create(_keys[0], labels: labels);
182183
CreateData(ts, 50);
183184
var expected = new List<TimeSeriesTuple> {
184185
new TimeSeriesTuple(0,1),
@@ -187,7 +188,7 @@ public void TestMRangeAlign()
187188
};
188189
var results = ts.MRange(0, "+", new List<string> { "key=MRangeAlign" }, align: "-", aggregation: TsAggregation.Count, timeBucket: 10, count: 3);
189190
Assert.Equal(1, results.Count);
190-
Assert.Equal(keys[0], results[0].key);
191+
Assert.Equal(_keys[0], results[0].key);
191192
Assert.Equal(expected, results[0].values);
192193
results = ts.MRange(1, 500, new List<string> { "key=MRangeAlign" }, align: "+", aggregation: TsAggregation.Count, timeBucket: 10, count: 1);
193194
Assert.Equal(expected[1], results[0].values[0]);
@@ -201,7 +202,7 @@ public void TestMissingFilter()
201202
var ts = db.TS();
202203
TimeSeriesLabel label = new TimeSeriesLabel("key", "MissingFilter");
203204
var labels = new List<TimeSeriesLabel> { label };
204-
foreach (string key in keys)
205+
foreach (string key in _keys)
205206
{
206207
ts.Create(key, labels: labels);
207208
}
@@ -219,7 +220,7 @@ public void TestMissingTimeBucket()
219220
var ts = db.TS();
220221
TimeSeriesLabel label = new TimeSeriesLabel("key", "MissingTimeBucket");
221222
var labels = new List<TimeSeriesLabel> { label };
222-
foreach (string key in keys)
223+
foreach (string key in _keys)
223224
{
224225
ts.Create(key, labels: labels);
225226
}
@@ -235,22 +236,22 @@ public void TestMRangeGroupby()
235236
IDatabase db = redisFixture.Redis.GetDatabase();
236237
db.Execute("FLUSHALL");
237238
var ts = db.TS();
238-
for (int i = 0; i < keys.Length; i++)
239+
for (int i = 0; i < _keys.Length; i++)
239240
{
240241
var label1 = new TimeSeriesLabel("key", "MRangeGroupby");
241242
var label2 = new TimeSeriesLabel("group", i.ToString());
242-
ts.Create(keys[i], labels: new List<TimeSeriesLabel> { label1, label2 });
243+
ts.Create(_keys[i], labels: new List<TimeSeriesLabel> { label1, label2 });
243244
}
244245

245246
var tuples = CreateData(ts, 50);
246247
var results = ts.MRange("-", "+", new List<string> { "key=MRangeGroupby" }, withLabels: true, groupbyTuple: ("group", TsReduce.Min));
247-
Assert.Equal(keys.Length, results.Count);
248+
Assert.Equal(_keys.Length, results.Count);
248249
for (int i = 0; i < results.Count; i++)
249250
{
250251
Assert.Equal("group=" + i, results[i].key);
251252
Assert.Equal(new TimeSeriesLabel("group", i.ToString()), results[i].labels[0]);
252253
Assert.Equal(new TimeSeriesLabel("__reducer__", "min"), results[i].labels[1]);
253-
Assert.Equal(new TimeSeriesLabel("__source__", keys[i]), results[i].labels[2]);
254+
Assert.Equal(new TimeSeriesLabel("__source__", _keys[i]), results[i].labels[2]);
254255
Assert.Equal(tuples, results[i].values);
255256
}
256257
}
@@ -261,7 +262,7 @@ public void TestMRangeReduce()
261262
IDatabase db = redisFixture.Redis.GetDatabase();
262263
db.Execute("FLUSHALL");
263264
var ts = db.TS();
264-
foreach (var key in keys)
265+
foreach (var key in _keys)
265266
{
266267
var label = new TimeSeriesLabel("key", "MRangeReduce");
267268
ts.Create(key, labels: new List<TimeSeriesLabel> { label });
@@ -273,7 +274,7 @@ public void TestMRangeReduce()
273274
Assert.Equal("key=MRangeReduce", results[0].key);
274275
Assert.Equal(new TimeSeriesLabel("key", "MRangeReduce"), results[0].labels[0]);
275276
Assert.Equal(new TimeSeriesLabel("__reducer__", "sum"), results[0].labels[1]);
276-
Assert.Equal(new TimeSeriesLabel("__source__", string.Join(",", keys)), results[0].labels[2]);
277+
Assert.Equal(new TimeSeriesLabel("__source__", string.Join(",", _keys)), results[0].labels[2]);
277278
for (int i = 0; i < results[0].values.Count; i++)
278279
{
279280
Assert.Equal(tuples[i].Val * 2, results[0].values[i].Val);
@@ -288,7 +289,7 @@ public void TestMRangeFilterBy()
288289
var ts = db.TS();
289290
TimeSeriesLabel label = new TimeSeriesLabel("key", "MRangeFilterBy");
290291
var labels = new List<TimeSeriesLabel> { label };
291-
foreach (string key in keys)
292+
foreach (string key in _keys)
292293
{
293294
ts.Create(key, labels: labels);
294295
}
@@ -306,5 +307,36 @@ public void TestMRangeFilterBy()
306307
Assert.Equal(tuples.GetRange(0, 1), results[i].values);
307308
}
308309
}
310+
311+
[SkipIfRedis(Is.OSSCluster)]
312+
public void TestMRangeLatest()
313+
{
314+
IDatabase db = redisFixture.Redis.GetDatabase();
315+
db.Execute("FLUSHALL");
316+
var ts = db.TS();
317+
var label = new TimeSeriesLabel("key", "MRangeLatest");
318+
var compactedLabel = new TimeSeriesLabel("compact", "true");
319+
string primaryTsKey = _keys[0], compactedTsKey = _keys[1];
320+
var compactionRule = new TimeSeriesRule(
321+
compactedTsKey,
322+
(long)TimeSpan.FromHours(1).TotalMilliseconds, // 1h used to force partial bucket
323+
TsAggregation.Sum);
324+
325+
ts.Create(primaryTsKey, labels: [label]);
326+
ts.Create(compactedTsKey, labels: [label, compactedLabel]);
327+
ts.CreateRule(primaryTsKey, compactionRule);
328+
var tuples = CreateData(ts, 50, [primaryTsKey]);
329+
330+
var results = ts.MRange("-", "+", ["key=MRangeLatest", "compact=true"], latest: true);
331+
Assert.Single(results);
332+
Assert.Equal(compactedTsKey, results[0].key);
333+
Assert.NotEmpty(results[0].values);
334+
Assert.Equal(tuples.Sum(x => x.Val), results[0].values.Sum(x => x.Val));
335+
336+
results = ts.MRange("-", "+", ["key=MRangeLatest", "compact=true"], latest: false);
337+
Assert.Single(results);
338+
Assert.Equal(compactedTsKey, results[0].key);
339+
Assert.Empty(results[0].values);
340+
}
309341
}
310342
}

0 commit comments

Comments
 (0)