1
"""High performance data structures
4
# Copied and completed from the sandbox of CPython
5
# (nondist/sandbox/collections/pydeque.py rev 1.1, Raymond Hettinger)
10
from thread import get_ident as _thread_ident
23
def __new__(cls, iterable=()):
24
self = super(deque, cls).__new__(cls)
28
def __init__(self, iterable=()):
34
self.right = self.left = [None] * BLOCKSIZ
35
self.rightndx = n//2 # points to last written element
43
if self.rightndx == n:
44
newblock = [None] * BLOCKSIZ
45
self.right[RGTLNK] = newblock
46
newblock[LFTLNK] = self.right
50
self.right[self.rightndx] = x
52
def appendleft(self, x):
55
if self.leftndx == -1:
56
newblock = [None] * BLOCKSIZ
57
self.left[LFTLNK] = newblock
58
newblock[RGTLNK] = self.left
62
self.left[self.leftndx] = x
64
def extend(self, iterable):
68
def extendleft(self, iterable):
73
if self.left is self.right and self.leftndx > self.rightndx:
74
raise IndexError, "pop from an empty deque"
75
x = self.right[self.rightndx]
76
self.right[self.rightndx] = None
80
if self.rightndx == -1:
81
prevblock = self.right[LFTLNK]
83
# the deque has become empty; recenter instead of freeing block
87
prevblock[RGTLNK] = None
88
self.right[LFTLNK] = None
89
self.right = prevblock
94
if self.left is self.right and self.leftndx > self.rightndx:
95
raise IndexError, "pop from an empty deque"
96
x = self.left[self.leftndx]
97
self.left[self.leftndx] = None
101
if self.leftndx == n:
102
prevblock = self.left[RGTLNK]
103
if prevblock is None:
104
# the deque has become empty; recenter instead of freeing block
106
self.leftndx = n//2+1
108
prevblock[LFTLNK] = None
109
self.left[RGTLNK] = None
110
self.left = prevblock
114
def remove(self, value):
115
del self[operator.indexOf(self, value)]
117
def rotate(self, n=1):
121
halflen = (length+1) >> 1
122
if n > halflen or n < -halflen:
129
self.appendleft(self.pop())
132
self.append(self.popleft())
136
threadlocalattr = '__repr' + str(_thread_ident())
137
if threadlocalattr in self.__dict__:
138
return 'deque([...])'
140
self.__dict__[threadlocalattr] = True
142
return 'deque(%r)' % (list(self),)
144
del self.__dict__[threadlocalattr]
147
return deque_iterator(self, self._iter_impl)
149
def _iter_impl(self, original_state, giveup):
150
if self.state != original_state:
155
if block is self.left:
157
if block is self.right:
158
r = self.rightndx + 1
159
for elem in block[l:r]:
161
if self.state != original_state:
163
block = block[RGTLNK]
165
def __reversed__(self):
166
return deque_iterator(self, self._reversed_impl)
168
def _reversed_impl(self, original_state, giveup):
169
if self.state != original_state:
174
if block is self.left:
176
if block is self.right:
177
r = self.rightndx + 1
178
for elem in reversed(block[l:r]):
180
if self.state != original_state:
182
block = block[LFTLNK]
189
# block = block[RGTLNK]
190
#return sum + self.rightndx - self.leftndx + 1 - n
193
def __getref(self, index):
198
if block is self.left:
200
if block is self.right:
201
r = self.rightndx + 1
204
return block, l+index
206
block = block[RGTLNK]
211
if block is self.left:
213
if block is self.right:
214
r = self.rightndx + 1
216
if index >= negative_span:
217
return block, r+index
218
index -= negative_span
219
block = block[LFTLNK]
220
raise IndexError("deque index out of range")
222
def __getitem__(self, index):
223
block, index = self.__getref(index)
226
def __setitem__(self, index, value):
227
block, index = self.__getref(index)
230
def __delitem__(self, index):
234
raise IndexError("deque index out of range")
241
raise IndexError("deque index out of range")
246
def __reduce_ex__(self, proto):
247
return type(self), (), self.__dict__, iter(self), None
250
raise TypeError, "deque objects are unhashable"
253
return self.__class__(self)
255
# XXX make comparison more efficient
256
def __eq__(self, other):
257
if isinstance(other, deque):
258
return list(self) == list(other)
260
return NotImplemented
262
def __ne__(self, other):
263
if isinstance(other, deque):
264
return list(self) != list(other)
266
return NotImplemented
268
def __lt__(self, other):
269
if isinstance(other, deque):
270
return list(self) < list(other)
272
return NotImplemented
274
def __le__(self, other):
275
if isinstance(other, deque):
276
return list(self) <= list(other)
278
return NotImplemented
280
def __gt__(self, other):
281
if isinstance(other, deque):
282
return list(self) > list(other)
284
return NotImplemented
286
def __ge__(self, other):
287
if isinstance(other, deque):
288
return list(self) >= list(other)
290
return NotImplemented
292
class deque_iterator(object):
294
def __init__(self, deq, itergen):
295
self.counter = len(deq)
298
raise RuntimeError, "deque mutated during iteration"
299
self._gen = itergen(deq.state, giveup)
302
res = self._gen.next()