提交 5631940a authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore bugfixes

上级 979413fb
......@@ -84,13 +84,14 @@ public class MVMap<K, V> extends AbstractMap<K, V>
*
* @param p the page
* @param writeVersion the write version
* @param removeOld whether the old page should be marked as deleted
* @return a page with the given write version
*/
protected Page copyOnWrite(Page p, long writeVersion) {
protected Page copyOnWrite(Page p, long writeVersion, boolean removeOld) {
if (p.getVersion() == writeVersion) {
return p;
}
return p.copy(writeVersion);
return p.copy(writeVersion, removeOld);
}
/**
......@@ -107,7 +108,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
beforeWrite();
try {
long v = writeVersion;
Page p = copyOnWrite(root, v);
Page p = copyOnWrite(root, v, true);
p = splitRootIfNeeded(p, v);
Object result = put(p, v, key, value);
newRoot(p);
......@@ -166,14 +167,14 @@ public class MVMap<K, V> extends AbstractMap<K, V>
} else {
index++;
}
Page c = copyOnWrite(p.getChildPage(index), writeVersion);
Page c = copyOnWrite(p.getChildPage(index), writeVersion, true);
if (c.getMemory() > store.getPageSplitSize() && c.getKeyCount() > 1) {
// split on the way down
int at = c.getKeyCount() / 2;
Object k = c.getKey(at);
Page split = c.split(at);
p.setChild(index, split);
p.setCounts(index, c);
p.setCounts(index, split);
p.insertNode(index, k, c);
// now we are not sure where to add
return put(p, writeVersion, key, value);
......@@ -551,7 +552,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
beforeWrite();
try {
long v = writeVersion;
Page p = copyOnWrite(root, v);
Page p = copyOnWrite(root, v, true);
@SuppressWarnings("unchecked")
V result = (V) remove(p, v, key);
newRoot(p);
......@@ -670,11 +671,12 @@ public class MVMap<K, V> extends AbstractMap<K, V>
index++;
}
Page cOld = p.getChildPage(index);
Page c = copyOnWrite(cOld, writeVersion);
Page c = copyOnWrite(cOld, writeVersion, false);
result = remove(c, writeVersion, key);
if (result == null) {
return null;
}
cOld.removePage();
if (c.getTotalCount() == 0) {
// this child was deleted
if (p.getKeyCount() == 0) {
......
......@@ -29,8 +29,8 @@ public class MVMapConcurrent<K, V> extends MVMap<K, V> {
}
@Override
protected Page copyOnWrite(Page p, long writeVersion) {
return p.copy(writeVersion);
protected Page copyOnWrite(Page p, long writeVersion, boolean removeOld) {
return p.copy(writeVersion, removeOld);
}
@Override
......@@ -48,7 +48,7 @@ public class MVMapConcurrent<K, V> extends MVMap<K, V> {
get(key);
long v = writeVersion;
synchronized (this) {
Page p = copyOnWrite(root, v);
Page p = copyOnWrite(root, v, true);
p = splitRootIfNeeded(p, v);
V result = (V) put(p, v, key, value);
newRoot(p);
......@@ -75,7 +75,7 @@ public class MVMapConcurrent<K, V> extends MVMap<K, V> {
}
long v = writeVersion;
synchronized (this) {
Page p = copyOnWrite(root, v);
Page p = copyOnWrite(root, v, true);
result = (V) remove(p, v, key);
newRoot(p);
}
......
......@@ -330,7 +330,10 @@ public class MVStore {
// setWriteDelay starts the thread, but only if
// the parameter is different than the current value
setWriteDelay(1000);
o = config.get("writeDelay");
int writeDelay = o == null ? 1000 : (Integer) o;
setWriteDelay(writeDelay);
}
/**
......@@ -2104,6 +2107,20 @@ public class MVStore {
return set("fileStore", store);
}
/**
* Set the initial write delay.
*
* @param writeDelay the write delay
* @return this
*/
public Builder writeDelay(int writeDelay) {
// we have a separate config option so that
// no thread is started if the write delay is 0
// (if we only had a setter in the MVStore,
// the thread would need to be started in any case)
return set("writeDelay", writeDelay);
}
/**
* Open the store.
*
......
......@@ -267,10 +267,14 @@ public class Page {
* Create a copy of this page.
*
* @param version the new version
* @param removeOld whether the old page should be marked as deleted
* @return a page with the given version
*/
public Page copy(long version) {
removePage();
public Page copy(long version, boolean removeOld) {
if (removeOld) {
int todoRemoveAtCaller;
removePage();
}
Page newPage = create(map, version,
keyCount, keys, values, children, childrenPages,
counts, totalCount,
......
......@@ -169,7 +169,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
// this will mark the old page as deleted
// so we need to update the parent in any case
// (otherwise the old page might be deleted again)
Page c = copyOnWrite(cOld, writeVersion);
Page c = copyOnWrite(cOld, writeVersion, true);
long oldSize = c.getTotalCount();
result = remove(c, writeVersion, key);
p.setChild(i, c);
......@@ -224,7 +224,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
beforeWrite();
try {
long v = writeVersion;
Page p = copyOnWrite(root, v);
Page p = copyOnWrite(root, v, true);
Object result;
if (alwaysAdd || get(key) == null) {
if (p.getMemory() > store.getPageSplitSize() && p.getKeyCount() > 1) {
......@@ -268,13 +268,15 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
if (!p.isLeaf()) {
for (int i = 0; i < p.getKeyCount(); i++) {
if (contains(p, i, key)) {
Page c = copyOnWrite(p.getChildPage(i), writeVersion);
Page c = copyOnWrite(p.getChildPage(i), writeVersion, true);
Object result = set(c, writeVersion, key, value);
if (result != null) {
p.setChild(i, c);
p.setCounts(i, c);
return result;
if (result == null) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_INTERNAL, "Key did not exist");
}
p.setChild(i, c);
p.setCounts(i, c);
return result;
}
}
} else {
......@@ -312,11 +314,11 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
}
}
}
Page c = copyOnWrite(p.getChildPage(index), writeVersion);
Page c = copyOnWrite(p.getChildPage(index), writeVersion, true);
if (c.getMemory() > store.getPageSplitSize() && c.getKeyCount() > 1) {
// split on the way down
Page split = split(c, writeVersion);
p = copyOnWrite(p, writeVersion);
p = copyOnWrite(p, writeVersion, true);
p.setKey(index, getBounds(c));
p.setChild(index, c);
p.setCounts(index, c);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论