tahoe-lafs/contrib/fuse/impl_b/pyfuse/OrderedDict.py

85 lines
2.2 KiB
Python

from UserDict import DictMixin
DELETED = object()
class OrderedDict(DictMixin):
def __init__(self, *args, **kwds):
self.clear()
self.update(*args, **kwds)
def clear(self):
self._keys = []
self._content = {} # {key: (index, value)}
self._deleted = 0
def copy(self):
return OrderedDict(self)
def __iter__(self):
for key in self._keys:
if key is not DELETED:
yield key
def keys(self):
return [key for key in self._keys if key is not DELETED]
def popitem(self):
while 1:
try:
k = self._keys.pop()
except IndexError:
raise KeyError, 'OrderedDict is empty'
if k is not DELETED:
return k, self._content.pop(k)[1]
def __getitem__(self, key):
index, value = self._content[key]
return value
def __setitem__(self, key, value):
try:
index, oldvalue = self._content[key]
except KeyError:
index = len(self._keys)
self._keys.append(key)
self._content[key] = index, value
def __delitem__(self, key):
index, oldvalue = self._content.pop(key)
self._keys[index] = DELETED
if self._deleted <= len(self._content):
self._deleted += 1
else:
# compress
newkeys = []
for k in self._keys:
if k is not DELETED:
i, value = self._content[k]
self._content[k] = len(newkeys), value
newkeys.append(k)
self._keys = newkeys
self._deleted = 0
def __len__(self):
return len(self._content)
def __repr__(self):
res = ['%r: %r' % (key, self._content[key][1]) for key in self]
return 'OrderedDict(%s)' % (', '.join(res),)
def __cmp__(self, other):
if not isinstance(other, OrderedDict):
return NotImplemented
keys = self.keys()
r = cmp(keys, other.keys())
if r:
return r
for k in keys:
r = cmp(self[k], other[k])
if r:
return r
return 0