Skip to content

Commit

Permalink
Issue ReactiveX#39 ring bit set copying constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
storozhukBM authored and RobWin committed Jan 6, 2017
1 parent cf2965a commit 34e2119
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,18 @@ int set(int bitIndex, boolean value) {
int size() {
return size;
}
}

/**
* Gets the bit at the specified index.
*
* @param bitIndex a bit index
* @return state of bitIndex that can be {@code true} or {@code false}
* @throws IndexOutOfBoundsException if the specified index is negative
*/
boolean get(int bitIndex) {
int wordIndex = wordIndex(bitIndex);
long bitMask = 1L << bitIndex;
boolean bitValue = (words[wordIndex] & bitMask) != 0;
return bitValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ public RingBitSet(int bitSetSize) {
bitSet = new BitSetMod(bitSetSize);
}

public RingBitSet(int bitSetSize, RingBitSet sourceSet) {
this(bitSetSize);

int targetLength = Integer.min(bitSetSize, sourceSet.length);
int sourceIndex = sourceSet.index;
for (int i = 0; i < targetLength; i++) {
this.setNextBit(sourceSet.bitSet.get(sourceIndex));
sourceIndex = (sourceIndex + 1) % sourceSet.size;
}
}

/**
* Sets the bit at the next index to the specified value.
*
Expand Down Expand Up @@ -94,6 +105,19 @@ public int length() {
return length;
}

/**
* Prints the current state of internal bit set.
* @return string representation on internal bit set.
*/
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < size; i++) {
result.append(bitSet.get(i) ? '1' : '0');
}
return result.toString();
}

/**
* Returns the current index of this {@code RingBitSet}.
* Use only for debugging and testing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
*
* Copyright 2016 Robert Winkler and Bohdan Storozhuk
*
* 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 io.github.robwin.circuitbreaker.internal;

import static org.assertj.core.api.BDDAssertions.then;

import org.junit.Test;

public class BitSetModTest {
public static final int CAPACITY = 5;

@Test
public void get() {
BitSetMod source = new BitSetMod(CAPACITY);
for (int i = 0; i < CAPACITY; i++) {
then(source.get(i)).isFalse();
}
source.set(0, true);
source.set(2, true);
source.set(4, true);
for (int i = 0; i < CAPACITY; i++) {
if (i % 2 == 0) {
then(source.get(i)).isTrue();
} else {
then(source.get(i)).isFalse();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public void testRingBitSet() {

assertThat(ringBitSet.getIndex()).isEqualTo(3);


assertThat(ringBitSet.setNextBit(false)).isEqualTo(2);
// The index has reached the maximum size and is set back to 0
assertThat(ringBitSet.getIndex()).isEqualTo(0);
Expand Down Expand Up @@ -98,4 +97,144 @@ public void testRingBitSetWithSlightlyLessCapacity() {
assertThat(ringBitSet.size()).isEqualTo(128);
assertThat(ringBitSet.length()).isEqualTo(100);
}

@Test
public void testRingBitSetCopyFromTheSameSize() {
RingBitSet sourceSet = new RingBitSet(4);
// The initial index is -1
assertThat(sourceSet.getIndex()).isEqualTo(-1);
assertThat(sourceSet.toString()).isEqualTo("0000");

assertThat(sourceSet.setNextBit(true)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("1000");

assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(false)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("1000");

assertThat(sourceSet.getIndex()).isEqualTo(1);
assertThat(sourceSet.setNextBit(true)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("1010");

assertThat(sourceSet.getIndex()).isEqualTo(2);
assertThat(sourceSet.setNextBit(true)).isEqualTo(3);
assertThat(sourceSet.toString()).isEqualTo("1011");

assertThat(sourceSet.getIndex()).isEqualTo(3);
assertThat(sourceSet.setNextBit(false)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("0011");

// The index has reached the maximum size and is set back to 0
assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(false)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("0011");

assertThat(sourceSet.getIndex()).isEqualTo(1);

RingBitSet setCopy = new RingBitSet(4, sourceSet);

assertThat(setCopy.getIndex()).isEqualTo(3);
assertThat(setCopy.toString()).isEqualTo("0110");

assertThat(setCopy.cardinality()).isEqualTo(2);

// The size is 64-bit, because the bits are stored in an array of one long value
assertThat(setCopy.size()).isEqualTo(64);

// The length must be 4, because the ring bit set contains 4 entries
assertThat(setCopy.length()).isEqualTo(4);
}

@Test
public void testRingBitSetCopyFromTheLongerSet() {
RingBitSet sourceSet = new RingBitSet(5);
// The initial index is -1
assertThat(sourceSet.getIndex()).isEqualTo(-1);
assertThat(sourceSet.toString()).isEqualTo("00000");

assertThat(sourceSet.setNextBit(true)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("10000");

assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(false)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("10000");

assertThat(sourceSet.getIndex()).isEqualTo(1);
assertThat(sourceSet.setNextBit(true)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("10100");

assertThat(sourceSet.getIndex()).isEqualTo(2);
assertThat(sourceSet.setNextBit(true)).isEqualTo(3);
assertThat(sourceSet.toString()).isEqualTo("10110");

assertThat(sourceSet.getIndex()).isEqualTo(3);
assertThat(sourceSet.setNextBit(false)).isEqualTo(3);
assertThat(sourceSet.toString()).isEqualTo("10110");

assertThat(sourceSet.getIndex()).isEqualTo(4);
assertThat(sourceSet.setNextBit(false)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("00110");

// The index has reached the maximum size and is set back to 0
assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(true)).isEqualTo(3);
assertThat(sourceSet.toString()).isEqualTo("01110");

assertThat(sourceSet.getIndex()).isEqualTo(1);

RingBitSet setCopy = new RingBitSet(4, sourceSet);

assertThat(setCopy.getIndex()).isEqualTo(3);
assertThat(setCopy.toString()).isEqualTo("1110");

assertThat(setCopy.cardinality()).isEqualTo(3);

// The size is 64-bit, because the bits are stored in an array of one long value
assertThat(setCopy.size()).isEqualTo(64);

// The length must be 4, because the ring bit set contains 4 entries
assertThat(setCopy.length()).isEqualTo(4);
}

@Test
public void testRingBitSetCopyFromTheShorterSet() {
RingBitSet sourceSet = new RingBitSet(3);
// The initial index is -1
assertThat(sourceSet.getIndex()).isEqualTo(-1);
assertThat(sourceSet.toString()).isEqualTo("000");

assertThat(sourceSet.setNextBit(true)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("100");

assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(false)).isEqualTo(1);
assertThat(sourceSet.toString()).isEqualTo("100");

assertThat(sourceSet.getIndex()).isEqualTo(1);
assertThat(sourceSet.setNextBit(true)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("101");

assertThat(sourceSet.getIndex()).isEqualTo(2);
assertThat(sourceSet.setNextBit(true)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("101");

assertThat(sourceSet.getIndex()).isEqualTo(0);
assertThat(sourceSet.setNextBit(false)).isEqualTo(2);
assertThat(sourceSet.toString()).isEqualTo("101");

assertThat(sourceSet.getIndex()).isEqualTo(1);

RingBitSet setCopy = new RingBitSet(4, sourceSet);

assertThat(setCopy.getIndex()).isEqualTo(2);
assertThat(setCopy.toString()).isEqualTo("0110");

assertThat(setCopy.cardinality()).isEqualTo(2);

// The size is 64-bit, because the bits are stored in an array of one long value
assertThat(setCopy.size()).isEqualTo(64);

// The length must be 3, because the ring bit set contains only 3 entries after copying
assertThat(setCopy.length()).isEqualTo(3);
}
}

0 comments on commit 34e2119

Please sign in to comment.