From 86442612f318722e796aceed4c47b144850e42ff Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Tue, 12 Dec 2006 19:52:03 +0000 Subject: [PATCH] SpanOrQuery simplification and test: LUCENE-742 git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@486295 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/search/spans/SpanOrQuery.java | 66 ++++++++----------- .../apache/lucene/search/spans/TestSpans.java | 66 +++++++++++++++++++ 2 files changed, 92 insertions(+), 40 deletions(-) diff --git a/src/java/org/apache/lucene/search/spans/SpanOrQuery.java b/src/java/org/apache/lucene/search/spans/SpanOrQuery.java index 1f23f0276b5..399e71c47ab 100644 --- a/src/java/org/apache/lucene/search/spans/SpanOrQuery.java +++ b/src/java/org/apache/lucene/search/spans/SpanOrQuery.java @@ -133,6 +133,7 @@ public class SpanOrQuery extends SpanQuery { return h; } + private class SpanQueue extends PriorityQueue { public SpanQueue(int size) { initialize(size); @@ -159,66 +160,51 @@ public class SpanOrQuery extends SpanQuery { return ((SpanQuery)clauses.get(0)).getSpans(reader); return new Spans() { - private List all = new ArrayList(clauses.size()); - private SpanQueue queue = new SpanQueue(clauses.size()); + private SpanQueue queue = null; - { + private boolean initSpanQueue(int target) throws IOException { + queue = new SpanQueue(clauses.size()); Iterator i = clauses.iterator(); - while (i.hasNext()) { // initialize all - all.add(((SpanQuery)i.next()).getSpans(reader)); + while (i.hasNext()) { + Spans spans = ((SpanQuery)i.next()).getSpans(reader); + if ( ((target == -1) && spans.next()) + || ((target != -1) && spans.skipTo(target))) { + queue.put(spans); + } } + return queue.size() != 0; } - private boolean firstTime = true; - public boolean next() throws IOException { - if (firstTime) { // first time -- initialize - for (int i = 0; i < all.size(); i++) { - Spans spans = (Spans)all.get(i); - if (spans.next()) { // move to first entry - queue.put(spans); // build queue - } else { - all.remove(i--); - } - } - firstTime = false; - return queue.size() != 0; + if (queue == null) { + return initSpanQueue(-1); } - if (queue.size() == 0) { // all done + if (queue.size() == 0) { // all done return false; } - if (top().next()) { // move to next + if (top().next()) { // move to next queue.adjustTop(); return true; } - all.remove(queue.pop()); // exhausted a clause - + queue.pop(); // exhausted a clause return queue.size() != 0; } private Spans top() { return (Spans)queue.top(); } public boolean skipTo(int target) throws IOException { - if (firstTime) { - for (int i = 0; i < all.size(); i++) { - Spans spans = (Spans)all.get(i); - if (spans.skipTo(target)) { // skip each spans in all - queue.put(spans); // build queue - } else { - all.remove(i--); - } - } - firstTime = false; - } else { - while (queue.size() != 0 && top().doc() < target) { - if (top().skipTo(target)) { - queue.adjustTop(); - } else { - all.remove(queue.pop()); - } + if (queue == null) { + return initSpanQueue(target); + } + + while (queue.size() != 0 && top().doc() < target) { + if (top().skipTo(target)) { + queue.adjustTop(); + } else { + queue.pop(); } } @@ -231,7 +217,7 @@ public class SpanOrQuery extends SpanQuery { public String toString() { return "spans("+SpanOrQuery.this+")@"+ - (firstTime?"START" + ((queue == null)?"START" :(queue.size()>0?(doc()+":"+start()+"-"+end()):"END")); } diff --git a/src/test/org/apache/lucene/search/spans/TestSpans.java b/src/test/org/apache/lucene/search/spans/TestSpans.java index dcd26500306..a2b27a9ee7d 100644 --- a/src/test/org/apache/lucene/search/spans/TestSpans.java +++ b/src/test/org/apache/lucene/search/spans/TestSpans.java @@ -190,4 +190,70 @@ public class TestSpans extends TestCase { assertFalse("third range", spans.next()); } + + private Spans orSpans(String[] terms) throws Exception { + SpanQuery[] sqa = new SpanQuery[terms.length]; + for (int i = 0; i < terms.length; i++) { + sqa[i] = makeSpanTermQuery(terms[i]); + } + return (new SpanOrQuery(sqa)).getSpans(searcher.getIndexReader()); + } + + private void tstNextSpans(Spans spans, int doc, int start, int end) + throws Exception { + assertTrue("next", spans.next()); + assertEquals("doc", doc, spans.doc()); + assertEquals("start", start, spans.start()); + assertEquals("end", end, spans.end()); + } + + public void testSpanOrEmpty() throws Exception { + Spans spans = orSpans(new String[0]); + assertFalse("empty next", spans.next()); + } + + public void testSpanOrSingle() throws Exception { + Spans spans = orSpans(new String[] {"w5"}); + tstNextSpans(spans, 0, 4, 5); + assertFalse("final next", spans.next()); + } + + public void testSpanOrDouble() throws Exception { + Spans spans = orSpans(new String[] {"w5", "yy"}); + tstNextSpans(spans, 0, 4, 5); + tstNextSpans(spans, 2, 3, 4); + tstNextSpans(spans, 3, 4, 5); + tstNextSpans(spans, 7, 3, 4); + assertFalse("final next", spans.next()); + } + + public void testSpanOrDoubleSkip() throws Exception { + Spans spans = orSpans(new String[] {"w5", "yy"}); + assertTrue("initial skipTo", spans.skipTo(3)); + assertEquals("doc", 3, spans.doc()); + assertEquals("start", 4, spans.start()); + assertEquals("end", 5, spans.end()); + tstNextSpans(spans, 7, 3, 4); + assertFalse("final next", spans.next()); + } + + public void testSpanOrUnused() throws Exception { + Spans spans = orSpans(new String[] {"w5", "unusedTerm", "yy"}); + tstNextSpans(spans, 0, 4, 5); + tstNextSpans(spans, 2, 3, 4); + tstNextSpans(spans, 3, 4, 5); + tstNextSpans(spans, 7, 3, 4); + assertFalse("final next", spans.next()); + } + + public void testSpanOrTripleSameDoc() throws Exception { + Spans spans = orSpans(new String[] {"t1", "t2", "t3"}); + tstNextSpans(spans, 11, 0, 1); + tstNextSpans(spans, 11, 1, 2); + tstNextSpans(spans, 11, 2, 3); + tstNextSpans(spans, 11, 3, 4); + tstNextSpans(spans, 11, 4, 5); + tstNextSpans(spans, 11, 5, 6); + assertFalse("final next", spans.next()); + } }