Skip to content

Commit db90048

Browse files
committed
Merge branch 'release-5.5.1'
2 parents 766cfc7 + f87c24b commit db90048

12 files changed

Lines changed: 425 additions & 34 deletions

File tree

btrdb/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from btrdb.exceptions import ConnectionError
2121
from btrdb.version import get_version
2222
from btrdb.utils.credentials import credentials_by_profile, credentials
23+
from btrdb.stream import MINIMUM_TIME, MAXIMUM_TIME
2324

2425
##########################################################################
2526
## Module Variables
@@ -31,6 +32,7 @@
3132
BTRDB_API_KEY = "BTRDB_API_KEY"
3233
BTRDB_PROFILE = "BTRDB_PROFILE"
3334

35+
3436
##########################################################################
3537
## Functions
3638
##########################################################################

btrdb/endpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def rawValues(self, uu, start, end, version = 0):
4242
yield result.values, result.versionMajor
4343

4444
def alignedWindows(self, uu, start, end, pointwidth, version = 0):
45-
params = btrdb_pb2.AlignedWindowsParams(uuid = uu.bytes, start = start, end = end, versionMajor = version, pointWidth = pointwidth)
45+
params = btrdb_pb2.AlignedWindowsParams(uuid = uu.bytes, start = start, end = end, versionMajor = version, pointWidth = int(pointwidth))
4646
for result in self.stub.AlignedWindows(params):
4747
BTrDBError.checkProtoStat(result.stat)
4848
yield result.values, result.versionMajor

btrdb/point.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def __str__(self):
8585
return self.__repr__()
8686

8787
def __eq__(self, other):
88+
if not hasattr(other, "time") or not hasattr(other, "value"):
89+
return False
8890
return self.time == other.time and self.value == other.value
8991

9092

@@ -218,6 +220,10 @@ def __str__(self):
218220
return self.__repr__()
219221

220222
def __eq__(self, other):
223+
for attr in "time", "min", "mean", "max", "count", "stddev":
224+
if not hasattr(other, attr):
225+
return False
226+
221227
return self.time == other.time and \
222228
self.min == other.min and \
223229
self.mean == other.mean and \

btrdb/stream.py

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
##########################################################################
3535

3636
INSERT_BATCH_SIZE = 5000
37+
MINIMUM_TIME = -(16 << 56)
38+
MAXIMUM_TIME = (48 << 56) - 1
3739

3840
try:
3941
RE_PATTERN = re._pattern_type
@@ -196,12 +198,14 @@ def collection(self):
196198

197199
def earliest(self, version=0):
198200
"""
199-
Returns the first point of data in the stream. Returns None if error
201+
Returns the first point of data in the stream. Returns None if error
200202
encountered during lookup or no values in stream.
201203
202204
Parameters
203205
----------
204-
None
206+
version : int, default: 0
207+
Specify the version of the stream to query; if zero, queries the latest
208+
stream state rather than pinning to a version.
205209
206210
Returns
207211
-------
@@ -210,18 +214,19 @@ def earliest(self, version=0):
210214
the value was retrieved at (tuple(RawPoint, int)).
211215
212216
"""
213-
start = 0
217+
start = MINIMUM_TIME
214218
return self.nearest(start, version=version, backward=False)
215219

216220
def latest(self, version=0):
217221
"""
218-
Returns last point of data in the stream. Note that this method will
219-
return None if no point can be found that is less than the current
220-
date/time.
222+
Returns last point of data in the stream. Returns None if error
223+
encountered during lookup or no values in stream.
221224
222225
Parameters
223226
----------
224-
None
227+
version : int, default: 0
228+
Specify the version of the stream to query; if zero, queries the latest
229+
stream state rather than pinning to a version.
225230
226231
Returns
227232
-------
@@ -230,9 +235,30 @@ def latest(self, version=0):
230235
the value was retrieved at (tuple(RawPoint, int)).
231236
232237
"""
233-
start = currently_as_ns()
238+
start = MAXIMUM_TIME
234239
return self.nearest(start, version=version, backward=True)
235240

241+
def current(self, version=0):
242+
"""
243+
Returns the point that is closest to the current timestamp, e.g. the latest
244+
point in the stream up until now. Note that no future values will be returned.
245+
Returns None if errors during lookup or there are no values before now.
246+
247+
Parameters
248+
----------
249+
version : int, default: 0
250+
Specify the version of the stream to query; if zero, queries the latest
251+
stream state rather than pinning to a version.
252+
253+
Returns
254+
-------
255+
tuple
256+
The last data point in the stream up until now and the version of the stream
257+
the value was retrieved at (tuple(RawPoint, int)).
258+
"""
259+
start = currently_as_ns()
260+
return self.nearest(start, version, backward=True)
261+
236262
def tags(self, refresh=False):
237263
"""
238264
Returns the stream's tags.
@@ -728,8 +754,7 @@ def versions(self):
728754

729755
def earliest(self):
730756
"""
731-
Returns earliest points of data in streams using available
732-
filters.
757+
Returns earliest points of data in streams using available filters.
733758
734759
Parameters
735760
----------
@@ -743,7 +768,7 @@ def earliest(self):
743768
"""
744769
earliest = []
745770
params = self._params_from_filters()
746-
start = params.get("start", 0)
771+
start = params.get("start", MINIMUM_TIME)
747772

748773
for s in self._streams:
749774
version = self.versions()[s.uuid]
@@ -754,10 +779,7 @@ def earliest(self):
754779

755780
def latest(self):
756781
"""
757-
Returns latest points of data in the streams using available
758-
filters. Note that this method will return None if no
759-
end filter is provided and point cannot be found that is less than the
760-
current date/time.
782+
Returns latest points of data in the streams using available filters.
761783
762784
Parameters
763785
----------
@@ -771,7 +793,7 @@ def latest(self):
771793
"""
772794
latest = []
773795
params = self._params_from_filters()
774-
start = params.get("end", currently_as_ns())
796+
start = params.get("end", MAXIMUM_TIME)
775797

776798
for s in self._streams:
777799
version = self.versions()[s.uuid]
@@ -780,6 +802,37 @@ def latest(self):
780802

781803
return tuple(latest)
782804

805+
def current(self):
806+
"""
807+
Returns the points of data in the streams closest to the current timestamp. If
808+
the current timestamp is outside of the filtered range of data, a ValueError is
809+
raised.
810+
811+
Parameters
812+
----------
813+
None
814+
815+
Returns
816+
-------
817+
tuple
818+
The latest points of data found among all streams
819+
"""
820+
latest = []
821+
params = self._params_from_filters()
822+
now = currently_as_ns()
823+
end = params.get("end", None)
824+
start = params.get("start", None)
825+
826+
if (end is not None and end <= now) or (start is not None and start > now):
827+
raise ValueError("current time is not included in filtered stream range")
828+
829+
for s in self._streams:
830+
version = self.versions()[s.uuid]
831+
point, _ = s.nearest(now, version=version, backward=True)
832+
latest.append(point)
833+
834+
return tuple(latest)
835+
783836
def filter(self, start=None, end=None, collection=None, name=None, unit=None,
784837
tags=None, annotations=None):
785838
"""

btrdb/utils/general.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,154 @@ def unpack_stream_descriptor(desc):
3030
for ann in desc.annotations:
3131
anns[ann.key] = ann.val.value
3232
return tags, anns
33+
34+
35+
##########################################################################
36+
## Pointwidth Helpers
37+
##########################################################################
38+
39+
class pointwidth(object):
40+
"""
41+
A representation of a period of time described by the BTrDB tree (and used in
42+
aligned_windows queries). The pointwidth allows users to traverse to different
43+
levels of the BTrDB tree and to select StatPoints directly, vastly improving the
44+
performance of queries. However, because the real duration of the pointwidth is
45+
defined in powers of 2 (e.g. 2**pointwidth nanoseconds), the durations do not map
46+
to human time periods (e.g. weeks or hours).
47+
48+
Parameters
49+
----------
50+
p : int
51+
cast an integer to the specified pointwidth
52+
"""
53+
54+
@classmethod
55+
def from_timedelta(cls, delta):
56+
"""
57+
Returns the closest pointwidth for the given timedelta without going over the
58+
specified duration. Because pointwidths are in powers of 2, be sure to check
59+
that the returned real duration is sufficient.
60+
"""
61+
return cls.from_nanoseconds(delta.total_seconds()*1e9)
62+
63+
@classmethod
64+
def from_nanoseconds(cls, nsec):
65+
"""
66+
Returns the closest pointwidth for the given number of nanoseconds without going
67+
over the specified duration. Because pointwidths are in powers of 2, be sure to
68+
check that the returned real duration is sufficient.
69+
"""
70+
for pos in range(62):
71+
nsec = nsec >> 1
72+
if nsec == 0:
73+
break
74+
return cls(pos)
75+
76+
def __init__(self, p):
77+
self._pointwidth = int(p)
78+
79+
@property
80+
def nanoseconds(self):
81+
return 2**self._pointwidth
82+
83+
@property
84+
def microseconds(self):
85+
return self.nanoseconds / 1e3
86+
87+
@property
88+
def milliseconds(self):
89+
return self.nanoseconds / 1e6
90+
91+
@property
92+
def seconds(self):
93+
return self.nanoseconds / 1e9
94+
95+
@property
96+
def minutes(self):
97+
return self.nanoseconds / 6e10
98+
99+
@property
100+
def hours(self):
101+
return self.nanoseconds / 3.6e12
102+
103+
@property
104+
def days(self):
105+
return self.nanoseconds / 8.64e13
106+
107+
@property
108+
def weeks(self):
109+
return self.nanoseconds / 6.048e14
110+
111+
@property
112+
def months(self):
113+
return self.nanoseconds / 2.628e15
114+
115+
@property
116+
def years(self):
117+
return self.nanoseconds / 3.154e16
118+
119+
def decr(self):
120+
return pointwidth(self-1)
121+
122+
def incr(self):
123+
return pointwidth(self+1)
124+
125+
def __int__(self):
126+
return self._pointwidth
127+
128+
def __eq__(self, other):
129+
return int(self) == int(other)
130+
131+
def __lt__(self, other):
132+
return int(self) < int(other)
133+
134+
def __le__(self, other):
135+
return int(self) <= int(other)
136+
137+
def __gt__(self, other):
138+
return int(self) > int(other)
139+
140+
def __ge__(self, other):
141+
return int(self) >= int(other)
142+
143+
def __add__(self, other):
144+
return pointwidth(int(self)+int(other))
145+
146+
def __sub__(self, other):
147+
return pointwidth(int(self)-int(other))
148+
149+
def __str__(self):
150+
"""
151+
Returns the pointwidth to the closest unit
152+
"""
153+
if self >= 55:
154+
return "{:0.2f} years".format(self.years)
155+
156+
if self >= 52:
157+
return "{:0.2f} months".format(self.months)
158+
159+
if self >= 50:
160+
return "{:0.2f} weeks".format(self.weeks)
161+
162+
if self >= 47:
163+
return "{:0.2f} days".format(self.days)
164+
165+
if self >= 42:
166+
return "{:0.2f} hours".format(self.hours)
167+
168+
if self >= 36:
169+
return "{:0.2f} minutes".format(self.minutes)
170+
171+
if self >= 30:
172+
return "{:0.2f} seconds".format(self.seconds)
173+
174+
if self >= 20:
175+
return "{:0.2f} milliseconds".format(self.milliseconds)
176+
177+
if self >= 10:
178+
return "{:0.2f} microseconds".format(self.microseconds)
179+
180+
return "{:0.0f} nanoseconds".format(self.nanoseconds)
181+
182+
def __repr__(self):
183+
return "<pointwidth {}>".format(int(self))

btrdb/version.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
__version_info__ = {
1919
'major': 5,
2020
'minor': 5,
21-
'micro': 0,
21+
'micro': 1,
2222
'releaselevel': 'final',
23-
'serial': 8,
23+
'serial': 9,
2424
}
2525

2626
##########################################################################

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ python_files = tests/*
1111
flakes-ignore =
1212
tests/* ALL
1313
btrdb/grpcinterface/btrdb_pb2.py UnusedImport
14+
btrdb/__init__.py UnusedImport

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ def get_description_type(path=PKG_DESCRIBE):
129129
"description": DESCRIPTION,
130130
"long_description": read(PKG_DESCRIBE),
131131
"long_description_content_type": get_description_type(PKG_DESCRIBE),
132-
"classifiers": CLASSIFIERS,
133-
"keywords": KEYWORDS,
132+
"classifiers": list(CLASSIFIERS),
133+
"keywords": list(KEYWORDS),
134134
"license": LICENSE,
135135
"author": AUTHOR,
136136
"author_email": EMAIL,

tests/btrdb/test_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
## Test Constants
2727
##########################################################################
2828

29-
EXPECTED_VERSION = "5.5"
29+
EXPECTED_VERSION = "5.5.1"
3030

3131

3232
##########################################################################

0 commit comments

Comments
 (0)