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

A persistent tree map (work in progress)

上级 756c6fa4
...@@ -29,7 +29,7 @@ public class TestTreeMapStore extends TestBase { ...@@ -29,7 +29,7 @@ public class TestTreeMapStore extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
// testReuseSpace(); testReuseSpace();
testRandom(); testRandom();
testKeyValueClasses(); testKeyValueClasses();
testIterate(); testIterate();
...@@ -39,28 +39,26 @@ public class TestTreeMapStore extends TestBase { ...@@ -39,28 +39,26 @@ public class TestTreeMapStore extends TestBase {
private void testReuseSpace() { private void testReuseSpace() {
String fileName = getBaseDir() + "/data.h3"; String fileName = getBaseDir() + "/data.h3";
FileUtils.delete(fileName); FileUtils.delete(fileName);
long initialLength = 0;
for (int j = 0; j < 10; j++) { for (int j = 0; j < 10; j++) {
System.out.println("@@@open");
TreeMapStore s = TreeMapStore.open(fileName); TreeMapStore s = TreeMapStore.open(fileName);
StoredMap<Integer, String> m = s.openMap("data", Integer.class, String.class); StoredMap<Integer, String> m = s.openMap("data", Integer.class, String.class);
System.out.println(s);
System.out.println("get0: " + m.get(0));
System.out.println("@@@add");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
m.put(i, "Hello"); m.put(i, "Hello");
} }
s.store(); s.store();
System.out.println(s);
System.out.println("@@@remove");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
m.remove(i); m.remove(i);
} }
s.store(); s.store();
System.out.println(s);
System.out.println("@@@close");
s.close(); s.close();
long len = FileUtils.size(fileName);
if (initialLength == 0) {
initialLength = len;
} else {
assertTrue(len <= initialLength * 2);
}
} }
if(true)System.exit(0);
} }
private void testRandom() { private void testRandom() {
......
...@@ -11,6 +11,7 @@ import java.io.File; ...@@ -11,6 +11,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
...@@ -95,7 +96,7 @@ public class TreeMapStore { ...@@ -95,7 +96,7 @@ public class TreeMapStore {
String root = meta.get("map." + name); String root = meta.get("map." + name);
m = StoredMap.open(this, name, keyClass, valueClass); m = StoredMap.open(this, name, keyClass, valueClass);
maps.put(name, m); maps.put(name, m);
if (root != null) { if (root != null && !root.equals("0")) {
m.setRoot(Long.parseLong(root)); m.setRoot(Long.parseLong(root));
} }
} }
...@@ -221,6 +222,20 @@ public class TreeMapStore { ...@@ -221,6 +222,20 @@ public class TreeMapStore {
return offset; return offset;
} }
private int count(Node n) {
if (n == null) {
return 0;
}
int count = 1;
if (n.getLeftId() < 0) {
count += count(n.getLeft());
}
if (n.getRightId() < 0) {
count += count(n.getRight());
}
return count;
}
private void store(ByteBuffer buff, Node n) { private void store(ByteBuffer buff, Node n) {
if (n == null) { if (n == null) {
return; return;
...@@ -264,6 +279,16 @@ public class TreeMapStore { ...@@ -264,6 +279,16 @@ public class TreeMapStore {
for (Block x : blocks) { for (Block x : blocks) {
if (x.liveCount == 0) { if (x.liveCount == 0) {
meta.remove("block." + x.id); meta.remove("block." + x.id);
} else {
meta.put("block." + x.id, "temp " + x.toString());
}
}
// modifying the meta can itself affect the metadata
// TODO solve this in a better way
for (Block x : new ArrayList<Block>(blocks)) {
if (x.liveCount == 0) {
meta.remove("block." + x.id);
blocks.remove(x);
} else { } else {
meta.put("block." + x.id, x.toString()); meta.put("block." + x.id, x.toString());
} }
...@@ -273,19 +298,27 @@ public class TreeMapStore { ...@@ -273,19 +298,27 @@ public class TreeMapStore {
long storePos = allocate(lenEstimate); long storePos = allocate(lenEstimate);
int test;
// System.out.println("use " + storePos + ".." + (storePos + lenEstimate));
long end = storePos + 1 + 8; long end = storePos + 1 + 8;
for (StoredMap<?, ?> m : mapsChanged.values()) { for (StoredMap<?, ?> m : mapsChanged.values()) {
meta.put("map." + m.getName(), String.valueOf(end)); Node r = m.getRoot();
end = updateId(m.getRoot(), end); long p = r == null ? 0 : end;
meta.put("map." + m.getName(), String.valueOf(p));
end = updateId(r, end);
} }
long metaPos = end; long metaPos = end;
// add a dummy entry so the count is correct
meta.put("block." + b.id, b.toString());
int count = 0;
for (StoredMap<?, ?> m : mapsChanged.values()) {
count += count(m.getRoot());
}
count += count(meta.getRoot());
b.start = storePos; b.start = storePos;
b.entryCount = tempNodeId; b.entryCount = count;
b.liveCount = b.entryCount; b.liveCount = b.entryCount;
meta.put("block." + b.id, b.toString()); meta.put("block." + b.id, b.toString());
end = updateId(meta.getRoot(), end); end = updateId(meta.getRoot(), end);
...@@ -430,6 +463,9 @@ public class TreeMapStore { ...@@ -430,6 +463,9 @@ public class TreeMapStore {
void removeNode(long id) { void removeNode(long id) {
if (id > 0) { if (id > 0) {
if (getBlock(id).liveCount == 0) {
System.out.println("??");
}
getBlock(id).liveCount--; getBlock(id).liveCount--;
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论