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

LIRS replacement algorithm

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