提交 54d90c04 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: simplify the builder API a bit

上级 b12bb799
......@@ -44,7 +44,6 @@ H:3,...
TODO:
- cache: change API to better match guava / Android
- MVStore: improved API thanks to Simo Tripodi
- implement table engine for H2
- automated 'kill process' and 'power failure' test
......@@ -1401,4 +1400,107 @@ public class MVStore {
return DataUtils.parseMap(m).get("name");
}
/**
* A builder for an MVStore.
*/
public static class Builder {
private final HashMap<String, Object> config = New.hashMap();
private Builder set(String key, Object value) {
if (config.containsKey(key)) {
throw DataUtils.illegalArgumentException("Parameter " + config.get(key) + " is already set");
}
config.put(key, value);
return this;
}
/**
* Use the following file name. If the file does not exist, it is
* automatically created.
*
* @param fileName the file name
* @return this
*/
public Builder fileName(String fileName) {
return set("fileName", fileName);
}
/**
* Open the file in read-only mode. In this case, a shared lock will be
* acquired to ensure the file is not concurrently opened in write mode.
* <p>
* If this option is not used, the file is locked exclusively.
* <p>
* Please note a store may only be opened once in every JVM (no matter
* whether it is opened in read-only or read-write mode), because each file
* may be locked only once in a process.
*
* @return this
*/
public Builder readOnly() {
return set("openMode", "r");
}
/**
* Set the read cache size in MB. The default is 16 MB.
*
* @param mb the cache size
* @return this
*/
public Builder cacheSizeMB(int mb) {
return set("cacheSize", Integer.toString(mb));
}
/**
* Compress data before writing using the LZF algorithm. This setting only
* affects writes; it is not necessary to enable compression when reading,
* even if compression was enabled when writing.
*
* @return this
*/
public Builder compressData() {
return set("compress", "1");
}
/**
* Use the given data type factory.
*
* @param factory the data type factory
* @return this
*/
public Builder with(DataTypeFactory factory) {
return set("dataTypeFactory", factory);
}
/**
* Open the store.
*
* @return the opened store
*/
public MVStore open() {
MVStore s = new MVStore(config);
s.open();
return s;
}
public String toString() {
return DataUtils.appendMap(new StringBuilder(), config).toString();
}
/**
* Read the configuration from a string.
*
* @param s the string representation
* @return the builder
*/
public static Builder fromString(String s) {
HashMap<String, String> config = DataUtils.parseMap(s);
Builder builder = new Builder();
builder.config.putAll(config);
return builder;
}
}
}
/*
* 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.mvstore;
import java.util.HashMap;
import org.h2.mvstore.type.DataTypeFactory;
import org.h2.util.New;
/**
* A builder for an MVStore.
*/
public class MVStoreBuilder {
private final HashMap<String, Object> config = New.hashMap();
/**
* Use the following file name. If the file does not exist, it is
* automatically created.
*
* @param fileName the file name
* @return this
*/
public static MVStoreBuilder fileBased(String fileName) {
return new MVStoreBuilder().fileName(fileName);
}
/**
* Open the store in-memory. In this case, no data may be saved.
*
* @return the store
*/
public static MVStoreBuilder inMemory() {
return new MVStoreBuilder();
}
private MVStoreBuilder set(String key, Object value) {
if (config.containsKey(key)) {
throw DataUtils.illegalArgumentException("Parameter " + config.get(key) + " is already set");
}
config.put(key, value);
return this;
}
private MVStoreBuilder fileName(String fileName) {
return set("fileName", fileName);
}
/**
* Open the file in read-only mode. In this case, a shared lock will be
* acquired to ensure the file is not concurrently opened in write mode.
* <p>
* If this option is not used, the file is locked exclusively.
* <p>
* Please note a store may only be opened once in every JVM (no matter
* whether it is opened in read-only or read-write mode), because each file
* may be locked only once in a process.
*
* @return this
*/
public MVStoreBuilder readOnly() {
return set("openMode", "r");
}
/**
* Set the read cache size in MB. The default is 16 MB.
*
* @param mb the cache size
* @return this
*/
public MVStoreBuilder cacheSizeMB(int mb) {
return set("cacheSize", Integer.toString(mb));
}
/**
* Compress data before writing using the LZF algorithm. This setting only
* affects writes; it is not necessary to enable compression when reading,
* even if compression was enabled when writing.
*
* @return this
*/
public MVStoreBuilder compressData() {
return set("compress", "1");
}
/**
* Use the given data type factory.
*
* @param factory the data type factory
* @return this
*/
public MVStoreBuilder with(DataTypeFactory factory) {
return set("dataTypeFactory", factory);
}
/**
* Open the store.
*
* @return the opened store
*/
public MVStore open() {
MVStore s = new MVStore(config);
s.open();
return s;
}
public String toString() {
return DataUtils.appendMap(new StringBuilder(), config).toString();
}
/**
* Read the configuration from a string.
*
* @param s the string representation
* @return the builder
*/
public static MVStoreBuilder fromString(String s) {
HashMap<String, String> config = DataUtils.parseMap(s);
MVStoreBuilder builder = new MVStoreBuilder();
builder.config.putAll(config);
return builder;
}
}
......@@ -16,7 +16,6 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.message.DbException;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.MVStoreBuilder;
import org.h2.mvstore.type.DataTypeFactory;
import org.h2.table.TableBase;
import org.h2.util.New;
......@@ -47,20 +46,19 @@ public class MVTableEngine implements TableEngine {
public TableBase createTable(CreateTableData data) {
Database db = data.session.getDatabase();
String storeName = db.getDatabasePath();
MVStoreBuilder storeBuilder;
MVStore.Builder builder = new MVStore.Builder();
Store store;
DataTypeFactory f = new ValueDataTypeFactory(db.getCompareMode(), db);
if (storeName == null) {
storeBuilder = MVStoreBuilder.inMemory();
storeBuilder.with(f);
store = new Store(db, storeBuilder.open());
builder.with(f);
store = new Store(db, builder.open());
} else {
synchronized (STORES) {
store = STORES.get(storeName);
if (store == null) {
storeBuilder = MVStoreBuilder.fileBased(storeName + Constants.SUFFIX_MV_FILE);
storeBuilder.with(f);
store = new Store(db, storeBuilder.open());
builder.fileName(storeName + Constants.SUFFIX_MV_FILE);
builder.with(f);
store = new Store(db, builder.open());
STORES.put(storeName, store);
} else if (store.db != db) {
throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, storeName);
......
......@@ -17,7 +17,6 @@ import java.util.Random;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVMapConcurrent;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.MVStoreBuilder;
import org.h2.mvstore.type.ObjectDataTypeFactory;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
......@@ -168,7 +167,7 @@ public class TestConcurrent extends TestMVStore {
}
private void testConcurrentIterate() {
MVStore s = MVStoreBuilder.inMemory().
MVStore s = new MVStore.Builder().
with(new ObjectDataTypeFactory()).open();
s.setPageSize(3);
final MVMap<Integer, Integer> map = s.openMap("test");
......
......@@ -16,7 +16,6 @@ import java.util.TreeMap;
import org.h2.mvstore.Cursor;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.MVStoreBuilder;
import org.h2.mvstore.type.DataType;
import org.h2.mvstore.type.ObjectDataType;
import org.h2.mvstore.type.ObjectDataTypeFactory;
......@@ -106,7 +105,8 @@ public class TestMVStore extends TestBase {
String fileName = getBaseDir() + "/testCacheSize.h3";
MVStore s;
MVMap<Integer, String> map;
s = MVStoreBuilder.fileBased(fileName).
s = new MVStore.Builder().
fileName(fileName).
compressData().
with(new ObjectDataTypeFactory()).open();
map = s.openMap("test");
......@@ -120,7 +120,8 @@ public class TestMVStore extends TestBase {
3408, 2590, 1924, 1440, 1102, 956, 918
};
for (int cacheSize = 0; cacheSize <= 6; cacheSize += 4) {
s = MVStoreBuilder.fileBased(fileName).
s = new MVStore.Builder().
fileName(fileName).
cacheSizeMB(1 + 3 * cacheSize).
with(new ObjectDataTypeFactory()).open();
map = s.openMap("test");
......@@ -139,16 +140,16 @@ public class TestMVStore extends TestBase {
private void testConcurrentOpen() {
String fileName = getBaseDir() + "/testConcurrentOpen.h3";
MVStore s = MVStoreBuilder.fileBased(fileName).open();
MVStore s = new MVStore.Builder().fileName(fileName).open();
try {
MVStore s1 = MVStoreBuilder.fileBased(fileName).open();
MVStore s1 = new MVStore.Builder().fileName(fileName).open();
s1.close();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
MVStore s1 = MVStoreBuilder.fileBased(fileName).readOnly().open();
MVStore s1 = new MVStore.Builder().fileName(fileName).readOnly().open();
s1.close();
fail();
} catch (IllegalStateException e) {
......@@ -351,7 +352,7 @@ public class TestMVStore extends TestBase {
private void testIterateOldVersion() {
MVStore s;
Map<Integer, Integer> map;
s = MVStoreBuilder.inMemory().
s = new MVStore.Builder().
with(new ObjectDataTypeFactory()).open();
map = s.openMap("test");
int len = 100;
......@@ -377,7 +378,7 @@ public class TestMVStore extends TestBase {
FileUtils.delete(fileName);
MVStore s;
Map<Object, Object> map;
s = MVStoreBuilder.fileBased(fileName).
s = new MVStore.Builder().fileName(fileName).
with(new ObjectDataTypeFactory()).open();
map = s.openMap("test");
map.put(1, "Hello");
......@@ -385,7 +386,7 @@ public class TestMVStore extends TestBase {
map.put(new Object[1], new Object[]{1, "2"});
s.store();
s.close();
s = MVStoreBuilder.fileBased(fileName).
s = new MVStore.Builder().fileName(fileName).
with(new ObjectDataTypeFactory()).open();
map = s.openMap("test");
assertEquals("Hello", map.get(1).toString());
......@@ -1133,7 +1134,8 @@ public class TestMVStore extends TestBase {
* @return the store
*/
protected static MVStore openStore(String fileName) {
MVStore store = MVStoreBuilder.fileBased(fileName).
MVStore store = new MVStore.Builder().
fileName(fileName).
with(new SampleTypeFactory()).open();
store.setPageSize(1000);
return store;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论