Skip to content

Commit ecf859a

Browse files
committed
add properties and minor changes
1 parent 76208dd commit ecf859a

File tree

1 file changed

+114
-9
lines changed

1 file changed

+114
-9
lines changed

NumpyDeque/NumpyDeque.py

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"NumpyDeque",
4848
]
4949

50+
_PRIORITY_FLAG = {"e": "equal", "l": "left", "lo": "leftonly", "r": "right", "ro": "rightonly"}
5051
_MAX_AUTO_BUFFER = 2**11 # Maximum size increase of buffer allowed to include user requested buffer and auto-buffer
5152

5253

@@ -205,6 +206,16 @@ def dtype(self) -> np.dtype:
205206
"""Get the data type of the elements stored in the deque."""
206207
return self._data.dtype
207208

209+
@property
210+
def priority(self):
211+
"""Get the buffer priority of the deque."""
212+
return _PRIORITY_FLAG[self._priority]
213+
214+
@property
215+
def buffer_size(self):
216+
"""Get the maximum capacity of the buffer that contains the deque."""
217+
return self._bcap
218+
208219
@classmethod
209220
def array(
210221
cls,
@@ -254,7 +265,14 @@ def array(
254265
try:
255266
size = object.size
256267
except (AttributeError, TypeError): # assume its a scalar
257-
return cls(1, object, dtype, buffer_padding, _force_buffer_size)
268+
if maxsize is not None:
269+
maxsize = max(1, maxsize)
270+
return cls(maxsize, object, dtype, buffer_padding, _force_buffer_size)
271+
272+
if maxsize is None:
273+
maxsize = size
274+
else:
275+
maxsize = max(size, maxsize)
258276

259277
if dtype is None:
260278
try:
@@ -266,9 +284,9 @@ def array(
266284
dtype = np.array(object[0]).dtype
267285

268286
if buffer_padding is None and isinstance(object, NumpyDeque):
269-
buffer_padding = object._bcap
287+
_force_buffer_size = object._bcap
270288

271-
ob = cls(size, None, dtype, buffer_padding, priority, _force_buffer_size)
289+
ob = cls(maxsize, None, dtype, buffer_padding, priority, _force_buffer_size=_force_buffer_size)
272290
ob._i = ob._s
273291
ob._j = ob._i + size
274292
ob._data[ob._i : ob._j] = object
@@ -293,9 +311,29 @@ def put(self, value):
293311
self._j += 1
294312
self.deque = self._data[self._i : self._j]
295313

314+
def putleft(self, value):
315+
"""
316+
Add a value to the left end of the deque. If the len(deque) == maxsize,
317+
the right-most value (index=-1) is dropped.
318+
319+
Parameters:
320+
value: The value to be added to the deque.
321+
"""
322+
323+
if self._j - self._i == self._qcap:
324+
self._j -= 1
325+
326+
self._i -= 1
327+
if self._i == -1:
328+
self._shift_buffer()
329+
330+
self._data[self._i] = value
331+
332+
self.deque = self._data[self._i : self._j]
333+
296334
def putter(self, values):
297335
"""
298-
Add multiple values to the deque in an optimized manner.
336+
Add multiple values to the right of the deque in an optimized manner.
299337
This is more efficient than repeatedly calling `put()` for each value.
300338
This is equivalent to:
301339
```
@@ -317,7 +355,8 @@ def putter(self, values):
317355
return
318356

319357
if dim >= self._qcap: # overwriting the entire deque move to buffer start
320-
self._i, self._j = self._s, self._i + self._qcap
358+
self._i = self._s
359+
self._j = self._i + self._qcap
321360
self._data[self._i : self._j] = values[dim - self._qcap :]
322361
self.deque = self._data[self._i : self._j]
323362
return
@@ -333,6 +372,62 @@ def putter(self, values):
333372
self._j += dim
334373
self.deque = self._data[self._i : self._j]
335374

375+
def putterleft(self, values):
376+
"""
377+
Add multiple values to the left of the deque in an optimized manner.
378+
This is more efficient than repeatedly calling `putleft()` for each value.
379+
This is equivalent to:
380+
```
381+
for v in values:
382+
self.putleft(v)
383+
```
384+
385+
Parameters:
386+
values (iterable, array-like or scalar): The values to add to the deque.
387+
"""
388+
try:
389+
dim = len(values)
390+
except TypeError: # iterator so need to manually add values
391+
try:
392+
for v in values:
393+
self.putleft(v)
394+
except TypeError: # scalar, so just call regular put
395+
self.putleft(values)
396+
return
397+
398+
if dim >= self._qcap: # overwriting the entire deque move to buffer start
399+
self._i = self._s
400+
self._j = self._i + self._qcap
401+
self._data[self._i : self._j] = values[::-1][: self._qcap]
402+
self.deque = self._data[self._i : self._j]
403+
return
404+
405+
# if self._j - self._i == self._qcap:
406+
# self._j -= 1
407+
408+
# self._i -= 1
409+
# if self._i == -1:
410+
# self._shift_buffer()
411+
412+
# self._data[self._i] = value
413+
414+
# self.deque = self._data[self._i : self._j]
415+
416+
new_size = self._j - self._i + dim
417+
if new_size > self._qcap:
418+
self._j -= new_size - self._qcap
419+
420+
if self._i - dim < 0: # shift buffer
421+
s = self._s + dim
422+
j = s + self._j - self._i
423+
self._data[s:j] = self._data[self._i : self._j]
424+
self._i, self._j = self._s, j
425+
else:
426+
self._i -= dim
427+
428+
self._data[self._i : self._i + dim] = values[::-1]
429+
self.deque = self._data[self._i : self._j]
430+
336431
def pop(self):
337432
"""
338433
Remove and return the value from the right end of the deque (index=-1).
@@ -393,7 +488,7 @@ def drop(self, index):
393488

394489
if "o" in self._priority: # user specified priority for buffer
395490
priority = self._priority
396-
elif (self._j - self._s) <= (self._s - self._i): # index to drop is closer to _j
491+
elif (self._j - index) <= (index - self._i): # index to drop is closer to _j
397492
priority = "ro"
398493
else:
399494
priority = "lo"
@@ -434,7 +529,7 @@ def copy(self):
434529
Returns:
435530
NumpyDeque: A new instance of NumpyDeque that is a copy of the current deque.
436531
"""
437-
return NumpyDeque.array(self.deque, self.dtype, self._bcap, self._priority)
532+
return NumpyDeque.array(self.deque, None, self.dtype, self._bcap, self._priority)
438533

439534
def clear(self):
440535
"""
@@ -470,8 +565,18 @@ def _shift_buffer(self):
470565
"""
471566
Internally shift the buffer to accommodate newly added elements and ensure efficient use of buffer space.
472567
"""
473-
j = self._s + self._j - self._i
474-
self._data[self._s : j] = self._data[self._i : self._j]
568+
if self._i == -1: # putleft shift
569+
s = self._s + 1 # - self._i
570+
i = 0
571+
j = s + self._j # - i
572+
elif self._i >= 0: # put and putter shift
573+
s = self._s
574+
i = self._i
575+
j = self._s + self._j - self._i
576+
else:
577+
raise RuntimeError("NumpyDeque._shift_buffer encountered an invalid _i index.")
578+
579+
self._data[s:j] = self._data[i : self._j]
475580
self._i, self._j = self._s, j
476581

477582
@staticmethod

0 commit comments

Comments
 (0)