8317795: Add an ImmutableBitSetPredicate variant for bitsets <= 128 elements

Reviewed-by: pminborg, rriggs
This commit is contained in:
Claes Redestad 2023-10-10 17:01:57 +00:00
parent fb4098ff1a
commit 33591a30d2
2 changed files with 61 additions and 24 deletions

View file

@ -48,23 +48,21 @@ public class ImmutableBitSetPredicate implements IntPredicate {
this.words = original.toLongArray();
}
/**
* @param bitIndex the bit index to test
* @return true if the bit is in the range of the BitSet and the bit is set, otherwise false
*/
@Override
public boolean test(int bitIndex) {
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
if (bitIndex < 0) {
return false;
}
int wordIndex = wordIndex(bitIndex);
int wordIndex = bitIndex >> 6;
return (wordIndex < words.length)
&& ((words[wordIndex] & (1L << bitIndex)) != 0);
}
/**
* Given a bit index, return word index containing it.
*/
private static int wordIndex(int bitIndex) {
return bitIndex >> 6;
}
/**
* {@return a new {@link IntPredicate } representing the {@link BitSet#get(int)} method applied
* on an immutable snapshot of the current state of this BitSet}.
@ -79,7 +77,38 @@ public class ImmutableBitSetPredicate implements IntPredicate {
* @since 22
*/
public static IntPredicate of(BitSet original) {
if (original.size() <= 128) {
long[] array = original.toLongArray();
return new SmallImmutableBitSetPredicate(
array.length > 0 ? array[0] : 0L,
array.length > 1 ? array[1] : 0L);
}
return new ImmutableBitSetPredicate(original);
}
/**
* Specialization for small sets of 128 bits or less
* @param first - bits index 0 through 63, inclusive
* @param second - bits index 64 through 127, inclusive
*/
public record SmallImmutableBitSetPredicate(long first, long second) implements IntPredicate {
/**
* @param bitIndex the bit index to test
* @return true if the bit is in the range of the BitSet and the bit is set, otherwise false
*/
@Override
public boolean test(int bitIndex) {
if (bitIndex < 0) {
return false;
}
int wordIndex = bitIndex >> 6;
if (wordIndex > 1) {
return false;
}
long bits = wordIndex == 0 ? first : second;
return (bits & (1L << bitIndex)) != 0;
}
}
}