Add ImmutableBitSet.rebuild()
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/239babd8 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/239babd8 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/239babd8 Branch: refs/heads/master Commit: 239babd8fc26bf35be96a77fbfbea379138f3a37 Parents: c104c75 Author: Julian Hyde <[email protected]> Authored: Wed Jan 6 22:10:45 2016 -0800 Committer: Julian Hyde <[email protected]> Committed: Sun Jan 10 00:51:25 2016 -0800 ---------------------------------------------------------------------- .../apache/calcite/util/ImmutableBitSet.java | 61 +++++++++++++++----- .../calcite/util/ImmutableBitSetTest.java | 7 ++- 2 files changed, 51 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/239babd8/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java index cb911f1..a8d6a61 100644 --- a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java +++ b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java @@ -650,16 +650,16 @@ public class ImmutableBitSet /** Returns the union of this immutable bit set with a {@link BitSet}. */ public ImmutableBitSet union(BitSet other) { - return builder(this) + return rebuild() // remember "this" and try to re-use later .addAll(BitSets.toIter(other)) .build(); } /** Returns the union of this bit set with another. */ public ImmutableBitSet union(ImmutableBitSet other) { - return builder(this) + return rebuild() // remember "this" and try to re-use later .addAll(other) - .build(); + .build(other); // try to re-use "other" } /** Returns the union of a number of bit sets. */ @@ -677,9 +677,9 @@ public class ImmutableBitSet * * @see BitSet#andNot(java.util.BitSet) */ public ImmutableBitSet except(ImmutableBitSet that) { - final Builder builder = builder(this); + final Builder builder = rebuild(); builder.removeAll(that); - return builder.build(this); + return builder.build(); } /** Returns a bit set with all the bits set in both this set and in @@ -687,9 +687,9 @@ public class ImmutableBitSet * * @see BitSet#and */ public ImmutableBitSet intersect(ImmutableBitSet that) { - final Builder builder = builder(this); + final Builder builder = rebuild(); builder.intersect(that); - return builder.build(this); + return builder.build(); } /** @@ -773,12 +773,20 @@ public class ImmutableBitSet return words.length == 0; } + /** Creates an empty Builder. */ public static Builder builder() { - return new Builder(); + return new Builder(EMPTY_LONGS); } + @Deprecated // to be removed before 2.0 public static Builder builder(ImmutableBitSet bitSet) { - return new Builder(bitSet); + return bitSet.rebuild(); + } + + /** Creates a Builder whose initial contents are the same as this + * ImmutableBitSet. */ + public Builder rebuild() { + return new Rebuilder(this); } /** Returns the {@code n}th set bit. @@ -916,12 +924,8 @@ public class ImmutableBitSet public static class Builder { private long[] words; - public Builder(ImmutableBitSet bitSet) { - words = bitSet.words.clone(); - } - - public Builder() { - words = EMPTY_LONGS; + private Builder(long[] words) { + this.words = words; } /** Builds an ImmutableBitSet from the contents of this Builder. @@ -1086,6 +1090,33 @@ public class ImmutableBitSet trim(x); } } + + /** Refinement of {@link Builder} that remembers its original + * {@link org.apache.calcite.util.ImmutableBitSet} and tries to use it + * when {@link #build} is called. */ + private static class Rebuilder extends Builder { + private final ImmutableBitSet originalBitSet; + + private Rebuilder(ImmutableBitSet originalBitSet) { + super(originalBitSet.words.clone()); + this.originalBitSet = originalBitSet; + } + + @Override public ImmutableBitSet build() { + if (wouldEqual(originalBitSet)) { + return originalBitSet; + } + return super.build(); + } + + @Override public ImmutableBitSet build(ImmutableBitSet bitSet) { + // We try to re-use both originalBitSet and bitSet. + if (wouldEqual(originalBitSet)) { + return originalBitSet; + } + return super.build(bitSet); + } + } } // End ImmutableBitSet.java http://git-wip-us.apache.org/repos/asf/calcite/blob/239babd8/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java b/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java index a496fd9..bd25a32 100644 --- a/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java +++ b/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java @@ -293,11 +293,14 @@ public class ImmutableBitSetTest { * {@link org.apache.calcite.util.ImmutableBitSet.Builder#build(ImmutableBitSet)}. */ @Test public void testBuilderUseOriginal() { final ImmutableBitSet fives = ImmutableBitSet.of(5, 10, 15); + final ImmutableBitSet fives1 = + fives.rebuild().clear(2).set(10).build(); + assertTrue(fives1 == fives); final ImmutableBitSet fives2 = - ImmutableBitSet.builder(fives).clear(2).set(10).build(fives); + ImmutableBitSet.builder().addAll(fives).clear(2).set(10).build(fives); assertTrue(fives2 == fives); final ImmutableBitSet fives3 = - ImmutableBitSet.builder(fives).clear(2).set(10).build(); + ImmutableBitSet.builder().addAll(fives).clear(2).set(10).build(); assertTrue(fives3 != fives); assertTrue(fives3.equals(fives)); assertTrue(fives3.equals(fives2));
