Index: contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java =================================================================== --- contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java (revision 744207) +++ contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java (working copy) @@ -395,10 +395,7 @@ ) { if (precisionStep<1 || precisionStep>64) throw new IllegalArgumentException("precisionStep may only be 1..64"); - splitRange( - builder, 64, precisionStep, minBound, maxBound, - 0 /* start with no shift */ - ); + splitRange(builder, 64, precisionStep, minBound, maxBound); } /** @@ -414,50 +411,49 @@ ) { if (precisionStep<1 || precisionStep>32) throw new IllegalArgumentException("precisionStep may only be 1..32"); - splitRange( - builder, 32, precisionStep, (long)minBound, (long)maxBound, - 0 /* start with no shift */ - ); + splitRange(builder, 32, precisionStep, (long)minBound, (long)maxBound); } /** This helper does the splitting for both 32 and 64 bit. */ private static void splitRange( final Object builder, final int valSize, - final int precisionStep, final long minBound, final long maxBound, - final int shift + final int precisionStep, long minBound, long maxBound ) { - // calculate new bounds for inner precision - final long diff = 1L << (shift+precisionStep), - mask = ((1L<=valSize || nextMinBound>nextMaxBound) { - // We are in the lowest precision or the next precision is not available. - addRange(builder, valSize, precisionStep, minBound, maxBound, shift); - } else { + if (shift+precisionStep>=valSize || nextMinBound>nextMaxBound) { + // We are in the lowest precision or the next precision is not available. + addRange(builder, valSize, minBound, maxBound, shift, level); + // exit the split recursion loop + break; + } + if (hasLower) - addRange(builder, valSize, precisionStep, minBound, minBound | mask, shift); + addRange(builder, valSize, minBound, minBound | mask, shift, level); if (hasUpper) - addRange(builder, valSize, precisionStep, maxBound & ~mask, maxBound, shift); - // recurse down to next precision - splitRange( - builder, valSize, precisionStep, - nextMinBound, nextMaxBound, - shift+precisionStep - ); + addRange(builder, valSize, maxBound & ~mask, maxBound, shift, level); + + // recurse to next precision + minBound = nextMinBound; + maxBound = nextMaxBound; + shift += precisionStep; } } /** Helper that delegates to correct range builder */ private static void addRange( final Object builder, final int valSize, - final int precisionStep, long minBound, long maxBound, - final int shift + long minBound, long maxBound, + final int shift, final int level ) { // for the max bound set all lower bits (that were shifted away): // this is important for testing or other usages of the splitted range @@ -467,10 +463,10 @@ // delegate to correct range builder switch(valSize) { case 64: - ((LongRangeBuilder)builder).addRange(precisionStep, minBound, maxBound, shift); + ((LongRangeBuilder)builder).addRange(minBound, maxBound, shift, level); break; case 32: - ((IntRangeBuilder)builder).addRange(precisionStep, (int)minBound, (int)maxBound, shift); + ((IntRangeBuilder)builder).addRange((int)minBound, (int)maxBound, shift, level); break; default: // Should not happen! @@ -481,6 +477,8 @@ /** * Expert: Callback for {@link #splitLongRange}. * You need to overwrite only one of the methods. + *

WARNING: This is a very low-level interface, + * the method signatures may change in later versions. */ public static abstract class LongRangeBuilder { @@ -503,10 +501,10 @@ * Overwrite this method, if you like to receive the raw long range bounds. * You can use this for e.g. debugging purposes (print out range bounds). */ - public void addRange(final int precisionStep, final long min, final long max, final int shift) { + public void addRange(final long min, final long max, final int shift, final int level) { /*System.out.println(Long.toHexString((min^0x8000000000000000L) >>> shift)+".."+ Long.toHexString((max^0x8000000000000000L) >>> shift));*/ - addRange(longToPrefixCoded(min, shift), longToPrefixCoded(max, shift), shift/precisionStep); + addRange(longToPrefixCoded(min, shift), longToPrefixCoded(max, shift), level); } } @@ -514,6 +512,8 @@ /** * Expert: Callback for {@link #splitIntRange}. * You need to overwrite only one of the methods. + *

WARNING: This is a very low-level interface, + * the method signatures may change in later versions. */ public static abstract class IntRangeBuilder { @@ -536,10 +536,10 @@ * Overwrite this method, if you like to receive the raw int range bounds. * You can use this for e.g. debugging purposes (print out range bounds). */ - public void addRange(final int precisionStep, final int min, final int max, final int shift) { + public void addRange(final int min, final int max, final int shift, final int level) { /*System.out.println(Integer.toHexString((min^0x80000000) >>> shift)+".."+ Integer.toHexString((max^0x80000000) >>> shift));*/ - addRange(intToPrefixCoded(min, shift), intToPrefixCoded(max, shift), shift/precisionStep); + addRange(intToPrefixCoded(min, shift), intToPrefixCoded(max, shift), level); } } Index: contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieUtils.java =================================================================== --- contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieUtils.java (revision 744207) +++ contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieUtils.java (working copy) @@ -178,7 +178,8 @@ final OpenBitSet bits=useBitSet ? new OpenBitSet(upper-lower+1) : null; TrieUtils.splitLongRange(new TrieUtils.LongRangeBuilder() { - public void addRange(int precisionStep, long min, long max, int shift) { + //@Override + public void addRange(long min, long max, int shift, int level) { assertTrue("min, max should be inside bounds", min>=lower && min<=upper && max>=lower && max<=upper); if (useBitSet) for (long l=min; l<=max; l++) { assertFalse("ranges should not overlap", bits.getAndSet(l-lower) ); @@ -251,7 +252,8 @@ final OpenBitSet bits=useBitSet ? new OpenBitSet(upper-lower+1) : null; TrieUtils.splitIntRange(new TrieUtils.IntRangeBuilder() { - public void addRange(int precisionStep, int min, int max, int shift) { + //@Override + public void addRange(int min, int max, int shift, int level) { assertTrue("min, max should be inside bounds", min>=lower && min<=upper && max>=lower && max<=upper); if (useBitSet) for (int i=min; i<=max; i++) { assertFalse("ranges should not overlap", bits.getAndSet(i-lower) );