~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/src/java/org/apache/lucene/search/spans/SpanOrQuery.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.search.spans;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
import java.io.IOException;
21
 
 
22
 
import java.util.List;
23
 
import java.util.Collection;
24
 
import java.util.ArrayList;
25
 
import java.util.Iterator;
26
 
import java.util.Set;
27
 
 
28
 
import org.apache.lucene.index.IndexReader;
29
 
import org.apache.lucene.index.Term;
30
 
import org.apache.lucene.util.PriorityQueue;
31
 
import org.apache.lucene.util.ToStringUtils;
32
 
import org.apache.lucene.search.Query;
33
 
 
34
 
/** Matches the union of its clauses.*/
35
 
public class SpanOrQuery extends SpanQuery implements Cloneable {
36
 
  private List<SpanQuery> clauses;
37
 
  private String field;
38
 
 
39
 
  /** Construct a SpanOrQuery merging the provided clauses. */
40
 
  public SpanOrQuery(SpanQuery... clauses) {
41
 
 
42
 
    // copy clauses array into an ArrayList
43
 
    this.clauses = new ArrayList<SpanQuery>(clauses.length);
44
 
    for (int i = 0; i < clauses.length; i++) {
45
 
      addClause(clauses[i]);
46
 
    }
47
 
  }
48
 
 
49
 
  /** Adds a clause to this query */
50
 
  public final void addClause(SpanQuery clause) {
51
 
    if (field == null) {
52
 
      field = clause.getField();
53
 
    } else if (!clause.getField().equals(field)) {
54
 
      throw new IllegalArgumentException("Clauses must have same field.");
55
 
    }
56
 
    this.clauses.add(clause);
57
 
  }
58
 
  
59
 
  /** Return the clauses whose spans are matched. */
60
 
  public SpanQuery[] getClauses() {
61
 
    return clauses.toArray(new SpanQuery[clauses.size()]);
62
 
  }
63
 
 
64
 
  @Override
65
 
  public String getField() { return field; }
66
 
 
67
 
  @Override
68
 
  public void extractTerms(Set<Term> terms) {
69
 
    for(final SpanQuery clause: clauses) {
70
 
      clause.extractTerms(terms);
71
 
    }
72
 
  }
73
 
  
74
 
  @Override
75
 
  public Object clone() {
76
 
    int sz = clauses.size();
77
 
    SpanQuery[] newClauses = new SpanQuery[sz];
78
 
 
79
 
    for (int i = 0; i < sz; i++) {
80
 
      newClauses[i] = (SpanQuery) clauses.get(i).clone();
81
 
    }
82
 
    SpanOrQuery soq = new SpanOrQuery(newClauses);
83
 
    soq.setBoost(getBoost());
84
 
    return soq;
85
 
  }
86
 
 
87
 
  @Override
88
 
  public Query rewrite(IndexReader reader) throws IOException {
89
 
    SpanOrQuery clone = null;
90
 
    for (int i = 0 ; i < clauses.size(); i++) {
91
 
      SpanQuery c = clauses.get(i);
92
 
      SpanQuery query = (SpanQuery) c.rewrite(reader);
93
 
      if (query != c) {                     // clause rewrote: must clone
94
 
        if (clone == null)
95
 
          clone = (SpanOrQuery) this.clone();
96
 
        clone.clauses.set(i,query);
97
 
      }
98
 
    }
99
 
    if (clone != null) {
100
 
      return clone;                        // some clauses rewrote
101
 
    } else {
102
 
      return this;                         // no clauses rewrote
103
 
    }
104
 
  }
105
 
 
106
 
  @Override
107
 
  public String toString(String field) {
108
 
    StringBuilder buffer = new StringBuilder();
109
 
    buffer.append("spanOr([");
110
 
    Iterator<SpanQuery> i = clauses.iterator();
111
 
    while (i.hasNext()) {
112
 
      SpanQuery clause = i.next();
113
 
      buffer.append(clause.toString(field));
114
 
      if (i.hasNext()) {
115
 
        buffer.append(", ");
116
 
      }
117
 
    }
118
 
    buffer.append("])");
119
 
    buffer.append(ToStringUtils.boost(getBoost()));
120
 
    return buffer.toString();
121
 
  }
122
 
 
123
 
  @Override
124
 
  public boolean equals(Object o) {
125
 
    if (this == o) return true;
126
 
    if (o == null || getClass() != o.getClass()) return false;
127
 
 
128
 
    final SpanOrQuery that = (SpanOrQuery) o;
129
 
 
130
 
    if (!clauses.equals(that.clauses)) return false;
131
 
    if (!clauses.isEmpty() && !field.equals(that.field)) return false;
132
 
 
133
 
    return getBoost() == that.getBoost();
134
 
  }
135
 
 
136
 
  @Override
137
 
  public int hashCode() {
138
 
    int h = clauses.hashCode();
139
 
    h ^= (h << 10) | (h >>> 23);
140
 
    h ^= Float.floatToRawIntBits(getBoost());
141
 
    return h;
142
 
  }
143
 
 
144
 
 
145
 
  private class SpanQueue extends PriorityQueue<Spans> {
146
 
    public SpanQueue(int size) {
147
 
      initialize(size);
148
 
    }
149
 
 
150
 
    @Override
151
 
    protected final boolean lessThan(Spans spans1, Spans spans2) {
152
 
      if (spans1.doc() == spans2.doc()) {
153
 
        if (spans1.start() == spans2.start()) {
154
 
          return spans1.end() < spans2.end();
155
 
        } else {
156
 
          return spans1.start() < spans2.start();
157
 
        }
158
 
      } else {
159
 
        return spans1.doc() < spans2.doc();
160
 
      }
161
 
    }
162
 
  }
163
 
 
164
 
  @Override
165
 
  public Spans getSpans(final IndexReader reader) throws IOException {
166
 
    if (clauses.size() == 1)                      // optimize 1-clause case
167
 
      return (clauses.get(0)).getSpans(reader);
168
 
 
169
 
    return new Spans() {
170
 
        private SpanQueue queue = null;
171
 
 
172
 
        private boolean initSpanQueue(int target) throws IOException {
173
 
          queue = new SpanQueue(clauses.size());
174
 
          Iterator<SpanQuery> i = clauses.iterator();
175
 
          while (i.hasNext()) {
176
 
            Spans spans = i.next().getSpans(reader);
177
 
            if (   ((target == -1) && spans.next())
178
 
                || ((target != -1) && spans.skipTo(target))) {
179
 
              queue.add(spans);
180
 
            }
181
 
          }
182
 
          return queue.size() != 0;
183
 
        }
184
 
 
185
 
        @Override
186
 
        public boolean next() throws IOException {
187
 
          if (queue == null) {
188
 
            return initSpanQueue(-1);
189
 
          }
190
 
 
191
 
          if (queue.size() == 0) { // all done
192
 
            return false;
193
 
          }
194
 
 
195
 
          if (top().next()) { // move to next
196
 
            queue.updateTop();
197
 
            return true;
198
 
          }
199
 
 
200
 
          queue.pop();  // exhausted a clause
201
 
          return queue.size() != 0;
202
 
        }
203
 
 
204
 
        private Spans top() { return queue.top(); }
205
 
 
206
 
        @Override
207
 
        public boolean skipTo(int target) throws IOException {
208
 
          if (queue == null) {
209
 
            return initSpanQueue(target);
210
 
          }
211
 
  
212
 
          boolean skipCalled = false;
213
 
          while (queue.size() != 0 && top().doc() < target) {
214
 
            if (top().skipTo(target)) {
215
 
              queue.updateTop();
216
 
            } else {
217
 
              queue.pop();
218
 
            }
219
 
            skipCalled = true;
220
 
          }
221
 
  
222
 
          if (skipCalled) {
223
 
            return queue.size() != 0;
224
 
          }
225
 
          return next();
226
 
        }
227
 
 
228
 
        @Override
229
 
        public int doc() { return top().doc(); }
230
 
        @Override
231
 
        public int start() { return top().start(); }
232
 
        @Override
233
 
        public int end() { return top().end(); }
234
 
 
235
 
      @Override
236
 
      public Collection<byte[]> getPayload() throws IOException {
237
 
        ArrayList<byte[]> result = null;
238
 
        Spans theTop = top();
239
 
        if (theTop != null && theTop.isPayloadAvailable()) {
240
 
          result = new ArrayList<byte[]>(theTop.getPayload());
241
 
        }
242
 
        return result;
243
 
      }
244
 
 
245
 
      @Override
246
 
      public boolean isPayloadAvailable() {
247
 
        Spans top = top();
248
 
        return top != null && top.isPayloadAvailable();
249
 
      }
250
 
 
251
 
      @Override
252
 
      public String toString() {
253
 
          return "spans("+SpanOrQuery.this+")@"+
254
 
            ((queue == null)?"START"
255
 
             :(queue.size()>0?(doc()+":"+start()+"-"+end()):"END"));
256
 
        }
257
 
 
258
 
      };
259
 
  }
260
 
 
261
 
}