[pypy-commit] pypy default: Added an integer specialized dictionary.
alex_gaynor
noreply at buildbot.pypy.org
Sat Jul 2 04:50:26 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r45255:5f925529d17a
Date: 2011-07-01 19:57 -0700
http://bitbucket.org/pypy/pypy/changeset/5f925529d17a/
Log: Added an integer specialized dictionary.
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -6,7 +6,7 @@
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rlib.objectmodel import r_dict, we_are_translated
+from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
from pypy.rlib.debug import mark_dict_non_null
from pypy.rlib import rerased
@@ -163,15 +163,22 @@
#XXX implement other strategies later
if type(w_key) is self.space.StringObjectCls:
self.switch_to_string_strategy(w_dict)
- return
+ elif self.space.is_w(self.space.type(w_key), self.space.w_int):
+ self.switch_to_int_strategy(w_dict)
+ else:
+ strategy = self.space.fromcache(ObjectDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
- strategy = self.space.fromcache(ObjectDictStrategy)
+ def switch_to_string_strategy(self, w_dict):
+ strategy = self.space.fromcache(StringDictStrategy)
storage = strategy.get_empty_storage()
w_dict.strategy = strategy
w_dict.dstorage = storage
- def switch_to_string_strategy(self, w_dict):
- strategy = self.space.fromcache(StringDictStrategy)
+ def switch_to_int_strategy(self, w_dict):
+ strategy = self.space.fromcache(IntDictStrategy)
storage = strategy.get_empty_storage()
w_dict.strategy = strategy
w_dict.dstorage = storage
@@ -289,6 +296,9 @@
def get_empty_storage(self):
raise NotImplementedError("abstract base class")
+ def _never_equal_to(self, w_lookup_type):
+ raise NotImplementedError("abstract base class")
+
def setitem(self, w_dict, w_key, w_value):
space = self.space
if self.is_correct_type(w_key):
@@ -331,6 +341,8 @@
if self.is_correct_type(w_key):
return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
+ elif self._never_equal_to(space.type(w_key)):
+ return None
else:
self.switch_to_object_strategy(w_dict)
return w_dict.getitem(w_key)
@@ -363,7 +375,6 @@
w_dict.strategy = strategy
w_dict.dstorage = strategy.erase(d_new)
-
class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
erase, unerase = rerased.new_erasing_pair("object")
@@ -384,8 +395,11 @@
force_non_null=True)
return self.erase(new_dict)
+ def _never_equal_to(self, w_lookup_type):
+ return False
+
def iter(self, w_dict):
- return RDictIteratorImplementation(self.space, self, w_dict)
+ return ObjectIteratorImplementation(self.space, self, w_dict)
def keys(self, w_dict):
return self.unerase(w_dict.dstorage).keys()
@@ -414,6 +428,9 @@
mark_dict_non_null(res)
return self.erase(res)
+ def _never_equal_to(self, w_lookup_type):
+ return _never_equal_to_string(self.space, w_lookup_type)
+
def setitem_str(self, w_dict, key, w_value):
assert key is not None
self.unerase(w_dict.dstorage)[key] = w_value
@@ -424,9 +441,6 @@
if type(w_key) is space.StringObjectCls:
return self.getitem_str(w_dict, w_key.unwrap(space))
# -- End of performance hack --
- if _never_equal_to_string(space, space.type(w_key)):
- return None
-
return AbstractTypedStrategy.getitem(self, w_dict, w_key)
def getitem_str(self, w_dict, key):
@@ -440,27 +454,67 @@
class StrIteratorImplementation(IteratorImplementation):
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
- dict_w = strategy.unerase(dictimplementation.dstorage)
- self.iterator = dict_w.iteritems()
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
def next_entry(self):
# note that this 'for' loop only runs once, at most
- for str, w_value in self.iterator:
- return self.space.wrap(str), w_value
+ for key, w_value in self.iterator:
+ return self.dictimplementation.strategy.wrap(key), w_value
else:
return None, None
-class RDictIteratorImplementation(IteratorImplementation):
+class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
+ erase, unerase = rerased.new_erasing_pair("int")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def wrap(self, unwrapped):
+ return self.space.wrap(unwrapped)
+
+ def unwrap(self, wrapped):
+ return self.space.int_w(wrapped)
+
+ def get_empty_storage(self):
+ return self.erase({})
+
+ def is_correct_type(self, w_obj):
+ space = self.space
+ return space.is_w(space.type(w_obj), space.w_int)
+
+ def _never_equal_to(self, w_lookup_type):
+ space = self.space
+ # XXX there are many more types
+ return (space.is_w(w_lookup_type, space.w_NoneType) or
+ space.is_w(w_lookup_type, space.w_str) or
+ space.is_w(w_lookup_type, space.w_unicode)
+ )
+
+ def iter(self, w_dict):
+ return IntIteratorImplementation(self.space, self, w_dict)
+
+class IntIteratorImplementation(IteratorImplementation):
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
- d = strategy.unerase(dictimplementation.dstorage)
- self.iterator = d.iteritems()
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
def next_entry(self):
# note that this 'for' loop only runs once, at most
- for item in self.iterator:
- return item
+ for key, w_value in self.iterator:
+ return self.dictimplementation.strategy.wrap(key), w_value
+ else:
+ return None, None
+
+
+class ObjectIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key, w_value in self.iterator:
+ return self.dictimplementation.strategy.wrap(key), w_value
else:
return None, None
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -805,7 +805,12 @@
o.a = 1
assert "StringDictStrategy" in self.get_strategy(d)
-
+ def test_empty_to_int(self):
+ import sys
+ d = {}
+ d[1] = "hi"
+ assert "IntDictStrategy" in self.get_strategy(d)
+ assert d[1L] == "hi"
class FakeString(str):
@@ -846,6 +851,10 @@
assert isinstance(string, str)
return string
+ def int_w(self, integer):
+ assert isinstance(integer, int)
+ return integer
+
def wrap(self, obj):
return obj
More information about the pypy-commit
mailing list