[pypy-svn] r39906 - in pypy/dist/pypy: rpython/ootypesystem rpython/ootypesystem/test translator/cli/src

antocuni at codespeak.net antocuni at codespeak.net
Sun Mar 4 18:25:03 CET 2007


Author: antocuni
Date: Sun Mar  4 18:25:01 2007
New Revision: 39906

Modified:
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
   pypy/dist/pypy/rpython/ootypesystem/rdict.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py
   pypy/dist/pypy/translator/cli/src/pypylib.cs
Log:
so far each RPython-dictionary lookup resulted in two
CLI-dictionary-lookups: fix this.

Other backends should be also fixed (it's not trivial for java,
though).



Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Sun Mar  4 18:25:01 2007
@@ -499,6 +499,9 @@
             self.VALUETYPE_T: self._VALUETYPE
             })
 
+        # ll_get() is always used just after a call to ll_contains(),
+        # always with the same key, so backends can optimize/cache the
+        # result
         self._GENERIC_METHODS = frozendict({
             "ll_length": Meth([], Signed),
             "ll_get": Meth([self.KEYTYPE_T], self.VALUETYPE_T),
@@ -1188,15 +1191,17 @@
         self._TYPE = DICT
         self._dict = {}
         self._stamp = 0
+        self._last_key = object() # placeholder != to everything else
 
     def ll_length(self):
         # NOT_RPYTHON
         return len(self._dict)
 
     def ll_get(self, key):
-        # NOT_RPYTHON        
+        # NOT_RPYTHON
         assert typeOf(key) == self._TYPE._KEYTYPE
         assert key in self._dict
+        assert key == self._last_key
         return self._dict[key]
 
     def ll_set(self, key, value):
@@ -1219,6 +1224,7 @@
     def ll_contains(self, key):
         # NOT_RPYTHON
         assert typeOf(key) == self._TYPE._KEYTYPE
+        self._last_key = key
         return key in self._dict
 
     def ll_clear(self):

Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rdict.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rdict.py	Sun Mar  4 18:25:01 2007
@@ -299,7 +299,6 @@
 
 
 def ll_dict_getitem(d, key):
-    # TODO: this is inefficient because it does two lookups
     if d.ll_contains(key):
         return d.ll_get(key)
     else:
@@ -310,7 +309,6 @@
         raise KeyError
 
 def ll_dict_get(d, key, default):
-    # TODO: this is inefficient because it does two lookups
     if d.ll_contains(key):
         return d.ll_get(key)
     else:
@@ -339,7 +337,7 @@
             r.item1 = it.ll_current_value()
             result.ll_setitem_fast(i, r)
         i += 1
-    #assert i == length
+    assert i == length
     return result
 
 

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py	Sun Mar  4 18:25:01 2007
@@ -17,6 +17,7 @@
     DT = Dict(Signed, Float)
     d = new(DT)
     d.ll_set(42, 123.45)
+    assert d.ll_contains(42)
     assert d.ll_get(42) == 123.45
 
 def test_iteritems():
@@ -49,3 +50,10 @@
     assert isinstance(str(DT), str)
     assert isinstance(hash(DT), int)
 
+def test_invalid_cache():
+    DT = Dict(Signed, Signed)
+    d = new(DT)
+    py.test.raises(AssertionError, d.ll_get, 0)
+    d.ll_set(42, 1)
+    d.ll_contains(43)
+    py.test.raises(AssertionError, d.ll_get, 42)

Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/pypylib.cs	(original)
+++ pypy/dist/pypy/translator/cli/src/pypylib.cs	Sun Mar  4 18:25:01 2007
@@ -440,6 +440,8 @@
     public class Dict<TKey, TValue>: System.Collections.Generic.Dictionary<TKey, TValue>
     {
         IEqualityComparer<TKey> comparer = null;
+        TValue cache;
+
         public Dict() {}
         public Dict(IEqualityComparer<TKey> comparer): base(comparer) 
         { 
@@ -447,10 +449,10 @@
         }
 
         public int ll_length() { return this.Count; }
-        public TValue ll_get(TKey key) { return this[key]; }
+        public TValue ll_get(TKey key) { return cache; }
         public void ll_set(TKey key, TValue value) { this[key] = value; }
         public bool ll_remove(TKey key) { return this.Remove(key); }
-        public bool ll_contains(TKey key) { return this.ContainsKey(key); }
+        public bool ll_contains(TKey key) { return this.TryGetValue(key, out cache); }
         public void ll_clear() { this.Clear(); }
 
         public DictItemsIterator<TKey, TValue> ll_get_items_iterator()
@@ -484,6 +486,7 @@
         public void ll_set(TKey key) { this[key] = default(TValue); }
         public bool ll_remove(TKey key) { return this.Remove(key); }
         public bool ll_contains(TKey key) { return this.ContainsKey(key); }
+        public void ll_contains_get() { }
         public void ll_clear() { this.Clear(); }
 
         public DictItemsIterator<TKey, TValue> ll_get_items_iterator()
@@ -502,16 +505,26 @@
 
     public class DictVoidVoid
     {
-        public int ll_length() { return 0; }
+        private int length = 0;
+
+        public int ll_length() { return length; }
         public void ll_get() { }
-        public void ll_set() { }
-        public bool ll_remove() { return false; } // should it be true?
-        public bool ll_contains() { return false; }
-        public void ll_clear() { }
+        public void ll_set() { length = 1; }
+        public bool ll_remove() { 
+            if (length == 0)
+                return false;
+            length = 0;
+            return true;
+        }
+        public bool ll_contains() { return length != 0; }
+        public void ll_contains_get() { }
+        public void ll_clear() { length = 0; }
 
         public DictItemsIterator<int, int> ll_get_items_iterator()
         {
             List<KeyValuePair<int, int>> foo = new List<KeyValuePair<int, int>>();
+            if (length == 1)
+                foo.Add(new KeyValuePair<int, int>(0, 0));
             return new DictItemsIterator<int, int>(foo.GetEnumerator());
         }
     }


More information about the pypy-svn mailing list