[pypy-svn] r40072 - in pypy/dist/pypy: config doc/config objspace/std objspace/std/test

mwh at codespeak.net mwh at codespeak.net
Thu Mar 8 15:40:06 CET 2007


Author: mwh
Date: Thu Mar  8 15:40:04 2007
New Revision: 40072

Added:
   pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt   (contents, props changed)
Modified:
   pypy/dist/pypy/config/pypyoption.py
   pypy/dist/pypy/objspace/std/dictmultiobject.py
   pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py
   pypy/dist/pypy/objspace/std/test/test_dictobject.py
Log:
add a config option for using the small dictionary implementations.


Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Thu Mar  8 15:40:04 2007
@@ -157,6 +157,11 @@
                    default=False,
                    requires=[("objspace.std.withmultidict", True)]),
 
+        BoolOption("withsmalldicts",
+                   "handle small dictionaries differently",
+                   default=False,
+                   requires=[("objspace.std.withmultidict", True)]),
+
         BoolOption("withrangelist",
                    "enable special range list implementation that does not "
                    "actually create the full list until the resulting "

Added: pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt	Thu Mar  8 15:40:04 2007
@@ -0,0 +1 @@
+Use a specialized implementation for small (<5 elements) dictionaries.

Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/dictmultiobject.py	Thu Mar  8 15:40:04 2007
@@ -140,13 +140,17 @@
         return None
 
     def setitem(self, w_key, w_value):
-        if _is_str(self.space, w_key):
-            return StrDictImplementation(self.space).setitem_str(w_key, w_value)
-            #return SmallStrDictImplementation(self.space, w_key, w_value)
-        else:
-            space = self.space
-            return space.DefaultDictImpl(space).setitem(w_key, w_value)
-        #return SmallDictImplementation(self.space, w_key, w_value)
+        space = self.space
+        if _is_str(space, w_key):
+            if space.config.objspace.std.withsmalldicts:
+                return SmallStrDictImplementation(space, w_key, w_value)
+            else:
+                return StrDictImplementation(space).setitem_str(w_key, w_value)
+        else:
+            if space.config.objspace.std.withsmalldicts:
+                return SmallDictImplementation(space, w_key, w_value)
+            else:
+                return space.DefaultDictImpl(space).setitem(w_key, w_value)
     def setitem_str(self, w_key, w_value, shadows_type=True):
         return StrDictImplementation(self.space).setitem_str(w_key, w_value)
         #return SmallStrDictImplementation(self.space, w_key, w_value)
@@ -241,12 +245,17 @@
                 return self.space.emptydictimpl
             return self
         else:
-            raise KeyError        
-    
+            entry.w_key = None
+            raise KeyError
+
     def length(self):
         return self.valid
     def get(self, w_lookup):
-        return self._lookup(w_lookup).w_value
+        entry = self._lookup(w_lookup)
+        val = entry.w_value
+        if val is None:
+            entry.w_key = None
+        return val
 
     def iteritems(self):
         return self._convert_to_rdict().iteritems()
@@ -266,7 +275,6 @@
 
 class StrEntry(object):
     def __init__(self):
-        self.hash = 0
         self.key = None
         self.w_value = None
     def __repr__(self):
@@ -274,12 +282,11 @@
 
 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].hash = hash(key)
         self.entries[0].key = key
         self.entries[0].w_value = w_value
         self.valid = 1
@@ -289,11 +296,10 @@
         _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:
+            if hash(look_entry.key) == _hash and look_entry.key == key:
                 return look_entry
             i += 1
 
@@ -326,7 +332,7 @@
         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, shadows_type=True):
         entry = self._lookup(self.space.str_w(w_key))
         if entry.w_value is None:
@@ -351,20 +357,25 @@
                     return self.space.emptydictimpl
                 return self
             else:
+                entry.key = None
                 raise KeyError
         elif _is_sane_hash(self.space, w_key_type):
             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(space.str_w(w_lookup)).w_value
+            entry = self._lookup(space.str_w(w_lookup))
+            val = entry.w_value
+            if val is None:
+                entry.key = None
+            return val
         elif _is_sane_hash(self.space, w_lookup_type):
             return None
         else:

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	Thu Mar  8 15:40:04 2007
@@ -46,6 +46,15 @@
         l[0] = 24
         assert a.abc == 12
 
+class TestW_DictSmall(test_dictobject.TestW_DictObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withsmalldicts": True})
+
+class AppTest_DictSmall(test_dictobject.AppTest_DictObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withsmalldicts": True})
+
+class C: pass
 
 class FakeSpace(test_dictobject.FakeSpace):
     def str_w(self, string):

Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_dictobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_dictobject.py	Thu Mar  8 15:40:04 2007
@@ -384,6 +384,7 @@
 FakeSpace.config.objspace.std = Config()
 FakeSpace.config.objspace.std.withdictmeasurement = False
 FakeSpace.config.objspace.std.withsharingdict = False
+FakeSpace.config.objspace.std.withsmalldicts = False
 FakeSpace.config.objspace.opcodes = Config()
 FakeSpace.config.objspace.opcodes.CALL_LIKELY_BUILTIN = False
 



More information about the Pypy-commit mailing list