[Zope-CVS] CVS: Packages/pypes/pypes - interfaces.py:1.23
query.py:1.15
Casey Duncan
casey at zope.com
Fri May 14 00:39:03 EDT 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv23901
Modified Files:
interfaces.py query.py
Log Message:
Implement basic union & intersection for Join partial results
Implement actualized results
reload(sys)
=== Packages/pypes/pypes/interfaces.py 1.22 => 1.23 ===
--- Packages/pypes/pypes/interfaces.py:1.22 Tue May 11 23:48:47 2004
+++ Packages/pypes/pypes/interfaces.py Fri May 14 00:38:29 2004
@@ -716,13 +716,13 @@
PypesQueryError.
"""
- def magnitude(*names):
- """Return an integer which is the approximate length of the result
- with the names specified. If no names are specified then the magnitude
- for iterating all inputs is returned. Implementations should strive for
- efficiency over accuracy, although accuracy can help the query engine
- determine a more efficient plan.
- """
+ #def magnitude(*names):
+ # """Return an integer which is the approximate length of the result
+ # with the names specified. If no names are specified then the magnitude
+ # for iterating all inputs is returned. Implementations should strive for
+ # efficiency over accuracy, although accuracy can help the query engine
+ # determine a more efficient plan.
+ # """
def iterResult(*names):
"""Yield the items for the specified input names where the criteria
@@ -731,10 +731,10 @@
matching items from the cooresponding named inputs.
"""
- def resultSet(*names):
- """Return an ISet object containing the items from the inputs named.
- If a single name is specified, then return a set of matching objects
- from the input. If multiple names are specified, return a set of
- tuples of the matching items from the cooresponding named inputs.
- """
+ #def resultSet(*names):
+ # """Return an ISet object containing the items from the inputs named.
+ # If a single name is specified, then return a set of matching objects
+ # from the input. If multiple names are specified, return a set of
+ # tuples of the matching items from the cooresponding named inputs.
+ # """
=== Packages/pypes/pypes/query.py 1.14 => 1.15 ===
--- Packages/pypes/pypes/query.py:1.14 Thu May 13 00:33:37 2004
+++ Packages/pypes/pypes/query.py Fri May 14 00:38:29 2004
@@ -47,7 +47,7 @@
from operator import mul
from sets import Set
-from itertools import imap
+from itertools import imap, ifilter
from zope.interface import implements
from compiler import ast
from BTrees.OOBTree import OOBTree, OOTreeSet
@@ -330,7 +330,7 @@
'in': injoin}
def __init__(self, input_map, criteria):
- """Construct the joins
+ """Construct the join
input_map -- a mapping object mapping names => inputs.
@@ -387,6 +387,16 @@
def namesUsed(self):
return self._criteria.freeNames(self._inputs.keys())
+ def union(self, other):
+ inputs = union_input_maps(self.inputMap(), other.inputMap())
+ criteria = self.criteriaExpr() | other.criteriaExpr()
+ return CartProduct(inputs, criteria)
+
+ def intersection(self, other):
+ inputs = intersect_input_maps(self.inputMap(), other.inputMap())
+ criteria = self.criteriaExpr() & other.criteriaExpr()
+ return CartProduct(inputs, criteria)
+
def _iterJoin(self, reverse=False):
# Generates (left, right) pairs of joined terms
join = self._join_ops[self._operator]
@@ -427,6 +437,108 @@
return imap(output, self._iterJoin(self.reverse))
else:
raise NotImplementedError
+
+
+class ActualizedResult:
+ """Partial result with greedy evaluation.
+
+ When instantiated, the inputs are processed immediately against the
+ criteria. The criteria may consist of one or more terms each filtering
+ exactly one input. Multiple terms are contained in a single AND
+ boolean operation.
+ """
+
+ implements(IPartialResult)
+
+ def __init__(self, input_map, criteria=None):
+ """Construct the actualized result
+
+ input_map -- a mapping object mapping names => inputs.
+
+ criteria -- criteria expression, an IExpression object. Supported
+ criteria consists of one or more terms that each refer to a single
+ input. If criteria is omitted, then the actualized result is the
+ same as the inputs provided.
+
+ If the criteria is not supported, raise CantProcess
+ """
+ self._criteria = criteria
+ if criteria is not None:
+ node = criteria.ast().getChildNodes()[0]
+ if (len(criteria.freeNames(input_map.keys())) > 1
+ and isinstance(node, ast.And)):
+ terms = node.getChildNodes()
+ else:
+ terms = (node,)
+ bindings = criteria.bindings()
+ filters = {} # Map input name => filter expression
+ for term in terms:
+ term_expr = Expression.fromAstNode(term, bindings)
+ try:
+ input_name, = term_expr.freeNames()
+ except ValueError:
+ raise CantProcess, \
+ 'cannot actualize result for criteria containing join'
+ if input_name not in input_map:
+ raise PypesQueryInputError, \
+ 'name %s in criteria not found in inputs'
+ if input_name in filters:
+ filters[input_name] = filters[input_name] & term_expr
+ else:
+ filters[input_name] = term_expr
+
+ # Filter the inputs as results
+ self._inputs = {}
+ for name, ipt in input_map.items():
+ if name in filters:
+ self._inputs[name] = Set(
+ ifilter(filters[name].makeFunction(name), ipt))
+ else:
+ self._inputs[name] = ipt
+ else:
+ self._inputs = input_map.copy()
+
+ def inputMap(self):
+ return self._inputs.copy()
+
+ def criteriaExpr(self):
+ return self._criteria
+
+ def namesUsed(self):
+ return self._criteria.freeNames(self._inputs.keys())
+
+ def union(self, other):
+ """A union with an actualized result returns a new partial result
+ the same class as other, with inputs unioned with self
+ """
+ if isinstance(other, ActualizedResult):
+ # Actualized results have already realized the criteria,
+ # Drop the criteria here to avoid redundant processing
+ criteria = None
+ else:
+ criteria = other.criteriaExpr()
+ inputs = union_input_maps(self.inputMap(), other.inputMap())
+ return other.__class__(inputs, criteria)
+
+ def intersection(self, other):
+ """An intersection with an actualized result returns a new partial
+ result the same class as other, with inputs intersected with self
+ """
+ if isinstance(other, ActualizedResult):
+ # Actualized results have already realized the criteria,
+ # Drop the criteria here to avoid redundant processing
+ criteria = None
+ else:
+ criteria = other.criteriaExpr()
+ inputs = intersect_input_maps(self.inputMap(), other.inputMap())
+ return other.__class__(inputs, criteria)
+
+ def iterResult(self, *names):
+ if len(names) == 1:
+ return iter(self._inputs[names[0]])
+ else:
+ return CartProduct(self._inputs).iterResult(*names)
+
def sort(iterable, expression, order=ascending, limit=None):
"""Return a sequence containing the elements of iterable sorted in order
More information about the Zope-CVS
mailing list