/*
* Copyright 2016 higherfrequencytrading.com
*
* 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 net.openhft.lang.collection;
import net.openhft.lang.io.ByteBufferBytes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import static net.openhft.lang.collection.DirectBitSet.Bits;
import static org.junit.Assert.*;
@RunWith(value = Parameterized.class)
public class DirectBitSetTest {
private static final int[] INDICES = new int[]{0, 50, 100, 127, 128, 255};
private DirectBitSet bs;
private boolean singleThreaded;
private SingleThreadedDirectBitSet st;
public DirectBitSetTest(DirectBitSet bs) {
this.bs = bs;
singleThreaded = bs instanceof SingleThreadedDirectBitSet;
if (singleThreaded)
st = (SingleThreadedDirectBitSet) bs;
assertTrue(bs.size() >= 256);
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
int capacityInBytes = 256 / 8;
return Arrays.asList(new Object[][]{
{
ATSDirectBitSet.wrap(ByteBufferBytes.wrap(
ByteBuffer.allocate(capacityInBytes)))
},
{
new SingleThreadedDirectBitSet(ByteBufferBytes.wrap(
ByteBuffer.allocate(capacityInBytes)))
},
{
ATSDirectBitSet.wrap(ByteBufferBytes.wrap(
ByteBuffer.allocateDirect(capacityInBytes)))
},
{
new SingleThreadedDirectBitSet(ByteBufferBytes.wrap(
ByteBuffer.allocateDirect(capacityInBytes)))
}
});
}
private void setIndices() {
bs.clear();
for (int i : INDICES) {
bs.set(i);
}
}
private void setIndicesComplement() {
setIndices();
bs.flip(0, bs.size());
}
private void assertRangeIsClear(long from, long to) {
for (long i = from; i < to; i++) {
assertFalse(bs.get(i));
}
}
private void assertRangeIsClear(String message, long from, long to) {
for (long i = from; i < to; i++) {
assertFalse(message + ", bit: " + i, bs.get(i));
}
}
private void assertRangeIsSet(long from, long to) {
for (long i = from; i < to; i++) {
assertTrue(bs.get(i));
}
}
private void assertRangeIsSet(String message, long from, long to) {
for (long i = from; i < to; i++) {
assertTrue(message + ", bit: " + i, bs.get(i));
}
}
@Test
public void testGetSetClearAndCardinality() {
bs.clear();
assertEquals(0, bs.cardinality());
int c = 0;
for (int i : INDICES) {
c++;
assertFalse("At index " + i, bs.get(i));
assertFalse("At index " + i, bs.isSet(i));
assertTrue("At index " + i, bs.isClear(i));
bs.set(i);
assertTrue("At index " + i, bs.get(i));
assertTrue("At index " + i, bs.isSet(i));
assertFalse("At index " + i, bs.isClear(i));
assertEquals(c, bs.cardinality());
}
for (int i : INDICES) {
assertTrue("At index " + i, bs.get(i));
assertTrue("At index " + i, bs.isSet(i));
assertFalse("At index " + i, bs.isClear(i));
bs.clear(i);
assertFalse("At index " + i, bs.get(i));
assertFalse("At index " + i, bs.isSet(i));
assertTrue("At index " + i, bs.isClear(i));
}
for (int i : INDICES) {
assertEquals("At index " + i, true, bs.setIfClear(i));
assertEquals("At index " + i, false, bs.setIfClear(i));
}
for (int i : INDICES) {
assertEquals("At index " + i, true, bs.clearIfSet(i));
assertEquals("At index " + i, false, bs.clearIfSet(i));
}
}
@Test
public void testGetLong() {
setIndices();
long l0 = 1L | (1L << 50);
assertEquals(l0, bs.getLong(0));
long l1 = (1L << (100 - 64)) | (1L << (127 - 64));
assertEquals(l1, bs.getLong(1));
}
@Test
public void testFlip() {
bs.clear();
for (int i : INDICES) {
assertEquals("At index " + i, false, bs.get(i));
bs.flip(i);
assertEquals("At index " + i, true, bs.get(i));
bs.flip(i);
assertEquals("At index " + i, false, bs.get(i));
}
}
@Test
public void testNextSetBit() {
setIndices();
int order = 0;
for (long i = bs.nextSetBit(0L); i >= 0; i = bs.nextSetBit(i + 1)) {
assertEquals(INDICES[order], i);
order++;
}
assertEquals(-1, bs.nextSetBit(bs.size()));
bs.clear();
assertEquals(-1, bs.nextSetBit(0L));
}
@Test
public void testSetBitsIteration() {
setIndices();
int order = 0;
Bits bits = bs.setBits();
long i;
while ((i = bits.next()) >= 0) {
assertEquals(INDICES[order], i);
order++;
}
assertEquals(-1, bits.next());
bs.clear();
assertEquals(-1, bs.setBits().next());
}
@Test
public void testClearNextSetBit() {
setIndices();
long cardinality = bs.cardinality();
int order = 0;
for (long i = bs.clearNextSetBit(0L); i >= 0;
i = bs.clearNextSetBit(i + 1)) {
assertEquals(INDICES[order], i);
assertFalse(bs.get(i));
order++;
cardinality--;
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.clearNextSetBit(bs.size()));
assertEquals(0, bs.cardinality());
assertEquals(-1, bs.clearNextSetBit(0L));
}
@Test
public void testClearNext1SetBit() {
setIndices();
long cardinality = bs.cardinality();
int order = 0;
for (long i = bs.clearNextNContinuousSetBits(0L, 1); i >= 0;
i = bs.clearNextNContinuousSetBits(i + 1, 1)) {
assertEquals(INDICES[order], i);
assertFalse(bs.get(i));
order++;
cardinality--;
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.clearNextNContinuousSetBits(bs.size(), 1));
assertEquals(0, bs.cardinality());
assertEquals(-1, bs.clearNextNContinuousSetBits(0L, 1));
}
@Test
public void testNextSetLong() {
bs.clear();
bs.set(0);
bs.set(255);
long[] setLongs = {0, 3};
int order = 0;
for (long i = bs.nextSetLong(0L); i >= 0; i = bs.nextSetLong(i + 1)) {
assertEquals(setLongs[order], i);
order++;
}
assertEquals(-1, bs.nextSetLong(bs.size() / 64));
bs.clear();
assertEquals(-1, bs.nextSetLong(0L));
}
@Test
public void testNextClearBit() {
setIndicesComplement();
int order = 0;
for (long i = bs.nextClearBit(0L); i >= 0; i = bs.nextClearBit(i + 1)) {
assertEquals(INDICES[order], i);
order++;
}
assertEquals(-1, bs.nextClearBit(bs.size()));
bs.setAll();
assertEquals(-1, bs.nextClearBit(0L));
}
@Test
public void testSetNextClearBit() {
setIndicesComplement();
long cardinality = bs.cardinality();
int order = 0;
for (long i = bs.setNextClearBit(0L); i >= 0;
i = bs.setNextClearBit(i + 1)) {
assertEquals(INDICES[order], i);
assertTrue(bs.get(i));
order++;
cardinality++;
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.setNextClearBit(bs.size()));
assertEquals(bs.size(), bs.cardinality());
assertEquals(-1, bs.setNextClearBit(0L));
}
@Test
public void testSetNext1ClearBit() {
setIndicesComplement();
long cardinality = bs.cardinality();
int order = 0;
for (long i = bs.setNextNContinuousClearBits(0L, 1); i >= 0;
i = bs.setNextNContinuousClearBits(i + 1, 1)) {
assertEquals(INDICES[order], i);
assertTrue(bs.get(i));
order++;
cardinality++;
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.setNextNContinuousClearBits(bs.size(), 1));
assertEquals(bs.size(), bs.cardinality());
assertEquals(-1, bs.setNextNContinuousClearBits(0L, 1));
}
@Test
public void testNextClearLong() {
bs.setAll();
bs.clear(0);
bs.clear(255);
long[] clearLongs = {0, 3};
int order = 0;
for (long i = bs.nextClearLong(0L); i >= 0; i = bs.nextClearLong(i + 1)) {
assertEquals(clearLongs[order], i);
order++;
}
assertEquals(-1, bs.nextClearLong(bs.size() / 64));
bs.setAll();
assertEquals(-1, bs.nextClearLong(0L));
}
@Test
public void testPreviousSetBit() {
setIndices();
int order = INDICES.length;
for (long i = bs.size(); (i = bs.previousSetBit(i - 1)) >= 0; ) {
order--;
assertEquals(INDICES[order], i);
}
assertEquals(-1, bs.previousSetBit(-1));
bs.clear();
assertEquals(-1, bs.previousSetBit(bs.size()));
}
@Test
public void testClearPreviousSetBit() {
setIndices();
long cardinality = bs.cardinality();
int order = INDICES.length;
for (long i = bs.size(); (i = bs.clearPreviousSetBit(i - 1)) >= 0; ) {
order--;
cardinality--;
assertEquals(INDICES[order], i);
assertFalse(bs.get(i));
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.clearPreviousSetBit(-1));
assertEquals(0, bs.cardinality());
assertEquals(-1, bs.clearPreviousSetBit(bs.size()));
}
@Test
public void testClearPrevious1SetBit() {
setIndices();
long cardinality = bs.cardinality();
int order = INDICES.length;
for (long i = bs.size();
(i = bs.clearPreviousNContinuousSetBits(i - 1, 1)) >= 0; ) {
order--;
cardinality--;
assertEquals(INDICES[order], i);
assertFalse(bs.get(i));
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.clearPreviousNContinuousSetBits(-1, 1));
assertEquals(0, bs.cardinality());
assertEquals(-1, bs.clearPreviousNContinuousSetBits(bs.size(), 1));
}
@Test
public void testPreviousSetLong() {
bs.clear();
bs.set(0);
bs.set(255);
long[] setLongs = {0, 3};
int order = setLongs.length;
for (long i = bs.size() / 64; (i = bs.previousSetLong(i - 1)) >= 0; ) {
order--;
assertEquals(setLongs[order], i);
}
assertEquals(-1, bs.previousSetLong(-1));
bs.clear();
assertEquals(-1, bs.previousSetLong(bs.size() / 64));
}
@Test
public void testPreviousClearBit() {
setIndicesComplement();
int order = INDICES.length;
for (long i = bs.size(); (i = bs.previousClearBit(i - 1)) >= 0; ) {
order--;
assertEquals(INDICES[order], i);
}
assertEquals(-1, bs.previousClearBit(-1));
bs.setAll();
assertEquals(-1, bs.previousClearBit(bs.size()));
}
@Test
public void testSetPreviousClearBit() {
setIndicesComplement();
long cardinality = bs.cardinality();
int order = INDICES.length;
for (long i = bs.size(); (i = bs.setPreviousClearBit(i - 1)) >= 0; ) {
order--;
cardinality++;
assertEquals(INDICES[order], i);
assertTrue(bs.get(i));
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.setPreviousClearBit(-1));
assertEquals(bs.size(), bs.cardinality());
assertEquals(-1, bs.setPreviousClearBit(bs.size()));
}
@Test
public void testSetPrevious1ClearBit() {
setIndicesComplement();
long cardinality = bs.cardinality();
int order = INDICES.length;
for (long i = bs.size();
(i = bs.setPreviousNContinuousClearBits(i - 1, 1)) >= 0; ) {
order--;
cardinality++;
assertEquals(INDICES[order], i);
assertTrue(bs.get(i));
assertEquals(cardinality, bs.cardinality());
}
assertEquals(-1, bs.setPreviousNContinuousClearBits(-1, 1));
assertEquals(bs.size(), bs.cardinality());
assertEquals(-1, bs.setPreviousNContinuousClearBits(bs.size(), 1));
}
@Test
public void testPreviousClearLong() {
bs.setAll();
bs.clear(0);
bs.clear(255);
long[] clearLongs = {0, 3};
int order = clearLongs.length;
for (long i = bs.size() / 64; (i = bs.previousClearLong(i - 1)) >= 0; ) {
order--;
assertEquals(clearLongs[order], i);
}
assertEquals(-1, bs.previousClearLong(-1));
bs.setAll();
assertEquals(-1, bs.previousClearLong(bs.size() / 64));
}
@Test
public void testSetAll() {
bs.clear();
bs.setAll();
assertEquals(bs.size(), bs.cardinality());
}
@Test
public void testRangeOpsWithinLongCase() {
bs.clear();
if (singleThreaded) {
assertTrue(st.allClear(0, 0));
assertTrue(st.allClear(63, 63));
assertTrue(st.allSet(0, 0));
assertTrue(st.allSet(63, 63));
}
bs.flip(0, 0);
assertEquals(false, bs.get(0));
assertEquals(0, bs.cardinality());
bs.flip(0, 1);
assertEquals(true, bs.get(0));
assertEquals(1, bs.cardinality());
if (singleThreaded) {
assertTrue(st.allSet(0, 1));
assertFalse(st.allSet(0, 2));
assertFalse(st.allClear(0, 1));
}
bs.clear(0, 0);
assertEquals(true, bs.get(0));
assertEquals(1, bs.cardinality());
bs.clear(0, 1);
assertEquals(false, bs.get(0));
assertEquals(0, bs.cardinality());
bs.set(0, 0);
assertEquals(false, bs.get(0));
assertEquals(0, bs.cardinality());
bs.set(0, 1);
assertEquals(true, bs.get(0));
assertEquals(1, bs.cardinality());
}
@Test
public void testRangeOpsCrossLongCase() {
bs.clear();
bs.flip(63, 64);
assertEquals(true, bs.get(63));
assertEquals(false, bs.get(64));
assertEquals(1, bs.cardinality());
if (singleThreaded) {
assertFalse(st.allSet(63, 65));
assertFalse(st.allClear(63, 65));
}
bs.flip(63, 65);
assertEquals(false, bs.get(63));
assertEquals(true, bs.get(64));
assertEquals(1, bs.cardinality());
if (singleThreaded) {
assertFalse(st.allSet(63, 65));
assertFalse(st.allClear(63, 65));
}
bs.clear(64);
bs.set(63, 64);
assertEquals(true, bs.get(63));
assertEquals(false, bs.get(64));
assertEquals(1, bs.cardinality());
bs.set(64);
bs.clear(63, 64);
assertEquals(false, bs.get(63));
assertEquals(true, bs.get(64));
assertEquals(1, bs.cardinality());
bs.clear(64);
bs.set(63, 65);
assertEquals(true, bs.get(63));
assertEquals(true, bs.get(64));
assertEquals(2, bs.cardinality());
if (singleThreaded) {
assertTrue(st.allSet(63, 65));
assertFalse(st.allClear(63, 65));
}
bs.clear(63, 65);
assertEquals(false, bs.get(63));
assertEquals(false, bs.get(64));
assertEquals(0, bs.cardinality());
if (singleThreaded) {
assertFalse(st.allSet(63, 65));
assertTrue(st.allClear(63, 65));
}
}
@Test
public void testRangeOpsSpanLongCase() {
bs.clear();
if (singleThreaded) {
assertTrue(st.allClear(0, st.size()));
assertFalse(st.allSet(0, st.size()));
}
bs.set(0, bs.size());
assertEquals(bs.size(), bs.cardinality());
if (singleThreaded) {
assertFalse(st.allClear(0, st.size()));
assertTrue(st.allSet(0, st.size()));
}
bs.clear(0, bs.size());
assertEquals(0, bs.cardinality());
bs.flip(0, bs.size());
assertEquals(bs.size(), bs.cardinality());
}
private String m(int n) {
return "N: " + n + ", " + bs.getClass().getSimpleName();
}
@Test
public void testSetNextNContinuousClearBitsWithinLongCase() {
long size = (bs.size() + 63) / 64 * 64;
for (int n = 1; n <= 64; n *= 2) {
bs.clear();
for (int i = 0; i < size / n; i++) {
assertRangeIsClear(i * n, i * n + n);
assertEquals(m(n), i * n, bs.setNextNContinuousClearBits(0L, n));
assertRangeIsSet(i * n, i * n + n);
assertEquals(i * n + n, bs.cardinality());
}
}
for (int n = 2; n <= 64; n *= 2) {
bs.setAll();
bs.clear(size - n, size);
assertEquals(size - n, bs.setNextNContinuousClearBits(0L, n));
assertRangeIsSet(size - n, size);
long offset = (64 - n) / 2;
long from = size - n - offset;
long to = size - offset;
bs.clear(from, to);
assertEquals(from, bs.setNextNContinuousClearBits(from, n));
assertRangeIsSet(from, to);
bs.clear(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.clear(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.setNextNContinuousClearBits(0, n));
assertEquals(cardinality + n, bs.cardinality());
}
}
@Test
public void testSetNextNContinuousClearBitsCrossLongCase() {
if (bs instanceof ATSDirectBitSet)
return;
long size = bs.size();
for (int n : new int[]{3, 7, 13, 31, 33, 63, 65, 100, 127, 128, 129, 254, 255}) {
bs.clear();
for (int i = 0; i < size / n; i++) {
assertRangeIsClear(i * n, i * n + n);
assertEquals(m(n), i * n, bs.setNextNContinuousClearBits(0L, n));
assertRangeIsSet(i * n, i * n + n);
assertEquals(i * n + n, bs.cardinality());
}
}
long lastBound = size - (size % 64 == 0 ? 64 : size % 64);
for (int n : new int[]{2, 3, 7, 13, 31, 33, 63, 64, 65, 100, 127, 128, 129}) {
bs.setAll();
long from = n <= 64 ? lastBound - (n / 2) : 30;
long to = from + n;
bs.clear(from, to);
assertEquals("" + n, from, bs.setNextNContinuousClearBits(0L, n));
assertRangeIsSet(from, to);
bs.clear(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.clear(i);
}
for (long i = to + 1; i < bs.size(); i += 2) {
bs.clear(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.setNextNContinuousClearBits(from, n));
assertEquals(cardinality + n, bs.cardinality());
}
}
@Test
public void testClearNextNContinuousSetBitsWithinLongCase() {
long size = (bs.size() + 63) / 64 * 64;
for (int n = 1; n <= 64; n *= 2) {
bs.setAll();
long cardinality = bs.cardinality();
for (int i = 0; i < size / n; i++) {
assertRangeIsSet(i * n, i * n + n);
assertEquals(m(n), i * n, bs.clearNextNContinuousSetBits(0L, n));
assertRangeIsClear(i * n, i * n + n);
assertEquals(cardinality - (i * n + n), bs.cardinality());
}
}
for (int n = 2; n <= 64; n *= 2) {
bs.clear();
bs.set(size - n, size);
assertEquals(size - n, bs.clearNextNContinuousSetBits(0L, n));
assertRangeIsClear(size - n, size);
long offset = (64 - n) / 2;
long from = size - n - offset;
long to = size - offset;
bs.set(from, to);
assertEquals(from, bs.clearNextNContinuousSetBits(from, n));
assertRangeIsClear(from, to);
bs.set(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.set(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.clearNextNContinuousSetBits(0, n));
assertEquals(cardinality - n, bs.cardinality());
}
}
@Test
public void testClearNextNContinuousSetBitsCrossLongCase() {
if (bs instanceof ATSDirectBitSet)
return;
long size = bs.size();
for (int n : new int[]{3, 7, 13, 31, 33, 63}) {
bs.setAll();
long cardinality = bs.cardinality();
for (int i = 0; i < size / n; i++) {
assertRangeIsSet(i * n, i * n + n);
assertEquals(m(n), i * n, bs.clearNextNContinuousSetBits(0L, n));
assertRangeIsClear(i * n, i * n + n);
assertEquals(cardinality -= n, bs.cardinality());
}
}
long lastBound = size - (size % 64 == 0 ? 64 : size % 64);
for (int n : new int[]{2, 3, 7, 13, 31, 33, 63, 64}) {
bs.clear();
long from = lastBound - (n / 2);
long to = from + n;
bs.set(from, to);
assertEquals(from, bs.clearNextNContinuousSetBits(0L, n));
assertRangeIsClear(from, to);
bs.set(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.set(i);
}
for (long i = to + 1; i < bs.size(); i += 2) {
bs.set(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.clearNextNContinuousSetBits(from, n));
assertEquals(cardinality - n, bs.cardinality());
}
}
@Test
public void testSetPreviousNContinuousClearBitsWithinLongCase() {
long size = (bs.size() + 63) / 64 * 64;
for (int n = 1; n <= 64; n *= 2) {
bs.clear();
long cardinality = 0;
for (long i = size / n - 1; i >= 0; i--) {
assertRangeIsClear(i * n, i * n + n);
assertEquals(m(n), i * n, bs.setPreviousNContinuousClearBits(size, n));
assertRangeIsSet(i * n, i * n + n);
assertEquals(cardinality += n, bs.cardinality());
}
}
for (int n = 2; n <= 64; n *= 2) {
bs.setAll();
bs.clear(0, n);
assertEquals(0, bs.setPreviousNContinuousClearBits(bs.size(), n));
assertRangeIsSet(0, n);
long from = (64 - n) / 2;
long to = from + n;
bs.clear(from, to);
assertEquals(from, bs.setPreviousNContinuousClearBits(to - 1, n));
assertRangeIsSet(from, to);
bs.clear(from, to);
for (long i = to + 1; i < bs.size(); i += 2) {
bs.clear(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.setPreviousNContinuousClearBits(bs.size(), n));
assertEquals(cardinality + n, bs.cardinality());
}
}
@Test
public void testSetPreviousNContinuousClearBitsCrossLongCase() {
if (bs instanceof ATSDirectBitSet)
return;
long size = bs.size();
for (int n : new int[]{3, 7, 13, 31, 33, 63}) {
bs.clear();
long cardinality = 0;
for (long from = size - n; from >= 0; from -= n) {
assertRangeIsClear(from, from + n);
assertEquals(m(n), from, bs.setPreviousNContinuousClearBits(size, n));
assertRangeIsSet(from, from + n);
assertEquals(cardinality += n, bs.cardinality());
}
}
for (int n : new int[]{2, 3, 7, 13, 31, 33, 63, 64}) {
bs.setAll();
long from = 64 - (n / 2);
long to = from + n;
bs.clear(from, to);
assertEquals(from, bs.setPreviousNContinuousClearBits(size, n));
assertRangeIsSet(from, to);
bs.clear(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.clear(i);
}
for (long i = to + 1; i < bs.size(); i += 2) {
bs.clear(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.setPreviousNContinuousClearBits(to - 1, n));
assertEquals(cardinality + n, bs.cardinality());
}
}
@Test
public void testClearPreviousNContinuousSetBitsWithinLongCase() {
long size = (bs.size() + 63) / 64 * 64;
for (int n = 1; n <= 64; n *= 2) {
bs.setAll();
long cardinality = bs.cardinality();
for (long i = size / n - 1; i >= 0; i--) {
assertRangeIsSet(i * n, i * n + n);
assertEquals(m(n), i * n, bs.clearPreviousNContinuousSetBits(size, n));
assertRangeIsClear(m(n), i * n, i * n + n);
assertEquals(cardinality -= n, bs.cardinality());
}
}
for (int n = 2; n <= 64; n *= 2) {
bs.clear();
bs.set(0, n);
assertEquals(0, bs.clearPreviousNContinuousSetBits(bs.size(), n));
assertRangeIsClear(0, n);
long from = (64 - n) / 2;
long to = from + n;
bs.set(from, to);
assertEquals(from, bs.clearPreviousNContinuousSetBits(to - 1, n));
assertRangeIsClear(from, to);
bs.set(from, to);
for (long i = to + 1; i < bs.size(); i += 2) {
bs.set(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.clearPreviousNContinuousSetBits(bs.size(), n));
assertEquals(cardinality - n, bs.cardinality());
}
}
@Test
public void testClearPreviousNContinuousSetBitsCrossLongCase() {
if (bs instanceof ATSDirectBitSet)
return;
long size = bs.size();
for (int n : new int[]{3, 7, 13, 31, 33, 63}) {
bs.setAll();
long cardinality = bs.cardinality();
for (long from = size - n; from >= 0; from -= n) {
assertRangeIsSet(from, from + n);
assertEquals(m(n), from, bs.clearPreviousNContinuousSetBits(size, n));
assertRangeIsClear(from, from + n);
assertEquals(cardinality -= n, bs.cardinality());
}
}
for (int n : new int[]{2, 3, 7, 13, 31, 33, 63, 64}) {
bs.clear();
long from = 64 - (n / 2);
long to = from + n;
bs.set(from, to);
assertEquals(from, bs.clearPreviousNContinuousSetBits(size, n));
assertRangeIsClear(from, to);
bs.set(from, to);
for (long i = from - 2; i >= 0; i -= 2) {
bs.set(i);
}
for (long i = to + 1; i < bs.size(); i += 2) {
bs.set(i);
}
long cardinality = bs.cardinality();
assertEquals(from, bs.clearPreviousNContinuousSetBits(to - 1, n));
assertEquals(cardinality - n, bs.cardinality());
}
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeGetNegative() {
bs.get(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeGetOverCapacity() {
bs.get(bs.size());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetNegative() {
bs.set(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetOverCapacity() {
bs.set(bs.size());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetIfClearNegative() {
bs.setIfClear(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetIfClearOverCapacity() {
bs.setIfClear(bs.size());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearIfSetNegative() {
bs.clearIfSet(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearIfSetOverCapacity() {
bs.clearIfSet(bs.size());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeFlipNegative() {
bs.flip(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeFlipOverCapacity() {
bs.flip(bs.size());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeGetLongNegative() {
bs.getLong(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeGetLongOverCapacity() {
bs.getLong((bs.size() + 63) / 64);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeNextSetBit() {
bs.nextSetBit(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeNextSetLong() {
bs.nextSetLong(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeNextClearBit() {
bs.nextClearBit(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeNextClearLong() {
bs.nextClearLong(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobePreviousSetBit() {
bs.previousSetBit(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobePreviousSetLong() {
bs.previousSetLong(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobePreviousClearBit() {
bs.previousClearBit(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobePreviousClearLong() {
bs.previousClearLong(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearNextSetBit() {
bs.clearNextSetBit(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearNextNContinuousSetBits() {
bs.clearNextNContinuousSetBits(-1, 2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetNextClearBit() {
bs.setNextClearBit(-1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetNextNContinuousClearBits() {
bs.setNextNContinuousClearBits(-1, 2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearPreviousSetBit() {
bs.clearPreviousSetBit(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearPreviousNContinuousSetBit() {
bs.clearPreviousNContinuousSetBits(-2, 2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetPreviousClearBit() {
bs.setPreviousClearBit(-2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetPreviousNContinuousClearBit() {
bs.setPreviousNContinuousClearBits(-2, 2);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetRangeFromNegative() {
bs.set(-1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetRangeFromOverTo() {
bs.set(1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeSetRangeToOverCapacity() {
bs.set(0, bs.size() + 1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearRangeFromNegative() {
bs.clear(-1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearRangeFromOverTo() {
bs.clear(1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeClearRangeToOverCapacity() {
bs.clear(0, bs.size() + 1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeFlipRangeFromNegative() {
bs.flip(-1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeFlipRangeFromOverTo() {
bs.flip(1, 0);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testIoobeFlipRangeToOverCapacity() {
bs.flip(0, bs.size() + 1);
}
@Test(expected = IllegalArgumentException.class)
public void testIaeClearNextNContinuousSetBits() {
bs.clearNextNContinuousSetBits(0, 0);
}
@Test(expected = IllegalArgumentException.class)
public void testIaeSetNextNContinuousClearBits() {
bs.setNextNContinuousClearBits(0, 0);
}
@Test(expected = IllegalArgumentException.class)
public void testIaeClearPreviousNContinuousSetBits() {
bs.clearPreviousNContinuousSetBits(bs.size(), 0);
}
@Test(expected = IllegalArgumentException.class)
public void testIaeSetPreviousNContinuousClearBits() {
bs.setPreviousNContinuousClearBits(bs.size(), 0);
}
}