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

« back to all changes in this revision

Viewing changes to solr/core/src/java/org/apache/solr/search/DocSet.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
 
/**
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
 
18
 
package org.apache.solr.search;
19
 
 
20
 
import org.apache.solr.common.SolrException;
21
 
import org.apache.lucene.util.OpenBitSet;
22
 
import org.apache.lucene.search.DocIdSet;
23
 
import org.apache.lucene.search.Filter;
24
 
import org.apache.lucene.search.DocIdSetIterator;
25
 
import org.apache.lucene.index.IndexReader;
26
 
 
27
 
import java.io.IOException;
28
 
 
29
 
/**
30
 
 * <code>DocSet</code> represents an unordered set of Lucene Document Ids.
31
 
 *
32
 
 * <p>
33
 
 * WARNING: Any DocSet returned from SolrIndexSearcher should <b>not</b> be modified as it may have been retrieved from
34
 
 * a cache and could be shared.
35
 
 * </p>
36
 
 *
37
 
 * @version $Id: DocSet.java 1065312 2011-01-30 16:08:25Z rmuir $
38
 
 * @since solr 0.9
39
 
 */
40
 
public interface DocSet /* extends Collection<Integer> */ {
41
 
  
42
 
  /**
43
 
   * Adds the specified document if it is not currently in the DocSet
44
 
   * (optional operation).
45
 
   *
46
 
   * @see #addUnique
47
 
   * @throws SolrException if the implementation does not allow modifications
48
 
   */
49
 
  public void add(int doc);
50
 
 
51
 
  /**
52
 
   * Adds a document the caller knows is not currently in the DocSet
53
 
   * (optional operation).
54
 
   *
55
 
   * <p>
56
 
   * This method may be faster then <code>add(doc)</code> in some
57
 
   * implementaions provided the caller is certain of the precondition.
58
 
   * </p>
59
 
   *
60
 
   * @see #add
61
 
   * @throws SolrException if the implementation does not allow modifications
62
 
   */
63
 
  public void addUnique(int doc);
64
 
 
65
 
  /**
66
 
   * Returns the number of documents in the set.
67
 
   */
68
 
  public int size();
69
 
 
70
 
  /**
71
 
   * Returns true if a document is in the DocSet.
72
 
   */
73
 
  public boolean exists(int docid);
74
 
 
75
 
  /**
76
 
   * Returns an iterator that may be used to iterate over all of the documents in the set.
77
 
   *
78
 
   * <p>
79
 
   * The order of the documents returned by this iterator is
80
 
   * non-deterministic, and any scoring information is meaningless
81
 
   * </p>
82
 
   */
83
 
  public DocIterator iterator();
84
 
 
85
 
  /**
86
 
   * Returns a BitSet view of the DocSet.  Any changes to this BitSet <b>may</b>
87
 
   * be reflected in the DocSet, hence if the DocSet is shared or was returned from
88
 
   * a SolrIndexSearcher method, it's not safe to modify the BitSet.
89
 
   *
90
 
   * @return
91
 
   * An OpenBitSet with the bit number of every docid set in the set.
92
 
   * 
93
 
   * @deprecated Use {@link #iterator()} to access all docs instead.
94
 
   */
95
 
  @Deprecated
96
 
  public OpenBitSet getBits();
97
 
 
98
 
  /**
99
 
   * Returns the approximate amount of memory taken by this DocSet.
100
 
   * This is only an approximation and doesn't take into account java object overhead.
101
 
   *
102
 
   * @return
103
 
   * the approximate memory consumption in bytes
104
 
   */
105
 
  public long memSize();
106
 
 
107
 
  /**
108
 
   * Returns the intersection of this set with another set.  Neither set is modified - a new DocSet is
109
 
   * created and returned.
110
 
   * @return a DocSet representing the intersection
111
 
   */
112
 
  public DocSet intersection(DocSet other);
113
 
 
114
 
  /**
115
 
   * Returns the number of documents of the intersection of this set with another set.
116
 
   * May be more efficient than actually creating the intersection and then getting it's size.
117
 
   */
118
 
  public int intersectionSize(DocSet other);
119
 
 
120
 
  /**
121
 
   * Returns the union of this set with another set.  Neither set is modified - a new DocSet is
122
 
   * created and returned.
123
 
   * @return a DocSet representing the union
124
 
   */
125
 
  public DocSet union(DocSet other);
126
 
 
127
 
  /**
128
 
   * Returns the number of documents of the union of this set with another set.
129
 
   * May be more efficient than actually creating the union and then getting it's size.
130
 
   */
131
 
  public int unionSize(DocSet other);
132
 
 
133
 
  /**
134
 
   * Returns the documents in this set that are not in the other set. Neither set is modified - a new DocSet is
135
 
   * created and returned.
136
 
   * @return a DocSet representing this AND NOT other
137
 
   */
138
 
  public DocSet andNot(DocSet other);
139
 
 
140
 
  /**
141
 
   * Returns the number of documents in this set that are not in the other set.
142
 
   */
143
 
  public int andNotSize(DocSet other);
144
 
 
145
 
  /**
146
 
   * Returns a Filter for use in Lucene search methods, assuming this DocSet
147
 
   * was generated from the top-level MultiReader that the Lucene search
148
 
   * methods will be invoked with.
149
 
   */
150
 
  public Filter getTopFilter();
151
 
}
152
 
 
153
 
/** A base class that may be usefull for implementing DocSets */
154
 
abstract class DocSetBase implements DocSet {
155
 
 
156
 
  // Not implemented efficiently... for testing purposes only
157
 
  @Override
158
 
  public boolean equals(Object obj) {
159
 
    if (!(obj instanceof DocSet)) return false;
160
 
    DocSet other = (DocSet)obj;
161
 
    if (this.size() != other.size()) return false;
162
 
 
163
 
    if (this instanceof DocList && other instanceof DocList) {
164
 
      // compare ordering
165
 
      DocIterator i1=this.iterator();
166
 
      DocIterator i2=other.iterator();
167
 
      while(i1.hasNext() && i2.hasNext()) {
168
 
        if (i1.nextDoc() != i2.nextDoc()) return false;
169
 
      }
170
 
      return true;
171
 
      // don't compare matches
172
 
    }
173
 
 
174
 
    // if (this.size() != other.size()) return false;
175
 
    return this.getBits().equals(other.getBits());
176
 
  }
177
 
 
178
 
  /**
179
 
   * @throws SolrException Base implementation does not allow modifications
180
 
   */
181
 
  public void add(int doc) {
182
 
    throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Unsupported Operation");
183
 
  }
184
 
 
185
 
  /**
186
 
   * @throws SolrException Base implementation does not allow modifications
187
 
   */
188
 
  public void addUnique(int doc) {
189
 
    throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Unsupported Operation");
190
 
  }
191
 
 
192
 
  /**
193
 
   * Inefficient base implementation.
194
 
   *
195
 
   * @see BitDocSet#getBits
196
 
   */
197
 
  public OpenBitSet getBits() {
198
 
    OpenBitSet bits = new OpenBitSet();
199
 
    for (DocIterator iter = iterator(); iter.hasNext();) {
200
 
      bits.set(iter.nextDoc());
201
 
    }
202
 
    return bits;
203
 
  };
204
 
 
205
 
  public DocSet intersection(DocSet other) {
206
 
    // intersection is overloaded in the smaller DocSets to be more
207
 
    // efficient, so dispatch off of it instead.
208
 
    if (!(other instanceof BitDocSet)) {
209
 
      return other.intersection(this);
210
 
    }
211
 
 
212
 
    // Default... handle with bitsets.
213
 
    OpenBitSet newbits = (OpenBitSet)(this.getBits().clone());
214
 
    newbits.and(other.getBits());
215
 
    return new BitDocSet(newbits);
216
 
  }
217
 
 
218
 
  public DocSet union(DocSet other) {
219
 
    OpenBitSet newbits = (OpenBitSet)(this.getBits().clone());
220
 
    newbits.or(other.getBits());
221
 
    return new BitDocSet(newbits);
222
 
  }
223
 
 
224
 
  public int intersectionSize(DocSet other) {
225
 
    // intersection is overloaded in the smaller DocSets to be more
226
 
    // efficient, so dispatch off of it instead.
227
 
    if (!(other instanceof BitDocSet)) {
228
 
      return other.intersectionSize(this);
229
 
    }
230
 
    // less efficient way: do the intersection then get it's size
231
 
    return intersection(other).size();
232
 
  }
233
 
 
234
 
  public int unionSize(DocSet other) {
235
 
    return this.size() + other.size() - this.intersectionSize(other);
236
 
  }
237
 
 
238
 
  public DocSet andNot(DocSet other) {
239
 
    OpenBitSet newbits = (OpenBitSet)(this.getBits().clone());
240
 
    newbits.andNot(other.getBits());
241
 
    return new BitDocSet(newbits);
242
 
  }
243
 
 
244
 
  public int andNotSize(DocSet other) {
245
 
    return this.size() - this.intersectionSize(other);
246
 
  }
247
 
 
248
 
  public Filter getTopFilter() {
249
 
    final OpenBitSet bs = getBits();
250
 
 
251
 
    return new Filter() {
252
 
      @Override
253
 
      public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
254
 
        int offset = 0;
255
 
        SolrIndexReader r = (SolrIndexReader)reader;
256
 
        while (r.getParent() != null) {
257
 
          offset += r.getBase();
258
 
          r = r.getParent();
259
 
        }
260
 
 
261
 
        if (r==reader) return bs;
262
 
 
263
 
        final int base = offset;
264
 
        final int maxDoc = reader.maxDoc();
265
 
        final int max = base + maxDoc;   // one past the max doc in this segment.
266
 
 
267
 
        return new DocIdSet() {
268
 
          @Override
269
 
          public DocIdSetIterator iterator() throws IOException {
270
 
            return new DocIdSetIterator() {
271
 
              int pos=base-1;
272
 
              int adjustedDoc=-1;
273
 
 
274
 
              @Override
275
 
              public int docID() {
276
 
                return adjustedDoc;
277
 
              }
278
 
 
279
 
              @Override
280
 
              public int nextDoc() throws IOException {
281
 
                pos = bs.nextSetBit(pos+1);
282
 
                return adjustedDoc = (pos>=0 && pos<max) ? pos-base : NO_MORE_DOCS;
283
 
              }
284
 
 
285
 
              @Override
286
 
              public int advance(int target) throws IOException {
287
 
                if (target==NO_MORE_DOCS) return adjustedDoc=NO_MORE_DOCS;
288
 
                pos = bs.nextSetBit(target+base);
289
 
                return adjustedDoc = (pos>=0 && pos<max) ? pos-base : NO_MORE_DOCS;
290
 
              }
291
 
            };
292
 
          }
293
 
 
294
 
          @Override
295
 
          public boolean isCacheable() {
296
 
            return true;
297
 
          }
298
 
 
299
 
        };
300
 
      }
301
 
    };
302
 
  }
303
 
}
304
 
 
305
 
 
306
 
 
307
 
 
308