From 544d997664e1269d5d6d5b2e3130ab6bb31b95de Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Sun, 13 Oct 2013 08:21:32 +0000 Subject: [PATCH] LUCENE-5277: Modify FixedBitSet copy constructor to take numBits to allow grow/shrink the new bitset git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1531627 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 ++ .../org/apache/lucene/util/FixedBitSet.java | 21 ++++---- .../apache/lucene/util/TestFixedBitSet.java | 49 +++++++++++++++++-- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 73485eee5f7..d65c5c1fe17 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -146,6 +146,10 @@ API Changes: * LUCENE-5275: Change AttributeSource.toString() to display the current state of attributes. (Robert Muir) +* LUCENE-5277: Modify FixedBitSet copy constructor to take an additional + numBits parameter to allow growing/shrinking the copied bitset. You can + use FixedBitSet.clone() if you only need to clone the bitset. (Shai Erera) + Optimizations * LUCENE-5225: The ToParentBlockJoinQuery only keeps tracks of the the child diff --git a/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java b/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java index 42ad09625cc..99a3ee3844d 100644 --- a/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java +++ b/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java @@ -35,7 +35,6 @@ import org.apache.lucene.search.DocIdSetIterator; * * @lucene.internal **/ - public final class FixedBitSet extends DocIdSet implements Bits { private final long[] bits; private final int numBits; @@ -63,14 +62,18 @@ public final class FixedBitSet extends DocIdSet implements Bits { } this.numBits = numBits; 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 +406,7 @@ public final class FixedBitSet extends DocIdSet implements Bits { @Override public FixedBitSet clone() { - return new FixedBitSet(this); + return new FixedBitSet(this, numBits); } /** returns true if both sets have the same bits set */ diff --git a/lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java b/lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java index 0c726034d87..cda63e92860 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestFixedBitSet.java @@ -328,7 +328,50 @@ public class TestFixedBitSet extends BaseDocIdSetTestCase { 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); + } + } - - -