Viewing file: Optimizer.py (6.33 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # # File Name: Optimizer.py # # """ Support routines for Versa optimizations WWW: http://4suite.org/4XSLT e-mail: support@4suite.org
Copyright (c) 1999-2001 Fourthought Inc, USA. All Rights Reserved. See http://4suite.org/COPYRIGHT for license and copyright information """
import types
import DataTypes, NamedExpressions import ResourceExpressions, CoreFunctions, Literals, Traversal from Ft.Lib import boolean, number
def IsCoreFunction(expr, name): if isinstance(expr, NamedExpressions.FunctionCall) and \ expr._name == name: return 1 return 0
def IsSimpleTextSearch(expr): if isinstance(expr, Traversal.ForwardTraversal) and expr.isFilter and \ isinstance(expr.resources, ResourceExpressions.CurrentExpression) and \ (isinstance(expr.predicates, Literals.ResourceLiteral) or \ isinstance(expr.predicates, ResourceExpressions.PureQNameExpression)) and \ IsCoreFunction(expr.filterExpr, "contains") and \ isinstance(expr.filterExpr._args[0], Literals.StringLiteral): return expr.predicates, expr.filterExpr._args[0].evaluate(con) return None
def IsSimpleForwardTraverse(expr): if isinstance(expr, Traversal.ForwardTraversal) and \ isinstance(expr.resources, ResourceExpressions.CurrentExpression) and \ isinstance(expr.filterExpr, ResourceExpressions.LiteralExpression) and \ expr.filterExpr.value == boolean.true and \ (isinstance(expr.predicates, Literals.ResourceLiteral) or \ isinstance(expr.predicates, ResourceExpressions.PureQNameExpression)): return expr.predicates return None
def IsSimpleBackwardTraverse(expr): if isinstance(expr, Traversal.BackwardTraversal) and \ isinstance(expr.objects, ResourceExpressions.CurrentExpression) and \ isinstance(expr.filterExpr, ResourceExpressions.LiteralExpression) and \ expr.filterExpr.value == boolean.true and \ (isinstance(expr.predicates, Literals.ResourceLiteral) or \ isinstance(expr.predicates, ResourceExpressions.PureQNameExpression)): return expr.predicates return None
def IsSimpleForwardTraverseChain(expr, con): if IsSimpleForwardTraverse(expr): return [expr.predicates.evaluate(con)] if isinstance(expr, Traversal.ForwardTraversal) and \ isinstance(expr.resources, Traversal.ForwardTraversal) and \ isinstance(expr.filterExpr, ResourceExpressions.LiteralExpression) and \ expr.filterExpr.value == boolean.true and \ (isinstance(expr.predicates, Literals.ResourceLiteral) or \ isinstance(expr.predicates, ResourceExpressions.PureQNameExpression)): return IsSimpleForwardTraverseChain(expr.resources, con) + \ [expr.predicates.evaluate(con)] return []
def IsFixedResourceCollection(expr): if isinstance(expr, Literals.ResourceLiteral) or \ isinstance(expr, ResourceExpressions.PureQNameExpression): return 1 if IsCoreFunction(expr, 'set') or \ IsCoreFunction(expr, 'list'): if len([ i for i in expr._args if isinstance(i, Literals.ResourceLiteral) or \ isinstance(i, ResourceExpressions.PureQNameExpression) ]) == len(expr._args): return 1 return 0
def IsDotExpression(expr): if isinstance(expr, ResourceExpressions.CurrentExpression): return 1 return 0
#def SubQueryFunction(expr, con, relations): # pred = IsSimpleForwardTraverse(expr) # if pred and not relations.has_key(pred): # relations[pred] = ResourceExpressions.GetRelations(None, pred, con) # return lambda con:
def SubQueryFunction(expr, con): """ Handles subqueries of functions such as distribute, filter, map, etc. The main optimization is that in some cases, e.g. simple traversal, one overall relation can be computed and it's a simple dictionary lookup for each cycle of the function """ sft_pred = IsSimpleForwardTraverse(expr) sts_info = IsSimpleTextSearch(expr) sbt_pred = IsSimpleBackwardTraverse(expr) sftc_preds = IsSimpleForwardTraverseChain(expr, con) if sft_pred: #print "OPTIMIZER: sub-query as simple traversal" relations = ResourceExpressions.GetRelations(None, sft_pred.evaluate(con), con, 0) return lambda con, r=relations: r.get(DataTypes.ToResource(con.current), []) elif sbt_pred: #print "OPTIMIZER: sub-query as simple backward traversal" relations = ResourceExpressions.GetRelations(None, sbt_pred.evaluate(con), con, 1) return lambda con, r=relations: r.get(con.current, []) elif IsDotExpression(expr): #print "OPTIMIZER: sub-query as dot expression" return lambda con: con.current elif sftc_preds: #print "OPTIMIZER: sub-query as simple traversal chain" relations = ResourceExpressions.GetRelations(None, sftc_preds[0], con, 0) for p in sftc_preds[1:]: rel = ResourceExpressions.GetRelations(None, p, con, 0) for k in relations.keys(): next = [] for subj in relations[k]: next.extend(rel.get(subj, [])) relations[k] = next return lambda con, r=relations: r.get(DataTypes.ToResource(con.current), []) ## elif sts_info: ## pred, criteria = sts_info ## searched = TextSearch(None, criteria, con, 0) ## return lambda con, s=searched, p=preds: s.get(DataTypes.ToResource(con.current), []) else: #print "OPTIMIZER: unoptimized sub-query" return lambda con, e=expr: e.evaluate(con)
def TextSearch(start, criteria, con, useSubProps=1): """ Returns a dictionary of lists. The dict maps properties to text matches. Each list contains subjects that had the given text match for each property """ start = start and DataTypes.ToList(start) or None suspects = con.driver.complete(None, None, '.*'+criteria+'.*', None, con.scope, flags={"objectFlags": Model.REGEX}) sdict = {} for s in suspects: subj = DataTypes.ToResource(s[0]) if not start or subj in start: pred = DataTypes.ToResource(s[1]) if not sdict.has_key(pred): sdict[pred] = [] sdict[pred].append(subj) return sdict
|