提交 e8500c3d authored 作者: Thomas Mueller's avatar Thomas Mueller

A persistent multi-version map: avoid 'magic' casting in the comparator, because…

A persistent multi-version map: avoid 'magic' casting in the comparator, because strictly Collections.binarySearch could swap the parameter objects in the call to the compare method. This should also simplify porting the code to C.
上级 e655f650
...@@ -9,8 +9,6 @@ package org.h2.dev.store.btree; ...@@ -9,8 +9,6 @@ package org.h2.dev.store.btree;
import java.util.AbstractMap; import java.util.AbstractMap;
import java.util.AbstractSet; import java.util.AbstractSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
...@@ -565,32 +563,16 @@ public class MVMap<K, V> extends AbstractMap<K, V> { ...@@ -565,32 +563,16 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
if (oldest == -1) { if (oldest == -1) {
return; return;
} }
ArrayList<Page> list = oldRoots; int i = searchRoot(oldest);
int i = Collections.binarySearch(list, oldest, PAGE_VERSION_COMPARATOR);
if (i < 0) { if (i < 0) {
return; return;
} }
// create a new instance // create a new instance
// because another thread might iterate over it // because another thread might iterate over it
list = new ArrayList<Page>(); ArrayList<Page> list = new ArrayList<Page>();
list.addAll(oldRoots.subList(i, oldRoots.size())); list.addAll(oldRoots.subList(i, oldRoots.size()));
oldRoots = list; oldRoots = list;
} }
private static final Comparator<Object> PAGE_VERSION_COMPARATOR = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
Page p = (Page) o1;
Long key = (Long) o2;
if (p.getVersion() == key)
return 0;
else if (p.getVersion() < key)
return -1;
else
return 1;
}
};
public void setReadOnly(boolean readOnly) { public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly; this.readOnly = readOnly;
...@@ -684,20 +666,17 @@ public class MVMap<K, V> extends AbstractMap<K, V> { ...@@ -684,20 +666,17 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
if (r.getVersion() == version) { if (r.getVersion() == version) {
newest = r; newest = r;
} else { } else {
ArrayList<Page> list = oldRoots;
// find the newest page that has a getVersion() <= version // find the newest page that has a getVersion() <= version
int i = Collections.binarySearch(list, version, PAGE_VERSION_COMPARATOR); int i = searchRoot(version);
if (i > 0) { if (i < 0) {
newest = list.get(i); // not found
} else { if (i == -1) {
i = -(i+1); // calculate insertion point // smaller than all in-memory versions
if (i > 0) { return store.openMapVersion(version, name);
newest = list.get(i - 1);
} }
i = -i - 2;
} }
} newest = oldRoots.get(i);
if (newest == null) {
return store.openMapVersion(version, name);
} }
MVMap<K, V> m = new MVMap<K, V>(store, id, name, keyType, valueType, createVersion); MVMap<K, V> m = new MVMap<K, V>(store, id, name, keyType, valueType, createVersion);
m.readOnly = true; m.readOnly = true;
...@@ -705,6 +684,22 @@ public class MVMap<K, V> extends AbstractMap<K, V> { ...@@ -705,6 +684,22 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
return m; return m;
} }
private int searchRoot(long version) {
int low = 0, high = oldRoots.size() - 1;
while (low <= high) {
int x = (low + high) >>> 1;
long v = oldRoots.get(x).getVersion();
if (v < version) {
low = x + 1;
} else if (version < v) {
high = x - 1;
} else {
return x;
}
}
return -(low + 1);
}
public long getVersion() { public long getVersion() {
return root.getVersion(); return root.getVersion();
} }
......
...@@ -979,7 +979,8 @@ public class MVStore { ...@@ -979,7 +979,8 @@ public class MVStore {
} }
/** /**
* Which version to retain. If not set, all versions up to the last stored version are retained. * Which version to retain. If not set, all versions up to the last stored
* version are retained.
* *
* @param retainVersion the oldest version to retain * @param retainVersion the oldest version to retain
*/ */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论