[Zope-CVS] CVS: Products/ZCTextIndex - QueryEngine.py:1.1.2.2

Guido van Rossum guido@python.org
Wed, 1 May 2002 10:46:49 -0400


Update of /cvs-repository/Products/ZCTextIndex
In directory cvs.zope.org:/tmp/cvs-serv7231

Modified Files:
      Tag: TextIndexDS9-branch
	QueryEngine.py 
Log Message:
Rewrite the AND and OR queries to (a) be correct, and (b) be cleaner.
We use L.sort(cmpfunc) because the number of terms in an AND or OR
query is expected to be very small; this makes the code much cleaner.
The AND query is also rewritten to save all the NOT results for last.


=== Products/ZCTextIndex/QueryEngine.py 1.1.2.1 => 1.1.2.2 ===
         if kind == "AND":
             L = []
+            Nots = []
             for subtree in tree.getValue():
-                if len(L) == 0:
-                    set = self.executeQuery(index, subtree)
+                if subtree.nodeType() == "NOT":
+                    Nots.append(self.executeQuery(index, subtree.getValue()))
                 else:
-                    set = self._executeNotQuery(index, subtree)
-                L.append((len(set), set))
-            L.sort()
-            set = L[0][1]
-            for i in range(1, len(L)):
-                Li1 = L[i][1]
-                if isinstance(Li1, type(())):
-                    assert Li1[0] == "NOT"
-                    set = difference(set, Li1[1])
-                else:
-                    dummy, set = weightedIntersection(set, Li1)
+                    L.append(self.executeQuery(index, subtree))
+            assert L
+            L.sort(lambda x, y: cmp(len(x), len(y)))
+            set = L[0]
+            for x in L[1:]:
+                dummy, set = weightedIntersection(set, x)
+            if Nots:
+                Nots.sort(lambda x, y: cmp(len(x), len(y)))
+                notset = Nots[0]
+                for x in Nots[1:]:
+                    dummy, notset = weightedUnion(notset, x)
+                set = difference(set, notset)
             return set
         if kind == "OR":
             L = []
             for subtree in tree.getValue():
-                set = self.executeQuery(index, subtree)
-                L.append((len(set), set))
-            L.sort()
-            set = L[0][1]
-            for i in range(1, len(L)):
-                dummy, set = weightedUnion(set, L[i][1])
+                L.append(self.executeQuery(index, subtree))
+            L.sort(lambda x, y: cmp(len(x), len(y)))
+            set = L[0]
+            for x in L[1:]:
+                dummy, set = weightedUnion(set, x)
             return set
         if kind == "ATOM":
             return index.search(tree.getValue())
         if kind == "NOT":
             raise QueryError, "NOT operator must occur right after AND"
-
-    def _executeNotQuery(self, index, tree):
-        if tree.nodeType() == "NOT":
-            return ("NOT", self.executeQuery(index, tree.getValue()))
-        else:
-            return self.executeQuery(index, tree)