[pypy-svn] r31350 - in pypy/dist/pypy/objspace/std: . test
mwh at codespeak.net
mwh at codespeak.net
Wed Aug 16 17:55:52 CEST 2006
Author: mwh
Date: Wed Aug 16 17:55:51 2006
New Revision: 31350
Modified:
pypy/dist/pypy/objspace/std/dictmultiobject.py
pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py
Log:
tweaks, and a SmallStrDictImplementation which doesn't work, probably for
stupid reasons. but now i have to ru for a train, literally.
Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictmultiobject.py Wed Aug 16 17:55:51 2006
@@ -3,10 +3,15 @@
from pypy.rpython.objectmodel import r_dict, we_are_translated
+def _is_str(space, w_key):
+ return space.is_w(space.type(w_key), space.w_str)
+
class DictImplementation(object):
## def get(self, w_lookup):
## return w_value or None
+## def setitem_str(self, w_key, w_value):
+## return implementation
## def setitem(self, w_key, w_value):
## return implementation
## def delitem(self, w_key):
@@ -36,7 +41,15 @@
def get(self, w_lookup):
return None
def setitem(self, w_key, w_value):
- return SmallDictImplementation(self.space, w_key, w_value)
+ if _is_str(self.space, w_key):
+ return StrDictImplementation(self.space, w_key, w_value)
+ #return SmallStrDictImplementation(self.space, w_key, w_value)
+ else:
+ return RDictImplementation(self.space).setitem(w_key, w_value)
+ #return SmallDictImplementation(self.space, w_key, w_value)
+ def setitem_str(self, w_key, w_value):
+ return StrDictImplementation(self.space, w_key, w_value)
+ #return SmallStrDictImplementation(self.space, w_key, w_value)
def delitem(self, w_key):
raise KeyError
@@ -77,10 +90,6 @@
self.valid = 1
def _lookup(self, w_key):
-## for i in range(self.valid):
-## assert self.entries[i].w_value is not None
-## for i in range(self.valid+1, 5):
-## assert self.entries[i].w_value is None
hash = self.space.hash_w(w_key)
i = 0
last = self.entries[self.valid]
@@ -145,6 +154,123 @@
def items(self):
return [(e.w_key, e.w_value) for e in [self.entries[i] for i in range(self.valid)]]
+class StrEntry(object):
+ def __init__(self):
+ self.hash = 0
+ self.key = None
+ self.w_value = None
+ def __repr__(self):
+ return '<%r, %r, %r>'%(self.hash, self.key, self.w_value)
+
+class SmallStrDictImplementation(DictImplementation):
+ # XXX document the invariants here!
+
+ def __init__(self, space, w_key, w_value):
+ self.space = space
+ self.entries = [StrEntry(), StrEntry(), StrEntry(), StrEntry(), StrEntry()]
+ key = space.str_w(w_key)
+ self.entries[0].key = key
+ self.entries[0].hash = hash(key)
+ self.entries[0].w_value = w_value
+ self.valid = 1
+
+ def _lookup(self, key):
+ _hash = hash(key)
+ i = 0
+ last = self.entries[self.valid]
+ last.hash = _hash
+ last.key = key
+ while 1:
+ look_entry = self.entries[i]
+ if look_entry.hash == _hash and look_entry.key == key:
+ return look_entry
+ i += 1
+
+ def _convert_to_rdict(self):
+ newimpl = RDictImplementation(self.space)
+ i = 0
+ while 1:
+ entry = self.entries[i]
+ if entry.w_value is None:
+ break
+ newimpl.content[self.space.wrap(entry.key)] = entry.w_value
+ i += 1
+ return newimpl
+
+ def _convert_to_sdict(self, w_key, w_value):
+ newimpl = StrDictImplementation(self.space, w_key, w_value)
+ i = 0
+ while 1:
+ entry = self.entries[i]
+ if entry.w_value is None:
+ break
+ newimpl.content[entry.key] = entry.w_value
+ i += 1
+ return newimpl
+
+ def setitem(self, w_key, w_value):
+ if not _is_str(self.space, w_key):
+ return self._convert_to_rdict().setitem(w_key, w_value)
+ return self.setitem_str(w_key, w_value)
+
+ def setitem_str(self, w_key, w_value):
+ print w_key, w_value
+ if self.valid == 4:
+ return self._convert_to_sdict(w_key, w_value)
+ entry = self._lookup(self.space.str_w(w_key))
+ if entry.w_value is None:
+ self.valid += 1
+ entry.w_value = w_value
+ return self
+
+ def delitem(self, w_key):
+ space = self.space
+ if space.is_w(space.type(w_key), space.w_str):
+ entry = self._lookup(space.str_w(w_key))
+ if entry.w_value is not None:
+ for i in range(self.entries.index(entry), self.valid):
+ self.entries[i] = self.entries[i+1]
+ self.entries[self.valid] = entry
+ entry.w_value = None
+ self.valid -= 1
+ if self.valid == 0:
+ return self.space.emptydictimpl
+ return self
+ else:
+ raise KeyError
+ elif self._is_sane_hash(space.type(w_key)):
+ raise KeyError
+ else:
+ return self._convert_to_rdict().delitem(w_key)
+
+ def length(self):
+ return self.valid
+
+ def get(self, w_lookup):
+ space = self.space
+ w_lookup_type = space.type(w_lookup)
+ if space.is_w(w_lookup_type, space.w_str):
+ return self._lookup(w_lookup).w_value
+ elif self._is_sane_hash(w_lookup_type):
+ return None
+ else:
+ return self._convert_to_rdict().get(w_lookup)
+
+ def iteritems(self):
+ return self._convert_to_rdict().iteritems()
+ def iterkeys(self):
+ return self._convert_to_rdict().iterkeys()
+ def itervalues(self):
+ return self._convert_to_rdict().itervalues()
+
+ def keys(self):
+ return [self.space.wrap(self.entries[i].key) for i in range(self.valid)]
+ def values(self):
+ return [self.entries[i].w_value for i in range(self.valid)]
+ def items(self):
+ return [(self.space.wrap(e.key), e.w_value)
+ for e in [self.entries[i] for i in range(self.valid)]]
+
class RDictImplementation(DictImplementation):
def __init__(self, space):
self.space = space
@@ -156,6 +282,7 @@
def setitem(self, w_key, w_value):
self.content[w_key] = w_value
return self
+ setitem_str = setitem
def delitem(self, w_key):
del self.content[w_key]
if self.content:
@@ -183,11 +310,12 @@
return self.content.items()
class StrDictImplementation(DictImplementation):
- def __init__(self, space):
+ def __init__(self, space, w_key, w_value):
self.space = space
- self.content = {}
+ self.content = {space.str_w(w_key): w_value}
def setitem(self, w_key, w_value):
+ print 's', w_key, w_value
space = self.space
if space.is_w(space.type(w_key), space.w_str):
self.content[space.str_w(w_key)] = w_value
@@ -195,6 +323,10 @@
else:
return self._as_rdict().setitem(w_key, w_value)
+ def setitem_str(self, w_key, w_value):
+ self.content[self.space.str_w(w_key)] = w_value
+ return self
+
def delitem(self, w_key):
space = self.space
if space.is_w(space.type(w_key), space.w_str):
@@ -203,7 +335,7 @@
return self
else:
return space.emptydictimpl
- elif self._is_sane_hash(w_lookup_type):
+ elif self._is_sane_hash(space.type(w_key)):
raise KeyError
else:
return self._as_rdict().delitem(w_key)
@@ -265,7 +397,7 @@
def __init__(self):
self.id = len(self._dict_infos)
- self.setitems = 0; self.delitems = 0
+ self.setitem_strs = 0; self.setitems = 0; self.delitems = 0
self.lengths = 0; self.gets = 0
self.iteritems = 0; self.iterkeys = 0; self.itervalues = 0
self.keys = 0; self.values = 0; self.items = 0
@@ -350,6 +482,9 @@
self.content[w_key] = w_value
self.info.maxcontents = max(self.info.maxcontents, len(self.content))
return self
+ def setitem(self, w_key, w_value):
+ self.info.setitem_strs += 1
+ return self.setitem(w_key, w_value)
def delitem(self, w_key):
if not self.info.seen_non_string_in_write \
and not self.info.seen_non_string_in_read_first \
@@ -457,7 +592,7 @@
return w_default
def set_str_keyed_item(w_dict, w_key, w_value):
- w_dict.implementation = w_dict.implementation.setitem(w_key, w_value)
+ w_dict.implementation = w_dict.implementation.setitem_str(w_key, w_value)
registerimplementation(W_DictMultiObject)
Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Wed Aug 16 17:55:51 2006
@@ -1,7 +1,8 @@
import autopath
from pypy.objspace.std.dictmultiobject import \
W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \
- EmptyDictImplementation, RDictImplementation, StrDictImplementation, SmallDictImplementation
+ EmptyDictImplementation, RDictImplementation, StrDictImplementation, \
+ SmallDictImplementation, SmallStrDictImplementation
from pypy.conftest import gettestobjspace
from pypy.objspace.std.test import test_dictobject
@@ -60,8 +61,10 @@
def test_delitem(self):
self.impl.setitem(self.string, 1000)
self.impl.setitem(self.string2, 2000)
- assert self.impl.delitem(self.string) is self.impl
- assert self.impl.delitem(self.string2) is self.space.emptydictimpl
+ newimpl = self.impl.delitem(self.string)
+ assert newimpl is self.impl
+ newimpl = self.impl.delitem(self.string2)
+ assert newimpl is self.space.emptydictimpl
def test_keys(self):
self.impl.setitem(self.string, 1000)
@@ -94,9 +97,18 @@
class TestStrDictImplementation(TestRDictImplementation):
ImplementionClass = StrDictImplementation
+ def get_impl(self):
+ return self.ImplementionClass(self.space, self.string, self.string2)
+
class TestSmallDictImplementation(TestRDictImplementation):
ImplementionClass = SmallDictImplementation
def get_impl(self):
return self.ImplementionClass(self.space, self.string, self.string2)
+class TestSmallStrDictImplementation(TestRDictImplementation):
+ ImplementionClass = SmallStrDictImplementation
+
+ def get_impl(self):
+ return self.ImplementionClass(self.space, self.string, self.string2)
+
More information about the Pypy-commit
mailing list