add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / facet / src / java / org / apache / lucene / facet / search / FacetsAccumulator.java
1 package org.apache.lucene.facet.search;
2
3 import java.io.IOException;
4 import java.util.List;
5
6 import org.apache.lucene.index.IndexReader;
7
8 import org.apache.lucene.facet.search.params.FacetSearchParams;
9 import org.apache.lucene.facet.search.params.FacetRequest;
10 import org.apache.lucene.facet.search.results.FacetResult;
11 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
12
13 /**
14  * Licensed to the Apache Software Foundation (ASF) under one or more
15  * contributor license agreements.  See the NOTICE file distributed with
16  * this work for additional information regarding copyright ownership.
17  * The ASF licenses this file to You under the Apache License, Version 2.0
18  * (the "License"); you may not use this file except in compliance with
19  * the License.  You may obtain a copy of the License at
20  *
21  *     http://www.apache.org/licenses/LICENSE-2.0
22  *
23  * Unless required by applicable law or agreed to in writing, software
24  * distributed under the License is distributed on an "AS IS" BASIS,
25  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26  * See the License for the specific language governing permissions and
27  * limitations under the License.
28  */
29
30 /**
31  * Driver for Accumulating facets of faceted search requests over given
32  * documents.
33  * 
34  * @lucene.experimental
35  */
36 public abstract class FacetsAccumulator {
37
38   /**
39    * Default threshold for using the complements optimization.
40    * If accumulating facets for a document set larger than this ratio of the index size than 
41    * perform the complement optimization.
42    * @see #setComplementThreshold(double) for more info on the complements optimization.  
43    */
44   public static final double DEFAULT_COMPLEMENT_THRESHOLD = 0.6;
45
46   /**
47    * Passing this to {@link #setComplementThreshold(double)} will disable using complement optimization.
48    */
49   public static final double DISABLE_COMPLEMENT = Double.POSITIVE_INFINITY; // > 1 actually
50
51   /**
52    * Passing this to {@link #setComplementThreshold(double)} will force using complement optimization.
53    */
54   public static final double FORCE_COMPLEMENT = 0; // <=0  
55
56   private double complementThreshold = DEFAULT_COMPLEMENT_THRESHOLD;  
57
58   protected final TaxonomyReader taxonomyReader;
59   protected final IndexReader indexReader;
60   protected FacetSearchParams searchParams;
61
62   private boolean allowLabeling = true;
63
64   public FacetsAccumulator(FacetSearchParams searchParams,
65                             IndexReader indexReader,
66                             TaxonomyReader taxonomyReader) {
67     this.indexReader = indexReader;
68     this.taxonomyReader = taxonomyReader;
69     this.searchParams = searchParams;
70   }
71
72   /**
73    * Accumulate facets over given documents, according to facet requests in effect.
74    * @param docids documents (and their scores) for which facets are Accumulated.
75    * @return Accumulated facets.  
76    * @throws IOException on error.
77    */
78   // internal API note: it was considered to move the docids into the constructor as well, 
79   // but this prevents nice extension capabilities, especially in the way that 
80   // Sampling Accumulator works with the (any) delegated accumulator.
81   public abstract List<FacetResult> accumulate(ScoredDocIDs docids) throws IOException;
82
83   /**
84    * @return the complement threshold
85    * @see #setComplementThreshold(double)
86    */
87   public double getComplementThreshold() {
88     return complementThreshold;
89   }
90
91   /**
92    * Set the complement threshold.
93    * This threshold will dictate whether the complements optimization is applied.
94    * The optimization is to count for less documents. It is useful when the same 
95    * FacetSearchParams are used for varying sets of documents. The first time 
96    * complements is used the "total counts" are computed - counting for all the 
97    * documents in the collection. Then, only the complementing set of documents
98    * is considered, and used to decrement from the overall counts, thereby 
99    * walking through less documents, which is faster.
100    * <p>
101    * Note that this optimization is only available when searching an index
102    * whose {@link IndexReader} implements both 
103    * {@link IndexReader#directory()} and {@link IndexReader#getVersion()} 
104    * otherwise the optimization is silently disabled regardless of
105    * the complement threshold settings.
106    * <p>
107    * For the default settings see {@link #DEFAULT_COMPLEMENT_THRESHOLD}.
108    * <p>
109    * To forcing complements in all cases pass {@link #FORCE_COMPLEMENT}.
110    * This is mostly useful for testing purposes, as forcing complements when only 
111    * tiny fraction of available documents match the query does not make sense and 
112    * would incur performance degradations.
113    * <p>
114    * To disable complements pass {@link #DISABLE_COMPLEMENT}.
115    * @param complementThreshold the complement threshold to set
116    */
117   public void setComplementThreshold(double complementThreshold) {
118     this.complementThreshold = complementThreshold;
119   }
120
121   /**
122    * Check if labeling is allowed for this accumulator.
123    * <p>
124    * By default labeling is allowed.
125    * This allows one accumulator to invoke other accumulators for accumulation
126    * but keep to itself the responsibility of labeling.
127    * This might br handy since labeling is a costly operation. 
128    * @return true of labeling is allowed for this accumulator
129    * @see #setAllowLabeling(boolean)
130    */
131   protected boolean isAllowLabeling() {
132     return allowLabeling;
133   }
134
135   /**
136    * Set whether labeling is allowed for this accumulator.
137    * @param allowLabeling new setting for allow labeling
138    * @see #isAllowLabeling()
139    */
140   protected void setAllowLabeling(boolean allowLabeling) {
141     this.allowLabeling = allowLabeling;
142   }
143
144   /** check if all requests are complementable */
145   protected boolean mayComplement() {
146     for (FacetRequest freq:searchParams.getFacetRequests()) {
147       if (!freq.supportsComplements()) {
148         return false;
149       }
150     }
151     return true;
152   }
153 }