Skip to content

Conversation

AdityaTeltia
Copy link
Contributor

Closes #15038

  • Made BitSet a sealed abstract class permitting only FixedBitSet and SparseFixedBitSet.
  • Declared SparseFixedBitSet as final to comply with sealed hierarchy.
  • Removed test-only subclass JavaUtilBitSet which was no longer permitted.
  • Refactored BaseBitSetTestCase to introduce an abstract fromJavaUtilBitSet(...) factory.
  • Implemented fromJavaUtilBitSet(...) in TestFixedBitSet and TestSparseFixedBitSet to build the
    correct BitSet implementation from a java.util.BitSet for testing.

This ensures that only Lucene’s optimized implementations of BitSet are allowed, preventing
accidental performance regressions from custom subclasses, while keeping existing tests valid.

@benwtrent
Copy link
Member

10.3 is cut, so cannot go there. Possibly 10.4. But I would expect this to be a v11 change.

* @lucene.internal
*/
public abstract class BitSet implements Bits, Accountable {
public abstract sealed class BitSet implements Bits, Accountable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a small comment explaining that we're doing this to help call sites of methods on the BitSet class be bimorphic at most, to help with performance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added small comment explaining this.

(Ben Trent)

* GITHUB#15038: BitSet is now a sealed abstract class permitting only FixedBitSet and SparseFixedBitSet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to 11.0?

final int numBits = 1 + random().nextInt(100000);
for (float percentSet : new float[] {0, 0.01f, 0.1f, 0.5f, 0.9f, 0.99f, 1f}) {
BitSet set1 = new JavaUtilBitSet(randomSet(numBits, percentSet), numBits);
BitSet set1 = fromJavaUtilBitSet(randomSet(numBits, percentSet), numBits);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. doing just java.util.BitSet set1 = randomSet(numBits, percentSet); should be good enough here since we're only comparing cardinalities?

return randomSet(numBits, (int) (percentSet * numBits));
}

protected abstract T fromJavaUtilBitSet(java.util.BitSet set, int numBits);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry that copying from a java.util.BitSet defeats the purpose of the test, since most tests would be comparing two same implementations of BitSet instead of JavaUtilBitSet vs. a BitSet implementation. Can we try to refactor tests to work directly against a java.util.BitSet without copying to a BitSet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried refactoring it using java.util.Bitset.
Had to hack through two issues.

  1. java.util.BitSet.nextSetBit() returns -1 when there are no more set bits while lucene Bitset return DocIdSetIterator.NO_MORE_DOCS i.e. 2147483647.
  2. java.util.BitSet.clear() throws error if from > to while lucene does nothing.

@github-actions github-actions bot modified the milestones: 10.3.0, 11.0.0 Sep 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Seal the BitSet class
3 participants