diff --git a/activemq-core/src/test/java/org/apache/activemq/usecases/DurableSubscriptionOfflineTest.java b/activemq-core/src/test/java/org/apache/activemq/usecases/DurableSubscriptionOfflineTest.java index f337ca1b32..8232cd67c8 100644 --- a/activemq-core/src/test/java/org/apache/activemq/usecases/DurableSubscriptionOfflineTest.java +++ b/activemq-core/src/test/java/org/apache/activemq/usecases/DurableSubscriptionOfflineTest.java @@ -762,15 +762,14 @@ public class DurableSubscriptionOfflineTest extends org.apache.activemq.TestSupp return; } - // fails for numMessages > 3000 - final int numMessages = 100; + final int numMessages = 2750; KahaDBPersistenceAdapter kahaDBPersistenceAdapter = (KahaDBPersistenceAdapter)broker.getPersistenceAdapter(); PageFile pageFile = kahaDBPersistenceAdapter.getStore().getPageFile(); LOG.info("PageCount " + pageFile.getPageCount() + " f:" + pageFile.getFreePageCount() + ", fileSize:" + pageFile.getFile().length()); long lastDiff = 0; - for (int repeats=0; repeats<4; repeats++) { + for (int repeats=0; repeats<2; repeats++) { LOG.info("Iteration: "+ repeats + " Count:" + pageFile.getPageCount() + " f:" + pageFile.getFreePageCount()); @@ -801,7 +800,7 @@ public class DurableSubscriptionOfflineTest extends org.apache.activemq.TestSupp LOG.info("PageCount " + pageFile.getPageCount() + " f:" + pageFile.getFreePageCount() + " diff: " + (pageFile.getPageCount() - pageFile.getFreePageCount()) + " fileSize:" + pageFile.getFile().length()); if (lastDiff != 0) { - assertEquals("Only use X pages per iteration", lastDiff, pageFile.getPageCount() - pageFile.getFreePageCount()); + assertEquals("Only use X pages per iteration: " + repeats, lastDiff, pageFile.getPageCount() - pageFile.getFreePageCount()); } lastDiff = pageFile.getPageCount() - pageFile.getFreePageCount(); } diff --git a/kahadb/src/main/java/org/apache/kahadb/index/BTreeNode.java b/kahadb/src/main/java/org/apache/kahadb/index/BTreeNode.java index 96f13116cc..eb9fe2a314 100644 --- a/kahadb/src/main/java/org/apache/kahadb/index/BTreeNode.java +++ b/kahadb/src/main/java/org/apache/kahadb/index/BTreeNode.java @@ -282,7 +282,7 @@ public final class BTreeNode { idx = idx < 0 ? -(idx + 1) : idx + 1; BTreeNode child = getChild(tx, idx); if( child.getPageId() == index.getPageId() ) { - throw new IOException("BTree corrupted: Cylce detected."); + throw new IOException("BTree corrupted: Cycle detected."); } Value rc = child.remove(tx, key); @@ -293,6 +293,7 @@ public final class BTreeNode { if( child.isBranch() ) { // This is cause branches are never really empty.. they just go down to 1 child.. children[idx] = child.children[0]; + tx.free(child.getPage()); } else { // The child was a leaf. Then we need to actually remove it from this branch node.. @@ -508,7 +509,10 @@ public final class BTreeNode { if( prefix.length()>0 && parent == null ) { throw new IllegalStateException("Cycle back to root node detected."); } - + if (parent == null) { + prefix += "|"; + out.println(prefix + getPageId()); + } if( isBranch() ) { for(int i=0 ; i < children.length; i++) { BTreeNode child = getChild(tx, i); diff --git a/kahadb/src/test/java/org/apache/kahadb/index/BTreeIndexTest.java b/kahadb/src/test/java/org/apache/kahadb/index/BTreeIndexTest.java index 9426eadf44..ade158bd3c 100644 --- a/kahadb/src/test/java/org/apache/kahadb/index/BTreeIndexTest.java +++ b/kahadb/src/test/java/org/apache/kahadb/index/BTreeIndexTest.java @@ -25,6 +25,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.text.NumberFormat; +import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -421,6 +422,51 @@ public class BTreeIndexTest extends IndexTestSupport { tx.commit(); } + public void testIndexRepeatFillClearIncrementingPageReuse() throws Exception { + pf = new PageFile(directory, getClass().getName()); + pf.setPageSize(4*1024); + pf.load(); + + tx = pf.tx(); + long id = tx.allocate().getPageId(); + + BTreeIndex test = new BTreeIndex(pf, id); + test.setKeyMarshaller(LongMarshaller.INSTANCE); + test.setValueMarshaller(StringMarshaller.INSTANCE); + test.load(tx); + tx.commit(); + + final int count = 5000; + final int reps = 2; + final long[] diffs = new long[reps]; + long keyVal = 0; + final String payload = new String(new byte[50]); + + LOG.info("PF diff:" + (pf.getPageCount() - pf.getFreePageCount()) + " pc:" + pf.getPageCount() + " f:" + pf.getFreePageCount() ); + + for (int i=0; i