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

Guido van Rossum guido@python.org
Tue, 30 Apr 2002 17:54:24 -0400


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

Added Files:
      Tag: TextIndexDS9-branch
	IQueryEngine.py QueryEngine.py 
Log Message:
Add a query engine.

=== Added File Products/ZCTextIndex/IQueryEngine.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################

"""Query Engine Interface."""

import Interface

class IQueryEngine(Interface.Base):
    """Interface for a Query Engine."""

    def executeQuery(index, tree):
        """Execute a query represented by a parse tree on an index.

        The index should implement IIndex.IIndex.  The parse tree
        should implement IQueryParse.IQueryParseTree.

        Return an IIBucket.
        """


=== Added File Products/ZCTextIndex/QueryEngine.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################

"""Query Engine."""

from BTrees.IIBTree import difference, weightedIntersection, weightedUnion

class QueryError(Exception):
    pass

class QueryEngine:

    def __init__(self):
        pass # No state

    def executeQuery(self, index, tree):
        kind = tree.nodeType()
        if kind == "AND":
            L = []
            for subtree in tree.getValue():
                if len(L) == 0:
                    set = self.executeQuery(index, subtree)
                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)
            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])
            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)