| /* |
| * 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. |
| */ |
| package org.apache.solr.search; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| |
| import org.apache.lucene.search.TotalHits; |
| import org.apache.lucene.util.Accountable; |
| import org.apache.lucene.util.RamUsageEstimator; |
| |
| /** |
| * <code>DocSlice</code> implements DocList as an array of docids and optional scores. |
| * |
| * |
| * @since solr 0.9 |
| */ |
| public class DocSlice extends DocSetBase implements DocList { |
| private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(DocSlice.class) + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER; |
| |
| final int offset; // starting position of the docs (zero based) |
| final int len; // number of positions used in arrays |
| final int[] docs; // a slice of documents (docs 0-100 of the query) |
| |
| final float[] scores; // optional score list |
| final long matches; |
| final TotalHits.Relation matchesRelation; |
| final float maxScore; |
| final long ramBytesUsed; // cached value |
| |
| /** |
| * Primary constructor for a DocSlice instance. |
| * |
| * @param offset starting offset for this range of docs |
| * @param len length of results |
| * @param docs array of docids starting at position 0 |
| * @param scores array of scores that corresponds to docs, may be null |
| * @param matches total number of matches for the query |
| * @param matchesRelation Indicates if {@code matches} is exact or an approximation |
| */ |
| public DocSlice(int offset, int len, int[] docs, float[] scores, long matches, float maxScore, TotalHits.Relation matchesRelation) { |
| this.offset=offset; |
| this.len=len; |
| this.docs=docs; |
| this.scores=scores; |
| this.matches=matches; |
| this.maxScore=maxScore; |
| this.ramBytesUsed = BASE_RAM_BYTES_USED + (docs == null ? 0 : ((long)docs.length << 2)) + (scores == null ? 0 : ((long)scores.length<<2)+RamUsageEstimator.NUM_BYTES_ARRAY_HEADER); |
| this.matchesRelation = matchesRelation; |
| } |
| |
| @Override |
| public DocList subset(int offset, int len) { |
| if (this.offset == offset && this.len==len) return this; |
| |
| // if we didn't store enough (and there was more to store) |
| // then we can't take a subset. |
| int requestedEnd = offset + len; |
| if (requestedEnd > docs.length && this.matches > docs.length) return null; |
| int realEndDoc = Math.min(requestedEnd, docs.length); |
| int realLen = Math.max(realEndDoc-offset,0); |
| if (this.offset == offset && this.len == realLen) return this; |
| return new DocSlice(offset, realLen, docs, scores, matches, maxScore, matchesRelation); |
| } |
| |
| @Override |
| public boolean hasScores() { |
| return scores!=null; |
| } |
| |
| @Override |
| public float maxScore() { |
| return maxScore; |
| } |
| |
| |
| @Override |
| public int offset() { return offset; } |
| @Override |
| public int size() { return len; } |
| @Override |
| public long matches() { return matches; } |
| |
| |
| @Override |
| @Deprecated // see SOLR-14258 |
| public boolean exists(int doc) { |
| int end = offset+len; |
| for (int i=offset; i<end; i++) { |
| if (docs[i]==doc) return true; |
| } |
| return false; |
| } |
| |
| // Hmmm, maybe I could have reused the scorer interface here... |
| // except that it carries Similarity baggage... |
| @Override |
| public DocIterator iterator() { |
| return new DocIterator() { |
| int pos=offset; |
| final int end=offset+len; |
| @Override |
| public boolean hasNext() { |
| return pos < end; |
| } |
| |
| @Override |
| public Integer next() { |
| return nextDoc(); |
| } |
| |
| /** |
| * The remove operation is not supported by this Iterator. |
| */ |
| @Override |
| public void remove() { |
| throw new UnsupportedOperationException("The remove operation is not supported by this Iterator."); |
| } |
| |
| @Override |
| public int nextDoc() { |
| return docs[pos++]; |
| } |
| |
| @Override |
| public float score() { |
| return scores[pos-1]; |
| } |
| }; |
| } |
| |
| |
| @Override |
| @Deprecated // see SOLR-14258 |
| public DocSet intersection(DocSet other) { |
| if (other instanceof SortedIntDocSet || other instanceof HashDocSet) { |
| return other.intersection(this); |
| } |
| HashDocSet h = new HashDocSet(docs,offset,len); |
| return h.intersection(other); |
| } |
| |
| @Override |
| @Deprecated // see SOLR-14258 |
| public int intersectionSize(DocSet other) { |
| if (other instanceof SortedIntDocSet || other instanceof HashDocSet) { |
| return other.intersectionSize(this); |
| } |
| HashDocSet h = new HashDocSet(docs,offset,len); |
| return h.intersectionSize(other); |
| } |
| |
| @Override |
| @Deprecated // see SOLR-14258 |
| public boolean intersects(DocSet other) { |
| if (other instanceof SortedIntDocSet || other instanceof HashDocSet) { |
| return other.intersects(this); |
| } |
| HashDocSet h = new HashDocSet(docs,offset,len); |
| return h.intersects(other); |
| } |
| |
| @Override |
| @Deprecated // see SOLR-14258 |
| public DocSlice clone() { |
| return (DocSlice) super.clone(); |
| } |
| |
| /** WARNING: this can over-estimate real memory use since backing arrays are shared with other DocSlice instances */ |
| @Override |
| public long ramBytesUsed() { |
| return ramBytesUsed; |
| } |
| |
| @Override |
| public Collection<Accountable> getChildResources() { |
| return Collections.emptyList(); |
| } |
| |
| @Override |
| public TotalHits.Relation hitCountRelation() { |
| return matchesRelation; |
| } |
| } |