1 package org.apache.lucene.search.spans; 2 3 18 19 import java.io.IOException ; 20 21 import java.util.List ; 22 import java.util.Collection ; 23 import java.util.ArrayList ; 24 import java.util.Iterator ; 25 26 import org.apache.lucene.index.IndexReader; 27 import org.apache.lucene.util.PriorityQueue; 28 import org.apache.lucene.util.ToStringUtils; 29 import org.apache.lucene.search.Query; 30 31 32 public class SpanOrQuery extends SpanQuery { 33 private List clauses; 34 private String field; 35 36 37 public SpanOrQuery(SpanQuery[] clauses) { 38 39 this.clauses = new ArrayList (clauses.length); 41 for (int i = 0; i < clauses.length; i++) { 42 SpanQuery clause = clauses[i]; 43 if (i == 0) { field = clause.getField(); 45 } else if (!clause.getField().equals(field)) { 46 throw new IllegalArgumentException ("Clauses must have same field."); 47 } 48 this.clauses.add(clause); 49 } 50 } 51 52 53 public SpanQuery[] getClauses() { 54 return (SpanQuery[])clauses.toArray(new SpanQuery[clauses.size()]); 55 } 56 57 public String getField() { return field; } 58 59 public Collection getTerms() { 60 Collection terms = new ArrayList (); 61 Iterator i = clauses.iterator(); 62 while (i.hasNext()) { 63 SpanQuery clause = (SpanQuery)i.next(); 64 terms.addAll(clause.getTerms()); 65 } 66 return terms; 67 } 68 69 public Query rewrite(IndexReader reader) throws IOException { 70 SpanOrQuery clone = null; 71 for (int i = 0 ; i < clauses.size(); i++) { 72 SpanQuery c = (SpanQuery)clauses.get(i); 73 SpanQuery query = (SpanQuery) c.rewrite(reader); 74 if (query != c) { if (clone == null) 76 clone = (SpanOrQuery) this.clone(); 77 clone.clauses.set(i,query); 78 } 79 } 80 if (clone != null) { 81 return clone; } else { 83 return this; } 85 } 86 87 public String toString(String field) { 88 StringBuffer buffer = new StringBuffer (); 89 buffer.append("spanOr(["); 90 Iterator i = clauses.iterator(); 91 while (i.hasNext()) { 92 SpanQuery clause = (SpanQuery)i.next(); 93 buffer.append(clause.toString(field)); 94 if (i.hasNext()) { 95 buffer.append(", "); 96 } 97 } 98 buffer.append("])"); 99 buffer.append(ToStringUtils.boost(getBoost())); 100 return buffer.toString(); 101 } 102 103 public boolean equals(Object o) { 104 if (this == o) return true; 105 if (o == null || getClass() != o.getClass()) return false; 106 107 final SpanOrQuery that = (SpanOrQuery) o; 108 109 if (!clauses.equals(that.clauses)) return false; 110 if (!field.equals(that.field)) return false; 111 112 return getBoost() == that.getBoost(); 113 } 114 115 public int hashCode() { 116 int h = clauses.hashCode(); 117 h ^= (h << 10) | (h >>> 23); 118 h ^= Float.floatToRawIntBits(getBoost()); 119 return h; 120 } 121 122 private class SpanQueue extends PriorityQueue { 123 public SpanQueue(int size) { 124 initialize(size); 125 } 126 127 protected final boolean lessThan(Object o1, Object o2) { 128 Spans spans1 = (Spans)o1; 129 Spans spans2 = (Spans)o2; 130 if (spans1.doc() == spans2.doc()) { 131 if (spans1.start() == spans2.start()) { 132 return spans1.end() < spans2.end(); 133 } else { 134 return spans1.start() < spans2.start(); 135 } 136 } else { 137 return spans1.doc() < spans2.doc(); 138 } 139 } 140 } 141 142 143 public Spans getSpans(final IndexReader reader) throws IOException { 144 if (clauses.size() == 1) return ((SpanQuery)clauses.get(0)).getSpans(reader); 146 147 return new Spans() { 148 private List all = new ArrayList (clauses.size()); 149 private SpanQueue queue = new SpanQueue(clauses.size()); 150 151 { 152 Iterator i = clauses.iterator(); 153 while (i.hasNext()) { all.add(((SpanQuery)i.next()).getSpans(reader)); 155 } 156 } 157 158 private boolean firstTime = true; 159 160 public boolean next() throws IOException { 161 if (firstTime) { for (int i = 0; i < all.size(); i++) { 163 Spans spans = (Spans)all.get(i); 164 if (spans.next()) { queue.put(spans); } else { 167 all.remove(i--); 168 } 169 } 170 firstTime = false; 171 return queue.size() != 0; 172 } 173 174 if (queue.size() == 0) { return false; 176 } 177 178 if (top().next()) { queue.adjustTop(); 180 return true; 181 } 182 183 all.remove(queue.pop()); 185 return queue.size() != 0; 186 } 187 188 private Spans top() { return (Spans)queue.top(); } 189 190 public boolean skipTo(int target) throws IOException { 191 if (firstTime) { 192 for (int i = 0; i < all.size(); i++) { 193 Spans spans = (Spans)all.get(i); 194 if (spans.skipTo(target)) { queue.put(spans); } else { 197 all.remove(i--); 198 } 199 } 200 firstTime = false; 201 } else { 202 while (queue.size() != 0 && top().doc() < target) { 203 if (top().skipTo(target)) { 204 queue.adjustTop(); 205 } else { 206 all.remove(queue.pop()); 207 } 208 } 209 } 210 211 return queue.size() != 0; 212 } 213 214 public int doc() { return top().doc(); } 215 public int start() { return top().start(); } 216 public int end() { return top().end(); } 217 218 public String toString() { 219 return "spans("+SpanOrQuery.this+")@"+ 220 (firstTime?"START" 221 :(queue.size()>0?(doc()+":"+start()+"-"+end()):"END")); 222 } 223 224 }; 225 } 226 227 } 228 | Popular Tags |