@@ -8,12 +8,13 @@ namespace NRedisStack.Tests.TimeSeries.TestAPI
8
8
{
9
9
public class TestMRange : AbstractNRedisStackTest , IDisposable
10
10
{
11
- private readonly string [ ] keys = { "MRANGE_TESTS_1" , "MRANGE_TESTS_2" } ;
11
+ private readonly string [ ] _keys = { "MRANGE_TESTS_1" , "MRANGE_TESTS_2" } ;
12
12
13
13
public TestMRange ( RedisFixture redisFixture ) : base ( redisFixture ) { }
14
14
15
- private List < TimeSeriesTuple > CreateData ( ITimeSeriesCommands ts , int timeBucket )
15
+ private List < TimeSeriesTuple > CreateData ( ITimeSeriesCommands ts , int timeBucket , string [ ] ? keys = null )
16
16
{
17
+ keys ??= _keys ;
17
18
var tuples = new List < TimeSeriesTuple > ( ) ;
18
19
19
20
for ( int i = 0 ; i < 10 ; i ++ )
@@ -36,17 +37,17 @@ public void TestSimpleMRange()
36
37
var ts = db . TS ( ) ;
37
38
TimeSeriesLabel label = new TimeSeriesLabel ( "MRANGEkey" , "MRANGEvalue" ) ;
38
39
var labels = new List < TimeSeriesLabel > { label } ;
39
- foreach ( string key in keys )
40
+ foreach ( string key in _keys )
40
41
{
41
42
ts . Create ( key , labels : labels ) ;
42
43
}
43
44
44
45
var tuples = CreateData ( ts , 50 ) ;
45
46
var results = ts . MRange ( "-" , "+" , new List < string > { "MRANGEkey=MRANGEvalue" } ) ;
46
- Assert . Equal ( keys . Length , results . Count ) ;
47
+ Assert . Equal ( _keys . Length , results . Count ) ;
47
48
for ( int i = 0 ; i < results . Count ; i ++ )
48
49
{
49
- Assert . Equal ( keys [ i ] , results [ i ] . key ) ;
50
+ Assert . Equal ( _keys [ i ] , results [ i ] . key ) ;
50
51
Assert . Equal ( 0 , results [ i ] . labels . Count ) ;
51
52
Assert . Equal ( tuples , results [ i ] . values ) ;
52
53
}
@@ -59,17 +60,17 @@ public void TestMRangeWithLabels()
59
60
var ts = db . TS ( ) ;
60
61
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeWithLabels" ) ;
61
62
var labels = new List < TimeSeriesLabel > { label } ;
62
- foreach ( string key in keys )
63
+ foreach ( string key in _keys )
63
64
{
64
65
ts . Create ( key , labels : labels ) ;
65
66
}
66
67
67
68
var tuples = CreateData ( ts , 50 ) ;
68
69
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 ) ;
70
71
for ( int i = 0 ; i < results . Count ; i ++ )
71
72
{
72
- Assert . Equal ( keys [ i ] , results [ i ] . key ) ;
73
+ Assert . Equal ( _keys [ i ] , results [ i ] . key ) ;
73
74
Assert . Equal ( labels , results [ i ] . labels ) ;
74
75
Assert . Equal ( tuples , results [ i ] . values ) ;
75
76
}
@@ -83,9 +84,9 @@ public void TestMRangeSelectLabels()
83
84
var ts = db . TS ( ) ;
84
85
TimeSeriesLabel label1 = new TimeSeriesLabel ( "key" , "MRangeSelectLabels" ) ;
85
86
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 ++ )
87
88
{
88
- ts . Create ( keys [ i ] , labels : new List < TimeSeriesLabel > { label1 , labels [ i ] } ) ;
89
+ ts . Create ( _keys [ i ] , labels : new List < TimeSeriesLabel > { label1 , labels [ i ] } ) ;
89
90
}
90
91
91
92
var tuples = CreateData ( ts , 50 ) ;
@@ -95,10 +96,10 @@ public void TestMRangeSelectLabels()
95
96
Assert . Equal ( "withLabels and selectLabels cannot be specified together." , ex . Message ) ;
96
97
97
98
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 ) ;
99
100
for ( int i = 0 ; i < results . Count ; i ++ )
100
101
{
101
- Assert . Equal ( keys [ i ] , results [ i ] . key ) ;
102
+ Assert . Equal ( _keys [ i ] , results [ i ] . key ) ;
102
103
Assert . Equal ( labels [ i ] , results [ i ] . labels [ 0 ] ) ;
103
104
Assert . Equal ( tuples , results [ i ] . values ) ;
104
105
}
@@ -112,11 +113,11 @@ public void TestMRangeFilter()
112
113
var ts = db . TS ( ) ;
113
114
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeFilter" ) ;
114
115
var labels = new List < TimeSeriesLabel > { label } ;
115
- ts . Create ( keys [ 0 ] , labels : labels ) ;
116
+ ts . Create ( _keys [ 0 ] , labels : labels ) ;
116
117
var tuples = CreateData ( ts , 50 ) ;
117
118
var results = ts . MRange ( "-" , "+" , new List < string > { "key=MRangeFilter" } ) ;
118
119
Assert . Equal ( 1 , results . Count ) ;
119
- Assert . Equal ( keys [ 0 ] , results [ 0 ] . key ) ;
120
+ Assert . Equal ( _keys [ 0 ] , results [ 0 ] . key ) ;
120
121
Assert . Equal ( 0 , results [ 0 ] . labels . Count ) ;
121
122
Assert . Equal ( tuples , results [ 0 ] . values ) ;
122
123
}
@@ -129,18 +130,18 @@ public void TestMRangeCount()
129
130
var ts = db . TS ( ) ;
130
131
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeCount" ) ;
131
132
var labels = new List < TimeSeriesLabel > { label } ;
132
- foreach ( string key in keys )
133
+ foreach ( string key in _keys )
133
134
{
134
135
ts . Create ( key , labels : labels ) ;
135
136
}
136
137
137
138
var tuples = CreateData ( ts , 50 ) ;
138
139
long count = 5 ;
139
140
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 ) ;
141
142
for ( int i = 0 ; i < results . Count ; i ++ )
142
143
{
143
- Assert . Equal ( keys [ i ] , results [ i ] . key ) ;
144
+ Assert . Equal ( _keys [ i ] , results [ i ] . key ) ;
144
145
Assert . Equal ( 0 , results [ i ] . labels . Count ) ;
145
146
Assert . Equal ( tuples . GetRange ( 0 , ( int ) count ) , results [ i ] . values ) ;
146
147
}
@@ -154,17 +155,17 @@ public void TestMRangeAggregation()
154
155
var ts = db . TS ( ) ;
155
156
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeAggregation" ) ;
156
157
var labels = new List < TimeSeriesLabel > { label } ;
157
- foreach ( string key in keys )
158
+ foreach ( string key in _keys )
158
159
{
159
160
ts . Create ( key , labels : labels ) ;
160
161
}
161
162
162
163
var tuples = CreateData ( ts , 50 ) ;
163
164
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 ) ;
165
166
for ( int i = 0 ; i < results . Count ; i ++ )
166
167
{
167
- Assert . Equal ( keys [ i ] , results [ i ] . key ) ;
168
+ Assert . Equal ( _keys [ i ] , results [ i ] . key ) ;
168
169
Assert . Equal ( 0 , results [ i ] . labels . Count ) ;
169
170
Assert . Equal ( tuples , results [ i ] . values ) ;
170
171
}
@@ -178,7 +179,7 @@ public void TestMRangeAlign()
178
179
var ts = db . TS ( ) ;
179
180
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeAlign" ) ;
180
181
var labels = new List < TimeSeriesLabel > { label } ;
181
- ts . Create ( keys [ 0 ] , labels : labels ) ;
182
+ ts . Create ( _keys [ 0 ] , labels : labels ) ;
182
183
CreateData ( ts , 50 ) ;
183
184
var expected = new List < TimeSeriesTuple > {
184
185
new TimeSeriesTuple ( 0 , 1 ) ,
@@ -187,7 +188,7 @@ public void TestMRangeAlign()
187
188
} ;
188
189
var results = ts . MRange ( 0 , "+" , new List < string > { "key=MRangeAlign" } , align : "-" , aggregation : TsAggregation . Count , timeBucket : 10 , count : 3 ) ;
189
190
Assert . Equal ( 1 , results . Count ) ;
190
- Assert . Equal ( keys [ 0 ] , results [ 0 ] . key ) ;
191
+ Assert . Equal ( _keys [ 0 ] , results [ 0 ] . key ) ;
191
192
Assert . Equal ( expected , results [ 0 ] . values ) ;
192
193
results = ts . MRange ( 1 , 500 , new List < string > { "key=MRangeAlign" } , align : "+" , aggregation : TsAggregation . Count , timeBucket : 10 , count : 1 ) ;
193
194
Assert . Equal ( expected [ 1 ] , results [ 0 ] . values [ 0 ] ) ;
@@ -201,7 +202,7 @@ public void TestMissingFilter()
201
202
var ts = db . TS ( ) ;
202
203
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MissingFilter" ) ;
203
204
var labels = new List < TimeSeriesLabel > { label } ;
204
- foreach ( string key in keys )
205
+ foreach ( string key in _keys )
205
206
{
206
207
ts . Create ( key , labels : labels ) ;
207
208
}
@@ -219,7 +220,7 @@ public void TestMissingTimeBucket()
219
220
var ts = db . TS ( ) ;
220
221
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MissingTimeBucket" ) ;
221
222
var labels = new List < TimeSeriesLabel > { label } ;
222
- foreach ( string key in keys )
223
+ foreach ( string key in _keys )
223
224
{
224
225
ts . Create ( key , labels : labels ) ;
225
226
}
@@ -235,22 +236,22 @@ public void TestMRangeGroupby()
235
236
IDatabase db = redisFixture . Redis . GetDatabase ( ) ;
236
237
db . Execute ( "FLUSHALL" ) ;
237
238
var ts = db . TS ( ) ;
238
- for ( int i = 0 ; i < keys . Length ; i ++ )
239
+ for ( int i = 0 ; i < _keys . Length ; i ++ )
239
240
{
240
241
var label1 = new TimeSeriesLabel ( "key" , "MRangeGroupby" ) ;
241
242
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 } ) ;
243
244
}
244
245
245
246
var tuples = CreateData ( ts , 50 ) ;
246
247
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 ) ;
248
249
for ( int i = 0 ; i < results . Count ; i ++ )
249
250
{
250
251
Assert . Equal ( "group=" + i , results [ i ] . key ) ;
251
252
Assert . Equal ( new TimeSeriesLabel ( "group" , i . ToString ( ) ) , results [ i ] . labels [ 0 ] ) ;
252
253
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 ] ) ;
254
255
Assert . Equal ( tuples , results [ i ] . values ) ;
255
256
}
256
257
}
@@ -261,7 +262,7 @@ public void TestMRangeReduce()
261
262
IDatabase db = redisFixture . Redis . GetDatabase ( ) ;
262
263
db . Execute ( "FLUSHALL" ) ;
263
264
var ts = db . TS ( ) ;
264
- foreach ( var key in keys )
265
+ foreach ( var key in _keys )
265
266
{
266
267
var label = new TimeSeriesLabel ( "key" , "MRangeReduce" ) ;
267
268
ts . Create ( key , labels : new List < TimeSeriesLabel > { label } ) ;
@@ -273,7 +274,7 @@ public void TestMRangeReduce()
273
274
Assert . Equal ( "key=MRangeReduce" , results [ 0 ] . key ) ;
274
275
Assert . Equal ( new TimeSeriesLabel ( "key" , "MRangeReduce" ) , results [ 0 ] . labels [ 0 ] ) ;
275
276
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 ] ) ;
277
278
for ( int i = 0 ; i < results [ 0 ] . values . Count ; i ++ )
278
279
{
279
280
Assert . Equal ( tuples [ i ] . Val * 2 , results [ 0 ] . values [ i ] . Val ) ;
@@ -288,7 +289,7 @@ public void TestMRangeFilterBy()
288
289
var ts = db . TS ( ) ;
289
290
TimeSeriesLabel label = new TimeSeriesLabel ( "key" , "MRangeFilterBy" ) ;
290
291
var labels = new List < TimeSeriesLabel > { label } ;
291
- foreach ( string key in keys )
292
+ foreach ( string key in _keys )
292
293
{
293
294
ts . Create ( key , labels : labels ) ;
294
295
}
@@ -306,5 +307,36 @@ public void TestMRangeFilterBy()
306
307
Assert . Equal ( tuples . GetRange ( 0 , 1 ) , results [ i ] . values ) ;
307
308
}
308
309
}
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
+ }
309
341
}
310
342
}
0 commit comments