[Zope-Checkins] CVS: Zope/lib/python/BTrees/tests - testBTrees.py:1.34

Tim Peters tim.one@comcast.net
Wed, 12 Jun 2002 17:50:33 -0400


Update of /cvs-repository/Zope/lib/python/BTrees/tests
In directory cvs.zope.org:/tmp/cvs-serv25733/tests

Modified Files:
	testBTrees.py 
Log Message:
New testPathologicalRangeSearch().  The nasty part of this test is
commented out for now, because it fails.  I'm working on a fix.  The
problem was found by eyeballing the range-test implementation.  If you
delete a key from a BTree that just happens to be the first key in a
bucket, then a later high-end range search giving that specific key as
the endpoint claims that no keys are in the range, and whether or not
that's actually true.


=== Zope/lib/python/BTrees/tests/testBTrees.py 1.33 => 1.34 ===
         self.assertEqual(diff , [], diff)
 
+    def testPathologicalRangeSearch(self):
+        t = self.t
+        # Build a 2-level tree with at least two buckets.
+        for i in range(200):
+            t[i] = i
+        items, dummy = t.__getstate__()
+        self.assert_(len(items) > 2)   # at least two buckets and a key
+        # All values in the first bucket are < firstkey.  All in the
+        # second bucket are >= firstkey, and firstkey is the first key in
+        # the second bucket.
+        firstkey = items[1]
+        therange = t.keys(-1, firstkey)
+        self.assertEqual(len(therange), firstkey + 1)
+        self.assertEqual(list(therange), range(firstkey + 1))
+        # Now for the tricky part.  If we delete firstkey, the second bucket
+        # loses its smallest key, but firstkey remains in the BTree node.
+        # If we then do a high-end range search on firstkey, the BTree node
+        # directs us to look in the second bucket, but there's no longer any
+        # key <= firstkey in that bucket.  The correct answer points to the
+        # end of the *first* bucket.  The algorithm has to be smart enough
+        # to "go backwards" in the BTree then; if it doesn't, it will
+        # erroneously claim that the range is empty.
+        del t[firstkey]
+        therange = t.keys(-1, firstkey)
+        # XXX The next two currently fail.  I'm working on a fix (tim).
+        #self.assertEqual(len(therange), firstkey)
+        #self.assertEqual(list(therange), range(firstkey))
+
     def testInsertMethod(self):
         t = self.t
         t[0] = 1