[pypy-commit] pypy set-strategies: merged set- with liststrategies. when initializing a set with lists they can copy the storage and strategy from that list without wrapping the storages content
l.diekmann
noreply at buildbot.pypy.org
Tue Dec 20 13:44:08 CET 2011
Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r50751:b0d872ae3261
Date: 2011-12-20 13:42 +0100
http://bitbucket.org/pypy/pypy/changeset/b0d872ae3261/
Log: merged set- with liststrategies. when initializing a set with lists
they can copy the storage and strategy from that list without
wrapping the storages content
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -508,6 +508,11 @@
def getitems_copy(self, w_list):
return self._getitems_range(w_list, True)
+ getitems_wrapped = getitems_copy
+
+ def getitems_unwrapped(self, w_list):
+ return self._getitems_range(w_list, False)
+
def getstorage_copy(self, w_list):
# tuple is unmutable
return w_list.lstorage
@@ -698,6 +703,11 @@
def getitems_copy(self, w_list):
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
+ getitems_wrapped = getitems_copy
+
+ def getitems_unwrapped(self, w_list):
+ return self.unerase(w_list.lstorage)
+
@jit.unroll_safe
def getitems_unroll(self, w_list):
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
@@ -926,6 +936,8 @@
def getitems(self, w_list):
return self.unerase(w_list.lstorage)
+ getitems_wrapped = getitems
+
class IntegerListStrategy(AbstractUnwrappedStrategy, ListStrategy):
_none_value = 0
_applevel_repr = "int"
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -13,6 +13,8 @@
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.listobject import IntegerListStrategy, StringListStrategy,\
+ EmptyListStrategy, RangeListStrategy, ObjectListStrategy, FloatListStrategy
class W_BaseSetObject(W_Object):
typedef = None
@@ -280,6 +282,9 @@
def get_empty_storage(self):
return self.erase(None)
+ def get_storage_from_w_list(self, w_list):
+ return self.get_empty_storage()
+
def is_correct_type(self, w_key):
return False
@@ -384,6 +389,14 @@
setdata[self.unwrap(w_item)] = None
return self.erase(setdata)
+ def get_storage_from_w_list(self, w_list):
+ items = w_list.strategy.getitems_unwrapped(w_list)
+
+ setdata = self.get_empty_dict()
+ for item in items:
+ setdata[item] = None
+ return self.erase(setdata)
+
def length(self, w_set):
return len(self.unerase(w_set.sstorage))
@@ -746,6 +759,14 @@
def get_empty_storage(self):
return self.erase(self.get_empty_dict())
+ def get_storage_from_w_list(self, w_list):
+ items = w_list.strategy.getitems_wrapped(w_list)
+
+ setdata = self.get_empty_dict()
+ for item in items:
+ setdata[item] = None
+ return self.erase(setdata)
+
def get_empty_dict(self):
return newset(self.space)
@@ -883,6 +904,22 @@
def newset(space):
return r_dict(space.eq_w, space.hash_w, force_non_null=True)
+_strategy_map = {
+ EmptyListStrategy: EmptySetStrategy,
+ IntegerListStrategy: IntegerSetStrategy,
+ RangeListStrategy: IntegerSetStrategy,
+ StringListStrategy: StringSetStrategy,
+ FloatListStrategy: ObjectSetStrategy,
+ ObjectListStrategy: ObjectSetStrategy
+}
+
+def set_strategy_and_setdata_from_listobject(space, w_set, w_list):
+ strategy_class = _strategy_map[w_list.strategy.__class__]
+ strategy = space.fromcache(strategy_class)
+
+ w_set.sstorage = strategy.get_storage_from_w_list(w_list)
+ w_set.strategy = strategy
+
def set_strategy_and_setdata(space, w_set, w_iterable):
from pypy.objspace.std.intobject import W_IntObject
if w_iterable is None :
@@ -895,6 +932,10 @@
w_set.sstorage = w_iterable.get_storage_copy()
return
+ if isinstance(w_iterable, W_ListObject):
+ set_strategy_and_setdata_from_listobject(space, w_set, w_iterable)
+ return
+
iterable_w = space.listview(w_iterable)
if len(iterable_w) == 0:
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -8,7 +8,7 @@
is not too wrong.
"""
import py.test
-from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
+from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject, IntegerSetStrategy
from pypy.objspace.std.setobject import _initialize_set
from pypy.objspace.std.setobject import newset
from pypy.objspace.std.setobject import and__Set_Set
@@ -83,6 +83,45 @@
result = set_intersection__Set(space, a, [d,c,b])
assert space.is_true(self.space.eq(result, W_SetObject(space, self.space.wrap(""))))
+ def test_create_set_from_list(self):
+ from pypy.objspace.std.setobject import ObjectSetStrategy, StringSetStrategy
+ from pypy.objspace.std.floatobject import W_FloatObject
+ from pypy.objspace.std.model import W_Object
+
+ w = self.space.wrap
+ intstr = self.space.fromcache(IntegerSetStrategy)
+ tmp_func = intstr.get_storage_from_list
+ # test if get_storage_from_list is no longer used
+ intstr.get_storage_from_list = None
+
+ w_list = W_ListObject(self.space, [w(1), w(2), w(3)])
+ w_set = W_SetObject(self.space)
+ _initialize_set(self.space, w_set, w_list)
+ assert w_set.strategy is intstr
+ assert intstr.unerase(w_set.sstorage) == {1:None, 2:None, 3:None}
+
+ w_list = W_ListObject(self.space, [w("1"), w("2"), w("3")])
+ w_set = W_SetObject(self.space)
+ _initialize_set(self.space, w_set, w_list)
+ assert w_set.strategy is self.space.fromcache(StringSetStrategy)
+ assert w_set.strategy.unerase(w_set.sstorage) == {"1":None, "2":None, "3":None}
+
+ w_list = W_ListObject(self.space, [w("1"), w(2), w("3")])
+ w_set = W_SetObject(self.space)
+ _initialize_set(self.space, w_set, w_list)
+ assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+ for item in w_set.strategy.unerase(w_set.sstorage):
+ assert isinstance(item, W_Object)
+
+ w_list = W_ListObject(self.space, [w(1.0), w(2.0), w(3.0)])
+ w_set = W_SetObject(self.space)
+ _initialize_set(self.space, w_set, w_list)
+ assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+ for item in w_set.strategy.unerase(w_set.sstorage):
+ assert isinstance(item, W_FloatObject)
+
+ # changed cached object, need to change it back for other tests to pass
+ intstr.get_storage_from_list = tmp_func
class AppTestAppSetTest:
diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py
--- a/pypy/objspace/std/test/test_setstrategies.py
+++ b/pypy/objspace/std/test/test_setstrategies.py
@@ -5,7 +5,7 @@
class TestW_SetStrategies:
def wrapped(self, l):
- return W_ListObject([self.space.wrap(x) for x in l])
+ return W_ListObject(self.space, [self.space.wrap(x) for x in l])
def test_from_list(self):
s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
More information about the pypy-commit
mailing list