001: package org.apache.lucene.benchmark.byTask.tasks;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.benchmark.byTask.PerfRunData;
021: import org.apache.lucene.benchmark.byTask.feeds.QueryMaker;
022: import org.apache.lucene.document.Document;
023: import org.apache.lucene.index.IndexReader;
024: import org.apache.lucene.search.Hits;
025: import org.apache.lucene.search.IndexSearcher;
026: import org.apache.lucene.search.Query;
027: import org.apache.lucene.store.Directory;
028:
029: import java.io.IOException;
030:
031: /**
032: * Read index (abstract) task.
033: * Sub classes implement withSearch(), withWarm(), withTraverse() and withRetrieve()
034: * methods to configure the actual action.
035: *
036: * <p>Note: All ReadTasks reuse the reader if it is already open.
037: * Otherwise a reader is opened at start and closed at the end.
038: *
039: * <p>Other side effects: none.
040: */
041: public abstract class ReadTask extends PerfTask {
042:
043: public ReadTask(PerfRunData runData) {
044: super (runData);
045: }
046:
047: public int doLogic() throws Exception {
048: int res = 0;
049: boolean closeReader = false;
050:
051: // open reader or use existing one
052: IndexReader ir = getRunData().getIndexReader();
053: if (ir == null) {
054: Directory dir = getRunData().getDirectory();
055: ir = IndexReader.open(dir);
056: closeReader = true;
057: //res++; //this is confusing, comment it out
058: }
059:
060: // optionally warm and add num docs traversed to count
061: if (withWarm()) {
062: Document doc = null;
063: for (int m = 0; m < ir.maxDoc(); m++) {
064: if (!ir.isDeleted(m)) {
065: doc = ir.document(m);
066: res += (doc == null ? 0 : 1);
067: }
068: }
069: }
070:
071: if (withSearch()) {
072: res++;
073: IndexSearcher searcher = new IndexSearcher(ir);
074: QueryMaker queryMaker = getQueryMaker();
075: Query q = queryMaker.makeQuery();
076: Hits hits = searcher.search(q);
077: //System.out.println("searched: "+q);
078:
079: if (withTraverse() && hits != null) {
080: int traversalSize = Math.min(hits.length(),
081: traversalSize());
082: if (traversalSize > 0) {
083: boolean retrieve = withRetrieve();
084: for (int m = 0; m < hits.length(); m++) {
085: int id = hits.id(m);
086: res++;
087: if (retrieve) {
088: res += retrieveDoc(ir, id);
089: }
090: }
091: }
092: }
093:
094: searcher.close();
095: }
096:
097: if (closeReader) {
098: ir.close();
099: }
100: return res;
101: }
102:
103: protected int retrieveDoc(IndexReader ir, int id)
104: throws IOException {
105: return (ir.document(id) == null ? 0 : 1);
106: }
107:
108: /**
109: * Return query maker used for this task.
110: */
111: public abstract QueryMaker getQueryMaker();
112:
113: /**
114: * Return true if search should be performed.
115: */
116: public abstract boolean withSearch();
117:
118: /**
119: * Return true if warming should be performed.
120: */
121: public abstract boolean withWarm();
122:
123: /**
124: * Return true if, with search, results should be traversed.
125: */
126: public abstract boolean withTraverse();
127:
128: /**
129: * Specify the number of hits to traverse. Tasks should override this if they want to restrict the number
130: * of hits that are traversed when {@link #withTraverse()} is true. Must be greater than 0.
131: *
132: * Read task calculates the traversal as: Math.min(hits.length(), traversalSize())
133: * @return Integer.MAX_VALUE
134: */
135: public int traversalSize() {
136: return Integer.MAX_VALUE;
137: }
138:
139: /**
140: * Return true if, with search & results traversing, docs should be retrieved.
141: */
142: public abstract boolean withRetrieve();
143:
144: }
|