提交 32bae90e authored 作者: Thomas Mueller's avatar Thomas Mueller

A persistent multi-version map (work in progress).

上级 6ab864dc
...@@ -8,7 +8,7 @@ package org.h2.test.store; ...@@ -8,7 +8,7 @@ package org.h2.test.store;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.h2.dev.store.btree.DataType; import org.h2.dev.store.btree.DataType;
import org.h2.dev.store.btree.DataTypeFactory; import org.h2.dev.store.btree.MapFactory;
import org.h2.dev.store.btree.DataUtils; import org.h2.dev.store.btree.DataUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -115,7 +115,7 @@ public class RowType implements DataType { ...@@ -115,7 +115,7 @@ public class RowType implements DataType {
* @param factory the data type factory * @param factory the data type factory
* @return the row type * @return the row type
*/ */
static RowType fromString(String t, DataTypeFactory factory) { static RowType fromString(String t, MapFactory factory) {
if (!t.startsWith("r(") || !t.endsWith(")")) { if (!t.startsWith("r(") || !t.endsWith(")")) {
throw new RuntimeException("Unknown type: " + t); throw new RuntimeException("Unknown type: " + t);
} }
...@@ -123,7 +123,7 @@ public class RowType implements DataType { ...@@ -123,7 +123,7 @@ public class RowType implements DataType {
String[] array = StringUtils.arraySplit(t, ',', false); String[] array = StringUtils.arraySplit(t, ',', false);
DataType[] types = new DataType[array.length]; DataType[] types = new DataType[array.length];
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
types[i] = factory.fromString(array[i]); types[i] = factory.buildDataType(array[i]);
} }
return new RowType(types); return new RowType(types);
} }
......
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.store;
import org.h2.dev.store.btree.BtreeMap;
import org.h2.dev.store.btree.BtreeMapStore;
import org.h2.dev.store.btree.DataType;
/**
* A stored r-tree.
*
* @param <K> the key class
* @param <V> the value class
*/
public class RtreeMap<K, V> extends BtreeMap<K, V> {
RtreeMap(BtreeMapStore store, int id, String name, DataType keyType,
DataType valueType, long createVersion) {
super(store, id, name, keyType, valueType, createVersion);
}
}
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.store;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Set;
import org.h2.dev.store.btree.BtreeMap;
import org.h2.dev.store.btree.BtreeMapStore;
import org.h2.dev.store.btree.DataType;
/**
* A custom map returning the values 1 .. 10.
*
* @param <K> the key type
* @param <V> the key type
*/
public class SequenceMap<K, V> extends BtreeMap<K, V> {
int min = 1, max = 10;
SequenceMap(BtreeMapStore store, int id, String name, DataType keyType,
DataType valueType, long createVersion) {
super(store, id, name, keyType, valueType, createVersion);
setReadOnly(true);
}
public Set<K> keySet() {
return new AbstractSet<K>() {
@Override
public Iterator<K> iterator() {
return new Iterator<K>() {
int x = min;
@Override
public boolean hasNext() {
return x <= max;
}
@SuppressWarnings("unchecked")
@Override
public K next() {
return (K) Integer.valueOf(x++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public int size() {
return max - min + 1;
}
};
}
}
...@@ -29,6 +29,7 @@ public class TestBtreeMapStore extends TestBase { ...@@ -29,6 +29,7 @@ public class TestBtreeMapStore extends TestBase {
} }
public void test() { public void test() {
testCustomMapType();
testTruncateFile(); testTruncateFile();
testFastDelete(); testFastDelete();
testRollbackInMemory(); testRollbackInMemory();
...@@ -44,6 +45,20 @@ public class TestBtreeMapStore extends TestBase { ...@@ -44,6 +45,20 @@ public class TestBtreeMapStore extends TestBase {
testSimple(); testSimple();
} }
private void testCustomMapType() {
String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName);
BtreeMapStore s;
s = openStore(fileName);
SequenceMap<Integer, String> seq = s.openMap("data", "s", "i", "").cast();
StringBuilder buff = new StringBuilder();
for (int x : seq.keySet()) {
buff.append(x).append(';');
}
assertEquals("1;2;3;4;5;6;7;8;9;10;", buff.toString());
s.close();
}
private void testTruncateFile() { private void testTruncateFile() {
String fileName = getBaseDir() + "/testMeta.h3"; String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName); FileUtils.delete(fileName);
...@@ -233,11 +248,11 @@ public class TestBtreeMapStore extends TestBase { ...@@ -233,11 +248,11 @@ public class TestBtreeMapStore extends TestBase {
data.put("1", "Hello"); data.put("1", "Hello");
data.put("2", "World"); data.put("2", "World");
s.store(); s.store();
assertEquals("1/1//", m.get("map.data")); assertEquals("1/1///", m.get("map.data"));
assertTrue(m.containsKey("chunk.1")); assertTrue(m.containsKey("chunk.1"));
data.put("1", "Hallo"); data.put("1", "Hallo");
s.store(); s.store();
assertEquals("1/1//", m.get("map.data")); assertEquals("1/1///", m.get("map.data"));
assertTrue(m.get("root.1").length() > 0); assertTrue(m.get("root.1").length() > 0);
assertTrue(m.containsKey("chunk.1")); assertTrue(m.containsKey("chunk.1"));
assertTrue(m.containsKey("chunk.2")); assertTrue(m.containsKey("chunk.2"));
...@@ -255,8 +270,7 @@ public class TestBtreeMapStore extends TestBase { ...@@ -255,8 +270,7 @@ public class TestBtreeMapStore extends TestBase {
BtreeMapStore s = openStore(fileName); BtreeMapStore s = openStore(fileName);
// s.setCompressor(null); // s.setCompressor(null);
s.setMaxPageSize(40); s.setMaxPageSize(40);
RowType rowType = RowType.fromString("r(i,,)", new TestTypeFactory()); BtreeMap<Integer, Object[]> m = s.openMap("data", "", "i", "r(i,,)");
BtreeMap<Integer, Object[]> m = s.openMap("data", new IntegerType(), rowType);
int i = 0; int i = 0;
// long t = System.currentTimeMillis(); // long t = System.currentTimeMillis();
for (; i < len;) { for (; i < len;) {
...@@ -540,7 +554,7 @@ public class TestBtreeMapStore extends TestBase { ...@@ -540,7 +554,7 @@ public class TestBtreeMapStore extends TestBase {
} }
private static BtreeMapStore openStore(String fileName) { private static BtreeMapStore openStore(String fileName) {
BtreeMapStore store = BtreeMapStore.open(fileName, new TestTypeFactory()); BtreeMapStore store = BtreeMapStore.open(fileName, new TestMapFactory());
store.setMaxPageSize(10); store.setMaxPageSize(10);
return store; return store;
} }
......
...@@ -5,16 +5,29 @@ ...@@ -5,16 +5,29 @@
*/ */
package org.h2.test.store; package org.h2.test.store;
import org.h2.dev.store.btree.BtreeMap;
import org.h2.dev.store.btree.BtreeMapStore;
import org.h2.dev.store.btree.DataType; import org.h2.dev.store.btree.DataType;
import org.h2.dev.store.btree.DataTypeFactory; import org.h2.dev.store.btree.MapFactory;
import org.h2.dev.store.btree.StringType; import org.h2.dev.store.btree.StringType;
/** /**
* A data type factory. * A data type factory.
*/ */
public class TestTypeFactory implements DataTypeFactory { public class TestMapFactory implements MapFactory {
public DataType fromString(String s) { @Override
public <K, V> BtreeMap<K, V> buildMap(String mapType, BtreeMapStore store,
int id, String name, DataType keyType, DataType valueType,
long createVersion) {
if (mapType.equals("s")) {
return new SequenceMap<K, V>(store, id, name, keyType, valueType, createVersion);
}
throw new RuntimeException("Unsupported map type " + mapType);
}
@Override
public DataType buildDataType(String s) {
if (s.length() == 0) { if (s.length() == 0) {
return new StringType(); return new StringType();
} }
...@@ -27,9 +40,10 @@ public class TestTypeFactory implements DataTypeFactory { ...@@ -27,9 +40,10 @@ public class TestTypeFactory implements DataTypeFactory {
throw new RuntimeException("Unknown data type " + s); throw new RuntimeException("Unknown data type " + s);
} }
public DataType getDataType(Class<?> objectClass) { @Override
public String getDataType(Class<?> objectClass) {
if (objectClass == Integer.class) { if (objectClass == Integer.class) {
return new IntegerType(); return "i";
} }
throw new RuntimeException("Unsupported object class " + objectClass.toString()); throw new RuntimeException("Unsupported object class " + objectClass.toString());
} }
......
...@@ -13,14 +13,17 @@ import java.util.Iterator; ...@@ -13,14 +13,17 @@ import java.util.Iterator;
* A cursor to iterate over elements in ascending order. * A cursor to iterate over elements in ascending order.
* *
* @param <K> the key type * @param <K> the key type
* @param <V> the value type
*/ */
class Cursor<K> implements Iterator<K> { class Cursor<K, V> implements Iterator<K> {
private ArrayList<CursorPos> parents = new ArrayList<CursorPos>(); private final BtreeMap<K, V> map;
private final ArrayList<CursorPos> parents = new ArrayList<CursorPos>();
private K current; private K current;
Cursor(Page root, K from) { Cursor(BtreeMap<K, V> map, Page root, K from) {
Page.min(root, parents, from); this.map = map;
map.min(root, parents, from);
fetchNext(); fetchNext();
} }
...@@ -34,7 +37,7 @@ class Cursor<K> implements Iterator<K> { ...@@ -34,7 +37,7 @@ class Cursor<K> implements Iterator<K> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void fetchNext() { private void fetchNext() {
current = (K) Page.nextKey(parents); current = (K) map.nextKey(parents);
} }
public boolean hasNext() { public boolean hasNext() {
......
...@@ -64,9 +64,10 @@ public interface DataType { ...@@ -64,9 +64,10 @@ public interface DataType {
Object read(ByteBuffer buff); Object read(ByteBuffer buff);
/** /**
* Get the string representation of this type. * Get the stable string representation that is used to build this data
* type.
* *
* @return the string * @return the string representation
*/ */
String asString(); String asString();
......
...@@ -9,15 +9,31 @@ package org.h2.dev.store.btree; ...@@ -9,15 +9,31 @@ package org.h2.dev.store.btree;
/** /**
* A factory for data types. * A factory for data types.
*/ */
public interface DataTypeFactory { public interface MapFactory {
/** /**
* Read the data type. * Build a map.
* *
* @param s the string * @param mapType the map type and type specific meta data
* @param store the store
* @param id the unique map id
* @param name the map name
* @param keyType the key type
* @param valueType the value type
* @param createVersion when the map was created
* @return the map
*/
<K, V> BtreeMap<K, V> buildMap(
String mapType, BtreeMapStore store, int id, String name,
DataType keyType, DataType valueType, long createVersion);
/**
* Parse the data type.
*
* @param dataType the string and type specific meta data
* @return the type * @return the type
*/ */
DataType fromString(String s); DataType buildDataType(String dataType);
/** /**
* Get the data type object for the given class. * Get the data type object for the given class.
...@@ -25,6 +41,6 @@ public interface DataTypeFactory { ...@@ -25,6 +41,6 @@ public interface DataTypeFactory {
* @param objectClass the class * @param objectClass the class
* @return the data type object * @return the data type object
*/ */
DataType getDataType(Class<?> objectClass); String getDataType(Class<?> objectClass);
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论