Index: lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java (revision 1531190) +++ lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java (working copy) @@ -65,12 +65,16 @@ this.bits = storedBits; } - /** Makes full copy. */ - public FixedBitSet(FixedBitSet other) { - bits = new long[other.wordLength]; - System.arraycopy(other.bits, 0, bits, 0, other.wordLength); - numBits = other.numBits; - wordLength = other.wordLength; + /** + * Makes a full copy of the bits, while allowing to expand/shrink the bitset. + * If {@code numBits < other.numBits}, then only the first {@code numBits} + * are copied from other. + */ + public FixedBitSet(FixedBitSet other, int numBits) { + wordLength = bits2words(numBits); + bits = new long[wordLength]; + System.arraycopy(other.bits, 0, bits, 0, Math.min(other.wordLength, wordLength)); + this.numBits = numBits; } @Override @@ -403,7 +407,7 @@ @Override public FixedBitSet clone() { - return new FixedBitSet(this); + return new FixedBitSet(this, numBits); } /** returns true if both sets have the same bits set */ Index: lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java =================================================================== --- lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java (revision 1531190) +++ lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java (working copy) @@ -328,7 +328,50 @@ checkNextSetBitArray(new int[0], setBits.length + random().nextInt(10)); } -} + + public void testGrow() { + FixedBitSet bits = new FixedBitSet(5); + bits.set(1); + bits.set(4); + + FixedBitSet newBits = new FixedBitSet(bits, 8); // grow within the word + assertTrue(newBits.get(1)); + assertTrue(newBits.get(4)); + newBits = new FixedBitSet(bits, 72); // grow beyond one word + assertTrue(newBits.get(1)); + assertTrue(newBits.get(4)); + } + + public void testShrink() { + FixedBitSet bits = new FixedBitSet(72); + bits.set(1); + bits.set(4); + bits.set(69); + + FixedBitSet newBits = new FixedBitSet(bits, 66); // shrink within the word + assertTrue(newBits.get(1)); + assertTrue(newBits.get(4)); + boolean hitError = true; + try { + newBits.get(69); + hitError = false; + } catch (AssertionError e) { + hitError = true; + } + assertTrue(hitError); - + newBits = new FixedBitSet(bits, 8); // shrink beyond one word + assertTrue(newBits.get(1)); + assertTrue(newBits.get(4)); + hitError = true; + try { + newBits.get(69); + hitError = false; + } catch (AssertionError e) { + hitError = true; + } + assertTrue(hitError); + } + +}