001: package org.apache.lucene.search.function;
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.search.Explanation;
021:
022: /**
023: * Expert: represents field values as different types.
024: * Normally created via a
025: * {@link org.apache.lucene.search.function.ValueSource ValueSuorce}
026: * for a particular field and reader.
027: *
028: * <p><font color="#FF0000">
029: * WARNING: The status of the <b>search.function</b> package is experimental.
030: * The APIs introduced here might change in the future and will not be
031: * supported anymore in such a case.</font>
032: *
033: *
034: */
035: public abstract class DocValues {
036: /*
037: * DocValues is distinct from ValueSource because
038: * there needs to be an object created at query evaluation time that
039: * is not referenced by the query itself because:
040: * - Query objects should be MT safe
041: * - For caching, Query objects are often used as keys... you don't
042: * want the Query carrying around big objects
043: */
044:
045: /**
046: * Return doc value as a float.
047: * <P>Mandatory: every DocValues implementation must implement at least this method.
048: * @param doc document whose float value is requested.
049: */
050: public abstract float floatVal(int doc);
051:
052: /**
053: * Return doc value as an int.
054: * <P>Optional: DocValues implementation can (but don't have to) override this method.
055: * @param doc document whose int value is requested.
056: */
057: public int intVal(int doc) {
058: return (int) floatVal(doc);
059: }
060:
061: /**
062: * Return doc value as a long.
063: * <P>Optional: DocValues implementation can (but don't have to) override this method.
064: * @param doc document whose long value is requested.
065: */
066: public long longVal(int doc) {
067: return (long) floatVal(doc);
068: }
069:
070: /**
071: * Return doc value as a double.
072: * <P>Optional: DocValues implementation can (but don't have to) override this method.
073: * @param doc document whose double value is requested.
074: */
075: public double doubleVal(int doc) {
076: return (double) floatVal(doc);
077: }
078:
079: /**
080: * Return doc value as a string.
081: * <P>Optional: DocValues implementation can (but don't have to) override this method.
082: * @param doc document whose string value is requested.
083: */
084: public String strVal(int doc) {
085: return Float.toString(floatVal(doc));
086: }
087:
088: /**
089: * Return a string representation of a doc value, as reuired for Explanations.
090: */
091: public abstract String toString(int doc);
092:
093: /**
094: * Explain the scoring value for the input doc.
095: */
096: public Explanation explain(int doc) {
097: return new Explanation(floatVal(doc), toString(doc));
098: }
099:
100: /**
101: * Expert: for test purposes only, return the inner array of values, or null if not applicable.
102: * <p>
103: * Allows tests to verify that loaded values are:
104: * <ol>
105: * <li>indeed cached/reused.</li>
106: * <li>stored in the expected size/type (byte/short/int/float).</li>
107: * </ol>
108: * Note: implementations of DocValues must override this method for
109: * these test elements to be tested, Otherwise the test would not fail, just
110: * print a warning.
111: */
112: Object getInnerArray() {
113: throw new UnsupportedOperationException(
114: "this optional method is for test purposes only");
115: }
116:
117: // --- some simple statistics on values
118: private float minVal;
119: private float maxVal;
120: private float avgVal;
121: private boolean computed = false;
122:
123: // compute optional values
124: private void compute() {
125: if (computed) {
126: return;
127: }
128: minVal = Float.MAX_VALUE;
129: maxVal = 0;
130: float sum = 0;
131: int n = 0;
132: while (true) {
133: float val;
134: try {
135: val = floatVal(n);
136: } catch (ArrayIndexOutOfBoundsException e) {
137: break;
138: }
139: sum += val;
140: minVal = Math.min(minVal, val);
141: maxVal = Math.max(maxVal, val);
142: }
143: avgVal = sum / n;
144: computed = true;
145: }
146:
147: /**
148: * Optional op.
149: * Returns the minimum of all values.
150: */
151: public float getMinValue() {
152: compute();
153: return minVal;
154: }
155:
156: /**
157: * Optional op.
158: * Returns the maximum of all values.
159: */
160: public float getMaxValue() {
161: compute();
162: return maxVal;
163: }
164:
165: /**
166: * Returns the average of all values.
167: */
168: public float getAverageValue() {
169: compute();
170: return avgVal;
171: }
172:
173: }
|