Bumped the version and moved plutodb to a separate branch

This commit is contained in:
Tefek 2020-09-04 15:38:12 +02:00
parent 02034d25e9
commit 83f299bd9f
16 changed files with 1 additions and 621 deletions

View File

@ -8,7 +8,7 @@ allprojects {
apply plugin: 'java' apply plugin: 'java'
group = "cz.tefek" group = "cz.tefek"
version = "20.2.0.0-alpha.0" version = "20.2.0.0-alpha.1"
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.encoding = "UTF-8" options.encoding = "UTF-8"

1
plutodb/.gitignore vendored
View File

@ -1 +0,0 @@
/testdb

View File

@ -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"
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -1 +0,0 @@
package cz.tefek.pluto.lmdb;

View File

@ -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);
}
}
}
}

View File

@ -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;
}
}

View File

@ -1,5 +1,4 @@
include 'plutolib', include 'plutolib',
'plutodb',
'plutocommandparser', 'plutocommandparser',
'plutostatic', 'plutostatic',
'plutotexturing', 'plutotexturing',