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

LIRS replacement algorithm

上级 9b3ce19f
...@@ -848,7 +848,9 @@ public abstract class TestBase { ...@@ -848,7 +848,9 @@ public abstract class TestBase {
* @throws AssertionError if the condition is false * @throws AssertionError if the condition is false
*/ */
public void assertNull(Object obj) { public void assertNull(Object obj) {
assertTrue("Expected: null got: " + obj, obj == null); if (obj != null) {
fail("Expected: null got: " + obj);
}
} }
/** /**
......
...@@ -16,12 +16,12 @@ import java.util.Collections; ...@@ -16,12 +16,12 @@ import java.util.Collections;
import java.util.Comparator; 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.Properties; import java.util.Properties;
import org.h2.dev.store.FilePathCache; import org.h2.dev.store.FilePathCache;
import org.h2.store.fs.FilePath; import org.h2.store.fs.FilePath;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.SmallLRUCache;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
/* /*
...@@ -45,10 +45,10 @@ data ... ...@@ -45,10 +45,10 @@ data ...
todo: todo:
- garbage collection
- use page checksums - use page checksums
- compress chunks - compress chunks
- possibly encode the length in pos (1=32, 2=128, 3=512,...) - possibly encode the length in pos (1=32, 2=128, 3=512,...)
- rollback feature
- floating header (avoid duplicate header) - floating header (avoid duplicate header)
for each chunk, store chunk (a counter) for each chunk, store chunk (a counter)
...@@ -67,26 +67,29 @@ public class BtreeMapStore { ...@@ -67,26 +67,29 @@ public class BtreeMapStore {
private final String fileName; private final String fileName;
private final DataTypeFactory typeFactory; private final DataTypeFactory typeFactory;
private int readCacheSize = 2 * 1024 * 1024;
private int maxPageSize = 30;
private FileChannel file; private FileChannel file;
private int blockSize = 4 * 1024; private int blockSize = 4 * 1024;
private long rootChunkPos; private long rootChunkPos;
private HashMap<Long, Page> cache = SmallLRUCache.newInstance(5000);
private HashMap<Long, Page> temp = New.hashMap();
private HashMap<Integer, Chunk> chunks = New.hashMap();
private HashMap<String, BtreeMap<?, ?>> maps = New.hashMap();
private HashMap<String, BtreeMap<?, ?>> mapsChanged = New.hashMap();
private BtreeMap<String, String> meta;
// TODO use an int instead? (with rollover to 0) private int tempPageId;
private long transaction; private Map<Long, Page> cache = CacheLIRS.newInstance(readCacheSize, 2048);
private long tempPageId; private HashMap<Long, Page> temp = New.hashMap();
private int lastChunkId; private int lastChunkId;
private HashMap<Integer, Chunk> chunks = New.hashMap();
// TODO use bit set, and integer instead of long // TODO use bit set, and integer instead of long
private BtreeMap<String, String> meta;
private long lastMapId; private long lastMapId;
private HashMap<String, BtreeMap<?, ?>> maps = New.hashMap();
private HashMap<String, BtreeMap<?, ?>> mapsChanged = New.hashMap();
private int maxPageSize = 30; // TODO use an int instead? (with rollover to 0)
private long transaction;
// TODO support reading metadata to support quota (per map, per storage) // TODO support reading metadata to support quota (per map, per storage)
// TODO support r-tree // TODO support r-tree
......
...@@ -30,7 +30,7 @@ public class Page { ...@@ -30,7 +30,7 @@ public class Page {
} }
/** /**
* Create a new page. * Create a new page. The arrays are not cloned.
* *
* @param map the map * @param map the map
* @param keys the keys * @param keys the keys
...@@ -71,10 +71,10 @@ public class Page { ...@@ -71,10 +71,10 @@ public class Page {
return this; return this;
} }
map.removePage(id); map.removePage(id);
Page p2 = create(map, keys, values, children); Page newPage = create(map, keys, values, children);
p2.transaction = t; newPage.transaction = t;
p2.cachedCompare = cachedCompare; newPage.cachedCompare = cachedCompare;
return p2; return newPage;
} }
public String toString() { public String toString() {
...@@ -323,7 +323,7 @@ public class Page { ...@@ -323,7 +323,7 @@ public class Page {
int parentIndex = 0; int parentIndex = 0;
while (true) { while (true) {
if (parent != null) { if (parent != null) {
parent.children[parentIndex] = p.id; parent.setChild(parentIndex, p.id);
} }
if (!p.isLeaf()) { if (!p.isLeaf()) {
if (p.keyCount() >= map.getMaxPageSize()) { if (p.keyCount() >= map.getMaxPageSize()) {
...@@ -345,12 +345,7 @@ public class Page { ...@@ -345,12 +345,7 @@ public class Page {
int index = p.findKey(key); int index = p.findKey(key);
if (p.isLeaf()) { if (p.isLeaf()) {
if (index >= 0) { if (index >= 0) {
// create a copy p.setValue(index, value);
// TODO might not be required, but needs a "modified" flag
Object[] v2 = new Object[p.values.length];
System.arraycopy(p.values, 0, v2, 0, v2.length);
p.values = v2;
p.values[index] = value;
break; break;
} }
index = -index - 1; index = -index - 1;
...@@ -382,6 +377,22 @@ public class Page { ...@@ -382,6 +377,22 @@ public class Page {
return top; return top;
} }
private void setChild(int index, long value) {
long[] newChildren = new long[children.length];
System.arraycopy(children, 0, newChildren, 0, newChildren.length);
newChildren[index] = value;
children = newChildren;
}
private void setValue(int index, Object value) {
// create a copy - not always required, but avoid unnecessary cloning
// would require a "modified" flag
Object[] newValues = new Object[values.length];
System.arraycopy(values, 0, newValues, 0, newValues.length);
newValues[index] = value;
values = newValues;
}
/** /**
* Remove this page and all child pages. * Remove this page and all child pages.
*/ */
...@@ -436,7 +447,7 @@ public class Page { ...@@ -436,7 +447,7 @@ public class Page {
} }
} else { } else {
p = p.copyOnWrite(); p = p.copyOnWrite();
p.children[index] = c2.id; p.setChild(index, c2.id);
} }
return p; return p;
} }
...@@ -485,8 +496,8 @@ public class Page { ...@@ -485,8 +496,8 @@ public class Page {
throw new RuntimeException("Page map id mismatch, expected " + map.getId() + " got " + id); throw new RuntimeException("Page map id mismatch, expected " + map.getId() + " got " + id);
} }
boolean node = buff.get() == 1; boolean node = buff.get() == 1;
if (node) {
int len = DataUtils.readVarInt(buff); int len = DataUtils.readVarInt(buff);
if (node) {
children = new long[len]; children = new long[len];
keys = new Object[len - 1]; keys = new Object[len - 1];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
...@@ -496,7 +507,6 @@ public class Page { ...@@ -496,7 +507,6 @@ public class Page {
keys[i] = map.getKeyType().read(buff); keys[i] = map.getKeyType().read(buff);
} }
} else { } else {
int len = DataUtils.readVarInt(buff);
keys = new Object[len]; keys = new Object[len];
values = new Object[len]; values = new Object[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论