mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3956 - KahaDB pagefile (db.data) steady growth - BTreeIndex page leak. release the clild page when empty branch is promoted, additional tests
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1367924 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6f92d5f8b9
commit
8e60ca9a90
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -282,7 +282,7 @@ public final class BTreeNode<Key,Value> {
|
|||
idx = idx < 0 ? -(idx + 1) : idx + 1;
|
||||
BTreeNode<Key, Value> 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<Key,Value> {
|
|||
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<Key,Value> {
|
|||
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<Key, Value> child = getChild(tx, i);
|
||||
|
|
|
@ -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<Long, String> test = new BTreeIndex<Long, String>(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<reps; i++) {
|
||||
|
||||
for (int j = 0; j < count; j++) {
|
||||
tx = pf.tx();
|
||||
test.put(tx, keyVal++, payload);
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
tx = pf.tx();
|
||||
for (long k = keyVal - count; k < keyVal; k++) {
|
||||
test.remove(tx, k);
|
||||
}
|
||||
test.clear(tx);
|
||||
tx.commit();
|
||||
diffs[i] = pf.getPageCount() - pf.getFreePageCount();
|
||||
|
||||
LOG.info("PF diff:" + (pf.getPageCount() - pf.getFreePageCount()) + " pc:" + pf.getPageCount() + " f:" + pf.getFreePageCount());
|
||||
}
|
||||
for (int i=1; i<diffs.length; i++) {
|
||||
assertEquals("diff is constant:" + Arrays.toString(diffs), diffs[0],diffs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListIndexConsistancyOverTime() throws Exception {
|
||||
|
||||
final int NUM_ITERATIONS = 50;
|
||||
|
|
Loading…
Reference in New Issue