Moved data structures from fix to structures; changed implementation of MaxLengthQueue to a RingBuffer.

This commit is contained in:
Jeremy Fincher 2003-04-22 11:00:28 +00:00
parent ca4ad3882f
commit 45b4d95184
2 changed files with 224 additions and 129 deletions

View File

@ -147,104 +147,6 @@ class set(object):
## self.d = d
class queue(object):
__slots__ = ('front', 'back')
def __init__(self, seq=()):
self.back = []
self.front = []
for elt in seq:
self.enqueue(elt)
def enqueue(self, elt):
self.back.append(elt)
def dequeue(self):
try:
return self.front.pop()
except IndexError:
self.back.reverse()
self.front = self.back
self.back = []
return self.front.pop()
def peek(self):
if self.front:
return self.front[-1]
else:
return self.back[0]
def __len__(self):
return len(self.front) + len(self.back)
def __contains__(self, elt):
return elt in self.front or elt in self.back
def __iter__(self):
for elt in reviter(self.front):
yield elt
for elt in self.back:
yield elt
def __eq__(self, other):
if len(self) == len(other):
otheriter = iter(other)
for elt in self:
otherelt = otheriter.next()
if not (elt == otherelt):
return False
return True
else:
return False
def __repr__(self):
return 'queue([%s])' % ', '.join(map(repr, self))
def __getitem__(self, oidx):
(m, idx) = divmod(oidx, len(self))
if m and m != -1:
raise IndexError, oidx
if len(self.front) > idx:
return self.front[-(idx+1)]
else:
return self.back[(idx-len(self.front))]
def __setitem__(self, oidx, value):
(m, idx) = divmod(oidx, len(self))
if m and m != -1:
raise IndexError, oidx
if len(self.front) > idx:
self.front[-(idx+1)] = value
else:
self.back[(idx-len(self.front))] = value
def __getstate__(self):
return (list(self),)
def __setstate__(self, (L,)):
L.reverse()
self.front = L
self.back = []
class MaxLengthQueue(queue):
__slots__ = ('length',)
def __init__(self, length, *args):
self.length = length
queue.__init__(self, *args)
def __getstate__(self):
return (self.length, queue.__getstate__(self))
def __setstate__(self, (length, q)):
self.length = length
queue.__setstate__(self, q)
def enqueue(self, elt):
queue.enqueue(self, elt)
if len(self) > self.length:
self.dequeue()
class IterableMap(object):
"""Define .iteritems() in a class and subclass this to get the other iters.
"""
@ -350,5 +252,5 @@ def partition(p, L):
else:
no.append(elt)
return (yes, no)
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -33,24 +33,39 @@
Data structures for Python.
"""
from __future__ import generators
from fix import *
import types
__all__ = ['RingBuffer']
__all__ = ['RingBuffer', 'queue', 'MaxLengthQueue']
class RingBuffer(object):
#__slots__ = ('L', 'i')
#__slots__ = ('L', 'i', 'full')
def __init__(self, maxSize, seq=()):
## if not maxSize and seq:
## maxSize = len(seq)
if maxSize <= 0:
raise ValueError, 'maxSize must be > 0.'
self.i = maxSize
self.maxSize = maxSize
self.full = False
self.L = []
self.i = 0
for elt in seq:
self.append(elt)
def __len__(self):
return len(self.L)
def __eq__(self, other):
if self.__class__ == other.__class__ and \
self.maxSize == other.maxSize and len(self) == len(other):
iterator = iter(other)
for elt in self:
otherelt = iterator.next()
if not elt == otherelt:
return False
return True
return False
def __nonzero__(self):
return len(self) > 0
@ -59,47 +74,225 @@ class RingBuffer(object):
return elt in self.L
def append(self, elt):
if len(self) >= self.i:
self.__class__ = _FullRingBuffer
self.i = 0
self.append(elt)
if self.full:
self.L[self.i] = elt
self.i += 1
self.i %= len(self.L)
else:
self.L.append(elt)
if len(self) >= self.maxSize:
self.full = True
self.append(elt)
else:
self.L.append(elt)
def extend(self, seq):
for elt in seq:
self.append(elt)
def __getitem__(self, idx):
if type(idx) == types.SliceType:
pass
if self.full:
oidx = idx
if type(oidx) == types.SliceType:
L = []
for i in xrange(*sliceIndices(oidx, len(self))):
L.append(self[i])
return L
else:
(m, idx) = divmod(oidx, len(self.L))
if m and m != -1:
raise IndexError, oidx
idx = (idx + self.i) % len(self.L)
return self.L[idx]
else:
return self.L[idx]
if type(idx) == types.SliceType:
L = []
for i in xrange(*sliceIndices(idx, len(self))):
L.append(self[i])
return L
else:
return self.L[idx]
def __setitem__(self, idx, elt):
self.L[idx] = elt
if self.full:
oidx = idx
if type(oidx) == types.SliceType:
range = xrange(*sliceIndices(oidx, len(self)))
if len(range) != len(elt):
raise ValueError, 'seq must be the same length as slice.'
else:
for (i, x) in zip(range, elt):
self[i] = x
else:
(m, idx) = divmod(oidx, len(self.L))
if m and m != -1:
raise IndexError, oidx
idx = (idx + self.i) % len(self.L)
self.L[idx] = elt
else:
if type(idx) == types.SliceType:
range = xrange(*sliceIndices(idx, len(self)))
if len(range) != len(elt):
raise ValueError, 'seq must be the same length as slice.'
else:
for (i, x) in zip(range, elt):
self[i] = x
else:
self.L[idx] = elt
def __repr__(self):
return 'RingBuffer(%r, %r)' % (self.i, list(self))
if self.full:
return 'RingBuffer(%r, %r)' % (self.maxSize, list(self))
else:
return 'RingBuffer(%r, %r)' % (self.maxSize, list(self))
class queue(object):
__slots__ = ('front', 'back')
def __init__(self, seq=()):
self.back = []
self.front = []
for elt in seq:
self.enqueue(elt)
def enqueue(self, elt):
self.back.append(elt)
def dequeue(self):
try:
return self.front.pop()
except IndexError:
self.back.reverse()
self.front = self.back
self.back = []
return self.front.pop()
def peek(self):
if self.front:
return self.front[-1]
else:
return self.back[0]
def __len__(self):
return len(self.front) + len(self.back)
def __contains__(self, elt):
return elt in self.front or elt in self.back
def __iter__(self):
for elt in reviter(self.front):
yield elt
for elt in self.back:
yield elt
def __eq__(self, other):
if len(self) == len(other):
otheriter = iter(other)
for elt in self:
otherelt = otheriter.next()
if not (elt == otherelt):
return False
return True
else:
return False
def __repr__(self):
return 'queue([%s])' % ', '.join(map(repr, self))
class _FullRingBuffer(RingBuffer):
#__slots__ = ('L', 'i')
def append(self, elt):
self.L[self.i] = elt
self.i += 1
self.i %= len(self.L)
def __getitem__(self, oidx):
(m, idx) = divmod(oidx, len(self.L))
(m, idx) = divmod(oidx, len(self))
if m and m != -1:
raise IndexError, oidx
idx = (idx + self.i) % len(self.L)
return self.L[idx]
def __setitem__(self, oidx, elt):
(m, idx) = divmod(oidx, len(self.L))
if len(self.front) > idx:
return self.front[-(idx+1)]
else:
return self.back[(idx-len(self.front))]
def __setitem__(self, oidx, value):
(m, idx) = divmod(oidx, len(self))
if m and m != -1:
raise IndexError, oidx
idx = (idx + self.i) % len(self.L)
self.L[idx] = elt
if len(self.front) > idx:
self.front[-(idx+1)] = value
else:
self.back[(idx-len(self.front))] = value
def __repr__(self):
return 'RingBuffer(%r, %r)' % (len(self.L), list(self))
def __getstate__(self):
return (list(self),)
def __setstate__(self, (L,)):
L.reverse()
self.front = L
self.back = []
class MaxLengthQueue(queue):
__slots__ = ('length',)
def __init__(self, length, seq=()):
self.length = length
queue.__init__(self, seq)
def __getstate__(self):
return (self.length, queue.__getstate__(self))
def __setstate__(self, (length, q)):
self.length = length
queue.__setstate__(self, q)
def enqueue(self, elt):
queue.enqueue(self, elt)
if len(self) > self.length:
self.dequeue()
## class MaxLengthQueue(RingBuffer):
## enqueue = RingBuffer.append
## def peek(self):
## return self[0]
def sliceIndices(slice, length):
if slice.step is None:
step = 1
else:
if slice.step == 0:
raise ValueError, 'slice step cannot be zero'
step = slice.step
if step < 0:
defstart = length - 1
defstop = -1
else:
defstart = 0
defstop = length
if slice.start is None:
start = defstart
else:
start = slice.start
if start < 0:
start += length
if start < 0:
if step < 0:
start = -1
else:
start = 0
if start >= length:
if step < 0:
start = length - 1
else:
start = length
if slice.stop is None:
stop = defstop
else:
stop = slice.stop
if stop < 0:
stop += length
if stop < 0:
stop = -1
if stop > length:
stop = length
if (step < 0 and stop >= start) or \
(step > 0 and start >= stop):
slicelength = 0
elif step < 0:
slicelength = (stop - start + 1)/step + 1
else:
slicelength = (stop - start - 1)/step + 1
return (start, stop, step)