From c9fbf9f2d389162525ea6f8f0781c62f6dbb6bc0 Mon Sep 17 00:00:00 2001 From: helmutm Date: Wed, 22 Nov 2006 14:46:01 +0000 Subject: [PATCH] MultiKeyDict re-implemented git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1517 fd906abe-77d9-0310-91a1-e0d9ade77398 --- index/multikey.py | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/index/multikey.py b/index/multikey.py index 68b0e7f..a882251 100644 --- a/index/multikey.py +++ b/index/multikey.py @@ -28,8 +28,8 @@ class MultiKeyDict(dict): def __init__(self, keylen=None, **kw): super(MultiKeyDict, self).__init__(**kw) + self.submapping = {} self.keylen = keylen - self.data = {} def __setitem__(self, key, value): assert type(key) is tuple @@ -37,11 +37,10 @@ class MultiKeyDict(dict): self.keylen = len(key) assert len(key) == self.keylen k0 = key[0] - sub = None if len(key) > 1: - sub = MultiKeyDict(self.keylen-1) + sub = self.submapping.setdefault(k0, MultiKeyDict(self.keylen-1)) sub[key[1:]] = value - self.data[k0] = MultiKeyDictEntry(value, sub) + super(MultiKeyDict, self).__setitem__(k0, value) def __getitem__(self, key): r = self.get(key, _not_found) @@ -54,21 +53,26 @@ class MultiKeyDict(dict): assert len(key) == self.keylen k0 = key[0] rsub = _not_found - r0 = self.data.get(k0, _not_found) + r0 = super(MultiKeyDict, self).get(k0, _not_found) if r0 is _not_found: r0 = self.getFallback(k0) if r0 is _not_found: return default if len(key) > 1: - sub = r0.submapping - rsub = sub.get(key[1:], _not_found) - if rsub is _not_found: - return default # !!! leads to backtracking !!! - return rsub - return rsub is _not_found and r0.value or rsub + sub = self.submapping.get(k0, _not_found) + if sub is _not_found: + sub = self.getSubmappingFallback(key) + if sub is _not_found: + rsub = _not_found + else: + rsub = sub.get(key[1:], _not_found) + if rsub is _not_found: + return default + result = rsub is _not_found and r0 or rsub + return result is _not_found and default or result def getFallback(self, key): - return self.data.get(None, _not_found) + return super(MultiKeyDict, self).get(None, _not_found) def getSubmappingFallback(self, key): return self.submapping.get(None, _not_found) @@ -77,9 +81,3 @@ class MultiKeyDict(dict): return ('' % (super(MultiKeyDict, self).__repr__(), `self.submapping`)) - -class MultiKeyDictEntry(object): - - def __init__(self, value, submapping): - self.value = value - self.submapping = submapping