You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2010/09/27 17:32:21 UTC

svn commit: r1001781 - /lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java

Author: rmuir
Date: Mon Sep 27 15:32:21 2010
New Revision: 1001781

URL: http://svn.apache.org/viewvc?rev=1001781&view=rev
Log:
LUCENE-2672: speed up automaton seeking in nextString

Modified:
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java?rev=1001781&r1=1001780&r2=1001781&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/AutomatonTermsEnum.java Mon Sep 27 15:32:21 2010
@@ -22,6 +22,7 @@ import java.util.Comparator;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.IntsRef;
 import org.apache.lucene.util.automaton.Automaton;
 import org.apache.lucene.util.automaton.ByteRunAutomaton;
 import org.apache.lucene.util.automaton.SpecialOperations;
@@ -110,7 +111,6 @@ public class AutomatonTermsEnum extends 
     // used for path tracking, where each bit is a numbered state.
     visited = new long[runAutomaton.getSize()];
 
-    setUseTermsCache(finite);
     termComp = getComparator();
   }
   
@@ -201,6 +201,8 @@ public class AutomatonTermsEnum extends 
     linearUpperBound.length = length;
   }
 
+  private final IntsRef savedStates = new IntsRef(10);
+  
   /**
    * Increments the byte buffer to the next String in binary order after s that will not put
    * the machine into a reject state. If such a string does not exist, returns
@@ -214,17 +216,20 @@ public class AutomatonTermsEnum extends 
   private boolean nextString() {
     int state;
     int pos = 0;
-
+    savedStates.grow(seekBytesRef.length+1);
+    final int[] states = savedStates.ints;
+    states[0] = runAutomaton.getInitialState();
+    
     while (true) {
       curGen++;
       linear = false;
-      state = runAutomaton.getInitialState();
       // walk the automaton until a character is rejected.
-      for (pos = 0; pos < seekBytesRef.length; pos++) {
+      for (state = states[pos]; pos < seekBytesRef.length; pos++) {
         visited[state] = curGen;
         int nextState = runAutomaton.step(state, seekBytesRef.bytes[pos] & 0xff);
         if (nextState == -1)
           break;
+        states[pos+1] = nextState;
         // we found a loop, record it for faster enumeration
         if (!finite && !linear && visited[nextState] == curGen) {
           linear = true;
@@ -238,12 +243,16 @@ public class AutomatonTermsEnum extends 
       if (nextString(state, pos)) {
         return true;
       } else { /* no more solutions exist from this useful portion, backtrack */
-        if (!backtrack(pos)) /* no more solutions at all */
+        if ((pos = backtrack(pos)) < 0) /* no more solutions at all */
           return false;
-        else if (runAutomaton.run(seekBytesRef.bytes, 0, seekBytesRef.length)) 
+        final int newState = runAutomaton.step(states[pos], seekBytesRef.bytes[pos] & 0xff);
+        if (newState >= 0 && runAutomaton.isAccept(newState))
           /* String is good to go as-is */
           return true;
         /* else advance further */
+        // TODO: paranoia? if we backtrack thru an infinite DFA, the loop detection is important!
+        // for now, restart from scratch for all infinite DFAs 
+        if (!finite) pos = 0;
       }
     }
   }
@@ -332,20 +341,19 @@ public class AutomatonTermsEnum extends 
    * can match.
    * 
    * @param position current position in the input String
-   * @return true if more possible solutions exist for the DFA
+   * @return position >=0 if more possible solutions exist for the DFA
    */
-  private boolean backtrack(int position) {
-    while (position > 0) {
-      int nextChar = seekBytesRef.bytes[position - 1] & 0xff;
+  private int backtrack(int position) {
+    while (position-- > 0) {
+      int nextChar = seekBytesRef.bytes[position] & 0xff;
       // if a character is 0xff its a dead-end too,
       // because there is no higher character in binary sort order.
       if (nextChar++ != 0xff) {
-        seekBytesRef.bytes[position - 1] = (byte) nextChar;
-        seekBytesRef.length = position;
-        return true;
+        seekBytesRef.bytes[position] = (byte) nextChar;
+        seekBytesRef.length = position+1;
+        return position;
       }
-      position--;
     }
-    return false; /* all solutions exhausted */
+    return -1; /* all solutions exhausted */
   }
 }