Author: ssmiweve
Date: 2008-11-25 14:49:33 +0100 (Tue, 25 Nov 2008)
New Revision: 6980
Modified:
branches/2.17/query-api/src/main/java/no/sesat/search/query/finder/ChildFinder.java
branches/2.17/query-api/src/main/java/no/sesat/search/query/parser/alt/AbstractAlternation.java
Log:
Issue SKER5016: (Strange infinite loop in VeryFastTokenEvaluator.java on a few
number of newscase person pages)
Modified:
branches/2.17/query-api/src/main/java/no/sesat/search/query/finder/ChildFinder.java
===================================================================
---
branches/2.17/query-api/src/main/java/no/sesat/search/query/finder/ChildFinder.java
2008-11-25 07:59:41 UTC (rev 6979)
+++
branches/2.17/query-api/src/main/java/no/sesat/search/query/finder/ChildFinder.java
2008-11-25 13:49:33 UTC (rev 6980)
@@ -1,4 +1,4 @@
-/* Copyright (2007) Schibsted Søk AS
+/* Copyright (2007-2008) Schibsted Søk AS
* This file is part of SESAT.
*
* SESAT is free software: you can redistribute it and/or modify
@@ -23,13 +23,23 @@
import no.sesat.search.query.parser.*;
-final class ChildFinder extends AbstractReflectionVisitor {
-
+/** Used to find if a particular clause exists underneath another.
+ *
+ * @version $Id$
+ */
+public final class ChildFinder extends AbstractReflectionVisitor {
+
private boolean found;
private Clause child = null;
+ /** Does the child clause exist any depth underneath the parent.
+ *
+ * @param parent the parent clause
+ * @param child the child clause.
+ * @return Does the child clause exist any depth underneath the parent.
+ */
public synchronized boolean childExists(final OperationClause parent,
final Clause child) {
-
+
found = false;
this.child = child;
visit(parent);
@@ -42,7 +52,7 @@
clause.getSecondClause().accept(this);
}
}
-
+
protected void visitImpl(final OperationClause clause) {
if (!found ) { // still looking
clause.getFirstClause().accept(this);
@@ -50,7 +60,7 @@
}
protected void visitImpl(final LeafClause clause) {
-
+
found = clause == child;
}
Modified:
branches/2.17/query-api/src/main/java/no/sesat/search/query/parser/alt/AbstractAlternation.java
===================================================================
---
branches/2.17/query-api/src/main/java/no/sesat/search/query/parser/alt/AbstractAlternation.java
2008-11-25 07:59:41 UTC (rev 6979)
+++
branches/2.17/query-api/src/main/java/no/sesat/search/query/parser/alt/AbstractAlternation.java
2008-11-25 13:49:33 UTC (rev 6980)
@@ -1,4 +1,4 @@
-/* Copyright (2007) Schibsted Søk AS
+/* Copyright (2007-2008) Schibsted Søk AS
* This file is part of SESAT.
*
* SESAT is free software: you can redistribute it and/or modify
@@ -31,6 +31,7 @@
import no.sesat.search.query.OperationClause;
import no.sesat.search.query.OrClause;
import no.sesat.search.query.XorClause;
+import no.sesat.search.query.finder.ChildFinder;
import org.apache.log4j.Logger;
/** Base abstraction class for any Alternation implementation.
@@ -41,43 +42,43 @@
* @version <tt>$Id$</tt>
*/
public abstract class AbstractAlternation implements Alternation{
-
- // Constants -----------------------------------------------------
-
+
+ // Constants -----------------------------------------------------
+
private static final Logger LOG =
Logger.getLogger(AbstractAlternation.class);
-
+
private static final String ERR_MULTIPLE_POSSIBLE_PARENTS = "Multiple
parents exist with same (or sub) class as ";
-
+
// Attributes ----------------------------------------------------
-
+
/**
* The context to work within.
*/
- protected final Context context;
-
+ protected final Context context;
+
// Static --------------------------------------------------------
-
-
+
+
// Constructors --------------------------------------------------
-
- /** Creates a new instance of AbstractAlternation
- * @param cxt
+
+ /** Creates a new instance of AbstractAlternation
+ * @param cxt
*/
public AbstractAlternation(final Context cxt) {
context = cxt;
}
-
+
// Public --------------------------------------------------------
-
-
+
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
-
+
/** will return null instead of a leafClause
- * @param clause
- * @return
+ * @param clause
+ * @return
*/
protected <T extends DoubleOperatorClause> T leftOpChild(final T clause){
@@ -86,8 +87,8 @@
}
/** return the left child, left or operation.
- * @param clause
- * @return
+ * @param clause
+ * @return
*/
protected Clause leftChild(final OperationClause clause) {
@@ -97,8 +98,8 @@
}
/** will return null instead of a leafClause
- * @param clause
- * @return
+ * @param clause
+ * @return
*/
protected <T extends DoubleOperatorClause> T rightOpChild(final T clause){
@@ -107,8 +108,8 @@
}
/** will return right child, leaf or operation.
- * @param clause
- * @return
+ * @param clause
+ * @return
*/
protected Clause rightChild(final DoubleOperatorClause clause) {
@@ -121,8 +122,8 @@
* And the child must be a descendant of the root.
* The result will also be assignable from the root argument's class.
* If there exists multiple parents all of the required class an
IllegalStateException is thrown.
- * @param child
- * @param root
+ * @param child
+ * @param root
*/
protected <T extends OperationClause> T parent(final T root, final Clause
child) {
@@ -140,9 +141,9 @@
}
/** return all parents operation clauses of the given child.
- * @param root
- * @param child
- * @return
+ * @param root
+ * @param child
+ * @return
*/
protected <T extends OperationClause> List<T> parents(final T root, final
Clause child) {
@@ -150,13 +151,14 @@
}
/** Build new DoubleOperatorClauses from newChild all the way back up to
the root.
- * XXX Only handles single splits, or one layer of variations, denoted by
the childsParentBeforeRotation argument.
- * This could be solved by using an array, specifying ancestry line,
for the argument instead.
- ** @param root
- * @param newChild
- * @param originalChild
- * @param originalParent
- * @return
+ * XXX Only handles single splits, or one layer of variations, denoted by
the originalParent argument.
+ * This could be solved by using an array, specifying ancestry line,
for the argument instead. <br/><br/>
+ * If, under root, originalParent cannot be found then root is returned
unaltered.
+ * @param root the root clause. an altered version of this will be
returned.
+ * @param newChild the new child.
+ * @param originalChild the original child.
+ * @param originalParent the original parent of the original child.
expected to be found under root.
+ * @return the root clause where the originalChild has been replaced with
the newChild.
*/
protected OperationClause replaceDescendant(
final DoubleOperatorClause root,
@@ -164,46 +166,55 @@
final DoubleOperatorClause originalChild,
final DoubleOperatorClause originalParent){
- OperationClause nC = newChild;
- OperationClause rC = originalChild;
- OperationClause rCParent = originalParent;
+ // pre-condition check: originalParent must be found under root
somewhere
+ if(new ChildFinder().childExists(root, originalParent)){
- do{
- nC = replaceOperatorClause(nC, rC, rCParent);
- for(OperationClause parent :
context.getParentFinder().getParents(root, rC)){
- if(rCParent == parent){
- rC = parent;
- rCParent = root == rCParent
- ? rCParent
- : context.getParentFinder().getParent(root,
rCParent);
- break;
+ OperationClause nC = newChild;
+ OperationClause rC = originalChild;
+ OperationClause rCParent = originalParent;
+
+ do{
+ nC = replaceOperatorClause(nC, rC, rCParent);
+ for(OperationClause parent :
context.getParentFinder().getParents(root, rC)){
+ if(rCParent == parent){
+ rC = parent;
+ rCParent = root == rCParent
+ ? rCParent
+ : context.getParentFinder().getParent(root,
rCParent);
+ break;
+ }
}
- }
- }while(root != rC);
+ }while(root != rC);
- return nC;
+ return nC;
+
+ }else{
+ LOG.error("originalParent does not live inside root\n" +
originalParent + '\n' + root);
+ // return the unaltered root
+ return root;
+ }
}
/** Replace the originalChild that exists under the originalParent will
the newChild.
- *
- * @param newChild
- * @param originalChild
- * @param originalParent
- * @return
+ *
+ * @param newChild
+ * @param originalChild
+ * @param originalParent
+ * @return
*/
protected <T extends OperationClause> T replaceOperatorClause(
final Clause newChild,
final Clause originalChild,
final T originalParent) {
-
+
final Clause leftChild = leftChild(originalParent) == originalChild
? newChild
: leftChild(originalParent);
-
+
final Clause rightChild;
-
+
if(originalParent instanceof DoubleOperatorClause){
-
+
rightChild = rightChild((DoubleOperatorClause)originalParent) ==
originalChild
? newChild
: rightChild((DoubleOperatorClause)originalParent);
@@ -218,10 +229,10 @@
/** Create a new operator clause, of type opCls, with the left and right
children.
* We must also specify for whom it is to be a replacement for.
* The replacementFor must be from the original branch.
- ** @param left
- * @param right
- * @param replacementFor
- * @return
+ ** @param left
+ * @param right
+ * @param replacementFor
+ * @return
*/
protected <T extends OperationClause> T createOperatorClause(
final Clause left,
@@ -245,10 +256,10 @@
}else if (NotClause.class.isAssignableFrom(replacementFor.getClass())){
clause = (T) context.createNotClause(left);
-
+
}else if
(AndNotClause.class.isAssignableFrom(replacementFor.getClass())){
clause = (T) context.createAndNotClause(left);
-
+
}
return clause;
@@ -256,7 +267,7 @@
/** Create XorClauses required to present all the alternatives in the
query tree.
* There will be alternatives.size()-1 XorClauses aligned in a
right-leaning branch.
- *
+ *
* @param alternatives what will be leaves of the right-leaning XorClause
branch returned
* @return the right-leaning XorClause branch
*/
@@ -269,13 +280,13 @@
}
/** What XorClause.Hint is used for newly created XorClause alternations.
- *
+ *
* @return the XorClause.Hint used during this alternation process.
*/
protected abstract XorClause.Hint getAlternationHint();
-
+
// Private -------------------------------------------------------
-
+
// Inner classes -------------------------------------------------
-
+
}
_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits