Jetbrains Xodus とは
IntelliJ IDEAで有名なJetbrains社が開発してる Java 製の KVS データベースらしい。KVS と言うと Memcached とか Redis とかが代表的だけど、あっちが分散 KVS なのに対し、Xodus は Java 版 LevelDB とでもいうべき組み込み型のライブラリ。
特徴としては、最近の RDBMS では一般的になっている MVCC(マルチバージョン コンカレンシー コントロール)とスナップショット分離に対応したトランザクション制御が利用できるという点。
同系統で最近話題にのぼることが高い MapDB よりも速いとのこと。まだ正式版ではないので、本番には使えないし将来的に使い物になるかはわからないけど、使い方だけでもということで。
インストール
現在は Maven Central からは取得できないので、Sonatype のリポジトリから取得が必要(以下は gradle の場合の記載例)。
repositories {
mavenCentral() // for release artifacts
maven { // for snapshot artifacts
url 'https://oss.sonatype.org/content/groups/public'
}
}
dependencies {
compile group: 'org.jetbrains.xodus', name: 'xodus-environment', version: '1.0-SNAPSHOT'
}
使い方
基本的な流れ
基本的な流れは次の通り。いちいちトランザクション制御が入るところが面倒ですが、それ以外は単純。
- ファイルシステムから Environment(RDBMS でいうところのデータベース)を取得
- Environment から Store(RDBMS でいうところのテーブル)を取得
- Store にキーと値のペアを書き込んだり、キーを指定した値を取得したりする
openStore メソッドの第二引数に WITH_DUPLICATES を使うことで値の重複を許すことも可能。
Environment env = Environments.newInstance("./data");
try {
Store store = env.computeInTransaction(tx -> {
return env.openStore("store", StoreConfig.WITHOUT_DUPLICATES, tx);
});
...
} catch (Exception e) {
env.close();
}
値の設定
Store の put メソッドにキーと値を指定する。値は、最終的にバイト列にする必要があるが、逆に言えばバイト列にできれば何でも設定できるということで、エンティティ変換系のユーティリティも用意されている。
env.executeInTransaction(tx -> {
store.put(tx, StringBinding.stringToEntry("key"), StringBinding.stringToEntry("value"));
});
値の取得
Store の get メソッドにキーを指定する。
String result = env.computeInReadonlyTransaction(tx -> {
return StringBinding.entryToString(store.get(tx, StringBinding.stringToEntry("key")));
});
WITH_DUPLICATES で複数値ある場合には、openCursor メソッドを使って Cursor を回す必要がある(キーによる頭出しは可能)ようだ。
List<String> result = env.computeInReadonlyTransaction(tx -> {
List<String> list = new ArrayList<>();
try (Cursor cursor = store.openCursor(tx)) {
String key = "key";
if (cursor.getSearchKey(stringToEntry(key)) != null) {
do {
String ckey = entryToString(cursor.getKey());
if (key.equals(ckey)) {
list.add(entryToString(cursor.getValue()));
} else {
break;
}
} while (cursor.getNext());
}
}
return list;
});
まとめ
Pure Java ライブラリではない場合、マルチスレッド対応が不安になりますが、このライブラリなら安心かも。あとは、正式版が出てくれればというところでしょうか。