https://issues.apache.org/jira/browse/AMQ-5016
Added test and a fix. Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/ee9b3ef7 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/ee9b3ef7 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/ee9b3ef7 Branch: refs/heads/activemq-5.10.x Commit: ee9b3ef72ba8f029183dd8151b4ecbef528fd28b Parents: 100afb0 Author: Timothy Bish <[email protected]> Authored: Wed Jun 11 14:20:00 2014 -0400 Committer: Hadrian Zbarcea <[email protected]> Committed: Mon Dec 15 16:50:52 2014 -0500 ---------------------------------------------------------------------- .../org/apache/activemq/util/BitArrayBin.java | 28 ++-- .../apache/activemq/util/BitArrayBinTest.java | 134 ++++++++++--------- 2 files changed, 88 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/ee9b3ef7/activemq-client/src/main/java/org/apache/activemq/util/BitArrayBin.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/util/BitArrayBin.java b/activemq-client/src/main/java/org/apache/activemq/util/BitArrayBin.java index 592873b..528144e 100755 --- a/activemq-client/src/main/java/org/apache/activemq/util/BitArrayBin.java +++ b/activemq-client/src/main/java/org/apache/activemq/util/BitArrayBin.java @@ -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); http://git-wip-us.apache.org/repos/asf/activemq/blob/ee9b3ef7/activemq-client/src/test/java/org/apache/activemq/util/BitArrayBinTest.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/test/java/org/apache/activemq/util/BitArrayBinTest.java b/activemq-client/src/test/java/org/apache/activemq/util/BitArrayBinTest.java index e1276d8..2b17d8f 100644 --- a/activemq-client/src/test/java/org/apache/activemq/util/BitArrayBinTest.java +++ b/activemq-client/src/test/java/org/apache/activemq/util/BitArrayBinTest.java @@ -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)); + } + + @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()); } - - - 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)); + } }
