Author: Lukas Diekmann <lukas.diekm...@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])) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit