[pypy-svn] pypy default: Support in rmmap find(reverse=True).

arigo commits-noreply at bitbucket.org
Thu Feb 10 16:48:11 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41786:8f6d23bc36ce
Date: 2011-02-10 16:43 +0100
http://bitbucket.org/pypy/pypy/changeset/8f6d23bc36ce/

Log:	Support in rmmap find(reverse=True).

diff --git a/pypy/rlib/test/test_rmmap.py b/pypy/rlib/test/test_rmmap.py
--- a/pypy/rlib/test/test_rmmap.py
+++ b/pypy/rlib/test/test_rmmap.py
@@ -137,22 +137,31 @@
         interpret(func, [f.fileno()])
         f.close()
 
+    def test_find_rfind(self):
+        f = open(self.tmpname + "g", "w+")
+        f.write("foobarfoobar\0")
+        f.flush()
+        m = mmap.mmap(f.fileno(), 13)
+
+        for s1 in range(-20, 20):
+            for e1 in range(-20, 20):
+                expected = "foobarfoobar\0".find("ob", s1, e1)
+                assert m.find("ob", s1, e1, False) == expected
+                expected = "foobarfoobar\0".rfind("ob", s1, e1)
+                assert m.find("ob", s1, e1, True) == expected
+
+        m.close()
+        f.close()
+
     def test_find(self):
         f = open(self.tmpname + "g", "w+")
-
         f.write("foobarfoobar\0")
         f.flush()
 
-        # prebuilt a table of expected search results
-        expected = {}
-        for s1 in range(-20, 20):
-            for e1 in range(-20, 20):
-                res = "foobarfoobar\0".find("ob", s1, e1)
-                expected.setdefault(s1, {})[e1] = res
-
         def func(no):
             m = mmap.mmap(no, 12)
             assert m.find("\0", 0, 13) == -1    # no searching past the stop
+            assert m.find("\0", 0, 13, True) == -1
             m.close()
             #
             m = mmap.mmap(no, 13)
@@ -165,9 +174,6 @@
             assert m.find("o", 2, 4) == 2
             assert m.find("o", 2, -4) == 2
             assert m.find("o", 8, -5) == -1
-            for s1 in range(-20, 20):
-                for e1 in range(-20, 20):
-                    assert m.find("ob", s1, e1) == expected[s1][e1]
             m.close()
 
         func(f.fileno())

diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -361,7 +361,7 @@
         self.pos += len(res)
         return res
 
-    def find(self, tofind, start, end):
+    def find(self, tofind, start, end, reverse=False):
         self.check_valid()
 
         # XXX naive! how can we reuse the rstr algorithm?
@@ -375,16 +375,33 @@
                 end = 0
         elif end > self.size:
             end = self.size
+        #
+        upto = end - len(tofind)
+        if not reverse:
+            step = 1
+            p = start
+            if p > upto:
+                return -1      # failure (empty range to search)
+        else:
+            step = -1
+            p = upto
+            upto = start
+            if p < upto:
+                return -1      # failure (empty range to search)
+        #
         data = self.data
-        for p in xrange(start, end - len(tofind) + 1):
+        while True:
+            assert p >= 0
             for q in range(len(tofind)):
                 if data[p+q] != tofind[q]:
                     break     # position 'p' is not a match
             else:
                 # full match
                 return p
-        # failure
-        return -1
+            #
+            if p == upto:
+                return -1   # failure
+            p += step
 
     def seek(self, pos, whence=0):
         self.check_valid()


More information about the Pypy-commit mailing list