lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gsing...@apache.org
Subject svn commit: r1021357 - in /lucene/dev/trunk/lucene: ./ src/java/org/apache/lucene/search/spans/ src/java/org/apache/lucene/util/ src/test/org/apache/lucene/analysis/ src/test/org/apache/lucene/search/ src/test/org/apache/lucene/search/spans/
Date Mon, 11 Oct 2010 14:37:17 GMT
Author: gsingers
Date: Mon Oct 11 14:37:16 2010
New Revision: 1021357

URL: http://svn.apache.org/viewvc?rev=1021357&view=rev
Log:
LUCENE-2692: add some new SpanQuery classes

Added:
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearPayloadCheckQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockPayloadAnalyzer.java
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanFirstQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/ToStringUtils.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockAnalyzer.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestBasics.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Mon Oct 11 14:37:16 2010
@@ -261,6 +261,9 @@ New features
   pretend it's an atomic reader.  This is a convenience class (you can
   use MultiFields static methods directly, instead) if you need to use
   the flex APIs directly on a composite reader.  (Mike McCandless)
+
+* LUCENE-2692: Added several new SpanQuery classes for positional checking
+  (match is in a range, payload is a specific value) (Grant Ingersoll)  
   
 Optimizations
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanFirstQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanFirstQuery.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanFirstQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanFirstQuery.java Mon Oct 11 14:37:16 2010
@@ -17,37 +17,30 @@ package org.apache.lucene.search.spans;
  * limitations under the License.
  */
 
-import java.io.IOException;
-
-import java.util.Collection;
-import java.util.Set;
-import java.util.ArrayList;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.Query;
 import org.apache.lucene.util.ToStringUtils;
 
-/** Matches spans near the beginning of a field. */
-public class SpanFirstQuery extends SpanQuery implements Cloneable {
-  private SpanQuery match;
-  private int end;
+import java.io.IOException;
+
+/** Matches spans near the beginning of a field.
+ * <p/> 
+ * This class is a simple extension of {@link SpanPositionRangeQuery} in that it assumes the
+ * start to be zero and only checks the end boundary.
+ *
+ *
+ *  */
+public class SpanFirstQuery extends SpanPositionRangeQuery {
 
   /** Construct a SpanFirstQuery matching spans in <code>match</code> whose end
    * position is less than or equal to <code>end</code>. */
   public SpanFirstQuery(SpanQuery match, int end) {
-    this.match = match;
-    this.end = end;
+    super(match, 0, end);
   }
 
-  /** Return the SpanQuery whose matches are filtered. */
-  public SpanQuery getMatch() { return match; }
-
-  /** Return the maximum end position permitted in a match. */
-  public int getEnd() { return end; }
-
   @Override
-  public String getField() { return match.getField(); }
+  protected boolean acceptPosition(Spans spans) throws IOException {
+    return spans.end() <= end;
+  }
+
 
   @Override
   public String toString(String field) {
@@ -60,89 +53,13 @@ public class SpanFirstQuery extends Span
     buffer.append(ToStringUtils.boost(getBoost()));
     return buffer.toString();
   }
-  
+
   @Override
   public Object clone() {
     SpanFirstQuery spanFirstQuery = new SpanFirstQuery((SpanQuery) match.clone(), end);
     spanFirstQuery.setBoost(getBoost());
     return spanFirstQuery;
   }
-  
-  @Override
-  public void extractTerms(Set<Term> terms) {
-	    match.extractTerms(terms);
-  }
-
-  @Override
-  public Spans getSpans(final IndexReader reader) throws IOException {
-    return new Spans() {
-        private Spans spans = match.getSpans(reader);
-
-        @Override
-        public boolean next() throws IOException {
-          while (spans.next()) {                  // scan to next match
-            if (end() <= end)
-              return true;
-          }
-          return false;
-        }
-
-        @Override
-        public boolean skipTo(int target) throws IOException {
-          if (!spans.skipTo(target))
-            return false;
-
-          return spans.end() <= end || next();
-
-        }
-
-        @Override
-        public int doc() { return spans.doc(); }
-        @Override
-        public int start() { return spans.start(); }
-        @Override
-        public int end() { return spans.end(); }
-
-      // TODO: Remove warning after API has been finalized
-      @Override
-      public Collection<byte[]> getPayload() throws IOException {
-        ArrayList<byte[]> result = null;
-        if (spans.isPayloadAvailable()) {
-          result = new ArrayList<byte[]>(spans.getPayload());
-        }
-        return result;//TODO: any way to avoid the new construction?
-      }
-
-      // TODO: Remove warning after API has been finalized
-      @Override
-      public boolean isPayloadAvailable() {
-        return spans.isPayloadAvailable();
-      }
-
-      @Override
-      public String toString() {
-          return "spans(" + SpanFirstQuery.this.toString() + ")";
-        }
-
-      };
-  }
-
-  @Override
-  public Query rewrite(IndexReader reader) throws IOException {
-    SpanFirstQuery clone = null;
-
-    SpanQuery rewritten = (SpanQuery) match.rewrite(reader);
-    if (rewritten != match) {
-      clone = (SpanFirstQuery) this.clone();
-      clone.match = rewritten;
-    }
-
-    if (clone != null) {
-      return clone;                        // some clauses rewrote
-    } else {
-      return this;                         // no clauses rewrote
-    }
-  }
 
   @Override
   public boolean equals(Object o) {

Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearPayloadCheckQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearPayloadCheckQuery.java?rev=1021357&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearPayloadCheckQuery.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearPayloadCheckQuery.java Mon Oct 11 14:37:16 2010
@@ -0,0 +1,117 @@
+package org.apache.lucene.search.spans;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import org.apache.lucene.util.ToStringUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+
+/**
+ * Only return those matches that have a specific payload at
+ * the given position.
+ * <p/>
+ * 
+ */
+public class SpanNearPayloadCheckQuery extends SpanPositionCheckQuery {
+  protected final Collection<byte[]> payloadToMatch;
+
+  /**
+   * @param match          The underlying {@link SpanQuery} to check
+   * @param payloadToMatch The {@link java.util.Collection} of payloads to match
+   */
+  public SpanNearPayloadCheckQuery(SpanNearQuery match, Collection<byte[]> payloadToMatch) {
+    super(match);
+    this.payloadToMatch = payloadToMatch;
+  }
+
+  @Override
+  protected boolean acceptPosition(Spans spans) throws IOException {
+    boolean result = spans.isPayloadAvailable();
+    if (result == true) {
+      Collection<byte[]> candidate = spans.getPayload();
+      if (candidate.size() == payloadToMatch.size()) {
+        //TODO: check the byte arrays are the same
+        //hmm, can't rely on order here
+        int matches = 0;
+        for (byte[] candBytes : candidate) {
+          //Unfortunately, we can't rely on order, so we need to compare all
+          for (byte[] payBytes : payloadToMatch) {
+            if (Arrays.equals(candBytes, payBytes) == true) {
+              matches++;
+              break;
+            }
+          }
+        }
+        if (matches == payloadToMatch.size()){
+          //we've verified all the bytes
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    }
+    return false;
+  }
+
+  public String toString(String field) {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append("spanPayCheck(");
+    buffer.append(match.toString(field));
+    buffer.append(", payloadRef: ");
+    for (byte[] bytes : payloadToMatch) {
+      ToStringUtils.byteArray(buffer, bytes);
+      buffer.append(';');
+    }
+    buffer.append(")");
+    buffer.append(ToStringUtils.boost(getBoost()));
+    return buffer.toString();
+  }
+
+  @Override
+  public Object clone() {
+    SpanNearPayloadCheckQuery result = new SpanNearPayloadCheckQuery((SpanNearQuery) match.clone(), payloadToMatch);
+    result.setBoost(getBoost());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof SpanNearPayloadCheckQuery)) return false;
+
+    SpanNearPayloadCheckQuery other = (SpanNearPayloadCheckQuery) o;
+    return this.payloadToMatch.equals(other.payloadToMatch)
+            && this.match.equals(other.match)
+            && this.getBoost() == other.getBoost();
+  }
+
+  @Override
+  public int hashCode() {
+    int h = match.hashCode();
+    h ^= (h << 8) | (h >>> 25);  // reversible
+    //TODO: is this right?
+    h ^= payloadToMatch.hashCode();
+    h ^= Float.floatToRawIntBits(getBoost());
+    return h;
+  }
+}
\ No newline at end of file

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearQuery.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanNearQuery.java Mon Oct 11 14:37:16 2010
@@ -45,7 +45,11 @@ public class SpanNearQuery extends SpanQ
   /** Construct a SpanNearQuery.  Matches spans matching a span from each
    * clause, with up to <code>slop</code> total unmatched positions between
    * them.  * When <code>inOrder</code> is true, the spans from each clause
-   * must be * ordered as in <code>clauses</code>. */
+   * must be * ordered as in <code>clauses</code>.
+   * @param clauses the clauses to find near each other
+   * @param slop The slop value
+   * @param inOrder true if order is important
+   * */
   public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) {
     this(clauses, slop, inOrder, true);     
   }

Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java?rev=1021357&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java Mon Oct 11 14:37:16 2010
@@ -0,0 +1,118 @@
+package org.apache.lucene.search.spans;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import org.apache.lucene.util.ToStringUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+
+/**
+ *   Only return those matches that have a specific payload at
+ *  the given position.
+ *<p/>
+ * Do not use this with an SpanQuery that contains a {@link org.apache.lucene.search.spans.SpanNearQuery}.  Instead, use
+ * {@link SpanNearPayloadCheckQuery} since it properly handles the fact that payloads
+ * aren't ordered by {@link org.apache.lucene.search.spans.SpanNearQuery}.
+ *
+ **/
+public class SpanPayloadCheckQuery extends SpanPositionCheckQuery{
+  protected final Collection<byte[]> payloadToMatch;
+
+  /**
+   *
+   * @param match The underlying {@link org.apache.lucene.search.spans.SpanQuery} to check
+   * @param payloadToMatch The {@link java.util.Collection} of payloads to match
+   */
+  public SpanPayloadCheckQuery(SpanQuery match, Collection<byte[]> payloadToMatch) {
+    super(match);
+    if (match instanceof SpanNearQuery){
+      throw new IllegalArgumentException("SpanNearQuery not allowed");
+    }
+    this.payloadToMatch = payloadToMatch;
+  }
+
+  @Override
+  protected boolean acceptPosition(Spans spans) throws IOException {
+    boolean result = spans.isPayloadAvailable();
+    if (result == true){
+      Collection<byte[]> candidate = spans.getPayload();
+      if (candidate.size() == payloadToMatch.size()){
+        //TODO: check the byte arrays are the same
+        Iterator<byte[]> toMatchIter = payloadToMatch.iterator();
+        //check each of the byte arrays, in order
+        //hmm, can't rely on order here
+        for (byte[] candBytes : candidate) {
+          //if one is a mismatch, then return false
+          if (Arrays.equals(candBytes, toMatchIter.next()) == false){
+            return false;
+          }
+        }
+        //we've verified all the bytes
+        return true;
+      } else {
+        return false;
+      }
+    }
+    return result;
+  } 
+
+  public String toString(String field) {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append("spanPayCheck(");
+    buffer.append(match.toString(field));
+    buffer.append(", payloadRef: ");
+    for (byte[] bytes : payloadToMatch) {
+      ToStringUtils.byteArray(buffer, bytes);
+      buffer.append(';');
+    }
+    buffer.append(")");
+    buffer.append(ToStringUtils.boost(getBoost()));
+    return buffer.toString();
+  }
+
+  @Override
+  public Object clone() {
+    SpanPayloadCheckQuery result = new SpanPayloadCheckQuery((SpanQuery) match.clone(), payloadToMatch);
+    result.setBoost(getBoost());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof SpanPayloadCheckQuery)) return false;
+
+    SpanPayloadCheckQuery other = (SpanPayloadCheckQuery)o;
+    return this.payloadToMatch.equals(other.payloadToMatch)
+         && this.match.equals(other.match)
+         && this.getBoost() == other.getBoost();
+  }
+
+  @Override
+  public int hashCode() {
+    int h = match.hashCode();
+    h ^= (h << 8) | (h >>> 25);  // reversible
+    //TODO: is this right?
+    h ^= payloadToMatch.hashCode();
+    h ^= Float.floatToRawIntBits(getBoost()) ;
+    return h;
+  }
+}
\ No newline at end of file

Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java?rev=1021357&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java Mon Oct 11 14:37:16 2010
@@ -0,0 +1,183 @@
+package org.apache.lucene.search.spans;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+
+
+/**
+ *
+ *
+ **/
+public abstract class SpanPositionCheckQuery extends SpanQuery implements Cloneable {
+  protected SpanQuery match;
+
+
+  public SpanPositionCheckQuery(SpanQuery match) {
+    this.match = match;
+  }
+
+  /**
+   * @return the SpanQuery whose matches are filtered.
+   *
+   * */
+  public SpanQuery getMatch() { return match; }
+
+
+
+  @Override
+  public String getField() { return match.getField(); }
+
+
+
+  @Override
+  public void extractTerms(Set<Term> terms) {
+	    match.extractTerms(terms);
+  }
+
+  /**
+   * Implementing classes are required to return whether the current position is a match for the passed in
+   * "match" {@link org.apache.lucene.search.spans.SpanQuery}.
+   *
+   * This is only called if the underlying {@link org.apache.lucene.search.spans.Spans#next()} for the
+   * match is successful
+   *
+   *
+   * @param spans The {@link org.apache.lucene.search.spans.Spans} instance, positioned at the spot to check
+   * @return true if it is a match, else false.
+   *
+   * @see org.apache.lucene.search.spans.Spans#next()
+   *
+   */
+  protected abstract boolean acceptPosition(Spans spans) throws IOException;
+
+  /**
+   * Implementing classes are required to return whether the position at the target is someplace that
+   * can be skipped to.  For instance, the {@link org.apache.lucene.search.spans.SpanFirstQuery} returns
+   * false if the target position is beyond the maximum position allowed or if {@link Spans#next()} is true.
+   * <p/>
+   * Note, this method is only called if the underlying match {@link org.apache.lucene.search.spans.SpanQuery} can
+   * skip to the target.
+   * <p/>
+   * It is safe to assume that the passed in {@link org.apache.lucene.search.spans.Spans} object for the underlying {@link org.apache.lucene.search.spans.SpanQuery} is
+   * positioned at the target.
+   * <p/>
+   * The default implementation is to return true if either {@link #acceptPosition(Spans)} or {@link org.apache.lucene.search.spans.Spans#next()} is true for the
+   * passed in instance of Spans.
+   *<p/>
+   * @param spans The {@link org.apache.lucene.search.spans.Spans} to check
+   * @return true if the instance can skip to this position
+   *
+   * @see Spans#skipTo(int)
+   * @throws java.io.IOException if there is a low-level IO error
+   */
+  protected boolean acceptSkipTo(Spans spans) throws IOException{
+    return acceptPosition(spans) || spans.next();
+  }
+
+  @Override
+  public Spans getSpans(final IndexReader reader) throws IOException {
+    return new PositionCheckSpan(reader);
+  }
+
+
+  @Override
+  public Query rewrite(IndexReader reader) throws IOException {
+    SpanPositionCheckQuery clone = null;
+
+    SpanQuery rewritten = (SpanQuery) match.rewrite(reader);
+    if (rewritten != match) {
+      clone = (SpanPositionCheckQuery) this.clone();
+      clone.match = rewritten;
+    }
+
+    if (clone != null) {
+      return clone;                        // some clauses rewrote
+    } else {
+      return this;                         // no clauses rewrote
+    }
+  }
+
+  protected class PositionCheckSpan extends Spans {
+    private Spans spans;
+
+    private final IndexReader reader;
+
+    public PositionCheckSpan(IndexReader reader) throws IOException {
+      this.reader = reader;
+      spans = match.getSpans(reader);
+    }
+
+    @Override
+    public boolean next() throws IOException {
+      //TODO: optimize to skip ahead to start
+      while (spans.next()) {                  // scan to next match
+        if (acceptPosition(this))
+          return true;
+      }
+      return false;
+    }
+
+    @Override
+    public boolean skipTo(int target) throws IOException {
+      if (!spans.skipTo(target))
+        return false;
+
+      return acceptSkipTo(this);
+
+    }
+
+    @Override
+    public int doc() { return spans.doc(); }
+
+    @Override
+    public int start() { return spans.start(); }
+
+    @Override
+    public int end() { return spans.end(); }
+    // TODO: Remove warning after API has been finalized
+
+    @Override
+    public Collection<byte[]> getPayload() throws IOException {
+      ArrayList<byte[]> result = null;
+      if (spans.isPayloadAvailable()) {
+        result = new ArrayList<byte[]>(spans.getPayload());
+      }
+      return result;//TODO: any way to avoid the new construction?
+    }
+    // TODO: Remove warning after API has been finalized
+
+    @Override
+    public boolean isPayloadAvailable() {
+      return spans.isPayloadAvailable();
+    }
+
+    @Override
+    public String toString() {
+        return "spans(" + SpanPositionCheckQuery.this.toString() + ")";
+      }
+
+  }
+}
\ No newline at end of file

Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java?rev=1021357&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java Mon Oct 11 14:37:16 2010
@@ -0,0 +1,99 @@
+package org.apache.lucene.search.spans;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+
+import org.apache.lucene.util.ToStringUtils;
+
+import java.io.IOException;
+
+
+/**
+ * Checks to see if the {@link #getMatch()} lies between a start and end position
+ *
+ * @see org.apache.lucene.search.spans.SpanFirstQuery for a derivation that is optimized for the case where start position is 0
+ */
+public class SpanPositionRangeQuery extends SpanPositionCheckQuery {
+  protected int start = 0;
+  protected int end;
+
+  public SpanPositionRangeQuery(SpanQuery match, int start, int end) {
+    super(match);
+    this.start = start;
+    this.end = end;
+  }
+
+
+  @Override
+  protected boolean acceptPosition(Spans spans) throws IOException {
+    return spans.start() >= start && spans.end() <= end;
+  }
+
+
+  /**
+   * @return The minimum position permitted in a match
+   */
+  public int getStart() {
+    return start;
+  }
+
+  /**
+   * @return the maximum end position permitted in a match.
+   */
+  public int getEnd() {
+    return end;
+  }
+
+  @Override
+  public String toString(String field) {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append("spanPosRange(");
+    buffer.append(match.toString(field));
+    buffer.append(", ").append(start).append(", ");
+    buffer.append(end);
+    buffer.append(")");
+    buffer.append(ToStringUtils.boost(getBoost()));
+    return buffer.toString();
+  }
+
+  @Override
+  public Object clone() {
+    SpanPositionRangeQuery result = new SpanPositionRangeQuery((SpanQuery) match.clone(), start, end);
+    result.setBoost(getBoost());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof SpanPositionRangeQuery)) return false;
+
+    SpanPositionRangeQuery other = (SpanPositionRangeQuery)o;
+    return this.end == other.end && this.start == other.start
+         && this.match.equals(other.match)
+         && this.getBoost() == other.getBoost();
+  }
+
+  @Override
+  public int hashCode() {
+    int h = match.hashCode();
+    h ^= (h << 8) | (h >>> 25);  // reversible
+    h ^= Float.floatToRawIntBits(getBoost()) ^ end ^ start;
+    return h;
+  }
+
+}
\ No newline at end of file

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/ToStringUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/ToStringUtils.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/ToStringUtils.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/util/ToStringUtils.java Mon Oct 11 14:37:16 2010
@@ -21,11 +21,23 @@ package org.apache.lucene.util;
  * Helper methods to ease implementing {@link Object#toString()}.
  */
 public class ToStringUtils {
-  /** for printing boost only if not 1.0 */ 
+  /**
+   * for printing boost only if not 1.0
+   */
   public static String boost(float boost) {
     if (boost != 1.0f) {
       return "^" + Float.toString(boost);
     } else return "";
   }
 
+  public static void byteArray(StringBuilder buffer, byte[] bytes) {
+    for (int i = 0; i < bytes.length; i++) {
+      buffer.append("b[").append(i).append("]=").append(bytes[i]);
+      if (i < bytes.length - 1) {
+        buffer.append(',');
+      }
+
+    }
+  }
+
 }

Modified: lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockAnalyzer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockAnalyzer.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockAnalyzer.java (original)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockAnalyzer.java Mon Oct 11 14:37:16 2010
@@ -20,6 +20,10 @@ package org.apache.lucene.analysis;
 import java.io.IOException;
 import java.io.Reader;
 
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
+import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+import org.apache.lucene.index.Payload;
 import org.apache.lucene.util.automaton.CharacterRunAutomaton;
 
 /**
@@ -30,8 +34,13 @@ public final class MockAnalyzer extends 
   private final boolean lowerCase;
   private final CharacterRunAutomaton filter;
   private final boolean enablePositionIncrements;
+  private final boolean payload;
   private int positionIncrementGap;
 
+  public MockAnalyzer(CharacterRunAutomaton runAutomaton, boolean lowerCase, CharacterRunAutomaton filter, boolean enablePositionIncrements) {
+    this(runAutomaton, lowerCase, filter, enablePositionIncrements, false);    
+  }
+
   /**
    * Creates a new MockAnalyzer.
    * 
@@ -39,12 +48,14 @@ public final class MockAnalyzer extends 
    * @param lowerCase true if the tokenizer should lowercase terms
    * @param filter DFA describing how terms should be filtered (set of stopwords, etc)
    * @param enablePositionIncrements true if position increments should reflect filtered terms.
+   * @param payload if payloads should be added
    */
-  public MockAnalyzer(CharacterRunAutomaton runAutomaton, boolean lowerCase, CharacterRunAutomaton filter, boolean enablePositionIncrements) {
+  public MockAnalyzer(CharacterRunAutomaton runAutomaton, boolean lowerCase, CharacterRunAutomaton filter, boolean enablePositionIncrements, boolean payload) {
     this.runAutomaton = runAutomaton;
     this.lowerCase = lowerCase;
     this.filter = filter;
     this.enablePositionIncrements = enablePositionIncrements;
+    this.payload = payload;
   }
 
   /**
@@ -54,7 +65,11 @@ public final class MockAnalyzer extends 
    * @param lowerCase true if the tokenizer should lowercase terms
    */
   public MockAnalyzer(CharacterRunAutomaton runAutomaton, boolean lowerCase) {
-    this(runAutomaton, lowerCase, MockTokenFilter.EMPTY_STOPSET, false);
+    this(runAutomaton, lowerCase, MockTokenFilter.EMPTY_STOPSET, false, false);
+  }
+
+  public MockAnalyzer(CharacterRunAutomaton runAutomaton, boolean lowerCase, boolean payload) {
+    this(runAutomaton, lowerCase, MockTokenFilter.EMPTY_STOPSET, false, payload);
   }
   
   /** 
@@ -67,12 +82,16 @@ public final class MockAnalyzer extends 
   @Override
   public TokenStream tokenStream(String fieldName, Reader reader) {
     MockTokenizer tokenizer = new MockTokenizer(reader, runAutomaton, lowerCase);
-    return new MockTokenFilter(tokenizer, filter, enablePositionIncrements);
+    TokenFilter filt = new MockTokenFilter(tokenizer, filter, enablePositionIncrements);
+    if (payload){
+      filt = new SimplePayloadFilter(filt, fieldName);
+    }
+    return filt;
   }
 
   private class SavedStreams {
     MockTokenizer tokenizer;
-    MockTokenFilter filter;
+    TokenFilter filter;
   }
 
   @Override
@@ -83,10 +102,14 @@ public final class MockAnalyzer extends 
       saved = new SavedStreams();
       saved.tokenizer = new MockTokenizer(reader, runAutomaton, lowerCase);
       saved.filter = new MockTokenFilter(saved.tokenizer, filter, enablePositionIncrements);
+      if (payload){
+        saved.filter = new SimplePayloadFilter(saved.filter, fieldName);
+      }
       setPreviousTokenStream(saved);
       return saved.filter;
     } else {
       saved.tokenizer.reset(reader);
+      saved.filter.reset();
       return saved.filter;
     }
   }
@@ -99,4 +122,30 @@ public final class MockAnalyzer extends 
   public int getPositionIncrementGap(String fieldName){
     return positionIncrementGap;
   }
+}
+
+final class SimplePayloadFilter extends TokenFilter {
+  String fieldName;
+  int pos;
+  final PayloadAttribute payloadAttr;
+  final CharTermAttribute termAttr;
+
+  public SimplePayloadFilter(TokenStream input, String fieldName) {
+    super(input);
+    this.fieldName = fieldName;
+    pos = 0;
+    payloadAttr = input.addAttribute(PayloadAttribute.class);
+    termAttr = input.addAttribute(CharTermAttribute.class);
+  }
+
+  @Override
+  public boolean incrementToken() throws IOException {
+    if (input.incrementToken()) {
+      payloadAttr.setPayload(new Payload(("pos: " + pos).getBytes()));
+      pos++;
+      return true;
+    } else {
+      return false;
+    }
+  }
 }
\ No newline at end of file

Added: lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockPayloadAnalyzer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockPayloadAnalyzer.java?rev=1021357&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockPayloadAnalyzer.java (added)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/analysis/MockPayloadAnalyzer.java Mon Oct 11 14:37:16 2010
@@ -0,0 +1,93 @@
+package org.apache.lucene.analysis;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
+import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+import org.apache.lucene.index.Payload;
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+/**
+ *
+ *
+ **/
+public final class MockPayloadAnalyzer extends Analyzer {
+
+  @Override
+  public TokenStream tokenStream(String fieldName, Reader reader) {
+    TokenStream result = new MockTokenizer(reader, MockTokenizer.WHITESPACE, true);
+    return new MockPayloadFilter(result, fieldName);
+  }
+}
+
+
+/**
+ *
+ *
+ **/
+final class MockPayloadFilter extends TokenFilter {
+  String fieldName;
+
+  int pos;
+
+  int i;
+
+  final PositionIncrementAttribute posIncrAttr;
+  final PayloadAttribute payloadAttr;
+  final CharTermAttribute termAttr;
+
+  public MockPayloadFilter(TokenStream input, String fieldName) {
+    super(input);
+    this.fieldName = fieldName;
+    pos = 0;
+    i = 0;
+    posIncrAttr = input.addAttribute(PositionIncrementAttribute.class);
+    payloadAttr = input.addAttribute(PayloadAttribute.class);
+    termAttr = input.addAttribute(CharTermAttribute.class);
+  }
+
+  @Override
+  public boolean incrementToken() throws IOException {
+    if (input.incrementToken()) {
+      payloadAttr.setPayload(new Payload(("pos: " + pos).getBytes()));
+      int posIncr;
+      if (i % 2 == 1) {
+        posIncr = 1;
+      } else {
+        posIncr = 0;
+      }
+      posIncrAttr.setPositionIncrement(posIncr);
+      pos += posIncr;
+      i++;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public void reset() throws IOException {
+    i = 0;
+    pos = 0;
+  }
+}
+

Modified: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java (original)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java Mon Oct 11 14:37:16 2010
@@ -18,18 +18,16 @@ package org.apache.lucene.search;
  */
 
 import java.io.Reader;
-import java.io.IOException;
 import java.io.StringReader;
 import java.util.Collection;
-import java.util.Random;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.MockPayloadAnalyzer;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -41,8 +39,6 @@ import org.apache.lucene.index.SlowMulti
 import org.apache.lucene.index.Term;
 import org.apache.lucene.queryParser.QueryParser;
 import org.apache.lucene.store.Directory;
-import org.apache.lucene.analysis.TokenFilter;
-import org.apache.lucene.index.Payload;
 import org.apache.lucene.search.payloads.PayloadSpanUtil;
 import org.apache.lucene.search.spans.SpanNearQuery;
 import org.apache.lucene.search.spans.SpanQuery;
@@ -200,7 +196,7 @@ public class TestPositionIncrement exten
 
     // should not find "1 2" because there is a gap of 1 in the index
     QueryParser qp = new QueryParser(TEST_VERSION_CURRENT, "field",
-        new MockAnalyzer(MockTokenizer.WHITESPACE, false, stopStopList, false));
+        new MockAnalyzer(MockTokenizer.WHITESPACE, false, stopStopList, false, false));
     q = (PhraseQuery) qp.parse("\"1 2\"");
     hits = searcher.search(q, null, 1000).scoreDocs;
     assertEquals(0, hits.length);
@@ -224,7 +220,7 @@ public class TestPositionIncrement exten
       
     // when both qp qnd stopFilter propagate increments, we should find the doc.
     qp = new QueryParser(TEST_VERSION_CURRENT, "field",
-                         new MockAnalyzer(MockTokenizer.WHITESPACE, false, stopStopList, true));
+                         new MockAnalyzer(MockTokenizer.WHITESPACE, false, stopStopList, true, false));
     qp.setEnablePositionIncrements(true);
     q = (PhraseQuery) qp.parse("\"1 stop 2\"");
     hits = searcher.search(q, null, 1000).scoreDocs;
@@ -241,7 +237,7 @@ public class TestPositionIncrement exten
   
   public void testPayloadsPos0() throws Exception {
     Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random, dir, new TestPayloadAnalyzer());
+    RandomIndexWriter writer = new RandomIndexWriter(random, dir, new MockPayloadAnalyzer());
     Document doc = new Document();
     doc.add(new Field("content", new StringReader(
         "a a b c d e a f g h i j a b k k")));
@@ -327,57 +323,4 @@ public class TestPositionIncrement exten
     is.getIndexReader().close();
     dir.close();
   }
-}
-
-final class TestPayloadAnalyzer extends Analyzer {
-
-  @Override
-  public TokenStream tokenStream(String fieldName, Reader reader) {
-    TokenStream result = new MockTokenizer(reader, MockTokenizer.WHITESPACE, true);
-    return new PayloadFilter(result, fieldName);
-  }
-}
-
-final class PayloadFilter extends TokenFilter {
-  String fieldName;
-
-  int pos;
-
-  int i;
-
-  final PositionIncrementAttribute posIncrAttr;
-  final PayloadAttribute payloadAttr;
-  final CharTermAttribute termAttr;
-
-  public PayloadFilter(TokenStream input, String fieldName) {
-    super(input);
-    this.fieldName = fieldName;
-    pos = 0;
-    i = 0;
-    posIncrAttr = input.addAttribute(PositionIncrementAttribute.class);
-    payloadAttr = input.addAttribute(PayloadAttribute.class);
-    termAttr = input.addAttribute(CharTermAttribute.class);
-  }
-
-  @Override
-  public boolean incrementToken() throws IOException {
-    if (input.incrementToken()) {
-      payloadAttr.setPayload(new Payload(("pos: " + pos).getBytes()));
-      int posIncr;
-      if (i % 2 == 1) {
-        posIncr = 1;
-      } else {
-        posIncr = 0;
-      }
-      posIncrAttr.setPositionIncrement(posIncr);
-      pos += posIncr;
-      if (TestPositionIncrement.VERBOSE) {
-        System.out.println("term=" + termAttr + " pos=" + pos);
-      }
-      i++;
-      return true;
-    } else {
-      return false;
-    }
-  }
-}
+}
\ No newline at end of file

Modified: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestBasics.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestBasics.java?rev=1021357&r1=1021356&r2=1021357&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestBasics.java (original)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestBasics.java Mon Oct 11 14:37:16 2010
@@ -18,12 +18,18 @@ package org.apache.lucene.search.spans;
  */
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.MockPayloadAnalyzer;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Payload;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.SlowMultiReaderWrapper;
 import org.apache.lucene.index.Term;
@@ -65,11 +71,11 @@ public class TestBasics extends LuceneTe
   @BeforeClass
   public static void beforeClass() throws Exception {
     directory = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random, directory, 
-        newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(MockTokenizer.SIMPLE, true))
+    RandomIndexWriter writer = new RandomIndexWriter(random, directory,
+        newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(MockTokenizer.SIMPLE, true, true))
         .setMaxBufferedDocs(_TestUtil.nextInt(random, 50, 1000)));
     //writer.infoStream = System.out;
-    for (int i = 0; i < 1000; i++) {
+    for (int i = 0; i < 2000; i++) {
       Document doc = new Document();
       doc.add(newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
       writer.addDocument(doc);
@@ -94,12 +100,23 @@ public class TestBasics extends LuceneTe
     Query query = new TermQuery(new Term("field", "seventy"));
     checkHits(query, new int[]
       {70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170, 171, 172, 173, 174, 175,
-       176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279,
-       370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 470, 471, 472, 473,
-       474, 475, 476, 477, 478, 479, 570, 571, 572, 573, 574, 575, 576, 577,
-       578, 579, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 770, 771,
-       772, 773, 774, 775, 776, 777, 778, 779, 870, 871, 872, 873, 874, 875,
-       876, 877, 878, 879, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979});
+              176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278,
+              279, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 470, 471,
+              472, 473, 474, 475, 476, 477, 478, 479, 570, 571, 572, 573, 574,
+              575, 576, 577, 578, 579, 670, 671, 672, 673, 674, 675, 676, 677,
+              678, 679, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 870,
+              871, 872, 873, 874, 875, 876, 877, 878, 879, 970, 971, 972, 973,
+              974, 975, 976, 977, 978, 979, 1070, 1071, 1072, 1073, 1074, 1075,
+              1076, 1077, 1078, 1079, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
+              1177, 1178, 1179, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277,
+              1278, 1279, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378,
+              1379, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479,
+              1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1670,
+              1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1770, 1771,
+              1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1870, 1871, 1872,
+              1873, 1874, 1875, 1876, 1877,
+              1878, 1879, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978,
+              1979});
     }
 
   @Test
@@ -114,7 +131,8 @@ public class TestBasics extends LuceneTe
     query.add(new Term("field", "seventy"));
     query.add(new Term("field", "seven"));
     checkHits(query, new int[]
-      {77, 177, 277, 377, 477, 577, 677, 777, 877, 977});
+      {77, 177, 277, 377, 477, 577, 677, 777, 877,
+              977, 1077, 1177, 1277, 1377, 1477, 1577, 1677, 1777, 1877, 1977});
   }
 
   @Test
@@ -131,8 +149,10 @@ public class TestBasics extends LuceneTe
     query.add(new TermQuery(new Term("field", "seventy")), BooleanClause.Occur.MUST);
     query.add(new TermQuery(new Term("field", "seven")), BooleanClause.Occur.MUST);
     checkHits(query, new int[]
-      {77, 777, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775,
-       776, 778, 779, 877, 977});
+      {77, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 777,
+              778, 779, 877, 977, 1077, 1177, 1277, 1377, 1477, 1577, 1677,
+              1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1877,
+              1977});
   }
 
   @Test
@@ -150,7 +170,7 @@ public class TestBasics extends LuceneTe
     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {term1, term2},
                                             0, true);
     checkHits(query, new int[]
-      {77, 177, 277, 377, 477, 577, 677, 777, 877, 977});
+      {77, 177, 277, 377, 477, 577, 677, 777, 877, 977, 1077, 1177, 1277, 1377, 1477, 1577, 1677, 1777, 1877, 1977});
 
     assertTrue(searcher.explain(query, 77).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 977).getValue() > 0.0f);
@@ -168,8 +188,10 @@ public class TestBasics extends LuceneTe
                                             4, false);
 
     checkHits(query, new int[]
-      {609, 629, 639, 649, 659, 669, 679, 689, 699,
-       906, 926, 936, 946, 956, 966, 976, 986, 996});
+      {609, 629, 639, 649, 659, 669, 679, 689, 699, 906, 926, 936, 946, 956,
+              966, 976, 986, 996, 1609, 1629, 1639, 1649, 1659, 1669,
+              1679, 1689, 1699, 1906, 1926, 1936, 1946, 1956, 1966, 1976, 1986,
+              1996});
   }
 
   @Test
@@ -179,7 +201,7 @@ public class TestBasics extends LuceneTe
     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {term1, term2},
                                             4, true);
     checkHits(query, new int[]
-      {906, 926, 936, 946, 956, 966, 976, 986, 996});
+      {906, 926, 936, 946, 956, 966, 976, 986, 996, 1906, 1926, 1936, 1946, 1956, 1966, 1976, 1986, 1996});
   }
 
   @Test
@@ -192,7 +214,7 @@ public class TestBasics extends LuceneTe
     SpanNotQuery query = new SpanNotQuery(near, term3);
 
     checkHits(query, new int[]
-      {801, 821, 831, 851, 861, 871, 881, 891});
+      {801, 821, 831, 851, 861, 871, 881, 891, 1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
 
     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
@@ -211,7 +233,8 @@ public class TestBasics extends LuceneTe
     SpanNotQuery query = new SpanNotQuery(near, or);
 
     checkHits(query, new int[]
-      {801, 821, 831, 851, 861, 871, 881, 891});
+      {801, 821, 831, 851, 861, 871, 881, 891,
+              1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
 
     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
@@ -232,7 +255,7 @@ public class TestBasics extends LuceneTe
     SpanNotQuery query = new SpanNotQuery(near, or);
 
     checkHits(query, new int[]
-      {801, 821, 831, 851, 871, 891});
+      {801, 821, 831, 851, 871, 891, 1801, 1821, 1831, 1851, 1871, 1891});
 
     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
@@ -252,7 +275,8 @@ public class TestBasics extends LuceneTe
     SpanNotQuery query = new SpanNotQuery(near, exclude);
 
     checkHits(query, new int[]
-      {801, 821, 831, 851, 861, 871, 881, 891});
+      {801, 821, 831, 851, 861, 871, 881, 891,
+              1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
 
     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
@@ -271,8 +295,13 @@ public class TestBasics extends LuceneTe
     SpanFirstQuery exclude = new SpanFirstQuery(near, n-1);
     SpanNotQuery q = new SpanNotQuery(include, exclude);
     
-    checkHits(q, new int[]{40,41,42,43,44,45,46,47,48,49});
-    
+    checkHits(q, new int[]{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048,
+            1049, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1240, 1241, 1242, 1243, 1244,
+            1245, 1246, 1247, 1248, 1249, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1440, 1441, 1442,
+            1443, 1444, 1445, 1446, 1447, 1448, 1449, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1640,
+            1641, 1642, 1643, 1644, 1645, 1646, 1647,
+            1648, 1649, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1840, 1841, 1842, 1843, 1844, 1845, 1846,
+            1847, 1848, 1849, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949});
   }
   
   @Test
@@ -296,6 +325,108 @@ public class TestBasics extends LuceneTe
   }
 
   @Test
+  public void testSpanPositionRange() throws Exception {
+    SpanPositionRangeQuery query;
+    SpanTermQuery term1 = new SpanTermQuery(new Term("field", "five"));
+    query = new SpanPositionRangeQuery(term1, 1, 2);
+    checkHits(query, new int[]
+      {25,35, 45, 55, 65, 75, 85, 95});
+    assertTrue(searcher.explain(query, 25).getValue() > 0.0f);
+    assertTrue(searcher.explain(query, 95).getValue() > 0.0f);
+
+    query = new SpanPositionRangeQuery(term1, 0, 1);
+    checkHits(query, new int[]
+      {5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
+              513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525,
+              526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538,
+              539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551,
+              552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
+              565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577,
+              578, 579, 580, 581, 582, 583, 584,
+              585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597,
+              598, 599});
+
+    query = new SpanPositionRangeQuery(term1, 6, 7);
+    checkHits(query, new int[]{});
+  }
+
+  @Test
+  public void testSpanPayloadCheck() throws Exception {
+    SpanTermQuery term1 = new SpanTermQuery(new Term("field", "five"));
+    Payload pay = new Payload(("pos: " + 5).getBytes());
+    SpanQuery query = new SpanPayloadCheckQuery(term1, Collections.singletonList(pay.getData()));
+    checkHits(query, new int[]
+      {5});
+    assertTrue(searcher.explain(query, 5).getValue() > 0.0f);
+
+    SpanTermQuery term2 = new SpanTermQuery(new Term("field", "hundred"));
+    SpanNearQuery snq;
+    SpanQuery[] clauses;
+    List<byte[]> list;
+    Payload pay2;
+    clauses = new SpanQuery[2];
+    clauses[0] = term1;
+    clauses[1] = term2;
+    snq = new SpanNearQuery(clauses, 0, true);
+    pay = new Payload(("pos: " + 1656).getBytes());
+    pay2 = new Payload(("pos: " + 1657).getBytes());
+    list = new ArrayList<byte[]>();
+    list.add(pay.getData());
+    list.add(pay2.getData());
+    query = new SpanNearPayloadCheckQuery(snq, list);
+    checkHits(query, new int[]
+      {500});
+    clauses = new SpanQuery[3];
+    clauses[0] = term1;
+    clauses[1] = term2;
+    clauses[2] = new SpanTermQuery(new Term("field", "five"));
+    snq = new SpanNearQuery(clauses, 0, true);
+    pay = new Payload(("pos: " + 1670).getBytes());
+    pay2 = new Payload(("pos: " + 1671).getBytes());
+    Payload pay3 = new Payload(("pos: " + 1672).getBytes());
+    list = new ArrayList<byte[]>();
+    list.add(pay.getData());
+    list.add(pay2.getData());
+    list.add(pay3.getData());
+    query = new SpanNearPayloadCheckQuery(snq, list);
+    checkHits(query, new int[]
+      {505});
+  }
+
+  public void testComplexSpanChecks() throws Exception {
+    SpanTermQuery one = new SpanTermQuery(new Term("field", "one"));
+    SpanTermQuery thous = new SpanTermQuery(new Term("field", "thousand"));
+    //should be one position in between
+    SpanTermQuery hundred = new SpanTermQuery(new Term("field", "hundred"));
+    SpanTermQuery three = new SpanTermQuery(new Term("field", "three"));
+
+    SpanNearQuery oneThous = new SpanNearQuery(new SpanQuery[]{one, thous}, 0, true);
+    SpanNearQuery hundredThree = new SpanNearQuery(new SpanQuery[]{hundred, three}, 0, true);
+    SpanNearQuery oneThousHunThree = new SpanNearQuery(new SpanQuery[]{oneThous, hundredThree}, 1, true);
+    SpanQuery query;
+    //this one's too small
+    query = new SpanPositionRangeQuery(oneThousHunThree, 1, 2);
+    checkHits(query, new int[]{});
+    //this one's just right
+    query = new SpanPositionRangeQuery(oneThousHunThree, 0, 6);
+    checkHits(query, new int[]{1103, 1203,1303,1403,1503,1603,1703,1803,1903});
+
+    Collection<byte[]> payloads = new ArrayList<byte[]>();
+    Payload pay = new Payload(("pos: " + 3896).getBytes());
+    Payload pay2 = new Payload(("pos: " + 3897).getBytes());
+    Payload pay3 = new Payload(("pos: " + 3899).getBytes());
+    Payload pay4 = new Payload(("pos: " + 3900).getBytes());
+    payloads.add(pay.getData());
+    payloads.add(pay2.getData());
+    payloads.add(pay3.getData());
+    payloads.add(pay4.getData());
+    query = new SpanNearPayloadCheckQuery(oneThousHunThree, payloads);
+    checkHits(query, new int[]{1103});
+
+  }
+
+
+  @Test
   public void testSpanOr() throws Exception {
     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "thirty"));
     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "three"));
@@ -310,7 +441,8 @@ public class TestBasics extends LuceneTe
 
     checkHits(query, new int[]
       {33, 47, 133, 147, 233, 247, 333, 347, 433, 447, 533, 547, 633, 647, 733,
-       747, 833, 847, 933, 947});
+              747, 833, 847, 933, 947, 1033, 1047, 1133, 1147, 1233, 1247, 1333,
+              1347, 1433, 1447, 1533, 1547, 1633, 1647, 1733, 1747, 1833, 1847, 1933, 1947});
 
     assertTrue(searcher.explain(query, 33).getValue() > 0.0f);
     assertTrue(searcher.explain(query, 947).getValue() > 0.0f);
@@ -330,7 +462,7 @@ public class TestBasics extends LuceneTe
     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {near1, near2},
                                             0, true);
 
-    checkHits(query, new int[] {333});
+    checkHits(query, new int[] {333, 1333});
 
     assertTrue(searcher.explain(query, 333).getValue() > 0.0f);
   }
@@ -351,10 +483,13 @@ public class TestBasics extends LuceneTe
                                             10, true);
 
     checkHits(query, new int[]
-      {606, 607, 626, 627, 636, 637, 646, 647, 
-       656, 657, 666, 667, 676, 677, 686, 687, 696, 697,
-       706, 707, 726, 727, 736, 737, 746, 747, 
-       756, 757, 766, 767, 776, 777, 786, 787, 796, 797});
+      {606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677,
+              686, 687, 696, 697, 706, 707, 726, 727, 736, 737, 746, 747, 756,
+              757, 766, 767, 776, 777, 786, 787, 796, 797, 1606, 1607, 1626,
+              1627, 1636, 1637, 1646, 1647, 1656, 1657, 1666, 1667, 1676, 1677,
+              1686, 1687, 1696, 1697, 1706, 1707, 1726, 1727, 1736, 1737,
+              1746, 1747, 1756, 1757, 1766, 1767, 1776, 1777, 1786, 1787, 1796,
+              1797});
   }
 
   @Test
@@ -378,10 +513,12 @@ public class TestBasics extends LuceneTe
                                             100, true);
     
     checkHits(query, new int[]
-      {606, 607, 626, 627, 636, 637, 646, 647, 
-       656, 657, 666, 667, 676, 677, 686, 687, 696, 697,
-       706, 707, 726, 727, 736, 737, 746, 747, 
-       756, 757, 766, 767, 776, 777, 786, 787, 796, 797});
+      {606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696,
+              697, 706, 707, 726, 727, 736, 737, 746, 747, 756, 757,
+              766, 767, 776, 777, 786, 787, 796, 797, 1606, 1607, 1626, 1627, 1636, 1637, 1646,
+              1647, 1656, 1657,
+              1666, 1667, 1676, 1677, 1686, 1687, 1696, 1697, 1706, 1707, 1726, 1727, 1736, 1737,
+              1746, 1747, 1756, 1757, 1766, 1767, 1776, 1777, 1786, 1787, 1796, 1797});
   }
   
   @Test



Mime
View raw message