2727from btrdb .exceptions import BTrDBError , InvalidOperation
2828from btrdb .utils .timez import currently_as_ns , to_nanoseconds
2929from btrdb .utils .conversion import AnnotationEncoder , AnnotationDecoder
30+ from btrdb .utils .general import pointwidth as pw
3031
3132
3233##########################################################################
@@ -122,7 +123,7 @@ def exists(self):
122123 return False
123124 raise bte
124125
125- def count (self , start = MINIMUM_TIME , end = MAXIMUM_TIME , pointwidth = 62 , version = 0 ):
126+ def count (self , start = MINIMUM_TIME , end = MAXIMUM_TIME , pointwidth = 62 , precise = False , version = 0 ):
126127 """
127128 Compute the total number of points in the stream
128129
@@ -134,6 +135,9 @@ def count(self, start=MINIMUM_TIME, end=MAXIMUM_TIME, pointwidth=62, version=0):
134135 windows of time, you may also need to adjust the pointwidth to ensure
135136 that the count granularity is captured appropriately.
136137
138+ Alternatively you can set the precise argument to True which will
139+ give an exact count to the nanosecond but may be slower to execute.
140+
137141 Parameters
138142 ----------
139143 start : int or datetime like object, default: MINIMUM_TIME
@@ -145,7 +149,14 @@ def count(self, start=MINIMUM_TIME, end=MAXIMUM_TIME, pointwidth=62, version=0):
145149 :func:`btrdb.utils.timez.to_nanoseconds` for valid input types)
146150
147151 pointwidth : int, default: 62
148- Specify the number of ns between data points (2**pointwidth)
152+ Specify the number of ns between data points (2**pointwidth). If the value
153+ is too large for the time window than the next smallest, appropriate
154+ pointwidth will be used.
155+
156+ precise : bool, default: False
157+ Forces the use of a windows query instead of aligned_windows
158+ to determine exact count down to the nanosecond. This will
159+ be some amount slower than the aligned_windows version.
149160
150161 version : int, default: 0
151162 Version of the stream to query
@@ -155,8 +166,17 @@ def count(self, start=MINIMUM_TIME, end=MAXIMUM_TIME, pointwidth=62, version=0):
155166 int
156167 The total number of points in the stream for the specified window.
157168 """
158- points = self .aligned_windows (start , end , pointwidth , version )
159- return sum ([point .count for point , _ in points ])
169+
170+ if not precise :
171+ pointwidth = min (pointwidth , pw .from_nanoseconds (to_nanoseconds (end ) - to_nanoseconds (start ))- 1 )
172+ points = self .aligned_windows (start , end , pointwidth , version )
173+ return sum ([point .count for point , _ in points ])
174+
175+ depth = 0
176+ width = to_nanoseconds (end ) - to_nanoseconds (start )
177+ points = self .windows (start , end , width , depth , version )
178+ return sum ([point .count for point , _ in points ])
179+
160180
161181 @property
162182 def btrdb (self ):
@@ -867,14 +887,12 @@ def count(self):
867887 params = self ._params_from_filters ()
868888 start = params .get ("start" , MINIMUM_TIME )
869889 end = params .get ("end" , MAXIMUM_TIME )
870-
871- pointwidth = self .pointwidth if self .pointwidth is not None else 62
872890 versions = self ._pinned_versions if self ._pinned_versions else {}
873-
874891 count = 0
892+
875893 for s in self ._streams :
876894 version = versions .get (s .uuid , 0 )
877- count += s .count (start , end , pointwidth , version )
895+ count += s .count (start , end , version = version )
878896
879897 return count
880898
0 commit comments