blob: 071288e5482877e1deea18906911b727e38066b5 [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.emultest.java.util;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashSet;
/**
* Tests BitSet class.
*/
public class BitSetTest extends EmulTestBase {
/**
* This class is used to describe numerical patterns.
*/
private interface Pattern {
boolean contains(int i);
}
// count used for looping tests
private static final int TEST_SIZE = 509;
// this number has to be bigger than 100
private static final int BIG_NUMBER = (TEST_SIZE) * 10 + 101;
private static void assertTrue(BitSet set, int index) {
assertTrue("expected=true set[" + index + "]=false", set.get(index));
}
private static void assertFalse(BitSet set, int index) {
assertFalse("expected=false set[" + index + "]=true", set.get(index));
}
private static BitSet createSetOfMultiples(int multiple) {
BitSet set = new BitSet(TEST_SIZE);
for (int i = 0; i < TEST_SIZE; i += multiple) {
set.set(i);
}
return set;
}
// this checks to see the values given are true, and the others around are not
private static void checkValues(BitSet set, int... values) {
assertEquals(values.length, set.cardinality());
int highestIndex = values[values.length - 1];
boolean[] bits = new boolean[highestIndex + 1];
for (int value : values) {
bits[value] = true;
}
for (int index = 0; index < bits.length; index++) {
assertEquals(bits[index], set.get(index));
}
}
private static void checkEqualityTrue(BitSet setA, BitSet setB) {
assertTrue(setA.equals(setB));
assertTrue(setB.equals(setA));
assertTrue(setA.equals(setA));
assertTrue(setB.equals(setB));
}
private static void checkEqualityFalse(BitSet setA, BitSet setB) {
assertFalse(setA.equals(setB));
assertFalse(setB.equals(setA));
}
// Checks that the values in the given range are the only true values
private static void checkRange(BitSet set, int fromIndex, int toIndex) {
for (int i = fromIndex; i < toIndex; i++) {
assertTrue(set, i);
}
assertEquals(toIndex - fromIndex, set.cardinality());
}
// Checks that the values in the given range are the only true values
private static void checkRange(BitSet set, int fromIndex1, int toIndex1,
int fromIndex2, int toIndex2) {
for (int i = fromIndex1; i < toIndex1; i++) {
assertTrue(set, i);
}
for (int i = fromIndex2; i < toIndex2; i++) {
assertTrue(set, i);
}
assertEquals(toIndex1 - fromIndex1 + toIndex2 - fromIndex2,
set.cardinality());
}
private static void checkPattern(BitSet set, Pattern pattern) {
for (int i = 0; i < TEST_SIZE; i++) {
boolean contained = pattern.contains(i);
if (contained != set.get(i)) {
fail("expected=" + contained + " set[" + i + "]=" + !contained);
}
}
}
public void testConstructor() {
BitSet set = new BitSet();
// test what we know to be true of a new BitSet
assertTrue(set.isEmpty());
assertEquals(0, set.length());
assertEquals(0, set.cardinality());
// test exceptions
try {
set = new BitSet(-1);
fail("exception expected");
} catch (NegativeArraySizeException expected) {
}
set = new BitSet(0);
set = new BitSet(BIG_NUMBER);
}
public void testAnd() {
Pattern multiplesOf6 = new Pattern() {
@Override
public boolean contains(int i) {
return i % 6 == 0;
}
};
// setA will contain all multiples of 2
BitSet setA = createSetOfMultiples(2);
// setB will contain all multiples of 3
BitSet setB = createSetOfMultiples(3);
// and()ing the sets should give multiples of 6
setA.and(setB);
// verify by checking multiples of 6
checkPattern(setA, multiplesOf6);
// and()ing a set to itself should do nothing
setA.and(setA);
// verify by checking multiples of 6
checkPattern(setA, multiplesOf6);
// and()ing with a set identical to itself should do nothing
setA.and((BitSet) setA.clone());
// verify by checking multiples of 6
checkPattern(setA, multiplesOf6);
// and()ing with all trues should do nothing
BitSet trueSet = new BitSet(TEST_SIZE);
trueSet.set(0, TEST_SIZE);
setA.and(trueSet);
// verify by checking multiples of 6
checkPattern(setA, multiplesOf6);
// and()ing with all trues in a larger set should do nothing
trueSet.set(TEST_SIZE, TEST_SIZE * 2);
setA.and(trueSet);
// verify by checking multiples of 6
checkPattern(setA, multiplesOf6);
// there were "TEST_SIZE" extra trues, so lets verify those came out false
for (int i = TEST_SIZE; i < TEST_SIZE * 2; i++) {
assertFalse(setA.get(i));
}
// and()ing with an empty set should result in an empty set
setA.and(new BitSet());
assertEquals(0, setA.length());
// these close bits should not intersect
setB = new BitSet();
setA.set(0);
setB.set(1);
setA.and(setB);
assertTrue(setA.isEmpty());
// these bits should not intersect
setB = new BitSet();
setA.set(0);
setB.set(BIG_NUMBER);
setA.and(setB);
assertTrue(setA.isEmpty());
setA.set(0);
setB.and(setA);
assertTrue(setB.isEmpty());
setA = new BitSet();
setA.set(1);
setA.set(5);
setB = new BitSet();
setB.set(2);
setA.and(setB);
assertTrue(setA.isEmpty());
setA = new BitSet();
setA.set(1);
setA.set(5);
setB = new BitSet();
setB.set(5);
setA.and(setB);
assertTrue(setA.get(5));
assertEquals(1, setA.cardinality());
setA = new BitSet();
setA.set(2);
setB = new BitSet();
setB.set(1);
setB.set(3);
setA.and(setB);
assertEquals(0, setA.cardinality());
}
public void testAndNot() {
Pattern multiplesOf2Not3 = new Pattern() {
@Override
public boolean contains(int i) {
return i % 2 == 0 && i % 3 != 0;
}
};
// setA will contain all multiples of 2
BitSet setA = createSetOfMultiples(2);
// setB will contain all multiples of 3
BitSet setB = createSetOfMultiples(3);
// andNot() the sets
setA.andNot(setB);
// verify by checking for multiples of 2 that are not multiples of 3
checkPattern(setA, multiplesOf2Not3);
// andNot()ing with an empty set should do nothing
setA.andNot(new BitSet());
// verify by checking for multiples of 2 that are not multiples of 3
checkPattern(setA, multiplesOf2Not3);
// andNot()ing with all trues should result in an empty set
BitSet trueSet = new BitSet(TEST_SIZE * 2);
trueSet.set(0, TEST_SIZE * 2);
setA.andNot(trueSet);
assertTrue(setA.isEmpty());
// save setB in setA
setA = (BitSet) setB.clone();
// andNot()ing a set to itself should result in an empty set
setB.andNot(setB);
assertTrue(setB.isEmpty());
// andNot()ing a set identical to itself should result in an empty set
setA.andNot((BitSet) setA.clone());
assertTrue(setA.isEmpty());
setA = new BitSet();
setA.set(2);
setB = new BitSet();
setB.set(1);
setB.set(3);
setA.andNot(setB);
assertTrue(setA.get(2));
assertEquals(1, setA.cardinality());
}
public void testCardinality() {
BitSet set = new BitSet(TEST_SIZE);
// test the empty count
assertEquals(0, set.cardinality());
// test a count of 1
set.set(0);
assertEquals(1, set.cardinality());
// test a count of 2
set.set(BIG_NUMBER);
assertEquals(2, set.cardinality());
// clear them both and test again
set.clear(0);
set.clear(BIG_NUMBER);
assertEquals(0, set.cardinality());
// test different multiples
for (int multiple = 1; multiple < 33; multiple++) {
set = new BitSet();
set.set(BIG_NUMBER + multiple);
for (int i = 1; i < 33; i++) {
set.set(i * multiple);
assertEquals(i + 1, set.cardinality());
}
}
// test powers of 2
set = new BitSet();
int count = 0;
for (int i = 1; i < TEST_SIZE; i += i) {
set.set(i);
count++;
}
assertEquals(count, set.cardinality());
// test a long run
set = new BitSet();
for (int i = 0; i < TEST_SIZE; i++) {
set.set(i);
assertEquals(i + 1, set.cardinality());
}
}
public void testClear() {
BitSet set = new BitSet(TEST_SIZE);
for (int i = 0; i < TEST_SIZE; i++) {
set.set(i);
}
set.clear();
assertTrue(set.isEmpty());
set = new BitSet();
set.set(BIG_NUMBER);
set.clear();
assertFalse(set.get(BIG_NUMBER));
}
public void testClearInt() {
BitSet set = new BitSet();
set.set(0);
set.clear(0);
assertFalse(set.get(0));
set.set(BIG_NUMBER);
checkValues(set, BIG_NUMBER);
set.clear(BIG_NUMBER);
assertFalse(set.get(BIG_NUMBER));
set = new BitSet();
set.set(1);
set.set(2);
set.set(3);
set.set(18);
set.set(40);
set.clear(2);
checkValues(set, 1, 3, 18, 40);
set.clear(9);
checkValues(set, 1, 3, 18, 40);
set.clear(18);
checkValues(set, 1, 3, 40);
set.clear(7);
set.clear(6);
checkValues(set, 1, 3, 40);
set.clear(3);
checkValues(set, 1, 40);
set.clear(40);
checkValues(set, 1);
set.clear(1);
assertTrue(set.isEmpty());
// test exceptions
try {
set.clear(-1, 2);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.clear(3, 1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.clear(2, 2);
}
public void testClearIntIntAndSetIntInt() {
BitSet set = new BitSet();
set.set(7);
set.set(50);
set.set(BIG_NUMBER);
set.clear(0, BIG_NUMBER);
checkValues(set, BIG_NUMBER);
set.clear(0, BIG_NUMBER + 1);
assertTrue(set.isEmpty());
set.set(0, 65);
checkRange(set, 0, 65);
set.clear(0, 63);
checkRange(set, 63, 65);
set.clear(63, 65);
assertTrue(set.isEmpty());
set.set(0, 128);
set.clear(0, 64);
checkRange(set, 64, 128);
set.clear(0, 129);
assertTrue(set.isEmpty());
set.set(0, 65);
checkRange(set, 0, 65);
set.clear(0, 16);
checkRange(set, 16, 65);
set.set(0, 16);
checkRange(set, 0, 65);
set.clear(5, 5);
set.clear(7, 14);
set.clear(15, 42);
set.clear(43, 55);
set.clear(58, 62);
set.clear(BIG_NUMBER, BIG_NUMBER);
set.clear(BIG_NUMBER, BIG_NUMBER + 1);
checkValues(set, 0, 1, 2, 3, 4, 5, 6, 14, 42, 55, 56, 57, 62, 63, 64);
set.clear(0, 65);
assertTrue(set.isEmpty());
set.set(0, 33);
checkRange(set, 0, 33);
set.clear(0, 8);
checkRange(set, 8, 33);
for (int i = 0; i < 33; i++) {
// this shouldn't change anything
set.clear(i, i);
assertEquals(25, set.cardinality());
// nor should this
set.set(i, i);
assertEquals(25, set.cardinality());
}
for (int i = 0; i < 65; i++) {
set.set(0, 128);
set.clear(i, 128 - i);
checkRange(set, 0, i, 128 - i, 128);
}
set.clear(0, 128);
assertTrue(set.isEmpty());
set.set(7, 100);
checkRange(set, 7, 100);
set = new BitSet();
set.set(BIG_NUMBER, BIG_NUMBER);
assertEquals(0, set.cardinality());
set.set(BIG_NUMBER, BIG_NUMBER + 1);
checkRange(set, BIG_NUMBER, BIG_NUMBER + 1);
set.clear(BIG_NUMBER, BIG_NUMBER);
checkValues(set, BIG_NUMBER);
set.clear(BIG_NUMBER, BIG_NUMBER + 1);
assertEquals(0, set.cardinality());
set = new BitSet();
set.set(10, 12);
set.clear(11, 1000);
checkValues(set, 10);
set = new BitSet();
set.set(10, 12);
set.clear(0, 10);
set.set(BIG_NUMBER, BIG_NUMBER);
checkValues(set, 10, 11);
set.clear(10, 12);
assertTrue(set.isEmpty());
set = new BitSet();
set.set(1, 20);
set.clear(5, 10);
checkRange(set, 1, 5, 10, 20);
set = new BitSet();
set.set(1, 10);
set.clear(5, 15);
checkRange(set, 1, 5);
// test clear(int, int) exceptions
try {
set.clear(-1, 2);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.clear(3, 1);
fail("expected exception");
} catch (IndexOutOfBoundsException expected) {
}
set.clear(2, 2);
// test set(int, int) exceptions
try {
set.set(-1, 2);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.set(3, 1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.set(2, 2);
}
public void testClone() {
BitSet set = new BitSet();
set.set(2);
set.set(4);
set.set(32);
set.set(BIG_NUMBER);
BitSet clone = (BitSet) set.clone();
checkValues(clone, 2, 4, 32, BIG_NUMBER);
assertTrue(set.equals(clone));
assertEquals(4, clone.cardinality());
}
public void testEquals() {
BitSet setA = new BitSet();
BitSet setB = new BitSet();
checkEqualityTrue(setA, setB);
setA.set(0);
setB.set(0);
checkEqualityTrue(setA, setB);
setA.set(BIG_NUMBER);
setB.set(BIG_NUMBER);
checkEqualityTrue(setA, setB);
setA.clear(0);
setB.clear(0);
checkEqualityTrue(setA, setB);
setA.clear(BIG_NUMBER);
setB.clear(BIG_NUMBER);
checkEqualityTrue(setA, setB);
setA.set(0);
setB.set(1);
checkEqualityFalse(setA, setB);
setA.set(2);
setB.set(2);
checkEqualityFalse(setA, setB);
setA = new BitSet();
setB = new BitSet();
setA.set(Math.max(0, BIG_NUMBER - 8));
setB.set(BIG_NUMBER + 1);
checkEqualityFalse(setA, setB);
BitSet set1 = new BitSet();
set1.set(40);
BitSet set2 = new BitSet();
set2.set(1);
set2.set(40);
assertFalse(set1.equals(set2));
setA = new BitSet();
setA.set(2);
setB = new BitSet();
setB.set(1);
setB.set(3);
checkEqualityFalse(setA, setB);
}
public void testFlipInt() {
BitSet set = new BitSet();
set.flip(0);
assertTrue(set.get(0));
set.flip(0);
assertFalse(set.get(0));
set.flip(BIG_NUMBER);
assertTrue(set.get(BIG_NUMBER));
set.flip(BIG_NUMBER);
assertFalse(set.get(BIG_NUMBER));
set = new BitSet();
set.flip(1);
set.flip(2);
set.flip(3);
set.flip(4);
set.flip(6);
set.flip(4);
set.flip(6);
set.flip(6);
set.flip(6);
set.flip(8);
set.flip(10);
set.flip(8);
set.flip(2);
set.flip(8);
checkValues(set, 1, 3, 8, 10);
set.flip(8);
checkValues(set, 1, 3, 10);
set.flip(3);
checkValues(set, 1, 10);
set.flip(10);
set.flip(11);
checkValues(set, 1, 11);
set.flip(1);
checkValues(set, 11);
set.flip(11);
assertTrue(set.isEmpty());
// test exceptions
try {
set.flip(-1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.flip(BIG_NUMBER);
set.flip(BIG_NUMBER);
}
public void testFlipIntInt() {
BitSet set = new BitSet();
set.flip(0, BIG_NUMBER);
checkRange(set, 0, BIG_NUMBER);
set.flip(0, BIG_NUMBER - 1);
checkValues(set, BIG_NUMBER - 1);
set.clear(0, BIG_NUMBER);
assertTrue(set.isEmpty());
set.flip(0, 33);
set.flip(0, 8);
checkRange(set, 8, 33);
// current state is set.set(8,33)
for (int i = 0; i < 33; i++) {
// this shouldn't change anything
set.flip(i, i);
assertEquals(25, set.cardinality());
}
// current state is set.set(8,33)
set.flip(0, 8);
set.flip(7, 21);
set.flip(22, 27);
checkValues(set, 0, 1, 2, 3, 4, 5, 6, 21, 27, 28, 29, 30, 31, 32);
set = new BitSet();
set.flip(10, 12);
set.flip(11, 1000);
checkRange(set, 10, 11, 12, 1000);
set = new BitSet();
set.flip(10, 12);
set.flip(0, 10);
checkRange(set, 0, 12);
set.flip(0, 12);
assertTrue(set.isEmpty());
set.flip(0, 64);
set.flip(0, 63);
checkValues(set, 63);
set.flip(63, 64);
assertTrue(set.isEmpty());
set.flip(0, 130);
checkRange(set, 0, 130);
set.flip(0, 66);
checkRange(set, 66, 130);
set.flip(65, 131);
checkRange(set, 65, 66, 130, 131);
set = new BitSet();
set.flip(1, 20);
set.flip(5, 10);
checkRange(set, 1, 5, 10, 20);
set = new BitSet();
set.flip(1, 10);
set.flip(5, 15);
checkRange(set, 1, 5, 10, 15);
// test exceptions
try {
set.flip(-1, 2);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.flip(3, 1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.flip(2, 2);
}
public void testGetIntAndSetInt() {
BitSet set = new BitSet();
set.set(0);
assertTrue(set.get(0));
assertFalse(set.get(1));
assertFalse(set.get(2));
assertFalse(set.get(100));
set.set(BIG_NUMBER);
assertFalse(set.get(BIG_NUMBER - 1));
assertTrue(set.get(BIG_NUMBER));
assertFalse(set.get(BIG_NUMBER + 1));
set = new BitSet();
set.set(0);
set.set(4);
set.set(7);
set.set(10);
set.set(31);
set.set(32);
set.set(33);
set.set(69);
checkValues(set, 0, 4, 7, 10, 31, 32, 33, 69);
// test get() exceptions
try {
set.get(-1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.get(BIG_NUMBER);
// test set() exceptions
try {
set.set(-1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.set(BIG_NUMBER);
}
public void testGetIntInt() {
BitSet set = new BitSet();
set.set(1);
assertFalse(set.get(1, 1).get(0));
assertTrue(set.get(1, 2).get(0));
assertTrue(set.get(0, 2).get(1));
set.set(32);
set.set(50);
set.set(BIG_NUMBER);
BitSet subSet = set.get(0, BIG_NUMBER);
checkValues(subSet, 1, 32, 50);
subSet = set.get(1, BIG_NUMBER);
checkValues(subSet, 0, 31, 49);
subSet = set.get(2, BIG_NUMBER + 1);
checkValues(subSet, 30, 48, BIG_NUMBER - 2);
subSet = set.get(32, BIG_NUMBER * 2);
checkValues(subSet, 0, 18, BIG_NUMBER - 32);
assertEquals(3, subSet.cardinality());
subSet = set.get(0, BIG_NUMBER + 1);
assertEquals(set, subSet);
set = new BitSet();
for (int i = 8; i < 33; i++) {
set.set(i);
}
for (int i = 0; i < 33; i++) {
assertTrue(set.get(i, i).isEmpty());
}
// test exceptions
try {
set.get(-1, 2);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.get(3, 1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.get(2, 2);
}
public void testHashCode() {
// Note: Oracle's hashCode() implementation creates many collisions when
// testSize is big, causing this test to fail in development mode.
// Since this is an "unimportant test" as suggested by the original author,
// we can just test with a small number.
int testSize = 25;
HashSet<Integer> hashValues = new HashSet<>();
// count the collisions
int collisions = 0;
// hash an empty set
hashValues.add(new BitSet().hashCode());
// hash the set of {TEST_SIZE + 1}
BitSet set = new BitSet();
set.set(testSize + 1);
assertTrue(hashValues.add(set.hashCode()));
// hash the set of {0, TEST_SIZE + 1}
set.set(0);
assertTrue(hashValues.add(set.hashCode()));
// hash the set of {0}
set = new BitSet();
set.set(0);
assertTrue(hashValues.add(set.hashCode()));
for (int multiple = 1; multiple < 33; multiple++) {
set = new BitSet();
set.set(0);
// fill a set with multiples
for (int i = multiple; i < testSize; i += multiple) {
set.set(i);
// hash the current set, except in the case of {0}
if (i != 0) {
if (hashValues.add(set.hashCode()) == false) {
collisions++;
}
set.set(testSize + 1);
if (hashValues.add(set.hashCode()) == false) {
collisions++;
}
set.clear(testSize + 1);
}
}
}
assertEquals(0, collisions);
}
public void testIntersects() {
final int prime = 37;
for (int multiple = 1; multiple < prime; multiple++) {
int size = prime * multiple + 1;
// setA will contain all multiples of "multiple" up to "size"
BitSet setA = new BitSet(size);
for (int i = multiple; i < size; i += multiple) {
setA.set(i);
}
// setB will contain all multiples of "prime" up to "size"
BitSet setB = new BitSet();
for (int i = prime; i < size; i += prime) {
setB.set(i);
}
// the two sets should only intersect on the very last bit
assertTrue(setA.intersects(setB));
setA.clear(size - 1);
assertFalse(setA.intersects(setB));
// the inverse of a set should not intersect itself
setB = new BitSet();
for (int i = 0; i < prime; i++) {
setB.set(i, !setA.get(i));
}
assertFalse(setA.intersects(setB));
// a set intersects itself if it has any bits set
assertTrue(setA.intersects(setA));
setA = new BitSet();
assertFalse(setA.intersects(setA));
// an empty set doesn't intersect itself
assertFalse(new BitSet().intersects(new BitSet()));
}
BitSet setA = new BitSet();
setA.set(2);
BitSet setB = new BitSet();
setB.set(1);
setB.set(3);
assertFalse(setA.intersects(setB));
}
public void testIsEmpty() {
BitSet set = new BitSet();
assertTrue(set.isEmpty());
set.set(0);
assertFalse(set.isEmpty());
set = new BitSet();
set.set(BIG_NUMBER);
assertFalse(set.isEmpty());
}
public void testLength() {
BitSet set = new BitSet();
assertEquals(0, set.length());
set.set(30);
assertEquals(31, set.length());
set.clear(30);
set.set(31);
assertEquals(32, set.length());
set.clear(31);
set.set(100);
set.set(BIG_NUMBER);
assertEquals(BIG_NUMBER + 1, set.length());
set.clear(BIG_NUMBER);
assertEquals(101, set.length());
set.clear(100);
assertEquals(0, set.length());
set.set(0);
assertEquals(1, set.length());
set = new BitSet();
for (int i = 0; i < 640; i++) {
set.set(i);
assertEquals(i + 1, set.length());
}
for (int i = 0; i < 639; i++) {
set.clear(i);
assertEquals(640, set.length());
}
set.clear(639);
assertEquals(0, set.length());
}
public void testNextClearBit() {
BitSet set = new BitSet(10);
assertEquals(BIG_NUMBER, set.nextClearBit(BIG_NUMBER));
for (int i = 0; i < 10; i++) {
assertEquals(i, set.nextClearBit(i));
}
for (int i = 10; i < 100; i++) {
assertEquals(i, set.nextClearBit(i));
}
set.set(0, 9);
set.set(10, 50);
for (int i = 0; i <= 9; i++) {
assertEquals(9, set.nextClearBit(i));
}
for (int i = 10; i < 50; i++) {
assertEquals(50, set.nextClearBit(i));
}
for (int i = 50; i < 100; i++) {
assertEquals(i, set.nextClearBit(i));
}
set = new BitSet();
set.set(61);
for (int i = 0; i < 60; i++) {
set.set(i);
assertEquals(i + 1, set.nextClearBit(0));
}
set.clear(61);
for (int i = 60; i < 100; i++) {
set.set(i);
assertEquals(i + 1, set.nextClearBit(0));
}
assertEquals(BIG_NUMBER, set.nextClearBit(BIG_NUMBER));
try {
set.nextClearBit(-1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testNextSetBit() {
BitSet set = new BitSet();
assertEquals(-1, set.nextSetBit(0));
assertEquals(-1, set.nextSetBit(BIG_NUMBER));
set.set(0);
set.set(1);
set.set(3);
set.set(31);
set.set(32);
set.set(33);
assertEquals(0, set.nextSetBit(0));
assertEquals(1, set.nextSetBit(1));
assertEquals(3, set.nextSetBit(2));
assertEquals(3, set.nextSetBit(3));
assertEquals(31, set.nextSetBit(4));
assertEquals(31, set.nextSetBit(31));
assertEquals(32, set.nextSetBit(32));
assertEquals(33, set.nextSetBit(33));
assertEquals(-1, set.nextSetBit(34));
set = new BitSet();
set.set(BIG_NUMBER);
assertEquals(BIG_NUMBER, set.nextSetBit(0));
assertEquals(BIG_NUMBER, set.nextSetBit(BIG_NUMBER));
assertEquals(-1, set.nextSetBit(BIG_NUMBER + 1));
for (int i = 0; i < TEST_SIZE; i++) {
set.set(BIG_NUMBER + i);
}
set.set(TEST_SIZE / 2);
assertEquals(TEST_SIZE / 2, set.nextSetBit(0));
try {
set.nextSetBit(-1);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testPreviousClearBit() {
BitSet set = new BitSet();
assertEquals(-1, set.previousClearBit(-1));
assertEquals(0, set.previousClearBit(0));
assertEquals(100, set.previousClearBit(100));
set.set(0, 9);
set.set(10, 50);
for (int i = 100; i >= 50; i--) {
assertEquals(i, set.previousClearBit(i));
}
for (int i = 49; i >= 9; i--) {
assertEquals(9, set.previousClearBit(i));
}
for (int i = 8; i >= 0; i--) {
assertEquals(-1, set.previousClearBit(i));
}
try {
set.previousClearBit(-100);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testPreviousSetBit() {
BitSet set = new BitSet();
assertEquals(-1, set.previousSetBit(-1));
assertEquals(-1, set.previousSetBit(0));
assertEquals(-1, set.previousSetBit(100));
set.set(0, 9);
set.set(10, 50);
for (int i = 100; i >= 50; i--) {
assertEquals(49, set.previousSetBit(i));
}
for (int i = 49; i >= 10; i--) {
assertEquals(i, set.previousSetBit(i));
}
assertEquals(8, set.previousSetBit(9));
for (int i = 8; i >= 0; i--) {
assertEquals(i, set.previousSetBit(i));
}
try {
set.previousSetBit(-100);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testOr() {
Pattern multiplesOf2And5 = new Pattern() {
@Override
public boolean contains(int i) {
return i % 2 == 0 || i % 5 == 0;
}
};
// setA will contain all multiples of 2
BitSet setA = createSetOfMultiples(2);
// setB will contain all multiples of 5
BitSet setB = createSetOfMultiples(5);
// or() the two sets to get both multiples of 2 and 5
setA.or(setB);
// verify multiples of 2 and 5
checkPattern(setA, multiplesOf2And5);
// or()ing a set to itself should do nothing
setA.or(setA);
// verify multiples of 2 and 5
checkPattern(setA, multiplesOf2And5);
// or()ing with set identical to itself should do nothing
setA.or((BitSet) setA.clone());
// verify multiples of 2 and 5
checkPattern(setA, multiplesOf2And5);
// or()ing with an empty set (all falses) should do nothing
setA.or(new BitSet());
// verify multiples of 2 and 5
checkPattern(setA, multiplesOf2And5);
// or()ing with all trues should result in all trues
BitSet trueSet = new BitSet(TEST_SIZE * 2);
trueSet.set(0, TEST_SIZE * 2);
setA.or(trueSet);
assertEquals(TEST_SIZE * 2, setA.cardinality());
setA = new BitSet();
setA.set(2);
setB = new BitSet();
setB.set(1);
setB.set(3);
setA.or(setB);
checkRange(setA, 1, 4);
}
public void testSetIntBoolean() {
BitSet set = new BitSet();
set.set(0, true);
assertTrue(set.get(0));
set.set(0, false);
assertFalse(set.get(0));
set.set(BIG_NUMBER, true);
assertTrue(set.get(BIG_NUMBER));
set.set(BIG_NUMBER, false);
assertFalse(set.get(BIG_NUMBER));
set = new BitSet();
set.set(1, true);
set.set(2, true);
set.set(3, true);
set.set(4, true);
set.set(6, true);
set.set(4, false);
set.set(6, true);
set.set(6, false);
set.set(6, false);
set.set(8, true);
set.set(10, true);
set.set(8, false);
set.set(2, false);
set.set(8, true);
checkValues(set, 1, 3, 8, 10);
set.set(8, false);
checkValues(set, 1, 3, 10);
set.set(3, false);
checkValues(set, 1, 10);
set.set(10, false);
set.set(11, true);
checkValues(set, 1, 11);
set.set(1, false);
checkValues(set, 11);
set.set(11, false);
assertTrue(set.isEmpty());
}
public void testSetIntIntBoolean() {
BitSet set = new BitSet();
set.set(0, BIG_NUMBER, true);
assertEquals(BIG_NUMBER, set.cardinality());
set.set(0, BIG_NUMBER - 1, false);
assertEquals(1, set.cardinality());
set.set(0, BIG_NUMBER, false);
assertTrue(set.isEmpty());
set.set(0, 32, true);
checkRange(set, 0, 32);
set.set(0, 8, false);
checkRange(set, 8, 32);
set.set(0, 8, true);
checkRange(set, 0, 32);
set.set(7, 21, false);
checkValues(set, 0, 1, 2, 3, 4, 5, 6, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
set.set(22, 27, false);
checkValues(set, 0, 1, 2, 3, 4, 5, 6, 21, 27, 28, 29, 30, 31);
set = new BitSet();
set.set(11, 1000, true);
set.set(10, 12, false);
checkRange(set, 12, 1000);
assertEquals(988, set.cardinality());
set = new BitSet();
set.set(10, 12, true);
set.set(0, 10, true);
checkRange(set, 0, 12);
set.set(0, 12, false);
assertTrue(set.isEmpty());
set = new BitSet();
set.set(1, 20, true);
set.set(5, 10, false);
checkRange(set, 1, 5, 10, 20);
set = new BitSet();
set.set(1, 10, true);
set.set(5, 10, false);
set.set(10, 15, true);
checkRange(set, 1, 5, 10, 15);
// test exceptions
try {
set.set(-1, 2, true);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.set(3, 1, true);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.set(2, 2, true);
try {
set.set(-1, 2, false);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
try {
set.set(3, 1, false);
fail("exception expected");
} catch (IndexOutOfBoundsException expected) {
}
set.set(2, 2, false);
}
public void testSize() {
// this is an unimportant test
BitSet set = new BitSet(7);
assertTrue(set.size() >= 7);
set = new BitSet(BIG_NUMBER);
assertTrue(set.size() >= BIG_NUMBER);
}
public void testToString() {
BitSet set = new BitSet();
assertEquals("{}", set.toString());
set.set(32);
assertEquals("{32}", set.toString());
set.set(BIG_NUMBER);
assertEquals("{32, " + BIG_NUMBER + "}", set.toString());
set.set(1);
assertEquals("{1, 32, " + BIG_NUMBER + "}", set.toString());
set.set(2);
assertEquals("{1, 2, 32, " + BIG_NUMBER + "}", set.toString());
}
public void testXor() {
Pattern exclusiveMultiples = new Pattern() {
@Override
public boolean contains(int i) {
return (i % 2 == 0) ^ (i % 3 == 0);
}
};
// setA will contain all multiples of 2
BitSet setA = createSetOfMultiples(2);
// setB will contain all multiples of 3
BitSet setB = createSetOfMultiples(3);
// xor()ing the sets should give exclusive multiples of 2 and 3
setA.xor(setB);
// verify by checking for exclusive multiples of 2 and 3
checkPattern(setA, exclusiveMultiples);
// xor()ing a set to an empty set should do nothing
setA.xor(new BitSet());
// verify by checking for exclusive multiples of 2 and 3
checkPattern(setA, exclusiveMultiples);
// xor()ing a set with all trues should flip each bit
BitSet trueSet = new BitSet(TEST_SIZE * 2);
trueSet.set(0, TEST_SIZE * 2);
setA.xor(trueSet);
// verify by checking for !(exclusive multiples of 2 and 3)
checkPattern(setA, new Pattern() {
@Override
public boolean contains(int i) {
return !((i % 2 == 0) ^ (i % 3 == 0));
}
});
// there were "TEST_SIZE" extra trues, so verify those came out as true
for (int i = TEST_SIZE; i < TEST_SIZE * 2; i++) {
assertTrue(setA.get(i));
}
// xor()ing a set to itself should result in an empty set
setA.xor(setA);
assertTrue(setA.isEmpty());
// xor()ing a set identical to itself should result in an empty set
setB.xor((BitSet) setB.clone());
assertTrue(setB.isEmpty());
setA = new BitSet();
setA.set(2);
setB = new BitSet();
setB.set(1);
setB.set(3);
setA.xor(setB);
checkRange(setA, 1, 4);
}
public void testToByteArray() {
BitSet set = new BitSet();
assertEquals(0, set.toByteArray().length);
int[] bits = {7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 32, 33, 34, 35, 36, 37, 38,
47, 49, 51, 52, 53, 54, 55};
for (int bit : bits) {
set.set(bit);
}
byte[] expected = {(byte) -128, (byte) -1, (byte) 0, (byte) 31,
(byte) 127, (byte) 128, (byte) 250};
assertTrue(Arrays.equals(expected, set.toByteArray()));
set.clear();
assertEquals(0, set.toByteArray().length);
}
public void testToLongArray() {
BitSet set = new BitSet();
assertEquals(0, set.toLongArray().length);
int[] bits = {63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 287, 288, 289,
290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325,
326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343,
344, 345, 346, 347, 348, 349, 350, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412,
413, 414, 450, 453, 454, 514, 515, 516, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528,
529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546,
547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 584, 640, 641, 642, 643, 644, 645,
646, 711};
for (int bit : bits) {
set.set(bit);
}
long[] expected = {Long.MIN_VALUE, Long.MAX_VALUE, -1, 0, Integer.MIN_VALUE,
Integer.MAX_VALUE, 0x7fffffff, 100, -100, 256, 127, 128};
assertTrue(Arrays.equals(expected, set.toLongArray()));
set.clear();
assertEquals(0, set.toLongArray().length);
}
public void testValueOfBytes() {
BitSet set = BitSet.valueOf(new byte[0]);
assertTrue(set.isEmpty());
set = BitSet.valueOf(new byte[]{(byte) -128, (byte) -1, (byte) 0, (byte) 31,
(byte) 127, (byte) 128, (byte) 250});
assertEquals("{7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 32, 33, 34, 35, 36, 37, 38, " +
"47, 49, 51, 52, 53, 54, 55}", set.toString());
}
public void testValueOfLongs() {
BitSet set = BitSet.valueOf(new long[0]);
assertTrue(set.isEmpty());
set = BitSet.valueOf(new long[]{Long.MIN_VALUE, Long.MAX_VALUE, -1, 0, Integer.MIN_VALUE,
Integer.MAX_VALUE, 0x7fffffff, 100, -100, 256, 127, 128});
assertEquals("{63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, " +
"83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, " +
"104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, " +
"122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, " +
"141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, " +
"159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, " +
"177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 287, 288, 289, " +
"290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, " +
"308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, " +
"326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, " +
"344, 345, 346, 347, 348, 349, 350, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, " +
"395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, " +
"413, 414, 450, 453, 454, 514, 515, 516, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, " +
"529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, " +
"547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, " +
"565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 584, 640, 641, 642, 643, 644, 645, " +
"646, 711}", set.toString());
}
}