diff --git a/lucene/src/java/org/apache/lucene/search/FieldComparator.java b/lucene/src/java/org/apache/lucene/search/FieldComparator.java index 74e5ff87c50..fed7e9940e7 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldComparator.java +++ b/lucene/src/java/org/apache/lucene/search/FieldComparator.java @@ -26,9 +26,6 @@ import org.apache.lucene.search.cache.*; import org.apache.lucene.search.cache.CachedArray.*; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.packed.Direct16; -import org.apache.lucene.util.packed.Direct32; -import org.apache.lucene.util.packed.Direct8; import org.apache.lucene.util.packed.PackedInts; import java.io.IOException; @@ -1222,14 +1219,21 @@ public abstract class FieldComparator { final int docBase = context.docBase; termsIndex = FieldCache.DEFAULT.getTermsIndex(context.reader, field); final PackedInts.Reader docToOrd = termsIndex.getDocToOrd(); - FieldComparator perSegComp; - if (docToOrd instanceof Direct8) { - perSegComp = new ByteOrdComparator(((Direct8) docToOrd).getArray(), termsIndex, docBase); - } else if (docToOrd instanceof Direct16) { - perSegComp = new ShortOrdComparator(((Direct16) docToOrd).getArray(), termsIndex, docBase); - } else if (docToOrd instanceof Direct32) { - perSegComp = new IntOrdComparator(((Direct32) docToOrd).getArray(), termsIndex, docBase); - } else { + FieldComparator perSegComp = null; + if (docToOrd.hasArray()) { + final Object arr = docToOrd.getArray(); + if (arr instanceof byte[]) { + perSegComp = new ByteOrdComparator((byte[]) arr, termsIndex, docBase); + } else if (arr instanceof short[]) { + perSegComp = new ShortOrdComparator((short[]) arr, termsIndex, docBase); + } else if (arr instanceof int[]) { + perSegComp = new IntOrdComparator((int[]) arr, termsIndex, docBase); + } + // Don't specialize the long[] case since it's not + // possible, ie, worse case is MAX_INT-1 docs with + // every one having a unique value. + } + if (perSegComp == null) { perSegComp = new AnyOrdComparator(docToOrd, termsIndex, docBase); } diff --git a/lucene/src/java/org/apache/lucene/util/packed/Direct16.java b/lucene/src/java/org/apache/lucene/util/packed/Direct16.java index c698bd6ab1f..b4f628211b3 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/Direct16.java +++ b/lucene/src/java/org/apache/lucene/util/packed/Direct16.java @@ -28,7 +28,7 @@ import java.util.Arrays; * @lucene.internal */ -public class Direct16 extends PackedInts.ReaderImpl +class Direct16 extends PackedInts.ReaderImpl implements PackedInts.Mutable { private short[] values; private static final int BITS_PER_VALUE = 16; @@ -68,10 +68,6 @@ public class Direct16 extends PackedInts.ReaderImpl this.values = values; } - public short[] getArray() { - return values; - } - public long get(final int index) { return 0xFFFFL & values[index]; } @@ -88,4 +84,14 @@ public class Direct16 extends PackedInts.ReaderImpl public void clear() { Arrays.fill(values, (short)0); } + + @Override + public Object getArray() { + return values; + } + + @Override + public boolean hasArray() { + return true; + } } diff --git a/lucene/src/java/org/apache/lucene/util/packed/Direct32.java b/lucene/src/java/org/apache/lucene/util/packed/Direct32.java index c48d5b07d4c..8403ce0b870 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/Direct32.java +++ b/lucene/src/java/org/apache/lucene/util/packed/Direct32.java @@ -28,7 +28,7 @@ import java.util.Arrays; * @lucene.internal */ -public class Direct32 extends PackedInts.ReaderImpl +class Direct32 extends PackedInts.ReaderImpl implements PackedInts.Mutable { private int[] values; private static final int BITS_PER_VALUE = 32; @@ -64,10 +64,6 @@ public class Direct32 extends PackedInts.ReaderImpl this.values = values; } - public int[] getArray() { - return values; - } - public long get(final int index) { return 0xFFFFFFFFL & values[index]; } @@ -84,4 +80,14 @@ public class Direct32 extends PackedInts.ReaderImpl public void clear() { Arrays.fill(values, 0); } + + @Override + public int[] getArray() { + return values; + } + + @Override + public boolean hasArray() { + return true; + } } diff --git a/lucene/src/java/org/apache/lucene/util/packed/Direct64.java b/lucene/src/java/org/apache/lucene/util/packed/Direct64.java index 591483d02b4..a25ba52a1fb 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/Direct64.java +++ b/lucene/src/java/org/apache/lucene/util/packed/Direct64.java @@ -28,7 +28,7 @@ import java.util.Arrays; * @lucene.internal */ -public class Direct64 extends PackedInts.ReaderImpl +class Direct64 extends PackedInts.ReaderImpl implements PackedInts.Mutable { private long[] values; private static final int BITS_PER_VALUE = 64; @@ -48,10 +48,6 @@ public class Direct64 extends PackedInts.ReaderImpl this.values = values; } - public long[] getArray() { - return values; - } - /** * Creates an array backed by the given values. *

@@ -80,4 +76,14 @@ public class Direct64 extends PackedInts.ReaderImpl public void clear() { Arrays.fill(values, 0L); } + + @Override + public long[] getArray() { + return values; + } + + @Override + public boolean hasArray() { + return true; + } } diff --git a/lucene/src/java/org/apache/lucene/util/packed/Direct8.java b/lucene/src/java/org/apache/lucene/util/packed/Direct8.java index ab4000418ac..2353b7ec53f 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/Direct8.java +++ b/lucene/src/java/org/apache/lucene/util/packed/Direct8.java @@ -28,7 +28,7 @@ import java.util.Arrays; * @lucene.internal */ -public class Direct8 extends PackedInts.ReaderImpl +class Direct8 extends PackedInts.ReaderImpl implements PackedInts.Mutable { private byte[] values; private static final int BITS_PER_VALUE = 8; @@ -69,10 +69,6 @@ public class Direct8 extends PackedInts.ReaderImpl this.values = values; } - public byte[] getArray() { - return values; - } - public long get(final int index) { return 0xFFL & values[index]; } @@ -88,4 +84,14 @@ public class Direct8 extends PackedInts.ReaderImpl public void clear() { Arrays.fill(values, (byte)0); } + + @Override + public Object getArray() { + return values; + } + + @Override + public boolean hasArray() { + return true; + } } diff --git a/lucene/src/java/org/apache/lucene/util/packed/GrowableWriter.java b/lucene/src/java/org/apache/lucene/util/packed/GrowableWriter.java index 499387041fe..4d271b0ce88 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/GrowableWriter.java +++ b/lucene/src/java/org/apache/lucene/util/packed/GrowableWriter.java @@ -60,6 +60,16 @@ public class GrowableWriter implements PackedInts.Mutable { return current; } + @Override + public Object getArray() { + return current.getArray(); + } + + @Override + public boolean hasArray() { + return current.hasArray(); + } + public void set(int index, long value) { if (value >= currentMaxValue) { int bpv = getBitsPerValue(); diff --git a/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java b/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java index 02558685d97..815e3c3e2a5 100644 --- a/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java +++ b/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java @@ -65,6 +65,25 @@ public class PackedInts { * @return the number of values. */ int size(); + + /** + * Expert: if the bit-width of this reader matches one of + * java's native types, returns the underlying array + * (ie, byte[], short[], int[], long[]); else, returns + * null. Note that when accessing the array you must + * upgrade the type (bitwise AND with all ones), to + * interpret the full value as unsigned. Ie, + * bytes[idx]&0xFF, shorts[idx]&0xFFFF, etc. + */ + Object getArray(); + + /** + * Returns true if this implementation is backed by a + * native java array. + * + * @see #getArray + */ + boolean hasArray(); } /** @@ -137,6 +156,14 @@ public class PackedInts { public long getMaxValue() { // Convenience method return maxValue(bitsPerValue); } + + public Object getArray() { + return null; + } + + public boolean hasArray() { + return false; + } } /** A write-once Writer. diff --git a/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java b/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java index 62eee24eb16..4b0acc22683 100755 --- a/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java +++ b/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java @@ -28,9 +28,6 @@ import org.apache.lucene.util.PriorityQueue; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.UnicodeUtil; -import org.apache.lucene.util.packed.Direct16; -import org.apache.lucene.util.packed.Direct32; -import org.apache.lucene.util.packed.Direct8; import org.apache.lucene.util.packed.PackedInts; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.FacetParams; @@ -268,8 +265,15 @@ class PerSegmentSingleValuedFaceting { PackedInts.Reader ordReader = si.getDocToOrd(); int doc; - if (ordReader instanceof Direct32) { - int[] ords = ((Direct32)ordReader).getArray(); + final Object arr; + if (ordReader.hasArray()) { + arr = ordReader.getArray(); + } else { + arr = null; + } + + if (arr instanceof int[]) { + int[] ords = (int[]) arr; if (prefix==null) { while ((doc = iter.nextDoc()) < DocIdSetIterator.NO_MORE_DOCS) { counts[ords[doc]]++; @@ -281,8 +285,8 @@ class PerSegmentSingleValuedFaceting { if (arrIdx>=0 && arrIdx=0 && arrIdx=0 && arrIdx=0 && arrIdx { public static FieldComparator createComparator(IndexReader reader, TermOrdValComparator_SML parent) throws IOException { parent.termsIndex = FieldCache.DEFAULT.getTermsIndex(reader, parent.field); final PackedInts.Reader docToOrd = parent.termsIndex.getDocToOrd(); - PerSegmentComparator perSegComp; + PerSegmentComparator perSegComp = null; + if (docToOrd.hasArray()) { + final Object arr = docToOrd.getArray(); + if (arr instanceof byte[]) { + perSegComp = new ByteOrdComparator((byte[]) arr, parent); + } else if (arr instanceof short[]) { + perSegComp = new ShortOrdComparator((short[]) arr, parent); + } else if (arr instanceof int[]) { + perSegComp = new IntOrdComparator((int[]) arr, parent); + } + } - if (docToOrd instanceof Direct8) { - perSegComp = new ByteOrdComparator(((Direct8) docToOrd).getArray(), parent); - } else if (docToOrd instanceof Direct16) { - perSegComp = new ShortOrdComparator(((Direct16) docToOrd).getArray(), parent); - } else if (docToOrd instanceof Direct32) { - perSegComp = new IntOrdComparator(((Direct32) docToOrd).getArray(), parent); - } else { + if (perSegComp == null) { perSegComp = new AnyOrdComparator(docToOrd, parent); }