Skip to content
This repository was archived by the owner on Jan 24, 2023. It is now read-only.

Commit 9dec6a0

Browse files
author
Ariel Shtul
authored
Add COUNT + WITHLABELS options for MRANGE (#37)
* count + withlabels options * None -> True * per review
1 parent ace2c73 commit 9dec6a0

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

redistimeseries/client.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,22 @@ def __init__(self, *args, **kwargs):
109109
def appendRetention(params, retention):
110110
if retention is not None:
111111
params.extend(['RETENTION', retention])
112-
112+
113113
@staticmethod
114114
def appendLabels(params, labels):
115115
if labels:
116116
params.append('LABELS')
117117
for k, v in labels.items():
118118
params.extend([k,v])
119+
120+
@staticmethod
121+
def appendCount(params, count):
122+
if count is not None:
123+
params.extend(['COUNT', count])
119124

120125
@staticmethod
121126
def appendAggregation(params, aggregation_type,
122-
bucket_size_msec):
127+
bucket_size_msec):
123128
params.append('AGGREGATION')
124129
params.extend([aggregation_type, bucket_size_msec])
125130

@@ -218,32 +223,39 @@ def deleterule(self, source_key, dest_key):
218223
"""Deletes a compaction rule"""
219224
return self.execute_command(self.DELETERULE_CMD, source_key, dest_key)
220225

221-
def range(self, key, from_time, to_time,
226+
def range(self, key, from_time, to_time, count=None,
222227
aggregation_type=None, bucket_size_msec=0):
223228
"""
224229
Query a range from ``key``, from ``from_time`` to ``to_time``.
230+
``count`` limits the number of results.
225231
Can Aggregate for ``bucket_size_msec`` where an ``aggregation_type``
226232
can be ['avg', 'sum', 'min', 'max', 'range', 'count', 'first',
227233
'last', 'std.p', 'std.s', 'var.p', 'var.s']
228234
"""
229235
params = [key, from_time, to_time]
230-
if aggregation_type != None:
236+
self.appendCount(params, count)
237+
if aggregation_type is not None:
231238
self.appendAggregation(params, aggregation_type, bucket_size_msec)
232239

233240
return self.execute_command(self.RANGE_CMD, *params)
234241

235-
def mrange(self, from_time, to_time, filters,
236-
aggregation_type=None, bucket_size_msec=0):
242+
def mrange(self, from_time, to_time, filters, count=None,
243+
aggregation_type=None, bucket_size_msec=0, with_labels=False):
237244
"""
238245
Query a range based on filters,retention_msecs from ``from_time`` to ``to_time``.
246+
``count`` limits the number of results.
239247
``filters`` are a list strings such as ['Test=This'].
240248
Can Aggregate for ``bucket_size_msec`` where an ``aggregation_type``
241249
can be ['avg', 'sum', 'min', 'max', 'range', 'count', 'first',
242250
'last', 'std.p', 'std.s', 'var.p', 'var.s']
251+
``WITHLABELS`` appends labels to results.
243252
"""
244253
params = [from_time, to_time]
245-
if aggregation_type != None:
254+
self.appendCount(params, count)
255+
if aggregation_type is not None:
246256
self.appendAggregation(params, aggregation_type, bucket_size_msec)
257+
if with_labels:
258+
params.extend(['WITHLABELS'])
247259
params.extend(['FILTER'])
248260
params += filters
249261
return self.execute_command(self.MRANGE_CMD, *params)

test_commands.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def testAlter(self):
3737
self.assertEqual(10, rts.info(1).retention_msecs)
3838
pipe = rts.pipeline()
3939
self.assertTrue(pipe.create(2))
40+
4041
def testAdd(self):
4142
'''Test TS.ADD calls'''
4243

@@ -94,11 +95,13 @@ def testRange(self):
9495

9596
for i in range(100):
9697
rts.add(1, i, i % 7)
97-
self.assertTrue(100, len(rts.range(1, 0, 200)))
98+
self.assertEqual(100, len(rts.range(1, 0, 200)))
9899
for i in range(100):
99100
rts.add(1, i+200, i % 7)
100-
self.assertTrue(200, len(rts.range(1, 0, 500)))
101-
self.assertTrue(20, len(rts.range(1, 0, 500, aggregation_type='avg', bucket_size_msec=10)))
101+
self.assertEqual(200, len(rts.range(1, 0, 500)))
102+
#last sample isn't returned
103+
self.assertEqual(19, len(rts.range(1, 0, 500, aggregation_type='avg', bucket_size_msec=10)))
104+
self.assertEqual(10, len(rts.range(1, 0, 500, count=10)))
102105

103106
def testMultiRange(self):
104107
'''Test TS.MRANGE calls which returns range by filter'''
@@ -108,11 +111,25 @@ def testMultiRange(self):
108111
for i in range(100):
109112
rts.add(1, i, i % 7)
110113
rts.add(2, i, i % 11)
111-
self.assertTrue(100, len(rts.mrange(0, 200, filters=['Test=This'])))
114+
115+
res = rts.mrange(0, 200, filters=['Test=This'])
116+
self.assertEqual(2, len(res))
117+
self.assertEqual(100, len(res[0]['1'][1]))
118+
119+
res = rts.mrange(0, 200, filters=['Test=This'], count=10)
120+
self.assertEqual(10, len(res[0]['1'][1]))
121+
112122
for i in range(100):
113123
rts.add(1, i+200, i % 7)
114-
self.assertTrue(20, len(rts.mrange(0, 500, filters=['Test=This'],
115-
aggregation_type='avg', bucket_size_msec=10)))
124+
res = rts.mrange(0, 500, filters=['Test=This'],
125+
aggregation_type='avg', bucket_size_msec=10)
126+
self.assertEqual(2, len(res))
127+
self.assertEqual(19, len(res[0]['1'][1]))
128+
129+
#test withlabels
130+
self.assertEqual({}, res[0]['1'][0])
131+
res = rts.mrange(0, 200, filters=['Test=This'], with_labels=True)
132+
self.assertEqual({'Test': 'This'}, res[0]['1'][0])
116133

117134
def testGet(self):
118135
'''Test TS.GET calls'''
@@ -138,7 +155,7 @@ def testInfo(self):
138155
'''Test TS.INFO calls'''
139156
rts.create(1, retention_msecs=5, labels={'currentLabel' : 'currentData'})
140157
info = rts.info(1)
141-
self.assertTrue(info.retention_msecs == 5)
158+
self.assertEqual(5, info.retention_msecs)
142159
self.assertEqual(info.labels['currentLabel'], 'currentData')
143160

144161
def testQueryIndex(self):

0 commit comments

Comments
 (0)