org.mwg.RocksDBStorage Maven / Gradle / Ivy
package org.mwg;
import org.mwg.utility.Base64;
import org.mwg.plugin.Storage;
import org.mwg.struct.Buffer;
import org.mwg.struct.BufferIterator;
import org.rocksdb.*;
import java.io.File;
public class RocksDBStorage implements Storage {
private Options _options;
private RocksDB _db;
private Graph _graph;
private static final String _connectedError = "PLEASE CONNECT YOUR DATABASE FIRST";
private boolean _isConnected = false;
private final String _storagePath;
public RocksDBStorage(String storagePath) {
RocksDB.loadLibrary();
this._storagePath = storagePath;
}
@Override
public void get(Buffer keys, Callback callback) {
if (!_isConnected) {
throw new RuntimeException(_connectedError);
}
Buffer result = _graph.newBuffer();
BufferIterator it = keys.iterator();
boolean isFirst = true;
while (it.hasNext()) {
Buffer view = it.next();
try {
if (!isFirst) {
result.write(Constants.BUFFER_SEP);
} else {
isFirst = false;
}
byte[] res = _db.get(view.data());
if (res != null) {
result.writeAll(res);
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (callback != null) {
callback.on(result);
}
}
@Override
public void put(Buffer stream, Callback p_callback) {
if (!_isConnected) {
throw new RuntimeException(_connectedError);
}
WriteBatch batch = new WriteBatch();
BufferIterator it = stream.iterator();
while (it.hasNext()) {
Buffer keyView = it.next();
Buffer valueView = it.next();
if (valueView != null) {
batch.put(keyView.data(), valueView.data());
}
}
WriteOptions options = new WriteOptions();
options.setSync(false);
try {
_db.write(options, batch);
if (p_callback != null) {
p_callback.on(true);
}
} catch (RocksDBException e) {
e.printStackTrace();
if (p_callback != null) {
p_callback.on(false);
}
}
}
@Override
public void remove(Buffer keys, Callback callback) {
if (!_isConnected) {
throw new RuntimeException(_connectedError);
}
try {
BufferIterator it = keys.iterator();
while (it.hasNext()) {
Buffer view = it.next();
_db.remove(view.data());
}
if (callback != null) {
callback.on(null);
}
} catch (Exception e) {
e.printStackTrace();
if (callback != null) {
callback.on(false);
}
}
}
@Override
public void disconnect(Callback callback) {
//TODO write the prefix
try {
WriteOptions options = new WriteOptions();
options.sync();
_db.write(options, new WriteBatch());
_db.close();
_options.dispose();
_options = null;
_db = null;
if (callback != null) {
callback.on(true);
}
} catch (Exception e) {
e.printStackTrace();
if (callback != null) {
callback.on(false);
}
}
}
private static final byte[] prefixKey = "prefix".getBytes();
@Override
public void connect(Graph graph, Callback callback) {
if (_isConnected) {
if (callback != null) {
callback.on(null);
}
return;
}
_graph = graph;
//by default activate snappy compression of bytes
_options = new Options()
.setCreateIfMissing(true)
.setCompressionType(CompressionType.SNAPPY_COMPRESSION);
File location = new File(_storagePath);
if (!location.exists()) {
location.mkdirs();
}
File targetDB = new File(location, "data");
targetDB.mkdirs();
try {
_db = RocksDB.open(_options, targetDB.getAbsolutePath());
_isConnected = true;
if (callback != null) {
callback.on(true);
}
} catch (RocksDBException e) {
e.printStackTrace();
if (callback != null) {
callback.on(null);
}
}
}
@Override
public void lock(Callback callback) {
try {
byte[] current = _db.get(prefixKey);
if (current == null) {
current = new String("0").getBytes();
}
Short currentPrefix = Short.parseShort(new String(current));
_db.put(prefixKey, ((currentPrefix + 1) + "").getBytes());
if (callback != null) {
Buffer newBuf = _graph.newBuffer();
Base64.encodeIntToBuffer(currentPrefix,newBuf);
callback.on(newBuf);
}
} catch (RocksDBException e) {
e.printStackTrace();
if (callback != null) {
callback.on(null);
}
}
}
@Override
public void unlock(Buffer previousLock, Callback callback) {
//noop
callback.on(true);
}
}