Bumped the version and moved plutodb to a separate branch
This commit is contained in:
parent
02034d25e9
commit
83f299bd9f
|
@ -8,7 +8,7 @@ allprojects {
|
|||
apply plugin: 'java'
|
||||
|
||||
group = "cz.tefek"
|
||||
version = "20.2.0.0-alpha.0"
|
||||
version = "20.2.0.0-alpha.1"
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
/testdb
|
|
@ -1,12 +0,0 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
description = "A simple wrapper around LDMB."
|
||||
|
||||
dependencies {
|
||||
api project(":plutolib")
|
||||
|
||||
api "org.lwjgl:lwjgl"
|
||||
api "org.lwjgl:lwjgl-lmdb"
|
||||
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-lmdb::$lwjglNatives"
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public interface ILMDBValueRecipe
|
||||
{
|
||||
int sizeOf();
|
||||
|
||||
void serialize(ByteBuffer output);
|
||||
|
||||
void deserialize(ByteBuffer input);
|
||||
|
||||
static int sizeOfUTF8(CharSequence string)
|
||||
{
|
||||
return Integer.BYTES + MemoryUtil.memLengthUTF8(string, false);
|
||||
}
|
||||
|
||||
static void putUTF8(CharSequence string, ByteBuffer output)
|
||||
{
|
||||
int strLen = MemoryUtil.memUTF8(string, false, output, output.position() + Integer.BYTES);
|
||||
output.putInt(strLen);
|
||||
|
||||
output.position(output.position() + strLen);
|
||||
}
|
||||
|
||||
static String getUTF8(ByteBuffer input)
|
||||
{
|
||||
var strLen = input.getInt();
|
||||
var string = MemoryUtil.memUTF8(input, strLen);
|
||||
|
||||
input.position(input.position() + strLen);
|
||||
|
||||
return string;
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.LMDB;
|
||||
import org.lwjgl.util.lmdb.MDBVal;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBDatabase<K extends LMDBKey, V extends ILMDBValueRecipe>
|
||||
{
|
||||
private LMDBTransaction transaction;
|
||||
private int handle;
|
||||
private MethodHandle valueConstructor;
|
||||
|
||||
LMDBDatabase(LMDBTransaction transaction, int handle, Class<V> valueClass) throws NoSuchMethodException, IllegalAccessException
|
||||
{
|
||||
this.handle = handle;
|
||||
this.transaction = transaction;
|
||||
this.valueConstructor = MethodHandles.lookup().findConstructor(valueClass, MethodType.methodType(void.class));
|
||||
}
|
||||
|
||||
public long getHandle()
|
||||
{
|
||||
return this.handle;
|
||||
}
|
||||
|
||||
public void put(K key, V value)
|
||||
{
|
||||
try (var stack = MemoryStack.stackPush())
|
||||
{
|
||||
var keyStruct = key.toMDBVal(stack);
|
||||
|
||||
var size = value.sizeOf();
|
||||
|
||||
var data = stack.malloc(size);
|
||||
|
||||
value.serialize(data);
|
||||
|
||||
data.flip();
|
||||
|
||||
var valueStruct = MDBVal.mallocStack(stack).mv_data(data).mv_size(size);
|
||||
|
||||
int retval = LMDB.mdb_put(this.transaction.getAddress(), this.handle, keyStruct, valueStruct, 0);
|
||||
|
||||
if (retval != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("Error: mdb_put failed with the following error code: %d", retval));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public V get(K key)
|
||||
{
|
||||
try
|
||||
{
|
||||
var valueToUpdate = (V) this.valueConstructor.invoke();
|
||||
return this.get(key, valueToUpdate);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public V get(K key, V valueToUpdate)
|
||||
{
|
||||
try (var stack = MemoryStack.stackPush())
|
||||
{
|
||||
var keyStruct = key.toMDBVal(stack);
|
||||
|
||||
var valueStruct = MDBVal.mallocStack(stack);
|
||||
|
||||
int retval = LMDB.mdb_get(this.transaction.getAddress(), this.handle, keyStruct, valueStruct);
|
||||
|
||||
if (retval != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("Error: mdb_get failed with the following error code: %d", retval));
|
||||
}
|
||||
|
||||
valueToUpdate.deserialize(valueStruct.mv_data());
|
||||
|
||||
return valueToUpdate;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.LMDB;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
@ThreadSafe
|
||||
public class LMDBEnvironment implements AutoCloseable
|
||||
{
|
||||
private static final Set<File> envGuard = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
private final File path;
|
||||
private final long envPtr;
|
||||
private final int maxDBs;
|
||||
private static final int permissions = 0640;
|
||||
|
||||
public LMDBEnvironment(File path, int maxDBs, long mapSize) throws IOException
|
||||
{
|
||||
if (!envGuard.add(path))
|
||||
{
|
||||
throw new RuntimeException("Error: The LMDB Environment guard has detected a creation of an environment on an already locked file. To avoid synchronization issues, this cannot be permitted.");
|
||||
}
|
||||
|
||||
this.path = path;
|
||||
this.maxDBs = maxDBs;
|
||||
|
||||
try (var stack = MemoryStack.stackPush())
|
||||
{
|
||||
var ptrBuf = stack.mallocPointer(1);
|
||||
int createCode = LMDB.mdb_env_create(ptrBuf);
|
||||
|
||||
if (createCode != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("LMDB environment failed to create! Error code: %d", createCode));
|
||||
}
|
||||
|
||||
this.envPtr = ptrBuf.get(0);
|
||||
}
|
||||
|
||||
int mapSizeResult = LMDB.mdb_env_set_mapsize(this.envPtr, mapSize);
|
||||
|
||||
if (mapSizeResult != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("Failed to set the MDB map size! Error code: %d", mapSizeResult));
|
||||
}
|
||||
|
||||
int maxDBsResult = LMDB.mdb_env_set_maxdbs(this.envPtr, this.maxDBs);
|
||||
|
||||
if (maxDBsResult != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("Failed to set the MDB maximum database count! Error code: %d", maxDBsResult));
|
||||
}
|
||||
|
||||
if (!path.isDirectory())
|
||||
{
|
||||
path.mkdirs();
|
||||
}
|
||||
|
||||
int openCode = LMDB.mdb_env_open(this.envPtr, path.getAbsolutePath(), 0, permissions);
|
||||
|
||||
if (openCode != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("LMDB environment failed to open! Error code: %d", openCode));
|
||||
}
|
||||
}
|
||||
|
||||
public LMDBTransaction createTransaction()
|
||||
{
|
||||
return this.createTransaction(false);
|
||||
}
|
||||
|
||||
public synchronized LMDBTransaction createTransaction(boolean readOnly)
|
||||
{
|
||||
try (var stack = MemoryStack.stackPush())
|
||||
{
|
||||
var ptrBuf = stack.mallocPointer(1);
|
||||
|
||||
int code = LMDB.mdb_txn_begin(this.envPtr, 0, readOnly ? LMDB.MDB_RDONLY : 0, ptrBuf);
|
||||
|
||||
if (code != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
String errStr;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case LMDB.MDB_PANIC:
|
||||
errStr = "MDB_PANIC";
|
||||
break;
|
||||
|
||||
case LMDB.MDB_MAP_RESIZED:
|
||||
errStr = "MDB_MAP_RESIZED";
|
||||
break;
|
||||
|
||||
case LMDB.MDB_READERS_FULL:
|
||||
errStr = "MDB_READERS_FULL";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException(String.format("Failed to create a transaction. Error code: %d", code));
|
||||
}
|
||||
|
||||
throw new RuntimeException(String.format("Failed to create a transaction. Error code: %s", errStr));
|
||||
}
|
||||
|
||||
long ptr = ptrBuf.get(0);
|
||||
|
||||
return new LMDBTransaction(this, ptr, readOnly);
|
||||
}
|
||||
}
|
||||
|
||||
public long getAddress()
|
||||
{
|
||||
return this.envPtr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
LMDB.mdb_env_close(this.envPtr);
|
||||
envGuard.remove(this.path);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.MDBVal;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBIntegerKey extends LMDBKey
|
||||
{
|
||||
private final int key;
|
||||
|
||||
private LMDBIntegerKey(int key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static LMDBIntegerKey from(int rawKey)
|
||||
{
|
||||
return new LMDBIntegerKey(rawKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MDBVal toMDBVal(MemoryStack stack)
|
||||
{
|
||||
var keyBuf = stack.malloc(Integer.BYTES);
|
||||
|
||||
keyBuf.putInt(this.key);
|
||||
|
||||
return MDBVal.mallocStack(stack).mv_size(keyBuf.capacity()).mv_data(keyBuf);
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.MDBVal;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public abstract class LMDBKey
|
||||
{
|
||||
public abstract MDBVal toMDBVal(MemoryStack stack);
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.MDBVal;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBLongKey extends LMDBKey
|
||||
{
|
||||
private final long key;
|
||||
|
||||
private LMDBLongKey(long key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static LMDBLongKey from(long rawKey)
|
||||
{
|
||||
return new LMDBLongKey(rawKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MDBVal toMDBVal(MemoryStack stack)
|
||||
{
|
||||
var keyBuf = stack.malloc(Long.BYTES);
|
||||
|
||||
keyBuf.putLong(this.key);
|
||||
|
||||
return MDBVal.mallocStack(stack).mv_size(keyBuf.capacity()).mv_data(keyBuf);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBSchema<K extends LMDBKey, E extends ILMDBValueRecipe>
|
||||
{
|
||||
private String name;
|
||||
private Class<E> valueType;
|
||||
|
||||
public LMDBSchema(String name, Class<E> valueType)
|
||||
{
|
||||
this.name = name;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Class<E> getValueRecipe()
|
||||
{
|
||||
return this.valueType;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.MDBVal;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBStringKey extends LMDBKey
|
||||
{
|
||||
private final String key;
|
||||
|
||||
private LMDBStringKey(String key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static LMDBStringKey from(String rawKey)
|
||||
{
|
||||
return new LMDBStringKey(rawKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MDBVal toMDBVal(MemoryStack stack)
|
||||
{
|
||||
var keyBuf = stack.ASCII(this.key, false);
|
||||
|
||||
return MDBVal.mallocStack(stack).mv_size(keyBuf.capacity()).mv_data(keyBuf);
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.lmdb.LMDB;
|
||||
|
||||
/**
|
||||
* @deprecated Usage discouraged until tested well enough.
|
||||
* */
|
||||
@Deprecated
|
||||
public class LMDBTransaction implements AutoCloseable
|
||||
{
|
||||
private long ptr;
|
||||
private LMDBEnvironment env;
|
||||
private boolean readOnly;
|
||||
private boolean uncommited = true;
|
||||
|
||||
LMDBTransaction(LMDBEnvironment env, long ptr, boolean readOnly)
|
||||
{
|
||||
this.env = env;
|
||||
this.ptr = ptr;
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public long getAddress()
|
||||
{
|
||||
return this.ptr;
|
||||
}
|
||||
|
||||
public LMDBEnvironment getEnvironment()
|
||||
{
|
||||
return this.env;
|
||||
}
|
||||
|
||||
public boolean isReadOnly()
|
||||
{
|
||||
return this.readOnly;
|
||||
}
|
||||
|
||||
private int getDatabase(String name)
|
||||
{
|
||||
try (var stack = MemoryStack.stackPush())
|
||||
{
|
||||
var intPtr = stack.mallocInt(1);
|
||||
|
||||
int createFlag = this.readOnly ? 0 : LMDB.MDB_CREATE;
|
||||
|
||||
int returnCode = LMDB.mdb_dbi_open(this.ptr, name, createFlag, intPtr);
|
||||
|
||||
if (returnCode != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
switch (returnCode)
|
||||
{
|
||||
case LMDB.MDB_DBS_FULL:
|
||||
throw new RuntimeException("Error: mdb_dbi_open failed with the following error: DBS_FULL (too many open databases)");
|
||||
|
||||
case LMDB.MDB_NOTFOUND:
|
||||
throw new RuntimeException("Error: mdb_dbi_open failed with the following error: NOTFOUND (database was not found)");
|
||||
|
||||
default:
|
||||
throw new RuntimeException(String.format("Error: mdb_dbi_open failed with the following error code: %d", returnCode));
|
||||
}
|
||||
}
|
||||
|
||||
int dbHandle = intPtr.get(0);
|
||||
|
||||
return dbHandle;
|
||||
}
|
||||
}
|
||||
|
||||
public <K extends LMDBKey, V extends ILMDBValueRecipe> LMDBDatabase<K, V> getDatabase(LMDBSchema<K, V> schema)
|
||||
{
|
||||
var dbHandle = this.getDatabase(schema.getName());
|
||||
|
||||
var recipeClazz = schema.getValueRecipe();
|
||||
|
||||
try
|
||||
{
|
||||
return new LMDBDatabase<K, V>(this, dbHandle, recipeClazz);
|
||||
}
|
||||
catch (NoSuchMethodException | IllegalAccessException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void commit()
|
||||
{
|
||||
int returnCode = LMDB.mdb_txn_commit(this.ptr);
|
||||
|
||||
if (returnCode != LMDB.MDB_SUCCESS)
|
||||
{
|
||||
throw new RuntimeException(String.format("Error: mdb_txn_commit failed with the following error code: %d", returnCode));
|
||||
}
|
||||
|
||||
this.uncommited = false;
|
||||
}
|
||||
|
||||
public void abort()
|
||||
{
|
||||
LMDB.mdb_txn_abort(this.ptr);
|
||||
this.uncommited = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
if (this.readOnly || this.uncommited)
|
||||
{
|
||||
this.abort();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package cz.tefek.pluto.lmdb;
|
|
@ -1,43 +0,0 @@
|
|||
package cz.tefek.test.plutodb;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import cz.tefek.pluto.lmdb.LMDBEnvironment;
|
||||
import cz.tefek.pluto.lmdb.LMDBSchema;
|
||||
import cz.tefek.pluto.lmdb.LMDBStringKey;
|
||||
|
||||
public class LMDBTest
|
||||
{
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
var userSchema = new LMDBSchema<LMDBStringKey, UserData>("users", UserData.class);
|
||||
|
||||
try (var env = new LMDBEnvironment(new File("testdb"), 80, 1024 * 1024 * 256))
|
||||
{
|
||||
try (var txn = env.createTransaction())
|
||||
{
|
||||
var db = txn.getDatabase(userSchema);
|
||||
|
||||
var data = new UserData();
|
||||
data.money = -789;
|
||||
data.keks = 123456;
|
||||
data.text = "Hello world!";
|
||||
data.keys = 0x12C0FFEE;
|
||||
|
||||
db.put(LMDBStringKey.from("pepega"), data);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
try (var txn = env.createTransaction(true))
|
||||
{
|
||||
var db = txn.getDatabase(userSchema);
|
||||
|
||||
var data = db.get(LMDBStringKey.from("pepega"));
|
||||
|
||||
System.out.println(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package cz.tefek.test.plutodb;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import cz.tefek.pluto.lmdb.ILMDBValueRecipe;
|
||||
|
||||
public class UserData implements ILMDBValueRecipe
|
||||
{
|
||||
public long money;
|
||||
public long keks;
|
||||
public String text;
|
||||
public int keys;
|
||||
|
||||
@Override
|
||||
public void serialize(ByteBuffer output)
|
||||
{
|
||||
output.putLong(this.money);
|
||||
output.putLong(this.keks);
|
||||
ILMDBValueRecipe.putUTF8(this.text, output);
|
||||
output.putInt(this.keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(ByteBuffer input)
|
||||
{
|
||||
this.money = input.getLong();
|
||||
this.keks = input.getLong();
|
||||
this.text = ILMDBValueRecipe.getUTF8(input);
|
||||
this.keys = input.getInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "UserData [money=" + this.money + ", keks=" + this.keks + ", text=" + this.text + ", keys=" + this.keys + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sizeOf()
|
||||
{
|
||||
return Long.BYTES + Long.BYTES + ILMDBValueRecipe.sizeOfUTF8(this.text) + Integer.BYTES;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
include 'plutolib',
|
||||
'plutodb',
|
||||
'plutocommandparser',
|
||||
'plutostatic',
|
||||
'plutotexturing',
|
||||
|
|
Loading…
Reference in New Issue