track dirty status for btree structures

This commit is contained in:
Maxim.Mossienko
2012-06-04 18:12:51 +04:00
parent 48270054be
commit d837340f54
4 changed files with 43 additions and 16 deletions
@@ -182,10 +182,11 @@ class IntToIntBtree {
int index = myAccessNodeView.locate(key, true);
if (index < 0) {
++count;
myAccessNodeView.insert(key, value);
} else {
++count;
myAccessNodeView.setAddressAt(index, value);
if (!myAccessNodeView.myIsDirty) myAccessNodeView.markDirty();
}
}
@@ -243,6 +244,7 @@ class IntToIntBtree {
protected int myAddressInBuffer;
protected ByteBuffer myBuffer;
protected boolean myHasFullPagesAlongPath;
protected boolean myIsDirty;
public BtreePage(IntToIntBtree btree) {
this.btree = btree;
@@ -259,7 +261,8 @@ class IntToIntBtree {
protected void syncWithStore() {
PagedFileStorage pagedFileStorage = btree.storage.getPagedFileStorage();
myAddressInBuffer = pagedFileStorage.getOffsetInPage(address);
myBuffer = pagedFileStorage.getByteBuffer(address);
myBuffer = pagedFileStorage.getByteBuffer(address, false);
myIsDirty = false; // we will mark dirty on child count change, attrs change or existing key put
doInitFlags(myBuffer.getInt(myAddressInBuffer));
}
@@ -272,6 +275,12 @@ class IntToIntBtree {
if (flag) b |= mask;
else b &= ~mask;
myBuffer.put(myAddressInBuffer, b);
if (!myIsDirty) markDirty();
}
void markDirty() {
btree.storage.getPagedFileStorage().getByteBuffer(address, true);
myIsDirty = true;
}
protected final short getChildrenCount() {
@@ -281,6 +290,7 @@ class IntToIntBtree {
protected final void setChildrenCount(short value) {
myChildrenCount = value;
myBuffer.putShort(myAddressInBuffer + 1, value);
if (!myIsDirty) markDirty();
}
protected final void setNextPage(int nextPage) {
@@ -686,7 +696,6 @@ class IntToIntBtree {
btree.root.setAddressAt(0, -address);
btree.root.setAddressAt(1, -newIndexNode.address);
if (doSanityCheck) {
btree.root.dump("New root");
dump("First child");
@@ -952,7 +961,6 @@ class IntToIntBtree {
hashSetState(index, HASH_FULL);
setAddressAt(index, newValueId);
setChildrenCount((short)(recordCount + 1));
return;
}
}
@@ -73,10 +73,13 @@ public class PagedFileStorage implements Forceable {
private final StorageLockContext myStorageLockContext;
private int myLastPage = UNKNOWN_PAGE;
private int myLastPage2 = UNKNOWN_PAGE;
private int myLastPage3 = UNKNOWN_PAGE;
private ByteBufferWrapper myLastBuffer;
private ByteBufferWrapper myLastBuffer2;
private ByteBufferWrapper myLastBuffer3;
private int myLastChangeCount;
private int myLastChangeCount2;
private int myLastChangeCount3;
private int myStorageIndex;
private static final int MAX_PAGES_COUNT = 0xFFFF;
@@ -160,9 +163,9 @@ public class PagedFileStorage implements Forceable {
int getOffsetInPage(int addr) {
return addr % myPageSize;
}
ByteBuffer getByteBuffer(int address) {
return getBuffer(address / myPageSize);
ByteBuffer getByteBuffer(int address, boolean modify) {
return getBuffer(address / myPageSize, modify);
}
public final short getShort(int addr) {
@@ -294,8 +297,10 @@ public class PagedFileStorage implements Forceable {
myLastPage = UNKNOWN_PAGE;
myLastPage2 = UNKNOWN_PAGE;
myLastPage3 = UNKNOWN_PAGE;
myLastBuffer = null;
myLastBuffer2 = null;
myLastBuffer3 = null;
}
public void resize(int newSize) throws IOException {
@@ -364,14 +369,18 @@ public class PagedFileStorage implements Forceable {
if (modify) myLastBuffer.markDirty();
return buf;
}
}
if (myLastPage2 == page) {
} else if (myLastPage2 == page) {
ByteBuffer buf = myLastBuffer2.getCachedBuffer();
if (buf != null && myLastChangeCount2 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
if (modify) myLastBuffer2.markDirty();
return buf;
}
} else if (myLastPage3 == page) {
ByteBuffer buf = myLastBuffer3.getCachedBuffer();
if (buf != null && myLastChangeCount3 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
if (modify) myLastBuffer3.markDirty();
return buf;
}
}
try {
@@ -385,9 +394,14 @@ public class PagedFileStorage implements Forceable {
ByteBuffer buf = byteBufferWrapper.getBuffer();
if (myLastPage != page) {
myLastPage3 = myLastPage2;
myLastBuffer3 = myLastBuffer2;
myLastChangeCount3 = myLastChangeCount2;
myLastPage2 = myLastPage;
myLastBuffer2 = myLastBuffer;
myLastChangeCount2 = myLastChangeCount;
myLastBuffer = byteBufferWrapper;
myLastPage = page;
} else {
@@ -443,7 +457,7 @@ public class PagedFileStorage implements Forceable {
myDefaultStorageLockContext = new StorageLockContext(this);
mySizeLimit = UPPER_LIMIT;
myMap = new LinkedHashMap<Integer, ByteBufferWrapper>(10) {
myMap = new LinkedHashMap<Integer, ByteBufferWrapper>(10, 0.75f) {
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, ByteBufferWrapper> eldest) {
return mySize > mySizeLimit;
@@ -132,7 +132,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
assert offset + 4 < PAGE_SIZE;
if (toDisk) {
myStorage.putInt(offset, value);
if (myFirstPageStart == -1 || myStorage.getInt(offset) != value) myStorage.putInt(offset, value);
} else {
value = myStorage.getInt(offset);
}
@@ -255,7 +255,8 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
}
private final int[] myResultBuf = new int[1];
private int myExistingKeysEnumerated;
protected int enumerateImpl(final Data value, final boolean onlyCheckForExisting, boolean saveNewValue) throws IOException {
try {
lockStorage();
@@ -280,7 +281,10 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
if (IntToIntBtree.doSanityCheck) IntToIntBtree.myAssert(myDataDescriptor.getHashCode(candidate) == valueHC);
if (myDataDescriptor.isEqual(value, candidate)) {
if (!saveNewValue) return indexNodeValueAddress;
if (!saveNewValue) {
++myExistingKeysEnumerated;
return indexNodeValueAddress;
}
existingData = candidate;
}
@@ -320,6 +324,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
myFile +
", values " +
valuesCount +
", existing keys enumerated:"+ myExistingKeysEnumerated +
", storage size:" +
myStorage.length());
btree.dumpStatistics();
@@ -297,7 +297,7 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
protected void putMetaData(long data) throws IOException {
lockStorage();
try {
myStorage.putLong(META_DATA_OFFSET, data);
if (myStorage.length() < META_DATA_OFFSET + 8 || getMetaData() != data) myStorage.putLong(META_DATA_OFFSET, data);
}
finally {
unlockStorage();
@@ -317,7 +317,7 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
protected void putMetaData2(long data) throws IOException {
lockStorage();
try {
myStorage.putLong(META_DATA_OFFSET + 8, data);
if (myStorage.length() < META_DATA_OFFSET + 16 || getMetaData2() != data) myStorage.putLong(META_DATA_OFFSET + 8, data);
}
finally {
unlockStorage();