[pypy-commit] pypy set-strategies: added test and fix for inplace_and

l.diekmann noreply at buildbot.pypy.org
Thu Nov 10 13:49:27 CET 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r49145:bf74909839b4
Date: 2011-05-02 13:43 +0200
http://bitbucket.org/pypy/pypy/changeset/bf74909839b4/

Log:	added test and fix for inplace_and

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
@@ -116,6 +116,9 @@
     def intersect(self, w_other):
         return self.strategy.intersect(self, w_other)
 
+    def intersect_update(self, w_other):
+        return self.strategy.intersect_update(self, w_other)
+
     def intersect_multiple(self, others_w):
         return self.strategy.intersect_multiple(self, others_w)
 
@@ -299,6 +302,22 @@
                 result.add(w_key)
         return result
 
+    def intersect_update(self, w_set, w_other):
+        if w_set.length() > w_other.length():
+            return w_other.intersect(w_set)
+
+        setdata = newset(self.space)
+        items = self.cast_from_void_star(w_set.sstorage).keys()
+        for key in items:
+            w_key = self.wrap(key)
+            if w_other.has_key(w_key):
+                setdata[w_key] = None
+
+        # do not switch strategy here if other items match
+        w_set.strategy = strategy = self.space.fromcache(ObjectSetStrategy)
+        w_set.sstorage = strategy.cast_to_void_star(setdata)
+        return w_set
+
     def intersect_multiple(self, w_set, others_w):
         result = w_set
         for w_other in others_w:
@@ -747,11 +766,6 @@
 def and__Set_Set(space, w_left, w_other):
     new_set = w_left.intersect(w_other)
     return new_set
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _intersection_dict(space, ld, rd)
-    #XXX when both have same strategy, ini new set from storage
-    # therefore this must be moved to strategies
-    return w_left._newobj(space, new_ld)
 
 and__Set_Frozenset = and__Set_Set
 and__Frozenset_Set = and__Set_Set
@@ -773,10 +787,7 @@
     return
 
 def inplace_and__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _intersection_dict(space, ld, rd)
-    w_left.setdata = new_ld
-    return w_left
+    return w_left.intersect_update(w_other)
 
 inplace_and__Set_Frozenset = inplace_and__Set_Set
 
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
@@ -99,6 +99,12 @@
         c = [2,3]
         assert a.issuperset(c)
 
+    def test_inplace_and(test):
+        a = set([1,2,3,4])
+        b = set([0,2,3,5,6])
+        a &= b
+        assert a == set([2,3])
+
     def test_discard_remove(self):
         a = set([1,2,3,4,5])
         a.remove(1)


More information about the pypy-commit mailing list