[Mulgara-svn] r1771 - trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi
pag at mulgara.org
pag at mulgara.org
Wed Aug 12 19:01:42 UTC 2009
Author: pag
Date: 2009-08-12 12:01:41 -0700 (Wed, 12 Aug 2009)
New Revision: 1771
Added:
trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
Log:
A query transformation that moves OR expressions up to the root of the expression tree
Added: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java (rev 0)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java 2009-08-12 19:01:41 UTC (rev 1771)
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2009 DuraSpace, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mulgara.resolver.spi;
+
+import org.apache.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.mulgara.query.Constraint;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintFilter;
+
+/**
+ * A transformer that works on the basis of expanding a product of sums into a sum of products.
+ * This is needed because our disjunctions (sums) are very inefficient, particularly for searching.
+ *
+ * @created August 7, 2009
+ * @author Paul Gearon
+ * @copyright © 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public class SumOfProductExpansionTransformer extends AbstractSymbolicTransformer {
+ /** Logger */
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(SumOfProductExpansionTransformer.class.getName());
+
+
+ @Override
+ public ConstraintExpression transformExpression(SymbolicTransformationContext context, ConstraintExpression expr) throws SymbolicTransformationException {
+ // This is the main case.
+ if (expr instanceof ConstraintConjunction) {
+ return transformConjunction(context, (ConstraintConjunction)expr);
+ }
+
+ // all else go through the default handling
+ return super.transformExpression(context, expr);
+ }
+
+
+ protected ConstraintExpression transformConjunction(SymbolicTransformationContext context, ConstraintConjunction expr) throws SymbolicTransformationException {
+ List<ConstraintExpression> args = expr.getElements();
+ for (int i = 0; i < args.size(); i++) {
+ ConstraintExpression arg = args.get(i);
+
+ // depth first
+ ConstraintExpression tx = transformExpression(context, arg);
+ if (tx != arg) {
+ // there was a change, so reset and start again
+ List<ConstraintExpression> newArgs = new ArrayList<ConstraintExpression>(args);
+ newArgs.set(i, tx);
+ return new ConstraintConjunction(newArgs);
+ }
+
+ // test for expansion
+ if (arg instanceof ConstraintDisjunction) {
+ return expandConstraint((ConstraintDisjunction)arg, args, i);
+ }
+
+ // test filtered constraints for expansion
+ if (arg instanceof ConstraintFilter) {
+ ConstraintFilter filtered = (ConstraintFilter)arg;
+ ConstraintExpression innerArg = filtered.getUnfilteredConstraint();
+ if (innerArg instanceof ConstraintDisjunction) {
+ return new ConstraintFilter(expandConstraint((ConstraintDisjunction)arg, args, i), filtered.getFilter());
+ }
+ }
+ }
+ // no expandable terms found
+ return expr;
+ }
+
+
+ /**
+ * Creates a new ConstraintDisjunction of conjunctions with one fewer disjunctive term.
+ * @param arg The disjunction to be expanded into the outer conjunction.
+ * @param outerArgs The arguments of the parent expression to be distributed into.
+ * @param argOffset The position of the argument to be replaced in the outerArgs
+ * @return
+ */
+ private ConstraintDisjunction expandConstraint(ConstraintDisjunction arg, List<ConstraintExpression> outerArgs, int argOffset) {
+ // need to expand by duplicating the conjunction for each element in the disjunction
+ List<ConstraintExpression> disjArgs = arg.getElements();
+ // accumulate the arguments to the new parent disjunction
+ List<ConstraintExpression> expandedDisjArgs = new ArrayList<ConstraintExpression>();
+ for (ConstraintExpression disjArg: disjArgs) {
+ // copy the original arguments
+ List<ConstraintExpression> conjArgs = new ArrayList<ConstraintExpression>(outerArgs);
+ // replace the disjunction element with one of the arguments from the disjunction
+ conjArgs.set(argOffset, disjArg);
+ // create a new conjunction with these modified arguments
+ expandedDisjArgs.add(new ConstraintConjunction(conjArgs));
+ }
+ // check that the distibution is the same size
+ assert expandedDisjArgs.size() == disjArgs.size();
+ return new ConstraintDisjunction(expandedDisjArgs);
+ }
+
+ @Override
+ protected ConstraintExpression transformConstraint(SymbolicTransformationContext context, Constraint c)
+ throws SymbolicTransformationException {
+ return c;
+ }
+
+}
More information about the Mulgara-svn
mailing list