Index: contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java =================================================================== --- contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java (revision 764343) +++ contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java (working copy) @@ -18,6 +18,8 @@ */ import org.apache.lucene.search.SortField; +import org.apache.lucene.search.ValueSource; +import org.apache.lucene.search.CachingValueSource; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.ExtendedFieldCache; @@ -64,57 +66,12 @@ /** internal: maximum needed char[] buffer size for encoding */ static final int INT_BUF_SIZE = 31/7 + 2; - - /** - * A parser instance for filling a {@link ExtendedFieldCache}, that parses prefix encoded fields as longs. - */ - public static final ExtendedFieldCache.LongParser FIELD_CACHE_LONG_PARSER=new ExtendedFieldCache.LongParser(){ - public final long parseLong(final String val) { - final int shift = val.charAt(0)-SHIFT_START_LONG; - if (shift>0 && shift<=63) - throw new FieldCache.StopFillCacheException(); - return prefixCodedToLong(val); - } - }; /** - * A parser instance for filling a {@link FieldCache}, that parses prefix encoded fields as ints. + * A value source for the field cache, that parses prefix encoded fields. */ - public static final FieldCache.IntParser FIELD_CACHE_INT_PARSER=new FieldCache.IntParser(){ - public final int parseInt(final String val) { - final int shift = val.charAt(0)-SHIFT_START_INT; - if (shift>0 && shift<=31) - throw new FieldCache.StopFillCacheException(); - return prefixCodedToInt(val); - } - }; + public static final ValueSource TRIE_VALUE_SOURCE = new CachingValueSource(new TrieValueSource()); - /** - * A parser instance for filling a {@link ExtendedFieldCache}, that parses prefix encoded fields as doubles. - * This uses {@link #sortableLongToDouble} to convert the encoded long to a double. - */ - public static final ExtendedFieldCache.DoubleParser FIELD_CACHE_DOUBLE_PARSER=new ExtendedFieldCache.DoubleParser(){ - public final double parseDouble(final String val) { - final int shift = val.charAt(0)-SHIFT_START_LONG; - if (shift>0 && shift<=63) - throw new FieldCache.StopFillCacheException(); - return sortableLongToDouble(prefixCodedToLong(val)); - } - }; - - /** - * A parser instance for filling a {@link FieldCache}, that parses prefix encoded fields as floats. - * This uses {@link #sortableIntToFloat} to convert the encoded int to a float. - */ - public static final FieldCache.FloatParser FIELD_CACHE_FLOAT_PARSER=new FieldCache.FloatParser(){ - public final float parseFloat(final String val) { - final int shift = val.charAt(0)-SHIFT_START_INT; - if (shift>0 && shift<=31) - throw new FieldCache.StopFillCacheException(); - return sortableIntToFloat(prefixCodedToInt(val)); - } - }; - /** internal */ static int longToPrefixCoded(final long val, final int shift, final char[] buffer) { int nChars = (63-shift)/7 + 1, len = nChars+1; @@ -291,12 +248,12 @@ /** A factory method, that generates a {@link SortField} instance for sorting prefix encoded long values. */ public static SortField getLongSortField(final String field, final boolean reverse) { - return new SortField(field, FIELD_CACHE_LONG_PARSER, reverse); + return new SortField(field, SortField.LONG, TRIE_VALUE_SOURCE, reverse); } /** A factory method, that generates a {@link SortField} instance for sorting prefix encoded int values. */ public static SortField getIntSortField(final String field, final boolean reverse) { - return new SortField(field, FIELD_CACHE_INT_PARSER, reverse); + return new SortField(field, SortField.INT, TRIE_VALUE_SOURCE, reverse); } /** Index: contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java =================================================================== --- contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java (revision 0) +++ contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java (revision 0) @@ -0,0 +1,115 @@ +package org.apache.lucene.search.trie; + +import java.io.IOException; + +import org.apache.lucene.search.ValueSource; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermDocs; +import org.apache.lucene.index.TermEnum; + +public class TrieValueSource extends ValueSource { + + public double[] getDoubles(final IndexReader reader, String field) throws IOException { + final double[] retArray = new double[reader.maxDoc()]; + new TrieUninverter() { + private double doubleVal; + + protected void handleDoc(int index) { + retArray[index] = doubleVal; + } + + protected boolean newTerm(String value) { + final int shift = value.charAt(0)-TrieUtils.SHIFT_START_LONG; + if (shift>0 && shift<=63) return true; + this.doubleVal = TrieUtils.sortableLongToDouble(TrieUtils.prefixCodedToLong(value)); + return false; + } + }.go(reader, field); + return retArray; + } + + public float[] getFloats(final IndexReader reader, String field) throws IOException { + final float[] retArray = new float[reader.maxDoc()]; + new TrieUninverter() { + private float floatVal; + + protected void handleDoc(int index) { + retArray[index] = floatVal; + } + + protected boolean newTerm(String value) { + final int shift = value.charAt(0)-TrieUtils.SHIFT_START_INT; + if (shift>0 && shift<=63) return true; + this.floatVal = TrieUtils.sortableIntToFloat(TrieUtils.prefixCodedToInt(value)); + return false; + } + }.go(reader, field); + return retArray; + } + + public int[] getInts(final IndexReader reader, String field) throws IOException { + final int[] retArray = new int[reader.maxDoc()]; + new TrieUninverter() { + private int intVal; + + protected void handleDoc(int index) { + retArray[index] = intVal; + } + + protected boolean newTerm(String value) { + final int shift = value.charAt(0)-TrieUtils.SHIFT_START_INT; + if (shift>0 && shift<=31) return true; + this.intVal = TrieUtils.prefixCodedToInt(value); + return false; + } + }.go(reader, field); + return retArray; + } + + public long[] getLongs(final IndexReader reader, String field) throws IOException { + final long[] retArray = new long[reader.maxDoc()]; + new TrieUninverter() { + private long longVal; + + protected void handleDoc(int index) { + retArray[index] = longVal; + } + + protected boolean newTerm(String value) { + final int shift = value.charAt(0)-TrieUtils.SHIFT_START_LONG; + if (shift>0 && shift<=63) return true; + this.longVal = TrieUtils.prefixCodedToLong(value); + return false; + } + }.go(reader, field); + return retArray; + } + + protected static abstract class TrieUninverter { + public void go(IndexReader reader, String field) throws IOException { + TermDocs termDocs = reader.termDocs(); + TermEnum termEnum = reader.terms(new Term(field, "")); + try { + do { + Term term = termEnum.term(); + if (term == null || term.field() != field) + break; + if (newTerm(term.text())) break; + termDocs.seek(termEnum); + while (termDocs.next()) { + handleDoc(termDocs.doc()); + } + } while (termEnum.next()); + } finally { + termDocs.close(); + termEnum.close(); + } + } + + protected abstract void handleDoc(int docID); + + /** returns true, if parsing should be stopped */ + protected abstract boolean newTerm(String text); + } +}