mirror of https://github.com/apache/activemq.git
Added test and a fix.
This commit is contained in:
parent
1c75360ded
commit
91a0041915
|
@ -21,21 +21,21 @@ import java.util.LinkedList;
|
|||
|
||||
/**
|
||||
* Holder for many bitArrays - used for message audit
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class BitArrayBin implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private LinkedList<BitArray> list;
|
||||
private final LinkedList<BitArray> list;
|
||||
private int maxNumberOfArrays;
|
||||
private int firstIndex = -1;
|
||||
private long firstIndex = -1;
|
||||
private long lastInOrderBit=-1;
|
||||
|
||||
/**
|
||||
* Create a BitArrayBin to a certain window size (number of messages to
|
||||
* keep)
|
||||
*
|
||||
*
|
||||
* @param windowSize
|
||||
*/
|
||||
public BitArrayBin(int windowSize) {
|
||||
|
@ -49,7 +49,7 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
/**
|
||||
* Set a bit
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @param value
|
||||
* @return true if set
|
||||
|
@ -65,7 +65,7 @@ public class BitArrayBin implements Serializable {
|
|||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if in order
|
||||
* @param index
|
||||
|
@ -85,7 +85,7 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
/**
|
||||
* Get the boolean value at the index
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @return true/false
|
||||
*/
|
||||
|
@ -107,7 +107,7 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
/**
|
||||
* Get the BitArray for the index
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @return BitArray
|
||||
*/
|
||||
|
@ -123,7 +123,7 @@ public class BitArrayBin implements Serializable {
|
|||
list.add(new BitArray());
|
||||
overShoot--;
|
||||
}
|
||||
|
||||
|
||||
bin = maxNumberOfArrays - 1;
|
||||
}
|
||||
answer = list.get(bin);
|
||||
|
@ -137,7 +137,7 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
/**
|
||||
* Get the index of the bin from the total index
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @return the index of the bin
|
||||
*/
|
||||
|
@ -153,7 +153,7 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
/**
|
||||
* Get the offset into a bin from the total index
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @return the relative offset into a bin
|
||||
*/
|
||||
|
@ -167,9 +167,9 @@ public class BitArrayBin implements Serializable {
|
|||
|
||||
public long getLastSetIndex() {
|
||||
long result = -1;
|
||||
|
||||
|
||||
if (firstIndex >=0) {
|
||||
result = firstIndex;
|
||||
result = firstIndex;
|
||||
BitArray last = null;
|
||||
for (int lastBitArrayIndex = maxNumberOfArrays -1; lastBitArrayIndex >= 0; lastBitArrayIndex--) {
|
||||
last = list.get(lastBitArrayIndex);
|
||||
|
|
|
@ -16,16 +16,21 @@
|
|||
*/
|
||||
package org.apache.activemq.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class BitArrayBinTest extends TestCase {
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class BitArrayBinTest {
|
||||
|
||||
@Test
|
||||
public void testSetAroundWindow() throws Exception {
|
||||
doTestSetAroundWindow(500, 2000);
|
||||
doTestSetAroundWindow(512, 2000);
|
||||
doTestSetAroundWindow(128, 512);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetHiLo() throws Exception {
|
||||
BitArrayBin toTest = new BitArrayBin(50);
|
||||
toTest.setBit(0, true);
|
||||
|
@ -34,127 +39,136 @@ public class BitArrayBinTest extends TestCase {
|
|||
assertTrue("set", toTest.getBit(0));
|
||||
|
||||
toTest.setBit(0, true);
|
||||
assertTrue("set", toTest.getBit(0));
|
||||
assertTrue("set", toTest.getBit(0));
|
||||
}
|
||||
|
||||
|
||||
private void doTestSetAroundWindow(int window, int dataSize) throws Exception {
|
||||
|
||||
BitArrayBin toTest = new BitArrayBin(window);
|
||||
|
||||
for (int i=0; i <= dataSize; i++) {
|
||||
|
||||
for (int i = 0; i <= dataSize; i++) {
|
||||
assertTrue("not already set", !toTest.setBit(i, Boolean.TRUE));
|
||||
assertEquals("current is max", i, toTest.getLastSetIndex());
|
||||
}
|
||||
|
||||
assertEquals("last is max", dataSize, toTest.getLastSetIndex());
|
||||
|
||||
|
||||
int windowOfValidData = roundWindow(dataSize, window);
|
||||
int i=dataSize;
|
||||
for (; i >= dataSize -windowOfValidData; i--) {
|
||||
int i = dataSize;
|
||||
for (; i >= dataSize - windowOfValidData; i--) {
|
||||
assertTrue("was already set, id=" + i, toTest.setBit(i, Boolean.TRUE));
|
||||
}
|
||||
|
||||
assertEquals("last is still max", dataSize, toTest.getLastSetIndex());
|
||||
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
assertTrue("was not already set, id=" + i, !toTest.setBit(i, Boolean.TRUE));
|
||||
}
|
||||
|
||||
for (int j= dataSize +1; j<=(2*dataSize); j++) {
|
||||
|
||||
for (int j = dataSize + 1; j <= (2 * dataSize); j++) {
|
||||
assertTrue("not already set: id=" + j, !toTest.setBit(j, Boolean.TRUE));
|
||||
}
|
||||
|
||||
assertEquals("last still max*2", 2*dataSize, toTest.getLastSetIndex());
|
||||
|
||||
assertEquals("last still max*2", 2 * dataSize, toTest.getLastSetIndex());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetUnsetAroundWindow() throws Exception {
|
||||
doTestSetUnSetAroundWindow(500, 2000);
|
||||
doTestSetUnSetAroundWindow(512, 2000);
|
||||
doTestSetUnSetAroundWindow(128, 512);
|
||||
}
|
||||
|
||||
|
||||
private void doTestSetUnSetAroundWindow(int dataSize, int window) throws Exception {
|
||||
|
||||
BitArrayBin toTest = new BitArrayBin(window);
|
||||
|
||||
for (int i=0; i <=dataSize; i++) {
|
||||
|
||||
for (int i = 0; i <= dataSize; i++) {
|
||||
assertTrue("not already set", !toTest.setBit(i, Boolean.TRUE));
|
||||
}
|
||||
|
||||
|
||||
int windowOfValidData = roundWindow(dataSize, window);
|
||||
for (int i=dataSize; i >= 0 && i >=dataSize -windowOfValidData; i--) {
|
||||
for (int i = dataSize; i >= 0 && i >= dataSize - windowOfValidData; i--) {
|
||||
assertTrue("was already set, id=" + i, toTest.setBit(i, Boolean.FALSE));
|
||||
}
|
||||
|
||||
for (int i=0; i <=dataSize; i++) {
|
||||
for (int i = 0; i <= dataSize; i++) {
|
||||
assertTrue("not already set, id:" + i, !toTest.setBit(i, Boolean.TRUE));
|
||||
}
|
||||
|
||||
for (int j= 2*dataSize; j< 4*dataSize; j++) {
|
||||
for (int j = 2 * dataSize; j < 4 * dataSize; j++) {
|
||||
assertTrue("not already set: id=" + j, !toTest.setBit(j, Boolean.TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetAroundLongSizeMultiplier() throws Exception {
|
||||
int window = 512;
|
||||
int dataSize = 1000;
|
||||
for (int muliplier=1; muliplier <8; muliplier++) {
|
||||
for (int value=0; value <dataSize; value++) {
|
||||
for (int muliplier = 1; muliplier < 8; muliplier++) {
|
||||
for (int value = 0; value < dataSize; value++) {
|
||||
BitArrayBin toTest = new BitArrayBin(window);
|
||||
|
||||
int instance = value +muliplier*BitArray.LONG_SIZE;
|
||||
|
||||
int instance = value + muliplier * BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
assertTrue("not already set: id=" + value, !toTest.setBit(value, Boolean.TRUE));
|
||||
assertEquals("max set correct", instance, toTest.getLastSetIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testLargeGapInData(int window) throws Exception {
|
||||
|
||||
@Test
|
||||
public void testLargeGapInData() throws Exception {
|
||||
doTestLargeGapInData(128);
|
||||
doTestLargeGapInData(500);
|
||||
}
|
||||
|
||||
|
||||
public void doTestLargeGapInData(int window) throws Exception {
|
||||
BitArrayBin toTest = new BitArrayBin(window);
|
||||
|
||||
|
||||
int instance = BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
|
||||
instance = 12 *BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
|
||||
instance = 9 *BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
|
||||
instance = 12 * BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
|
||||
instance = 9 * BitArray.LONG_SIZE;
|
||||
assertTrue("not already set: id=" + instance, !toTest.setBit(instance, Boolean.TRUE));
|
||||
}
|
||||
|
||||
|
||||
public void testLastSeq() throws Exception {
|
||||
BitArrayBin toTest = new BitArrayBin(512);
|
||||
assertEquals("last not set", -1, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(1, Boolean.TRUE);
|
||||
assertEquals("last correct", 1, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(64, Boolean.TRUE);
|
||||
assertEquals("last correct", 64, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(68, Boolean.TRUE);
|
||||
assertEquals("last correct", 68, toTest.getLastSetIndex());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLastSeq() throws Exception {
|
||||
BitArrayBin toTest = new BitArrayBin(512);
|
||||
assertEquals("last not set", -1, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(1, Boolean.TRUE);
|
||||
assertEquals("last correct", 1, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(64, Boolean.TRUE);
|
||||
assertEquals("last correct", 64, toTest.getLastSetIndex());
|
||||
|
||||
toTest.setBit(68, Boolean.TRUE);
|
||||
assertEquals("last correct", 68, toTest.getLastSetIndex());
|
||||
}
|
||||
|
||||
// window moves in increments of BitArray.LONG_SIZE.
|
||||
// valid data window on low end can be larger than window
|
||||
private int roundWindow(int dataSetEnd, int windowSize) {
|
||||
|
||||
|
||||
int validData = dataSetEnd - windowSize;
|
||||
int validDataBin = validData / BitArray.LONG_SIZE;
|
||||
validDataBin += (windowSize % BitArray.LONG_SIZE > 0? 1:0);
|
||||
validDataBin += (windowSize % BitArray.LONG_SIZE > 0 ? 1 : 0);
|
||||
int startOfValid = validDataBin * BitArray.LONG_SIZE;
|
||||
|
||||
return dataSetEnd - startOfValid;
|
||||
|
||||
return dataSetEnd - startOfValid;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLargeNumber() throws Exception {
|
||||
BitArrayBin toTest = new BitArrayBin(1024);
|
||||
toTest.setBit(1, true);
|
||||
long largeNum = Integer.MAX_VALUE * 2L + 100L;
|
||||
toTest.setBit(largeNum, true);
|
||||
assertTrue("set", toTest.getBit(largeNum));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue