mirror of https://github.com/apache/activemq.git
Apply patch for https://issues.apache.org/activemq/browse/AMQ-1742
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@659082 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
edb21db5ec
commit
0446404c47
|
@ -28,7 +28,6 @@ public class BitArrayBin {
|
||||||
private LinkedList<BitArray> list;
|
private LinkedList<BitArray> list;
|
||||||
private int maxNumberOfArrays;
|
private int maxNumberOfArrays;
|
||||||
private int firstIndex = -1;
|
private int firstIndex = -1;
|
||||||
private int firstBin = -1;
|
|
||||||
private long lastInOrderBit=-1;
|
private long lastInOrderBit=-1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,16 +53,13 @@ public class BitArrayBin {
|
||||||
* @return true if set
|
* @return true if set
|
||||||
*/
|
*/
|
||||||
public boolean setBit(long index, boolean value) {
|
public boolean setBit(long index, boolean value) {
|
||||||
boolean answer = true;
|
boolean answer = false;
|
||||||
BitArray ba = getBitArray(index);
|
BitArray ba = getBitArray(index);
|
||||||
if (ba != null) {
|
if (ba != null) {
|
||||||
int offset = getOffset(index);
|
int offset = getOffset(index);
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
answer = ba.set(offset, value);
|
answer = ba.set(offset, value);
|
||||||
}
|
}
|
||||||
if (value) {
|
|
||||||
}else {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
@ -117,14 +113,16 @@ public class BitArrayBin {
|
||||||
int bin = getBin(index);
|
int bin = getBin(index);
|
||||||
BitArray answer = null;
|
BitArray answer = null;
|
||||||
if (bin >= 0) {
|
if (bin >= 0) {
|
||||||
if (firstIndex < 0) {
|
if (bin >= maxNumberOfArrays) {
|
||||||
firstIndex = 0;
|
int overShoot = bin - maxNumberOfArrays + 1;
|
||||||
}
|
while (overShoot > 0) {
|
||||||
if (bin >= list.size()) {
|
list.removeFirst();
|
||||||
list.removeFirst();
|
firstIndex += BitArray.LONG_SIZE;
|
||||||
firstIndex += BitArray.LONG_SIZE;
|
list.add(new BitArray());
|
||||||
list.add(new BitArray());
|
overShoot--;
|
||||||
bin = list.size() - 1;
|
}
|
||||||
|
|
||||||
|
bin = maxNumberOfArrays - 1;
|
||||||
}
|
}
|
||||||
answer = list.get(bin);
|
answer = list.get(bin);
|
||||||
if (answer == null) {
|
if (answer == null) {
|
||||||
|
@ -143,8 +141,8 @@ public class BitArrayBin {
|
||||||
*/
|
*/
|
||||||
private int getBin(long index) {
|
private int getBin(long index) {
|
||||||
int answer = 0;
|
int answer = 0;
|
||||||
if (firstBin < 0) {
|
if (firstIndex < 0) {
|
||||||
firstBin = 0;
|
firstIndex = (int) (index - (index % BitArray.LONG_SIZE));
|
||||||
} else if (firstIndex >= 0) {
|
} else if (firstIndex >= 0) {
|
||||||
answer = (int)((index - firstIndex) / BitArray.LONG_SIZE);
|
answer = (int)((index - firstIndex) / BitArray.LONG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,9 @@ public class ActiveMQMessageAuditTest extends TestCase {
|
||||||
list.add(id);
|
list.add(id);
|
||||||
assertFalse(audit.isDuplicate(id));
|
assertFalse(audit.isDuplicate(id));
|
||||||
}
|
}
|
||||||
for (String id : list) {
|
List<String> windowList = list.subList(list.size() -1 -audit.getAuditDepth(), list.size() -1);
|
||||||
assertTrue(audit.isDuplicate(id));
|
for (String id : windowList) {
|
||||||
|
assertTrue("duplicate, id:" + id, audit.isDuplicate(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +91,9 @@ public class ActiveMQMessageAuditTest extends TestCase {
|
||||||
list.add(msg);
|
list.add(msg);
|
||||||
assertFalse(audit.isDuplicate(msg.getMessageId()));
|
assertFalse(audit.isDuplicate(msg.getMessageId()));
|
||||||
}
|
}
|
||||||
for (MessageReference msg : list) {
|
List<MessageReference> windowList = list.subList(list.size() -1 -audit.getAuditDepth(), list.size() -1);
|
||||||
assertTrue(audit.isDuplicate(msg));
|
for (MessageReference msg : windowList) {
|
||||||
|
assertTrue("duplicate msg:" + msg, audit.isDuplicate(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
package org.apache.activemq.util;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class BitArrayBinTest extends TestCase {
|
||||||
|
|
||||||
|
public void testSetAroundWindow() throws Exception {
|
||||||
|
doTestSetAroundWindow(500, 2000);
|
||||||
|
doTestSetAroundWindow(512, 2000);
|
||||||
|
doTestSetAroundWindow(128, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTestSetAroundWindow(int window, int dataSize) throws Exception {
|
||||||
|
|
||||||
|
BitArrayBin toTest = new BitArrayBin(window);
|
||||||
|
|
||||||
|
for (int i=0; i <= dataSize; i++) {
|
||||||
|
assertTrue("not already set", !toTest.setBit(i, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
int windowOfValidData = roundWindow(dataSize, window);
|
||||||
|
int i=dataSize;
|
||||||
|
for (; i >= dataSize -windowOfValidData; i--) {
|
||||||
|
assertTrue("was already set, id=" + i, toTest.setBit(i, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
assertTrue("not already set: id=" + j, !toTest.setBit(j, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
assertTrue("not already set", !toTest.setBit(i, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
int windowOfValidData = roundWindow(dataSize, window);
|
||||||
|
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++) {
|
||||||
|
assertTrue("not already set, id:" + i, !toTest.setBit(i, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j= 2*dataSize; j< 4*dataSize; j++) {
|
||||||
|
assertTrue("not already set: id=" + j, !toTest.setBit(j, Boolean.TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
BitArrayBin toTest = new BitArrayBin(window);
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLargeGapInData(int window) 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
int startOfValid = validDataBin * BitArray.LONG_SIZE;
|
||||||
|
|
||||||
|
return dataSetEnd - startOfValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue