001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.solr.search;
017:
018: /**
019: * <code>DocSlice</code> implements DocList as an array of docids and optional scores.
020: *
021: * @author yonik
022: * @version $Id: DocSlice.java 539098 2007-05-17 20:01:40Z otis $
023: * @since solr 0.9
024: */
025: public class DocSlice extends DocSetBase implements DocList {
026: final int offset; // starting position of the docs (zero based)
027: final int len; // number of positions used in arrays
028: final int[] docs; // a slice of documents (docs 0-100 of the query)
029:
030: final float[] scores; // optional score list
031: final int matches;
032: final float maxScore;
033:
034: /**
035: * Primary constructor for a DocSlice instance.
036: *
037: * @param offset starting offset for this range of docs
038: * @param len length of results
039: * @param docs array of docids starting at position 0
040: * @param scores array of scores that corresponds to docs, may be null
041: * @param matches total number of matches for the query
042: */
043: public DocSlice(int offset, int len, int[] docs, float[] scores,
044: int matches, float maxScore) {
045: this .offset = offset;
046: this .len = len;
047: this .docs = docs;
048: this .scores = scores;
049: this .matches = matches;
050: this .maxScore = maxScore;
051: }
052:
053: public DocList subset(int offset, int len) {
054: if (this .offset == offset && this .len == len)
055: return this ;
056:
057: // if we didn't store enough (and there was more to store)
058: // then we can't take a subset.
059: int requestedEnd = offset + len;
060: if (requestedEnd > docs.length && this .matches > docs.length)
061: return null;
062: int realEndDoc = Math.min(requestedEnd, docs.length);
063: int realLen = Math.max(realEndDoc - offset, 0);
064: if (this .offset == offset && this .len == realLen)
065: return this ;
066: return new DocSlice(offset, realLen, docs, scores, matches,
067: maxScore);
068: }
069:
070: public boolean hasScores() {
071: return scores != null;
072: }
073:
074: public float maxScore() {
075: return maxScore;
076: }
077:
078: public int offset() {
079: return offset;
080: }
081:
082: public int size() {
083: return len;
084: }
085:
086: public int matches() {
087: return matches;
088: }
089:
090: public long memSize() {
091: return (docs.length << 2)
092: + (scores == null ? 0 : (scores.length << 2)) + 24;
093: }
094:
095: public boolean exists(int doc) {
096: for (int i : docs) {
097: if (i == doc)
098: return true;
099: }
100: return false;
101: }
102:
103: // Hmmm, maybe I could have reused the scorer interface here...
104: // except that it carries Similarity baggage...
105: public DocIterator iterator() {
106: return new DocIterator() {
107: int pos = offset;
108: final int end = offset + len;
109:
110: public boolean hasNext() {
111: return pos < end;
112: }
113:
114: public Integer next() {
115: return nextDoc();
116: }
117:
118: public void remove() {
119: }
120:
121: public int nextDoc() {
122: return docs[pos++];
123: }
124:
125: public float score() {
126: return scores[pos - 1];
127: }
128: };
129: }
130: }
|