Add thrift API, add datagen serialization

This commit is contained in:
Andrea Cavalli 2024-03-28 23:52:26 +01:00
parent b86540e192
commit b326a2f981
36 changed files with 25667 additions and 577 deletions

2
generate-api.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash -e
thrift -r --gen java:generated_annotations=suppress -out src/main/java src/main/resources/it/cavallium/rockserver/core/resources/rocksdb.thrift

70
pom.xml
View File

@ -9,8 +9,8 @@
<version>1.0.0-SNAPSHOT</version> <version>1.0.0-SNAPSHOT</version>
<properties> <properties>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>22</maven.compiler.target>
<native.maven.plugin.version>0.9.28</native.maven.plugin.version> <native.maven.plugin.version>0.9.28</native.maven.plugin.version>
<gestalt.version>0.25.3</gestalt.version> <gestalt.version>0.25.3</gestalt.version>
<rocksdb.version>9.0.0</rocksdb.version> <rocksdb.version>9.0.0</rocksdb.version>
@ -18,6 +18,32 @@
<mainClass>it.cavallium.rockserver.core.Main</mainClass> <mainClass>it.cavallium.rockserver.core.Main</mainClass>
</properties> </properties>
<repositories>
<repository>
<id>sonatype-snapshot</id>
<name>Sonatype OSS Snapshots</name>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-bom</artifactId>
<version>5.0.0.Alpha6-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.rocksdb</groupId> <groupId>org.rocksdb</groupId>
@ -31,8 +57,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.unimi.dsi</groupId> <groupId>it.unimi.dsi</groupId>
<artifactId>fastutil-core</artifactId> <artifactId>fastutil</artifactId>
<version>8.5.12</version> <version>8.5.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.seancfoley</groupId> <groupId>com.github.seancfoley</groupId>
@ -60,6 +86,27 @@
<artifactId>gestalt-hocon</artifactId> <artifactId>gestalt-hocon</artifactId>
<version>${gestalt.version}</version> <version>${gestalt.version}</version>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-buffer</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-codec-http2</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-transport-native-io_uring</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-transport-classes-io_uring</artifactId>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.20.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.lz4</groupId> <groupId>org.lz4</groupId>
@ -99,9 +146,6 @@
</goals> </goals>
<configuration> <configuration>
<mainClass>it.cavallium.rockserver.core.Main</mainClass> <mainClass>it.cavallium.rockserver.core.Main</mainClass>
<arguments>
<argument>--enable-preview</argument>
</arguments>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
@ -113,23 +157,13 @@
<configuration> <configuration>
<source>${maven.compiler.source}</source> <source>${maven.compiler.source}</source>
<target>${maven.compiler.source}</target> <target>${maven.compiler.source}</target>
<enablePreview>true</enablePreview>
<compilerArgs>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-failsafe-plugin</artifactId> <artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -209,7 +243,6 @@
<buildArg>-march=native</buildArg> <buildArg>-march=native</buildArg>
<buildArg>-H:IncludeResourceBundles=net.sourceforge.argparse4j.internal.ArgumentParserImpl</buildArg> <buildArg>-H:IncludeResourceBundles=net.sourceforge.argparse4j.internal.ArgumentParserImpl</buildArg>
<buildArg>-O1</buildArg> <buildArg>-O1</buildArg>
<buildArg>--enable-preview</buildArg>
<buildArg>-H:+StaticExecutableWithDynamicLibC</buildArg> <buildArg>-H:+StaticExecutableWithDynamicLibC</buildArg>
<buildArg>-H:+JNI</buildArg> <buildArg>-H:+JNI</buildArg>
<buildArg>-H:IncludeResources=librocksdbjni-linux64.so</buildArg> <buildArg>-H:IncludeResources=librocksdbjni-linux64.so</buildArg>
@ -235,7 +268,6 @@
<executable>java</executable> <executable>java</executable>
<workingDirectory>${project.build.directory}</workingDirectory> <workingDirectory>${project.build.directory}</workingDirectory>
<arguments> <arguments>
<argument>--enable-preview</argument>
<argument>-classpath</argument> <argument>-classpath</argument>
<classpath/> <classpath/>
<argument>${mainClass}</argument> <argument>${mainClass}</argument>

View File

@ -27,10 +27,14 @@ public class Main {
ArgumentParser parser = ArgumentParsers.newFor("rockserver-core").build() ArgumentParser parser = ArgumentParsers.newFor("rockserver-core").build()
.defaultHelp(true) .defaultHelp(true)
.description("RocksDB server core"); .description("RocksDB server core");
parser.addArgument("-u", "--url") parser.addArgument("-u", "--database-url")
.type(String.class) .type(String.class)
.setDefault(PRIVATE_MEMORY_URL.toString()) .setDefault(PRIVATE_MEMORY_URL.toString())
.help("Specify database rocksdb://hostname:port, or unix://<path>, or file://<path>"); .help("Specify database rocksdb://hostname:port, or unix://<path>, or file://<path>");
parser.addArgument("-l", "--listen-url")
.type(String.class)
.setDefault("http://127.0.0.1:5332")
.help("Specify database http://hostname:port, or unix://<path>, or file://<path>");
parser.addArgument("-n", "--name") parser.addArgument("-n", "--name")
.type(String.class) .type(String.class)
.setDefault("main") .setDefault("main")
@ -50,6 +54,7 @@ public class Main {
System.exit(1); System.exit(1);
} }
var clientBuilder = new it.cavallium.rockserver.core.client.ClientBuilder(); var clientBuilder = new it.cavallium.rockserver.core.client.ClientBuilder();
var serverBuilder = new it.cavallium.rockserver.core.server.ServerBuilder();
if (ns.getBoolean("print_default_config")) { if (ns.getBoolean("print_default_config")) {
requireNonNull(Main.class.getClassLoader() requireNonNull(Main.class.getClassLoader()
@ -62,14 +67,16 @@ public class Main {
LOG.info("Starting..."); LOG.info("Starting...");
RocksDBLoader.loadLibrary(); RocksDBLoader.loadLibrary();
var rawUrl = ns.getString("url"); var rawDatabaseUrl = ns.getString("database_url");
var rawListenUrl = ns.getString("listen_url");
var name = ns.getString("name"); var name = ns.getString("name");
var config = ns.getString("config"); var config = ns.getString("config");
var url = new URI(rawUrl); var databaseUrl = new URI(rawDatabaseUrl);
var listenUrl = new URI(rawListenUrl);
if (config != null) { if (config != null) {
if (!url.getScheme().equals("file")) { if (!databaseUrl.getScheme().equals("file")) {
System.err.println("Do not set --config if the database is not local!"); System.err.println("Do not set --config if the database is not local!");
System.exit(1); System.exit(1);
return; return;
@ -78,20 +85,36 @@ public class Main {
} }
} }
switch (url.getScheme()) { switch (databaseUrl.getScheme()) {
case "unix" -> clientBuilder.setUnixSocket(UnixDomainSocketAddress.of(Path.of(url.getPath()))); case "unix" -> clientBuilder.setUnixSocket(UnixDomainSocketAddress.of(Path.of(databaseUrl.getPath())));
case "file" -> clientBuilder.setEmbeddedPath(Path.of((url.getAuthority() != null ? url.getAuthority() : "") + url.getPath()).normalize()); case "file" -> clientBuilder.setEmbeddedPath(Path.of((databaseUrl.getAuthority() != null ? databaseUrl.getAuthority() : "") + databaseUrl.getPath()).normalize());
case "memory" -> clientBuilder.setEmbeddedInMemory(true); case "memory" -> clientBuilder.setEmbeddedInMemory(true);
case "rocksdb" -> clientBuilder.setAddress(new HostName(url.getHost()).asInetSocketAddress()); case "rocksdb" -> clientBuilder.setAddress(new HostName(databaseUrl.getHost()).asInetSocketAddress());
default -> throw new IllegalArgumentException("Invalid scheme: " + url.getScheme()); default -> throw new IllegalArgumentException("Invalid scheme: " + databaseUrl.getScheme());
}
switch (listenUrl.getScheme()) {
case "unix" -> serverBuilder.setUnixSocket(UnixDomainSocketAddress.of(Path.of(listenUrl.getPath())));
case "http" -> serverBuilder.setHttpAddress(listenUrl.getHost(), listenUrl.getPort());
case "rocksdb" -> serverBuilder.setAddress(new HostName(listenUrl.getHost()).asInetSocketAddress());
default -> throw new IllegalArgumentException("Invalid scheme: " + listenUrl.getScheme());
} }
clientBuilder.setName(name); clientBuilder.setName(name);
try (var connection = clientBuilder.build()) { try (var connection = clientBuilder.build()) {
LOG.log(Level.INFO, "Connected to {0}", connection); LOG.log(Level.INFO, "Connected to {0}", connection);
serverBuilder.setClient(connection);
CountDownLatch shutdownLatch = new CountDownLatch(1); CountDownLatch shutdownLatch = new CountDownLatch(1);
Runtime.getRuntime().addShutdownHook(new Thread(shutdownLatch::countDown)); Runtime.getRuntime().addShutdownHook(new Thread(shutdownLatch::countDown));
LOG.info("Shutting down...");
try (var server = serverBuilder.build()) {
shutdownLatch.await();
LOG.info("Shutting down...");
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted", e);
} }
LOG.info("Shut down successfully"); LOG.info("Shut down successfully");
} }

View File

@ -1,5 +1,6 @@
package it.cavallium.rockserver.core.client; package it.cavallium.rockserver.core.client;
import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.UnixDomainSocketAddress; import java.net.UnixDomainSocketAddress;
import java.nio.file.Path; import java.nio.file.Path;
@ -37,15 +38,15 @@ public class ClientBuilder {
this.embeddedConfig = embeddedConfig; this.embeddedConfig = embeddedConfig;
} }
public RocksDBConnection build() { public RocksDBConnection build() throws IOException {
if (embeddedInMemory) { if (embeddedInMemory) {
return new EmbeddedConnection(null, name, embeddedConfig); return new EmbeddedConnection(null, name, embeddedConfig);
} else if (embeddedPath != null) { } else if (embeddedPath != null) {
return new EmbeddedConnection(embeddedPath, name, embeddedConfig); return new EmbeddedConnection(embeddedPath, name, embeddedConfig);
} else if (unixAddress != null) { } else if (unixAddress != null) {
return new SocketConnectionUnix(unixAddress, name); throw new UnsupportedOperationException("Not implemented: unix socket");
} else if (iNetAddress != null) { } else if (iNetAddress != null) {
return new SocketConnectionInet(iNetAddress, name); throw new UnsupportedOperationException("Not implemented: inet address");
} else { } else {
throw new UnsupportedOperationException("Please set a connection type"); throw new UnsupportedOperationException("Please set a connection type");
} }

View File

@ -1,10 +1,14 @@
package it.cavallium.rockserver.core.client; package it.cavallium.rockserver.core.client;
import it.cavallium.rockserver.core.common.Callback.GetCallback; import it.cavallium.rockserver.core.common.RequestType;
import it.cavallium.rockserver.core.common.Callback.IteratorCallback; import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.Callback.PutCallback; import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.ColumnSchema; import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.RocksDBAPI;
import it.cavallium.rockserver.core.common.RocksDBAPICommand;
import it.cavallium.rockserver.core.common.RocksDBAsyncAPI;
import it.cavallium.rockserver.core.common.RocksDBException; import it.cavallium.rockserver.core.common.RocksDBException;
import it.cavallium.rockserver.core.common.RocksDBSyncAPI;
import it.cavallium.rockserver.core.impl.EmbeddedDB; import it.cavallium.rockserver.core.impl.EmbeddedDB;
import java.io.IOException; import java.io.IOException;
import java.lang.foreign.Arena; import java.lang.foreign.Arena;
@ -13,10 +17,11 @@ import java.net.URI;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletionStage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class EmbeddedConnection extends BaseConnection { public class EmbeddedConnection extends BaseConnection implements RocksDBAPI {
private final EmbeddedDB db; private final EmbeddedDB db;
public static final URI PRIVATE_MEMORY_URL = URI.create("memory://private"); public static final URI PRIVATE_MEMORY_URL = URI.create("memory://private");
@ -37,6 +42,16 @@ public class EmbeddedConnection extends BaseConnection {
return Optional.ofNullable(db.getPath()).map(Path::toUri).orElse(PRIVATE_MEMORY_URL); return Optional.ofNullable(db.getPath()).map(Path::toUri).orElse(PRIVATE_MEMORY_URL);
} }
@Override
public RocksDBSyncAPI getSyncApi() {
return this;
}
@Override
public RocksDBAsyncAPI getAsyncApi() {
return this;
}
@Override @Override
public long openTransaction(long timeoutMs) { public long openTransaction(long timeoutMs) {
return db.openTransaction(timeoutMs); return db.openTransaction(timeoutMs);
@ -67,14 +82,24 @@ public class EmbeddedConnection extends BaseConnection {
return db.getColumnId(name); return db.getColumnId(name);
} }
@Override
public <R> R requestSync(RocksDBAPICommand<R> req) {
return req.handleSync(this);
}
@Override
public <R> CompletionStage<R> requestAsync(RocksDBAPICommand<R> req) {
return req.handleAsync(this);
}
@Override @Override
public <T> T put(Arena arena, public <T> T put(Arena arena,
long transactionOrUpdateId, long transactionOrUpdateId,
long columnId, long columnId,
@NotNull MemorySegment @NotNull [] keys, @NotNull MemorySegment @NotNull [] keys,
@NotNull MemorySegment value, @NotNull MemorySegment value,
PutCallback<? super MemorySegment, T> callback) throws RocksDBException { RequestPut<? super MemorySegment, T> requestType) throws RocksDBException {
return db.put(arena, transactionOrUpdateId, columnId, keys, value, callback); return db.put(arena, transactionOrUpdateId, columnId, keys, value, requestType);
} }
@Override @Override
@ -82,8 +107,8 @@ public class EmbeddedConnection extends BaseConnection {
long transactionOrUpdateId, long transactionOrUpdateId,
long columnId, long columnId,
MemorySegment @NotNull [] keys, MemorySegment @NotNull [] keys,
GetCallback<? super MemorySegment, T> callback) throws RocksDBException { RequestGet<? super MemorySegment, T> requestType) throws RocksDBException {
return db.get(arena, transactionOrUpdateId, columnId, keys, callback); return db.get(arena, transactionOrUpdateId, columnId, keys, requestType);
} }
@Override @Override
@ -112,7 +137,7 @@ public class EmbeddedConnection extends BaseConnection {
long iterationId, long iterationId,
long skipCount, long skipCount,
long takeCount, long takeCount,
@NotNull IteratorCallback<? super MemorySegment, T> callback) throws RocksDBException { @NotNull RequestType.RequestIterate<? super MemorySegment, T> requestType) throws RocksDBException {
return db.subsequent(arena, iterationId, skipCount, takeCount, callback); return db.subsequent(arena, iterationId, skipCount, takeCount, requestType);
} }
} }

View File

@ -1,10 +1,11 @@
package it.cavallium.rockserver.core.client; package it.cavallium.rockserver.core.client;
import it.cavallium.rockserver.core.common.RocksDBAPI; import it.cavallium.rockserver.core.common.RocksDBAsyncAPI;
import it.cavallium.rockserver.core.common.RocksDBSyncAPI;
import java.io.Closeable; import java.io.Closeable;
import java.net.URI; import java.net.URI;
public interface RocksDBConnection extends Closeable, RocksDBAPI { public interface RocksDBConnection extends Closeable {
/** /**
* Get connection url * Get connection url
@ -12,4 +13,8 @@ public interface RocksDBConnection extends Closeable, RocksDBAPI {
* @return connection url * @return connection url
*/ */
URI getUrl(); URI getUrl();
RocksDBSyncAPI getSyncApi();
RocksDBAsyncAPI getAsyncApi();
} }

View File

@ -1,109 +0,0 @@
package it.cavallium.rockserver.core.client;
import it.cavallium.rockserver.core.common.Callback.GetCallback;
import it.cavallium.rockserver.core.common.Callback.IteratorCallback;
import it.cavallium.rockserver.core.common.Callback.PutCallback;
import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.RocksDBException;
import java.io.IOException;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.net.SocketAddress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class SocketConnection extends BaseConnection {
private final SocketAddress address;
public SocketConnection(SocketAddress address, String name) {
super(name);
this.address = address;
}
public SocketAddress getAddress() {
return address;
}
@Override
public void close() throws IOException {
super.close();
}
@Override
public long openTransaction(long timeoutMs) {
throw new UnsupportedOperationException();
}
@Override
public boolean closeTransaction(long transactionId, boolean commit) {
throw new UnsupportedOperationException();
}
@Override
public void closeFailedUpdate(long updateId) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public long createColumn(String name, @NotNull ColumnSchema schema) {
throw new UnsupportedOperationException();
}
@Override
public void deleteColumn(long columnId) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public long getColumnId(@NotNull String name) {
throw new UnsupportedOperationException();
}
@Override
public <T> T put(Arena arena,
long transactionOrUpdateId,
long columnId,
MemorySegment @NotNull [] keys,
@NotNull MemorySegment value,
PutCallback<? super MemorySegment, T> callback) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public <T> T get(Arena arena,
long transactionOrUpdateId,
long columnId,
MemorySegment @NotNull [] keys,
GetCallback<? super MemorySegment, T> callback) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public long openIterator(Arena arena,
long transactionId,
long columnId,
MemorySegment @NotNull [] startKeysInclusive,
@Nullable MemorySegment[] endKeysExclusive,
boolean reverse,
long timeoutMs) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public void closeIterator(long iteratorId) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public void seekTo(Arena arena, long iterationId, MemorySegment @NotNull [] keys) throws RocksDBException {
throw new UnsupportedOperationException();
}
@Override
public <T> T subsequent(Arena arena,
long iterationId,
long skipCount,
long takeCount,
@NotNull IteratorCallback<? super MemorySegment, T> callback) throws RocksDBException {
throw new UnsupportedOperationException();
}
}

View File

@ -1,22 +0,0 @@
package it.cavallium.rockserver.core.client;
import java.net.InetSocketAddress;
import java.net.URI;
public class SocketConnectionInet extends SocketConnection {
public SocketConnectionInet(InetSocketAddress address, String name) {
super(address, name);
}
@Override
public InetSocketAddress getAddress() {
return (InetSocketAddress) super.getAddress();
}
@Override
public URI getUrl() {
return URI.create("rocksdb://" + getAddress().getHostString());
}
}

View File

@ -1,29 +0,0 @@
package it.cavallium.rockserver.core.client;
import java.io.IOException;
import java.net.URI;
import java.net.UnixDomainSocketAddress;
import java.nio.file.Files;
public class SocketConnectionUnix extends SocketConnection {
public SocketConnectionUnix(UnixDomainSocketAddress address, String name) {
super(address, name);
}
@Override
public UnixDomainSocketAddress getAddress() {
return (UnixDomainSocketAddress) super.getAddress();
}
@Override
public void close() throws IOException {
super.close();
Files.deleteIfExists(getAddress().getPath());
}
@Override
public URI getUrl() {
return URI.create("unix://" + getAddress().getPath());
}
}

View File

@ -1,128 +0,0 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.common.Callback.CallbackForUpdate;
import it.cavallium.rockserver.core.common.Callback.CallbackPreviousPresence;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public sealed interface Callback<METHOD_DATA_TYPE, RESULT_TYPE> {
static boolean requiresGettingPreviousValue(PutCallback<?, ?> callback) {
return callback instanceof CallbackPrevious<?>
|| callback instanceof CallbackDelta<?>
|| callback instanceof CallbackChanged;
}
static boolean requiresGettingPreviousPresence(PutCallback<?, ?> callback) {
return callback instanceof Callback.CallbackPreviousPresence<?>;
}
static boolean requiresGettingCurrentValue(GetCallback<?, ?> callback) {
return callback instanceof CallbackCurrent<?>
|| callback instanceof Callback.CallbackForUpdate<?>;
}
static <U> U safeCast(Object previousValue) {
//noinspection unchecked
return (U) previousValue;
}
@SuppressWarnings("unchecked")
static <T> CallbackPrevious<T> previous() {
return (CallbackPrevious<T>) CallbackPrevious.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackCurrent<T> current() {
return (CallbackCurrent<T>) CallbackCurrent.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackForUpdate<T> forUpdate() {
return (CallbackForUpdate<T>) CallbackForUpdate.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackDelta<T> delta() {
return (CallbackDelta<T>) CallbackDelta.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackExists<T> exists() {
return (CallbackExists<T>) CallbackExists.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackMulti<T> multi() {
return (CallbackMulti<T>) CallbackMulti.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackChanged<T> changed() {
return (CallbackChanged<T>) CallbackChanged.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackPreviousPresence<T> previousPresence() {
return (CallbackPreviousPresence<T>) CallbackPreviousPresence.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> CallbackVoid<T> none() {
return (CallbackVoid<T>) CallbackVoid.INSTANCE;
}
sealed interface PutCallback<T, U> extends Callback<T, U> {}
sealed interface PatchCallback<T, U> extends Callback<T, U> {}
sealed interface GetCallback<T, U> extends Callback<T, U> {}
sealed interface IteratorCallback<T, U> extends Callback<T, U> {}
record CallbackVoid<T>() implements PutCallback<T, Void>, PatchCallback<T, Void>, IteratorCallback<T, Void>, GetCallback<T, Void> {
private static final CallbackVoid<Object> INSTANCE = new CallbackVoid<>();
}
record CallbackPrevious<T>() implements PutCallback<T, @Nullable T> {
private static final CallbackPrevious<Object> INSTANCE = new CallbackPrevious<>();
}
record CallbackCurrent<T>() implements GetCallback<T, @Nullable T> {
private static final CallbackCurrent<Object> INSTANCE = new CallbackCurrent<>();
}
record CallbackForUpdate<T>() implements GetCallback<T, @NotNull UpdateContext<@Nullable T>> {
private static final CallbackForUpdate<Object> INSTANCE = new CallbackForUpdate<>();
}
record CallbackExists<T>() implements GetCallback<T, Boolean>, IteratorCallback<T, Boolean> {
private static final CallbackExists<Object> INSTANCE = new CallbackExists<>();
}
record CallbackDelta<T>() implements PutCallback<T, Delta<T>> {
private static final CallbackDelta<Object> INSTANCE = new CallbackDelta<>();
}
record CallbackMulti<M>() implements IteratorCallback<M, List<M>> {
private static final CallbackMulti<Object> INSTANCE = new CallbackMulti<>();
}
record CallbackChanged<T>() implements PutCallback<T, Boolean>, PatchCallback<T, Boolean> {
private static final CallbackChanged<Object> INSTANCE = new CallbackChanged<>();
}
record CallbackPreviousPresence<T>() implements PutCallback<T, Boolean>, PatchCallback<T, Boolean> {
private static final CallbackPreviousPresence<Object> INSTANCE = new CallbackPreviousPresence<>();
}
}

View File

@ -0,0 +1,197 @@
package it.cavallium.rockserver.core.common;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public sealed interface RequestType<METHOD_DATA_TYPE, RESULT_TYPE> {
@SuppressWarnings("rawtypes")
enum RequestTypeId {
NOTHING(new RequestNothing()),
PREVIOUS(new RequestPrevious()),
CURRENT(new RequestCurrent()),
FOR_UPDATE(new RequestForUpdate()),
EXISTS(new RequestExists()),
DELTA(new RequestDelta()),
MULTI(new RequestMulti()),
CHANGED(new RequestChanged()),
PREVIOUS_PRESENCE(new RequestPreviousPresence());
private final RequestType requestType;
RequestTypeId(RequestType requestType) {
this.requestType = requestType;
}
public RequestType<?, ?> getRequestType() {
return requestType;
}
}
RequestTypeId getRequestTypeId();
static boolean requiresGettingPreviousValue(RequestPut<?, ?> requestType) {
return requestType instanceof RequestType.RequestPrevious<?>
|| requestType instanceof RequestType.RequestDelta<?>
|| requestType instanceof RequestType.RequestChanged;
}
static boolean requiresGettingPreviousPresence(RequestPut<?, ?> requestType) {
return requestType instanceof RequestType.RequestPreviousPresence<?>;
}
static boolean requiresGettingCurrentValue(RequestGet<?, ?> requestType) {
return requestType instanceof RequestType.RequestCurrent<?>
|| requestType instanceof RequestType.RequestForUpdate<?>;
}
static <U> U safeCast(Object previousValue) {
//noinspection unchecked
return (U) previousValue;
}
@SuppressWarnings("unchecked")
static <T> RequestPrevious<T> previous() {
return (RequestPrevious<T>) RequestPrevious.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestCurrent<T> current() {
return (RequestCurrent<T>) RequestCurrent.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestForUpdate<T> forUpdate() {
return (RequestForUpdate<T>) RequestForUpdate.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestDelta<T> delta() {
return (RequestDelta<T>) RequestDelta.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestExists<T> exists() {
return (RequestExists<T>) RequestExists.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestMulti<T> multi() {
return (RequestMulti<T>) RequestMulti.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestChanged<T> changed() {
return (RequestChanged<T>) RequestChanged.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestPreviousPresence<T> previousPresence() {
return (RequestPreviousPresence<T>) RequestPreviousPresence.INSTANCE;
}
@SuppressWarnings("unchecked")
static <T> RequestNothing<T> none() {
return (RequestNothing<T>) RequestNothing.INSTANCE;
}
sealed interface RequestPut<T, U> extends RequestType<T, U> {}
sealed interface RequestPatch<T, U> extends RequestType<T, U> {}
sealed interface RequestGet<T, U> extends RequestType<T, U> {}
sealed interface RequestIterate<T, U> extends RequestType<T, U> {}
record RequestNothing<T>() implements RequestPut<T, Void>, RequestPatch<T, Void>, RequestIterate<T, Void>,
RequestGet<T, Void> {
private static final RequestNothing<Object> INSTANCE = new RequestNothing<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.NOTHING;
}
}
record RequestPrevious<T>() implements RequestPut<T, @Nullable T> {
private static final RequestPrevious<Object> INSTANCE = new RequestPrevious<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.PREVIOUS;
}
}
record RequestCurrent<T>() implements RequestGet<T, @Nullable T> {
private static final RequestCurrent<Object> INSTANCE = new RequestCurrent<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.CURRENT;
}
}
record RequestForUpdate<T>() implements RequestGet<T, @NotNull UpdateContext<@Nullable T>> {
private static final RequestForUpdate<Object> INSTANCE = new RequestForUpdate<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.FOR_UPDATE;
}
}
record RequestExists<T>() implements RequestGet<T, Boolean>, RequestIterate<T, Boolean> {
private static final RequestExists<Object> INSTANCE = new RequestExists<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.EXISTS;
}
}
record RequestDelta<T>() implements RequestPut<T, Delta<T>> {
private static final RequestDelta<Object> INSTANCE = new RequestDelta<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.DELTA;
}
}
record RequestMulti<M>() implements RequestIterate<M, List<M>> {
private static final RequestMulti<Object> INSTANCE = new RequestMulti<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.MULTI;
}
}
record RequestChanged<T>() implements RequestPut<T, Boolean>, RequestPatch<T, Boolean> {
private static final RequestChanged<Object> INSTANCE = new RequestChanged<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.CHANGED;
}
}
record RequestPreviousPresence<T>() implements RequestPut<T, Boolean>, RequestPatch<T, Boolean> {
private static final RequestPreviousPresence<Object> INSTANCE = new RequestPreviousPresence<>();
@Override
public RequestTypeId getRequestTypeId() {
return RequestTypeId.PREVIOUS_PRESENCE;
}
}
}

View File

@ -1,133 +1,3 @@
package it.cavallium.rockserver.core.common; package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.common.Callback.GetCallback; public interface RocksDBAPI extends RocksDBAsyncAPI, RocksDBSyncAPI {}
import it.cavallium.rockserver.core.common.Callback.IteratorCallback;
import it.cavallium.rockserver.core.common.Callback.PutCallback;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RocksDBAPI {
/**
* Open a transaction
* @param timeoutMs timeout in milliseconds
* @return transaction id
*/
long openTransaction(long timeoutMs) throws RocksDBException;
/**
* Close a transaction
*
* @param transactionId transaction id to close
* @param commit true to commit the transaction, false to rollback it
* @return true if committed, if false, you should try again
*/
boolean closeTransaction(long transactionId, boolean commit) throws RocksDBException;
/**
* Close a failed update, discarding all changes
*
* @param updateId update id to close
*/
void closeFailedUpdate(long updateId) throws RocksDBException;
/**
* Create a column
* @param name column name
* @param schema column key-value schema
* @return column id
*/
long createColumn(String name, @NotNull ColumnSchema schema) throws RocksDBException;
/**
* Delete a column
* @param columnId column id
*/
void deleteColumn(long columnId) throws RocksDBException;
/**
* Get column id by name
* @param name column name
* @return column id
*/
long getColumnId(@NotNull String name) throws RocksDBException;
/**
* Put an element into the specified position
* @param arena arena
* @param transactionOrUpdateId transaction id, update id, or 0
* @param columnId column id
* @param keys column keys, or empty array if not needed
* @param value value, or null if not needed
* @param callback the callback will be executed on the same thread, exactly once.
*/
<T> T put(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull[] keys,
@NotNull MemorySegment value,
PutCallback<? super MemorySegment, T> callback) throws RocksDBException;
/**
* Get an element from the specified position
* @param arena arena
* @param transactionOrUpdateId transaction id, update id for retry operations, or 0
* @param columnId column id
* @param keys column keys, or empty array if not needed
* @param callback the callback will be executed on the same thread, exactly once.
*/
<T> T get(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull[] keys,
GetCallback<? super MemorySegment, T> callback) throws RocksDBException;
/**
* Open an iterator
* @param arena arena
* @param transactionId transaction id, or 0
* @param columnId column id
* @param startKeysInclusive start keys, inclusive. [] means "the beginning"
* @param endKeysExclusive end keys, exclusive. Null means "the end"
* @param reverse if true, seek in reverse direction
* @param timeoutMs timeout in milliseconds
* @return iterator id
*/
long openIterator(Arena arena,
long transactionId,
long columnId,
@NotNull MemorySegment @NotNull[] startKeysInclusive,
@NotNull MemorySegment @Nullable[] endKeysExclusive,
boolean reverse,
long timeoutMs) throws RocksDBException;
/**
* Close an iterator
* @param iteratorId iterator id
*/
void closeIterator(long iteratorId) throws RocksDBException;
/**
* Seek to the specific element during an iteration, or the subsequent one if not found
* @param arena arena
* @param iterationId iteration id
* @param keys keys, inclusive. [] means "the beginning"
*/
void seekTo(Arena arena, long iterationId, @NotNull MemorySegment @NotNull[] keys) throws RocksDBException;
/**
* Get the subsequent element during an iteration
* @param arena arena
* @param iterationId iteration id
* @param skipCount number of elements to skip
* @param takeCount number of elements to take
* @param callback the callback will be executed on the same thread, exactly once.
*/
<T> T subsequent(Arena arena,
long iterationId,
long skipCount,
long takeCount,
@NotNull IteratorCallback<? super MemorySegment, T> callback) throws RocksDBException;
}

View File

@ -0,0 +1,543 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.buffer.BufDataInput;
import it.cavallium.buffer.BufDataOutput;
import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.RequestType.RequestIterate;
import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.RequestType.RequestTypeId;
import it.cavallium.rockserver.core.impl.ColumnInstance;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletionStage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public sealed interface RocksDBAPICommand<R> {
enum CommandTypeId {
OPEN_TX,
CLOSE_TX,
CLOSE_FAILED_UPDATE,
CREATE_COLUMN,
DELETE_COLUMN,
GET_COLUMN_ID,
PUT,
GET,
OPEN_ITERATOR,
CLOSE_ITERATOR,
SEEK_TO,
SUBSEQUENT
}
R handleSync(RocksDBSyncAPI api);
CompletionStage<R> handleAsync(RocksDBAsyncAPI api);
void serializeToBuffer(BufDataOutput out);
CommandTypeId getCommandTypeId();
static <T> RocksDBAPICommand<T> deserializeCommand(Arena arena, BufDataInput in) {
return (RocksDBAPICommand<T>) switch (CommandTypeId.values()[in.readUnsignedByte()]) {
case OPEN_TX -> new OpenTransaction(in.readLong());
case CLOSE_TX -> new CloseTransaction(in.readLong(), in.readBoolean());
case CLOSE_FAILED_UPDATE -> new CloseFailedUpdate(in.readLong());
case CREATE_COLUMN -> {
var name = in.readShortText(StandardCharsets.UTF_8);
var keys = new int[in.readInt()];
for (int i = 0; i < keys.length; i++) {
keys[i] = in.readInt();
}
ColumnHashType[] variableTailKeys = new ColumnHashType[in.readInt()];
for (int i = 0; i < variableTailKeys.length; i++) {
variableTailKeys[i] = ColumnHashType.values()[in.readUnsignedByte()];
}
boolean hasValue = in.readBoolean();
var columnSchema = new ColumnSchema(IntArrayList.wrap(keys),
ObjectArrayList.wrap(variableTailKeys),
hasValue
);
yield new CreateColumn(name, columnSchema);
}
case DELETE_COLUMN -> new DeleteColumn(in.readLong());
case GET_COLUMN_ID -> new GetColumnId(in.readShortText(StandardCharsets.UTF_8));
case PUT -> {
var transactionOrUpdateId = in.readLong();
var columnId = in.readLong();
var keys = SerializationUtils.deserializeMemorySegmentArray(in);
var value = SerializationUtils.deserializeMemorySegment(in);
//noinspection unchecked
var requestType = (RequestPut<? super MemorySegment, ?>)
RequestTypeId.values()[in.readUnsignedByte()].getRequestType();
yield new Put<>(arena, transactionOrUpdateId, columnId, keys, value, requestType);
}
case GET -> {
var transactionOrUpdateId = in.readLong();
var columnId = in.readLong();
var keys = SerializationUtils.deserializeMemorySegmentArray(in);
//noinspection unchecked
var requestType = (RequestGet<? super MemorySegment, ?>)
RequestTypeId.values()[in.readUnsignedByte()].getRequestType();
yield new Get<>(arena, transactionOrUpdateId, columnId, keys, requestType);
}
case OPEN_ITERATOR -> {
var transactionId = in.readLong();
var columnId = in.readLong();
var startKeysInclusive = SerializationUtils.deserializeMemorySegmentArray(in);
var endKeysExclusive = SerializationUtils.deserializeNullableMemorySegmentArray(in);
var reverse = in.readBoolean();
var timeoutMs = in.readLong();
yield new OpenIterator(arena, transactionId, columnId, startKeysInclusive, endKeysExclusive, reverse, timeoutMs);
}
case CLOSE_ITERATOR -> new CloseIterator(in.readLong());
case SEEK_TO -> {
var iterationId = in.readLong();
var keys = SerializationUtils.deserializeMemorySegmentArray(in);
yield new SeekTo(arena, iterationId, keys);
}
case SUBSEQUENT -> {
var iterationId = in.readLong();
var skipCount = in.readLong();
var takeCount = in.readLong();
//noinspection unchecked
var requestType = (RequestIterate<? super MemorySegment, ?>)
RequestTypeId.values()[in.readUnsignedByte()].getRequestType();
yield new Subsequent<>(arena, iterationId, skipCount, takeCount, requestType);
}
};
}
/**
* Open a transaction
* @param timeoutMs timeout in milliseconds
* @return transaction id
*/
record OpenTransaction(long timeoutMs) implements RocksDBAPICommand<Long> {
@Override
public Long handleSync(RocksDBSyncAPI api) {
return api.openTransaction(timeoutMs);
}
@Override
public CompletionStage<Long> handleAsync(RocksDBAsyncAPI api) {
return api.openTransactionAsync(timeoutMs);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(timeoutMs);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.OPEN_TX;
}
}
/**
* Close a transaction
*
* @param transactionId transaction id to close
* @param commit true to commit the transaction, false to rollback it
* @return true if committed, if false, you should try again
*/
record CloseTransaction(long transactionId, boolean commit) implements RocksDBAPICommand<Boolean> {
@Override
public Boolean handleSync(RocksDBSyncAPI api) {
return api.closeTransaction(transactionId, commit);
}
@Override
public CompletionStage<Boolean> handleAsync(RocksDBAsyncAPI api) {
return api.closeTransactionAsync(transactionId, commit);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(transactionId);
out.writeBoolean(commit);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.CLOSE_TX;
}
}
/**
* Close a failed update, discarding all changes
*
* @param updateId update id to close
*/
record CloseFailedUpdate(long updateId) implements RocksDBAPICommand<Void> {
@Override
public Void handleSync(RocksDBSyncAPI api) {
api.closeFailedUpdate(updateId);
return null;
}
@Override
public CompletionStage<Void> handleAsync(RocksDBAsyncAPI api) {
return api.closeFailedUpdateAsync(updateId);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(updateId);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.CLOSE_FAILED_UPDATE;
}
}
/**
* Create a column
* @param name column name
* @param schema column key-value schema
* @return column id
*/
record CreateColumn(String name, @NotNull ColumnSchema schema) implements RocksDBAPICommand<Long> {
@Override
public Long handleSync(RocksDBSyncAPI api) {
return api.createColumn(name, schema);
}
@Override
public CompletionStage<Long> handleAsync(RocksDBAsyncAPI api) {
return api.createColumnAsync(name, schema);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeShortText(name, StandardCharsets.UTF_8);
var keys = schema.keys();
out.writeInt(keys.size());
keys.forEach(out::writeInt);
var variableTailKeys = schema.variableTailKeys();
out.writeInt(variableTailKeys.size());
for (ColumnHashType variableTailKey : variableTailKeys) {
out.writeByte(variableTailKey.ordinal());
}
out.writeBoolean(schema.hasValue());
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.CREATE_COLUMN;
}
}
/**
* Delete a column
* @param columnId column id
*/
record DeleteColumn(long columnId) implements RocksDBAPICommand<Void> {
@Override
public Void handleSync(RocksDBSyncAPI api) {
api.deleteColumn(columnId);
return null;
}
@Override
public CompletionStage<Void> handleAsync(RocksDBAsyncAPI api) {
return api.deleteColumnAsync(columnId);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(columnId);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.DELETE_COLUMN;
}
}
/**
* Get column id by name
* @param name column name
* @return column id
*/
record GetColumnId(@NotNull String name) implements RocksDBAPICommand<Long> {
@Override
public Long handleSync(RocksDBSyncAPI api) {
return api.getColumnId(name);
}
@Override
public CompletionStage<Long> handleAsync(RocksDBAsyncAPI api) {
return api.getColumnIdAsync(name);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeShortText(name, StandardCharsets.UTF_8);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.GET_COLUMN_ID;
}
}
/**
* Put an element into the specified position
* @param arena arena
* @param transactionOrUpdateId transaction id, update id, or 0
* @param columnId column id
* @param keys column keys, or empty array if not needed
* @param value value, or null if not needed
* @param requestType the request type determines which type of data will be returned.
*/
record Put<T>(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
@NotNull MemorySegment value,
RequestPut<? super MemorySegment, T> requestType) implements RocksDBAPICommand<T> {
@Override
public T handleSync(RocksDBSyncAPI api) {
return api.put(arena, transactionOrUpdateId, columnId, keys, value, requestType);
}
@Override
public CompletionStage<T> handleAsync(RocksDBAsyncAPI api) {
return api.putAsync(arena, transactionOrUpdateId, columnId, keys, value, requestType);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(transactionOrUpdateId);
out.writeLong(columnId);
out.writeInt(keys.length);
for (MemorySegment key : keys) {
var array = key.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
var valueArray = value.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(valueArray.length);
out.writeBytes(valueArray, 0, valueArray.length);
out.writeByte(requestType.getRequestTypeId().ordinal());
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.PUT;
}
}
/**
* Get an element from the specified position
* @param arena arena
* @param transactionOrUpdateId transaction id, update id for retry operations, or 0
* @param columnId column id
* @param keys column keys, or empty array if not needed
* @param requestType the request type determines which type of data will be returned.
*/
record Get<T>(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
RequestGet<? super MemorySegment, T> requestType) implements RocksDBAPICommand<T> {
@Override
public T handleSync(RocksDBSyncAPI api) {
return api.get(arena, transactionOrUpdateId, columnId, keys, requestType);
}
@Override
public CompletionStage<T> handleAsync(RocksDBAsyncAPI api) {
return api.getAsync(arena, transactionOrUpdateId, columnId, keys, requestType);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(transactionOrUpdateId);
out.writeLong(columnId);
out.writeInt(keys.length);
for (MemorySegment key : keys) {
var array = key.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
out.writeByte(requestType.getRequestTypeId().ordinal());
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.GET;
}
}
/**
* Open an iterator
* @param arena arena
* @param transactionId transaction id, or 0
* @param columnId column id
* @param startKeysInclusive start keys, inclusive. [] means "the beginning"
* @param endKeysExclusive end keys, exclusive. Null means "the end"
* @param reverse if true, seek in reverse direction
* @param timeoutMs timeout in milliseconds
* @return iterator id
*/
record OpenIterator(Arena arena,
long transactionId,
long columnId,
@NotNull MemorySegment @NotNull [] startKeysInclusive,
@NotNull MemorySegment @Nullable [] endKeysExclusive,
boolean reverse,
long timeoutMs) implements RocksDBAPICommand<Long> {
@Override
public Long handleSync(RocksDBSyncAPI api) {
return api.openIterator(arena, transactionId, columnId, startKeysInclusive, endKeysExclusive, reverse, timeoutMs);
}
@Override
public CompletionStage<Long> handleAsync(RocksDBAsyncAPI api) {
return api.openIteratorAsync(arena,
transactionId,
columnId,
startKeysInclusive,
endKeysExclusive,
reverse,
timeoutMs
);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(transactionId);
out.writeLong(columnId);
out.writeInt(startKeysInclusive.length);
SerializationUtils.serializeMemorySegmentArray(out, startKeysInclusive);
for (MemorySegment key : startKeysInclusive) {
var array = key.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
out.writeInt(endKeysExclusive == null ? -1 : endKeysExclusive.length);
if (endKeysExclusive != null) {
for (MemorySegment key : endKeysExclusive) {
var array = key.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
}
out.writeBoolean(reverse);
out.writeLong(timeoutMs);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.OPEN_ITERATOR;
}
}
/**
* Close an iterator
* @param iteratorId iterator id
*/
record CloseIterator(long iteratorId) implements RocksDBAPICommand<Void> {
@Override
public Void handleSync(RocksDBSyncAPI api) {
api.closeIterator(iteratorId);
return null;
}
@Override
public CompletionStage<Void> handleAsync(RocksDBAsyncAPI api) {
return api.closeIteratorAsync(iteratorId);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(iteratorId);
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.CLOSE_ITERATOR;
}
}
/**
* Seek to the specific element during an iteration, or the subsequent one if not found
* @param arena arena
* @param iterationId iteration id
* @param keys keys, inclusive. [] means "the beginning"
*/
record SeekTo(Arena arena, long iterationId, @NotNull MemorySegment @NotNull [] keys) implements
RocksDBAPICommand<Void> {
@Override
public Void handleSync(RocksDBSyncAPI api) {
api.seekTo(arena, iterationId, keys);
return null;
}
@Override
public CompletionStage<Void> handleAsync(RocksDBAsyncAPI api) {
return api.seekToAsync(arena, iterationId, keys);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(iterationId);
out.writeInt(keys.length);
for (MemorySegment key : keys) {
var array = key.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.SEEK_TO;
}
}
/**
* Get the subsequent element during an iteration
* @param arena arena
* @param iterationId iteration id
* @param skipCount number of elements to skip
* @param takeCount number of elements to take
* @param requestType the request type determines which type of data will be returned.
*/
record Subsequent<T>(Arena arena,
long iterationId,
long skipCount,
long takeCount,
@NotNull RequestType.RequestIterate<? super MemorySegment, T> requestType)
implements RocksDBAPICommand<T> {
@Override
public T handleSync(RocksDBSyncAPI api) {
return api.subsequent(arena, iterationId, skipCount, takeCount, requestType);
}
@Override
public CompletionStage<T> handleAsync(RocksDBAsyncAPI api) {
return api.subsequentAsync(arena, iterationId, skipCount, takeCount, requestType);
}
@Override
public void serializeToBuffer(BufDataOutput out) {
out.writeLong(iterationId);
out.writeLong(skipCount);
out.writeLong(takeCount);
out.writeByte(requestType.getRequestTypeId().ordinal());
}
@Override
public CommandTypeId getCommandTypeId() {
return CommandTypeId.SUBSEQUENT;
}
}
}

View File

@ -0,0 +1,111 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseFailedUpdate;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CreateColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.DeleteColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Get;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.GetColumnId;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Put;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.SeekTo;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Subsequent;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RocksDBAsyncAPI extends RocksDBAsyncAPIRequestHandler {
/** See: {@link OpenTransaction}. */
default CompletionStage<Long> openTransactionAsync(long timeoutMs) throws RocksDBException {
return requestAsync(new OpenTransaction(timeoutMs));
}
/** See: {@link CloseTransaction}. */
default CompletionStage<Boolean> closeTransactionAsync(long transactionId, boolean commit) throws RocksDBException {
return requestAsync(new CloseTransaction(transactionId, commit));
}
/** See: {@link CloseFailedUpdate}. */
default CompletionStage<Void> closeFailedUpdateAsync(long updateId) throws RocksDBException {
return requestAsync(new CloseFailedUpdate(updateId));
}
/** See: {@link CreateColumn}. */
default CompletionStage<Long> createColumnAsync(String name, @NotNull ColumnSchema schema) throws RocksDBException {
return requestAsync(new CreateColumn(name, schema));
}
/** See: {@link DeleteColumn}. */
default CompletionStage<Void> deleteColumnAsync(long columnId) throws RocksDBException {
return requestAsync(new DeleteColumn(columnId));
}
/** See: {@link GetColumnId}. */
default CompletionStage<Long> getColumnIdAsync(@NotNull String name) throws RocksDBException {
return requestAsync(new GetColumnId(name));
}
/** See: {@link Put}. */
default <T> CompletionStage<T> putAsync(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
@NotNull MemorySegment value,
RequestPut<? super MemorySegment, T> requestType) throws RocksDBException {
return requestAsync(new Put<>(arena, transactionOrUpdateId, columnId, keys, value, requestType));
}
/** See: {@link Get}. */
default <T> CompletionStage<T> getAsync(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
RequestGet<? super MemorySegment, T> requestType) throws RocksDBException {
return requestAsync(new Get<>(arena, transactionOrUpdateId, columnId, keys, requestType));
}
/** See: {@link OpenIterator}. */
default CompletionStage<Long> openIteratorAsync(Arena arena,
long transactionId,
long columnId,
@NotNull MemorySegment @NotNull [] startKeysInclusive,
@NotNull MemorySegment @Nullable [] endKeysExclusive,
boolean reverse,
long timeoutMs) throws RocksDBException {
return requestAsync(new OpenIterator(arena,
transactionId,
columnId,
startKeysInclusive,
endKeysExclusive,
reverse,
timeoutMs
));
}
/** See: {@link CloseIterator}. */
default CompletionStage<Void> closeIteratorAsync(long iteratorId) throws RocksDBException {
return requestAsync(new CloseIterator(iteratorId));
}
/** See: {@link SeekTo}. */
default CompletionStage<Void> seekToAsync(Arena arena, long iterationId, @NotNull MemorySegment @NotNull [] keys) throws RocksDBException {
return requestAsync(new SeekTo(arena, iterationId, keys));
}
/** See: {@link Subsequent}. */
default <T> CompletionStage<T> subsequentAsync(Arena arena,
long iterationId,
long skipCount,
long takeCount,
@NotNull RequestType.RequestIterate<? super MemorySegment, T> requestType) throws RocksDBException {
return requestAsync(new Subsequent<>(arena, iterationId, skipCount, takeCount, requestType));
}
}

View File

@ -0,0 +1,29 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseFailedUpdate;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CreateColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.DeleteColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Get;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.GetColumnId;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Put;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.SeekTo;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Subsequent;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RocksDBAsyncAPIRequestHandler {
default <R> CompletionStage<R> requestAsync(RocksDBAPICommand<R> req) {
return CompletableFuture.failedFuture(new UnsupportedOperationException("Unsupported request type: " + req));
}
}

View File

@ -0,0 +1,105 @@
package it.cavallium.rockserver.core.common;
import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseFailedUpdate;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CreateColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.DeleteColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Get;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.GetColumnId;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Put;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.SeekTo;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Subsequent;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RocksDBSyncAPI extends RocksDBSyncAPIRequestHandler {
/** See: {@link OpenTransaction}. */
default long openTransaction(long timeoutMs) throws RocksDBException {
return requestSync(new OpenTransaction(timeoutMs));
}
/** See: {@link CloseTransaction}. */
default boolean closeTransaction(long transactionId, boolean commit) throws RocksDBException {
return requestSync(new CloseTransaction(transactionId, commit));
}
/** See: {@link CloseFailedUpdate}. */
default void closeFailedUpdate(long updateId) throws RocksDBException {
requestSync(new CloseFailedUpdate(updateId));
}
/** See: {@link CreateColumn}. */
default long createColumn(String name, @NotNull ColumnSchema schema) throws RocksDBException {
return requestSync(new CreateColumn(name, schema));
}
/** See: {@link DeleteColumn}. */
default void deleteColumn(long columnId) throws RocksDBException {
requestSync(new DeleteColumn(columnId));
}
/** See: {@link GetColumnId}. */
default long getColumnId(@NotNull String name) throws RocksDBException {
return requestSync(new GetColumnId(name));
}
/** See: {@link Put}. */
default <T> T put(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
@NotNull MemorySegment value,
RequestPut<? super MemorySegment, T> requestType) throws RocksDBException {
return requestSync(new Put<>(arena, transactionOrUpdateId, columnId, keys, value, requestType));
}
/** See: {@link Get}. */
default <T> T get(Arena arena,
long transactionOrUpdateId,
long columnId,
@NotNull MemorySegment @NotNull [] keys,
RequestGet<? super MemorySegment, T> requestType) throws RocksDBException {
return requestSync(new Get<>(arena, transactionOrUpdateId, columnId, keys, requestType));
}
/** See: {@link OpenIterator}. */
default long openIterator(Arena arena,
long transactionId,
long columnId,
@NotNull MemorySegment @NotNull [] startKeysInclusive,
@NotNull MemorySegment @Nullable [] endKeysExclusive,
boolean reverse,
long timeoutMs) throws RocksDBException {
return requestSync(new OpenIterator(arena, transactionId, columnId, startKeysInclusive, endKeysExclusive, reverse, timeoutMs));
}
/** See: {@link CloseIterator}. */
default void closeIterator(long iteratorId) throws RocksDBException {
requestSync(new CloseIterator(iteratorId));
}
/** See: {@link SeekTo}. */
default void seekTo(Arena arena, long iterationId, @NotNull MemorySegment @NotNull [] keys) throws RocksDBException {
requestSync(new SeekTo(arena, iterationId, keys));
}
/** See: {@link Subsequent}. */
default <T> T subsequent(Arena arena,
long iterationId,
long skipCount,
long takeCount,
@NotNull RequestType.RequestIterate<? super MemorySegment, T> requestType) throws RocksDBException {
return requestSync(new Subsequent<>(arena, iterationId, skipCount, takeCount, requestType));
}
}

View File

@ -0,0 +1,27 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseFailedUpdate;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CloseTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.CreateColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.DeleteColumn;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Get;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.GetColumnId;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenIterator;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.OpenTransaction;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Put;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.SeekTo;
import it.cavallium.rockserver.core.common.RocksDBAPICommand.Subsequent;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RocksDBSyncAPIRequestHandler {
default <R> R requestSync(RocksDBAPICommand<R> req) {
throw new UnsupportedOperationException("Unsupported request type: " + req);
}
}

View File

@ -0,0 +1,56 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.buffer.BufDataInput;
import it.cavallium.buffer.BufDataOutput;
import it.cavallium.rockserver.core.impl.ColumnInstance;
import java.lang.foreign.MemorySegment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SerializationUtils {
public static void serializeMemorySegment(BufDataOutput out, @NotNull MemorySegment segment) {
var array = segment.toArray(ColumnInstance.BIG_ENDIAN_BYTES);
out.writeInt(array.length);
out.writeBytes(array, 0, array.length);
}
public static MemorySegment deserializeMemorySegment(BufDataInput in) {
return MemorySegment.ofArray(in.readNBytes(in.readInt()));
}
public static void serializeNullableMemorySegmentArray(BufDataOutput out, @NotNull MemorySegment @Nullable [] array) {
out.writeInt(array != null ? array.length : -1);
if (array != null) {
for (MemorySegment memorySegment : array) {
serializeMemorySegment(out, memorySegment);
}
}
}
public static void serializeMemorySegmentArray(BufDataOutput out, @NotNull MemorySegment @NotNull [] array) {
out.writeInt(array.length);
for (MemorySegment memorySegment : array) {
serializeMemorySegment(out, memorySegment);
}
}
public static @NotNull MemorySegment @Nullable [] deserializeNullableMemorySegmentArray(BufDataInput in) {
int size = in.readInt();
if (size == -1) {
return null;
} else {
var array = new MemorySegment @NotNull[size];
for (int i = 0; i < array.length; i++) {
array[i] = deserializeMemorySegment(in);
}
return array;
}
}
public static @NotNull MemorySegment @NotNull [] deserializeMemorySegmentArray(BufDataInput in) {
var array = new MemorySegment @NotNull [in.readInt()];
for (int i = 0; i < array.length; i++) {
array[i] = deserializeMemorySegment(in);
}
return array;
}
}

View File

@ -0,0 +1,46 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
public enum ColumnHashType implements org.apache.thrift.TEnum {
XXHASH32(1),
XXHASH8(2),
ALLSAME8(3);
private final int value;
private ColumnHashType(int value) {
this.value = value;
}
/**
* Get the integer value of this enum value, as defined in the Thrift IDL.
*/
@Override
public int getValue() {
return value;
}
/**
* Find a the enum type by its integer value, as defined in the Thrift IDL.
* @return null if the value is not found.
*/
@org.apache.thrift.annotation.Nullable
public static ColumnHashType findByValue(int value) {
switch (value) {
case 1:
return XXHASH32;
case 2:
return XXHASH8;
case 3:
return ALLSAME8;
default:
return null;
}
}
}

View File

@ -0,0 +1,701 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
public class ColumnSchema implements org.apache.thrift.TBase<ColumnSchema, ColumnSchema._Fields>, java.io.Serializable, Cloneable, Comparable<ColumnSchema> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ColumnSchema");
private static final org.apache.thrift.protocol.TField FIXED_KEYS_FIELD_DESC = new org.apache.thrift.protocol.TField("fixedKeys", org.apache.thrift.protocol.TType.LIST, (short)1);
private static final org.apache.thrift.protocol.TField VARIABLE_TAIL_KEYS_FIELD_DESC = new org.apache.thrift.protocol.TField("variableTailKeys", org.apache.thrift.protocol.TType.LIST, (short)2);
private static final org.apache.thrift.protocol.TField HAS_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("hasValue", org.apache.thrift.protocol.TType.BOOL, (short)3);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ColumnSchemaStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ColumnSchemaTupleSchemeFactory();
public @org.apache.thrift.annotation.Nullable java.util.List<java.lang.Integer> fixedKeys; // required
public @org.apache.thrift.annotation.Nullable java.util.List<ColumnHashType> variableTailKeys; // required
public boolean hasValue; // required
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
FIXED_KEYS((short)1, "fixedKeys"),
VARIABLE_TAIL_KEYS((short)2, "variableTailKeys"),
HAS_VALUE((short)3, "hasValue");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // FIXED_KEYS
return FIXED_KEYS;
case 2: // VARIABLE_TAIL_KEYS
return VARIABLE_TAIL_KEYS;
case 3: // HAS_VALUE
return HAS_VALUE;
default:
return null;
}
}
/**
* Find the _Fields constant that matches fieldId, throwing an exception
* if it is not found.
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
return fields;
}
/**
* Find the _Fields constant that matches name, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByName(java.lang.String name) {
return byName.get(name);
}
private final short _thriftId;
private final java.lang.String _fieldName;
_Fields(short thriftId, java.lang.String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
@Override
public short getThriftFieldId() {
return _thriftId;
}
@Override
public java.lang.String getFieldName() {
return _fieldName;
}
}
// isset id assignments
private static final int __HASVALUE_ISSET_ID = 0;
private byte __isset_bitfield = 0;
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.FIXED_KEYS, new org.apache.thrift.meta_data.FieldMetaData("fixedKeys", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
tmpMap.put(_Fields.VARIABLE_TAIL_KEYS, new org.apache.thrift.meta_data.FieldMetaData("variableTailKeys", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ColumnHashType.class))));
tmpMap.put(_Fields.HAS_VALUE, new org.apache.thrift.meta_data.FieldMetaData("hasValue", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ColumnSchema.class, metaDataMap);
}
public ColumnSchema() {
}
public ColumnSchema(
java.util.List<java.lang.Integer> fixedKeys,
java.util.List<ColumnHashType> variableTailKeys,
boolean hasValue)
{
this();
this.fixedKeys = fixedKeys;
this.variableTailKeys = variableTailKeys;
this.hasValue = hasValue;
setHasValueIsSet(true);
}
/**
* Performs a deep copy on <i>other</i>.
*/
public ColumnSchema(ColumnSchema other) {
__isset_bitfield = other.__isset_bitfield;
if (other.isSetFixedKeys()) {
java.util.List<java.lang.Integer> __this__fixedKeys = new java.util.ArrayList<java.lang.Integer>(other.fixedKeys);
this.fixedKeys = __this__fixedKeys;
}
if (other.isSetVariableTailKeys()) {
java.util.List<ColumnHashType> __this__variableTailKeys = new java.util.ArrayList<ColumnHashType>(other.variableTailKeys.size());
for (ColumnHashType other_element : other.variableTailKeys) {
__this__variableTailKeys.add(other_element);
}
this.variableTailKeys = __this__variableTailKeys;
}
this.hasValue = other.hasValue;
}
@Override
public ColumnSchema deepCopy() {
return new ColumnSchema(this);
}
@Override
public void clear() {
this.fixedKeys = null;
this.variableTailKeys = null;
setHasValueIsSet(false);
this.hasValue = false;
}
public int getFixedKeysSize() {
return (this.fixedKeys == null) ? 0 : this.fixedKeys.size();
}
@org.apache.thrift.annotation.Nullable
public java.util.Iterator<java.lang.Integer> getFixedKeysIterator() {
return (this.fixedKeys == null) ? null : this.fixedKeys.iterator();
}
public void addToFixedKeys(int elem) {
if (this.fixedKeys == null) {
this.fixedKeys = new java.util.ArrayList<java.lang.Integer>();
}
this.fixedKeys.add(elem);
}
@org.apache.thrift.annotation.Nullable
public java.util.List<java.lang.Integer> getFixedKeys() {
return this.fixedKeys;
}
public ColumnSchema setFixedKeys(@org.apache.thrift.annotation.Nullable java.util.List<java.lang.Integer> fixedKeys) {
this.fixedKeys = fixedKeys;
return this;
}
public void unsetFixedKeys() {
this.fixedKeys = null;
}
/** Returns true if field fixedKeys is set (has been assigned a value) and false otherwise */
public boolean isSetFixedKeys() {
return this.fixedKeys != null;
}
public void setFixedKeysIsSet(boolean value) {
if (!value) {
this.fixedKeys = null;
}
}
public int getVariableTailKeysSize() {
return (this.variableTailKeys == null) ? 0 : this.variableTailKeys.size();
}
@org.apache.thrift.annotation.Nullable
public java.util.Iterator<ColumnHashType> getVariableTailKeysIterator() {
return (this.variableTailKeys == null) ? null : this.variableTailKeys.iterator();
}
public void addToVariableTailKeys(ColumnHashType elem) {
if (this.variableTailKeys == null) {
this.variableTailKeys = new java.util.ArrayList<ColumnHashType>();
}
this.variableTailKeys.add(elem);
}
@org.apache.thrift.annotation.Nullable
public java.util.List<ColumnHashType> getVariableTailKeys() {
return this.variableTailKeys;
}
public ColumnSchema setVariableTailKeys(@org.apache.thrift.annotation.Nullable java.util.List<ColumnHashType> variableTailKeys) {
this.variableTailKeys = variableTailKeys;
return this;
}
public void unsetVariableTailKeys() {
this.variableTailKeys = null;
}
/** Returns true if field variableTailKeys is set (has been assigned a value) and false otherwise */
public boolean isSetVariableTailKeys() {
return this.variableTailKeys != null;
}
public void setVariableTailKeysIsSet(boolean value) {
if (!value) {
this.variableTailKeys = null;
}
}
public boolean isHasValue() {
return this.hasValue;
}
public ColumnSchema setHasValue(boolean hasValue) {
this.hasValue = hasValue;
setHasValueIsSet(true);
return this;
}
public void unsetHasValue() {
__isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __HASVALUE_ISSET_ID);
}
/** Returns true if field hasValue is set (has been assigned a value) and false otherwise */
public boolean isSetHasValue() {
return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __HASVALUE_ISSET_ID);
}
public void setHasValueIsSet(boolean value) {
__isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __HASVALUE_ISSET_ID, value);
}
@Override
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case FIXED_KEYS:
if (value == null) {
unsetFixedKeys();
} else {
setFixedKeys((java.util.List<java.lang.Integer>)value);
}
break;
case VARIABLE_TAIL_KEYS:
if (value == null) {
unsetVariableTailKeys();
} else {
setVariableTailKeys((java.util.List<ColumnHashType>)value);
}
break;
case HAS_VALUE:
if (value == null) {
unsetHasValue();
} else {
setHasValue((java.lang.Boolean)value);
}
break;
}
}
@org.apache.thrift.annotation.Nullable
@Override
public java.lang.Object getFieldValue(_Fields field) {
switch (field) {
case FIXED_KEYS:
return getFixedKeys();
case VARIABLE_TAIL_KEYS:
return getVariableTailKeys();
case HAS_VALUE:
return isHasValue();
}
throw new java.lang.IllegalStateException();
}
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
@Override
public boolean isSet(_Fields field) {
if (field == null) {
throw new java.lang.IllegalArgumentException();
}
switch (field) {
case FIXED_KEYS:
return isSetFixedKeys();
case VARIABLE_TAIL_KEYS:
return isSetVariableTailKeys();
case HAS_VALUE:
return isSetHasValue();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
if (that instanceof ColumnSchema)
return this.equals((ColumnSchema)that);
return false;
}
public boolean equals(ColumnSchema that) {
if (that == null)
return false;
if (this == that)
return true;
boolean this_present_fixedKeys = true && this.isSetFixedKeys();
boolean that_present_fixedKeys = true && that.isSetFixedKeys();
if (this_present_fixedKeys || that_present_fixedKeys) {
if (!(this_present_fixedKeys && that_present_fixedKeys))
return false;
if (!this.fixedKeys.equals(that.fixedKeys))
return false;
}
boolean this_present_variableTailKeys = true && this.isSetVariableTailKeys();
boolean that_present_variableTailKeys = true && that.isSetVariableTailKeys();
if (this_present_variableTailKeys || that_present_variableTailKeys) {
if (!(this_present_variableTailKeys && that_present_variableTailKeys))
return false;
if (!this.variableTailKeys.equals(that.variableTailKeys))
return false;
}
boolean this_present_hasValue = true;
boolean that_present_hasValue = true;
if (this_present_hasValue || that_present_hasValue) {
if (!(this_present_hasValue && that_present_hasValue))
return false;
if (this.hasValue != that.hasValue)
return false;
}
return true;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = hashCode * 8191 + ((isSetFixedKeys()) ? 131071 : 524287);
if (isSetFixedKeys())
hashCode = hashCode * 8191 + fixedKeys.hashCode();
hashCode = hashCode * 8191 + ((isSetVariableTailKeys()) ? 131071 : 524287);
if (isSetVariableTailKeys())
hashCode = hashCode * 8191 + variableTailKeys.hashCode();
hashCode = hashCode * 8191 + ((hasValue) ? 131071 : 524287);
return hashCode;
}
@Override
public int compareTo(ColumnSchema other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0;
lastComparison = java.lang.Boolean.compare(isSetFixedKeys(), other.isSetFixedKeys());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetFixedKeys()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fixedKeys, other.fixedKeys);
if (lastComparison != 0) {
return lastComparison;
}
}
lastComparison = java.lang.Boolean.compare(isSetVariableTailKeys(), other.isSetVariableTailKeys());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetVariableTailKeys()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.variableTailKeys, other.variableTailKeys);
if (lastComparison != 0) {
return lastComparison;
}
}
lastComparison = java.lang.Boolean.compare(isSetHasValue(), other.isSetHasValue());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetHasValue()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hasValue, other.hasValue);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@org.apache.thrift.annotation.Nullable
@Override
public _Fields fieldForId(int fieldId) {
return _Fields.findByThriftId(fieldId);
}
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@Override
public java.lang.String toString() {
java.lang.StringBuilder sb = new java.lang.StringBuilder("ColumnSchema(");
boolean first = true;
sb.append("fixedKeys:");
if (this.fixedKeys == null) {
sb.append("null");
} else {
sb.append(this.fixedKeys);
}
first = false;
if (!first) sb.append(", ");
sb.append("variableTailKeys:");
if (this.variableTailKeys == null) {
sb.append("null");
} else {
sb.append(this.variableTailKeys);
}
first = false;
if (!first) sb.append(", ");
sb.append("hasValue:");
sb.append(this.hasValue);
first = false;
sb.append(")");
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bitfield = 0;
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class ColumnSchemaStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public ColumnSchemaStandardScheme getScheme() {
return new ColumnSchemaStandardScheme();
}
}
private static class ColumnSchemaStandardScheme extends org.apache.thrift.scheme.StandardScheme<ColumnSchema> {
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot, ColumnSchema struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 1: // FIXED_KEYS
if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
{
org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
struct.fixedKeys = new java.util.ArrayList<java.lang.Integer>(_list0.size);
int _elem1;
for (int _i2 = 0; _i2 < _list0.size; ++_i2)
{
_elem1 = iprot.readI32();
struct.fixedKeys.add(_elem1);
}
iprot.readListEnd();
}
struct.setFixedKeysIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 2: // VARIABLE_TAIL_KEYS
if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
{
org.apache.thrift.protocol.TList _list3 = iprot.readListBegin();
struct.variableTailKeys = new java.util.ArrayList<ColumnHashType>(_list3.size);
@org.apache.thrift.annotation.Nullable ColumnHashType _elem4;
for (int _i5 = 0; _i5 < _list3.size; ++_i5)
{
_elem4 = it.cavallium.rockserver.core.common.api.ColumnHashType.findByValue(iprot.readI32());
if (_elem4 != null)
{
struct.variableTailKeys.add(_elem4);
}
}
iprot.readListEnd();
}
struct.setVariableTailKeysIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 3: // HAS_VALUE
if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
struct.hasValue = iprot.readBool();
struct.setHasValueIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot, ColumnSchema struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.fixedKeys != null) {
oprot.writeFieldBegin(FIXED_KEYS_FIELD_DESC);
{
oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, struct.fixedKeys.size()));
for (int _iter6 : struct.fixedKeys)
{
oprot.writeI32(_iter6);
}
oprot.writeListEnd();
}
oprot.writeFieldEnd();
}
if (struct.variableTailKeys != null) {
oprot.writeFieldBegin(VARIABLE_TAIL_KEYS_FIELD_DESC);
{
oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, struct.variableTailKeys.size()));
for (ColumnHashType _iter7 : struct.variableTailKeys)
{
oprot.writeI32(_iter7.getValue());
}
oprot.writeListEnd();
}
oprot.writeFieldEnd();
}
oprot.writeFieldBegin(HAS_VALUE_FIELD_DESC);
oprot.writeBool(struct.hasValue);
oprot.writeFieldEnd();
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class ColumnSchemaTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public ColumnSchemaTupleScheme getScheme() {
return new ColumnSchemaTupleScheme();
}
}
private static class ColumnSchemaTupleScheme extends org.apache.thrift.scheme.TupleScheme<ColumnSchema> {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, ColumnSchema struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetFixedKeys()) {
optionals.set(0);
}
if (struct.isSetVariableTailKeys()) {
optionals.set(1);
}
if (struct.isSetHasValue()) {
optionals.set(2);
}
oprot.writeBitSet(optionals, 3);
if (struct.isSetFixedKeys()) {
{
oprot.writeI32(struct.fixedKeys.size());
for (int _iter8 : struct.fixedKeys)
{
oprot.writeI32(_iter8);
}
}
}
if (struct.isSetVariableTailKeys()) {
{
oprot.writeI32(struct.variableTailKeys.size());
for (ColumnHashType _iter9 : struct.variableTailKeys)
{
oprot.writeI32(_iter9.getValue());
}
}
}
if (struct.isSetHasValue()) {
oprot.writeBool(struct.hasValue);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, ColumnSchema struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet incoming = iprot.readBitSet(3);
if (incoming.get(0)) {
{
org.apache.thrift.protocol.TList _list10 = iprot.readListBegin(org.apache.thrift.protocol.TType.I32);
struct.fixedKeys = new java.util.ArrayList<java.lang.Integer>(_list10.size);
int _elem11;
for (int _i12 = 0; _i12 < _list10.size; ++_i12)
{
_elem11 = iprot.readI32();
struct.fixedKeys.add(_elem11);
}
}
struct.setFixedKeysIsSet(true);
}
if (incoming.get(1)) {
{
org.apache.thrift.protocol.TList _list13 = iprot.readListBegin(org.apache.thrift.protocol.TType.I32);
struct.variableTailKeys = new java.util.ArrayList<ColumnHashType>(_list13.size);
@org.apache.thrift.annotation.Nullable ColumnHashType _elem14;
for (int _i15 = 0; _i15 < _list13.size; ++_i15)
{
_elem14 = it.cavallium.rockserver.core.common.api.ColumnHashType.findByValue(iprot.readI32());
if (_elem14 != null)
{
struct.variableTailKeys.add(_elem14);
}
}
}
struct.setVariableTailKeysIsSet(true);
}
if (incoming.get(2)) {
struct.hasValue = iprot.readBool();
struct.setHasValueIsSet(true);
}
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
}
}

View File

@ -0,0 +1,518 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
public class Delta implements org.apache.thrift.TBase<Delta, Delta._Fields>, java.io.Serializable, Cloneable, Comparable<Delta> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Delta");
private static final org.apache.thrift.protocol.TField PREVIOUS_FIELD_DESC = new org.apache.thrift.protocol.TField("previous", org.apache.thrift.protocol.TType.STRING, (short)1);
private static final org.apache.thrift.protocol.TField CURRENT_FIELD_DESC = new org.apache.thrift.protocol.TField("current", org.apache.thrift.protocol.TType.STRING, (short)2);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DeltaStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DeltaTupleSchemeFactory();
public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer previous; // optional
public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer current; // optional
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
PREVIOUS((short)1, "previous"),
CURRENT((short)2, "current");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // PREVIOUS
return PREVIOUS;
case 2: // CURRENT
return CURRENT;
default:
return null;
}
}
/**
* Find the _Fields constant that matches fieldId, throwing an exception
* if it is not found.
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
return fields;
}
/**
* Find the _Fields constant that matches name, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByName(java.lang.String name) {
return byName.get(name);
}
private final short _thriftId;
private final java.lang.String _fieldName;
_Fields(short thriftId, java.lang.String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
@Override
public short getThriftFieldId() {
return _thriftId;
}
@Override
public java.lang.String getFieldName() {
return _fieldName;
}
}
// isset id assignments
private static final _Fields optionals[] = {_Fields.PREVIOUS,_Fields.CURRENT};
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.PREVIOUS, new org.apache.thrift.meta_data.FieldMetaData("previous", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)));
tmpMap.put(_Fields.CURRENT, new org.apache.thrift.meta_data.FieldMetaData("current", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Delta.class, metaDataMap);
}
public Delta() {
}
/**
* Performs a deep copy on <i>other</i>.
*/
public Delta(Delta other) {
if (other.isSetPrevious()) {
this.previous = org.apache.thrift.TBaseHelper.copyBinary(other.previous);
}
if (other.isSetCurrent()) {
this.current = org.apache.thrift.TBaseHelper.copyBinary(other.current);
}
}
@Override
public Delta deepCopy() {
return new Delta(this);
}
@Override
public void clear() {
this.previous = null;
this.current = null;
}
public byte[] getPrevious() {
setPrevious(org.apache.thrift.TBaseHelper.rightSize(previous));
return previous == null ? null : previous.array();
}
public java.nio.ByteBuffer bufferForPrevious() {
return org.apache.thrift.TBaseHelper.copyBinary(previous);
}
public Delta setPrevious(byte[] previous) {
this.previous = previous == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(previous.clone());
return this;
}
public Delta setPrevious(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer previous) {
this.previous = org.apache.thrift.TBaseHelper.copyBinary(previous);
return this;
}
public void unsetPrevious() {
this.previous = null;
}
/** Returns true if field previous is set (has been assigned a value) and false otherwise */
public boolean isSetPrevious() {
return this.previous != null;
}
public void setPreviousIsSet(boolean value) {
if (!value) {
this.previous = null;
}
}
public byte[] getCurrent() {
setCurrent(org.apache.thrift.TBaseHelper.rightSize(current));
return current == null ? null : current.array();
}
public java.nio.ByteBuffer bufferForCurrent() {
return org.apache.thrift.TBaseHelper.copyBinary(current);
}
public Delta setCurrent(byte[] current) {
this.current = current == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(current.clone());
return this;
}
public Delta setCurrent(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer current) {
this.current = org.apache.thrift.TBaseHelper.copyBinary(current);
return this;
}
public void unsetCurrent() {
this.current = null;
}
/** Returns true if field current is set (has been assigned a value) and false otherwise */
public boolean isSetCurrent() {
return this.current != null;
}
public void setCurrentIsSet(boolean value) {
if (!value) {
this.current = null;
}
}
@Override
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case PREVIOUS:
if (value == null) {
unsetPrevious();
} else {
if (value instanceof byte[]) {
setPrevious((byte[])value);
} else {
setPrevious((java.nio.ByteBuffer)value);
}
}
break;
case CURRENT:
if (value == null) {
unsetCurrent();
} else {
if (value instanceof byte[]) {
setCurrent((byte[])value);
} else {
setCurrent((java.nio.ByteBuffer)value);
}
}
break;
}
}
@org.apache.thrift.annotation.Nullable
@Override
public java.lang.Object getFieldValue(_Fields field) {
switch (field) {
case PREVIOUS:
return getPrevious();
case CURRENT:
return getCurrent();
}
throw new java.lang.IllegalStateException();
}
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
@Override
public boolean isSet(_Fields field) {
if (field == null) {
throw new java.lang.IllegalArgumentException();
}
switch (field) {
case PREVIOUS:
return isSetPrevious();
case CURRENT:
return isSetCurrent();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
if (that instanceof Delta)
return this.equals((Delta)that);
return false;
}
public boolean equals(Delta that) {
if (that == null)
return false;
if (this == that)
return true;
boolean this_present_previous = true && this.isSetPrevious();
boolean that_present_previous = true && that.isSetPrevious();
if (this_present_previous || that_present_previous) {
if (!(this_present_previous && that_present_previous))
return false;
if (!this.previous.equals(that.previous))
return false;
}
boolean this_present_current = true && this.isSetCurrent();
boolean that_present_current = true && that.isSetCurrent();
if (this_present_current || that_present_current) {
if (!(this_present_current && that_present_current))
return false;
if (!this.current.equals(that.current))
return false;
}
return true;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = hashCode * 8191 + ((isSetPrevious()) ? 131071 : 524287);
if (isSetPrevious())
hashCode = hashCode * 8191 + previous.hashCode();
hashCode = hashCode * 8191 + ((isSetCurrent()) ? 131071 : 524287);
if (isSetCurrent())
hashCode = hashCode * 8191 + current.hashCode();
return hashCode;
}
@Override
public int compareTo(Delta other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0;
lastComparison = java.lang.Boolean.compare(isSetPrevious(), other.isSetPrevious());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetPrevious()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.previous, other.previous);
if (lastComparison != 0) {
return lastComparison;
}
}
lastComparison = java.lang.Boolean.compare(isSetCurrent(), other.isSetCurrent());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetCurrent()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.current, other.current);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@org.apache.thrift.annotation.Nullable
@Override
public _Fields fieldForId(int fieldId) {
return _Fields.findByThriftId(fieldId);
}
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@Override
public java.lang.String toString() {
java.lang.StringBuilder sb = new java.lang.StringBuilder("Delta(");
boolean first = true;
if (isSetPrevious()) {
sb.append("previous:");
if (this.previous == null) {
sb.append("null");
} else {
org.apache.thrift.TBaseHelper.toString(this.previous, sb);
}
first = false;
}
if (isSetCurrent()) {
if (!first) sb.append(", ");
sb.append("current:");
if (this.current == null) {
sb.append("null");
} else {
org.apache.thrift.TBaseHelper.toString(this.current, sb);
}
first = false;
}
sb.append(")");
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
try {
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class DeltaStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public DeltaStandardScheme getScheme() {
return new DeltaStandardScheme();
}
}
private static class DeltaStandardScheme extends org.apache.thrift.scheme.StandardScheme<Delta> {
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot, Delta struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 1: // PREVIOUS
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.previous = iprot.readBinary();
struct.setPreviousIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 2: // CURRENT
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.current = iprot.readBinary();
struct.setCurrentIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot, Delta struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.previous != null) {
if (struct.isSetPrevious()) {
oprot.writeFieldBegin(PREVIOUS_FIELD_DESC);
oprot.writeBinary(struct.previous);
oprot.writeFieldEnd();
}
}
if (struct.current != null) {
if (struct.isSetCurrent()) {
oprot.writeFieldBegin(CURRENT_FIELD_DESC);
oprot.writeBinary(struct.current);
oprot.writeFieldEnd();
}
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class DeltaTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public DeltaTupleScheme getScheme() {
return new DeltaTupleScheme();
}
}
private static class DeltaTupleScheme extends org.apache.thrift.scheme.TupleScheme<Delta> {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, Delta struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetPrevious()) {
optionals.set(0);
}
if (struct.isSetCurrent()) {
optionals.set(1);
}
oprot.writeBitSet(optionals, 2);
if (struct.isSetPrevious()) {
oprot.writeBinary(struct.previous);
}
if (struct.isSetCurrent()) {
oprot.writeBinary(struct.current);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, Delta struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet incoming = iprot.readBitSet(2);
if (incoming.get(0)) {
struct.previous = iprot.readBinary();
struct.setPreviousIsSet(true);
}
if (incoming.get(1)) {
struct.current = iprot.readBinary();
struct.setCurrentIsSet(true);
}
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
}
}

View File

@ -0,0 +1,490 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
/**
* Structs can also be exceptions, if they are nasty.
*/
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
public class InvalidOperation extends org.apache.thrift.TException implements org.apache.thrift.TBase<InvalidOperation, InvalidOperation._Fields>, java.io.Serializable, Cloneable, Comparable<InvalidOperation> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InvalidOperation");
private static final org.apache.thrift.protocol.TField WHAT_OP_FIELD_DESC = new org.apache.thrift.protocol.TField("whatOp", org.apache.thrift.protocol.TType.I32, (short)1);
private static final org.apache.thrift.protocol.TField WHY_FIELD_DESC = new org.apache.thrift.protocol.TField("why", org.apache.thrift.protocol.TType.STRING, (short)2);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new InvalidOperationStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new InvalidOperationTupleSchemeFactory();
public int whatOp; // required
public @org.apache.thrift.annotation.Nullable java.lang.String why; // required
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
WHAT_OP((short)1, "whatOp"),
WHY((short)2, "why");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // WHAT_OP
return WHAT_OP;
case 2: // WHY
return WHY;
default:
return null;
}
}
/**
* Find the _Fields constant that matches fieldId, throwing an exception
* if it is not found.
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
return fields;
}
/**
* Find the _Fields constant that matches name, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByName(java.lang.String name) {
return byName.get(name);
}
private final short _thriftId;
private final java.lang.String _fieldName;
_Fields(short thriftId, java.lang.String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
@Override
public short getThriftFieldId() {
return _thriftId;
}
@Override
public java.lang.String getFieldName() {
return _fieldName;
}
}
// isset id assignments
private static final int __WHATOP_ISSET_ID = 0;
private byte __isset_bitfield = 0;
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.WHAT_OP, new org.apache.thrift.meta_data.FieldMetaData("whatOp", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
tmpMap.put(_Fields.WHY, new org.apache.thrift.meta_data.FieldMetaData("why", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(InvalidOperation.class, metaDataMap);
}
public InvalidOperation() {
}
public InvalidOperation(
int whatOp,
java.lang.String why)
{
this();
this.whatOp = whatOp;
setWhatOpIsSet(true);
this.why = why;
}
/**
* Performs a deep copy on <i>other</i>.
*/
public InvalidOperation(InvalidOperation other) {
__isset_bitfield = other.__isset_bitfield;
this.whatOp = other.whatOp;
if (other.isSetWhy()) {
this.why = other.why;
}
}
@Override
public InvalidOperation deepCopy() {
return new InvalidOperation(this);
}
@Override
public void clear() {
setWhatOpIsSet(false);
this.whatOp = 0;
this.why = null;
}
public int getWhatOp() {
return this.whatOp;
}
public InvalidOperation setWhatOp(int whatOp) {
this.whatOp = whatOp;
setWhatOpIsSet(true);
return this;
}
public void unsetWhatOp() {
__isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WHATOP_ISSET_ID);
}
/** Returns true if field whatOp is set (has been assigned a value) and false otherwise */
public boolean isSetWhatOp() {
return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WHATOP_ISSET_ID);
}
public void setWhatOpIsSet(boolean value) {
__isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WHATOP_ISSET_ID, value);
}
@org.apache.thrift.annotation.Nullable
public java.lang.String getWhy() {
return this.why;
}
public InvalidOperation setWhy(@org.apache.thrift.annotation.Nullable java.lang.String why) {
this.why = why;
return this;
}
public void unsetWhy() {
this.why = null;
}
/** Returns true if field why is set (has been assigned a value) and false otherwise */
public boolean isSetWhy() {
return this.why != null;
}
public void setWhyIsSet(boolean value) {
if (!value) {
this.why = null;
}
}
@Override
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case WHAT_OP:
if (value == null) {
unsetWhatOp();
} else {
setWhatOp((java.lang.Integer)value);
}
break;
case WHY:
if (value == null) {
unsetWhy();
} else {
setWhy((java.lang.String)value);
}
break;
}
}
@org.apache.thrift.annotation.Nullable
@Override
public java.lang.Object getFieldValue(_Fields field) {
switch (field) {
case WHAT_OP:
return getWhatOp();
case WHY:
return getWhy();
}
throw new java.lang.IllegalStateException();
}
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
@Override
public boolean isSet(_Fields field) {
if (field == null) {
throw new java.lang.IllegalArgumentException();
}
switch (field) {
case WHAT_OP:
return isSetWhatOp();
case WHY:
return isSetWhy();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
if (that instanceof InvalidOperation)
return this.equals((InvalidOperation)that);
return false;
}
public boolean equals(InvalidOperation that) {
if (that == null)
return false;
if (this == that)
return true;
boolean this_present_whatOp = true;
boolean that_present_whatOp = true;
if (this_present_whatOp || that_present_whatOp) {
if (!(this_present_whatOp && that_present_whatOp))
return false;
if (this.whatOp != that.whatOp)
return false;
}
boolean this_present_why = true && this.isSetWhy();
boolean that_present_why = true && that.isSetWhy();
if (this_present_why || that_present_why) {
if (!(this_present_why && that_present_why))
return false;
if (!this.why.equals(that.why))
return false;
}
return true;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = hashCode * 8191 + whatOp;
hashCode = hashCode * 8191 + ((isSetWhy()) ? 131071 : 524287);
if (isSetWhy())
hashCode = hashCode * 8191 + why.hashCode();
return hashCode;
}
@Override
public int compareTo(InvalidOperation other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0;
lastComparison = java.lang.Boolean.compare(isSetWhatOp(), other.isSetWhatOp());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetWhatOp()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.whatOp, other.whatOp);
if (lastComparison != 0) {
return lastComparison;
}
}
lastComparison = java.lang.Boolean.compare(isSetWhy(), other.isSetWhy());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetWhy()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.why, other.why);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@org.apache.thrift.annotation.Nullable
@Override
public _Fields fieldForId(int fieldId) {
return _Fields.findByThriftId(fieldId);
}
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@Override
public java.lang.String toString() {
java.lang.StringBuilder sb = new java.lang.StringBuilder("InvalidOperation(");
boolean first = true;
sb.append("whatOp:");
sb.append(this.whatOp);
first = false;
if (!first) sb.append(", ");
sb.append("why:");
if (this.why == null) {
sb.append("null");
} else {
sb.append(this.why);
}
first = false;
sb.append(")");
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bitfield = 0;
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class InvalidOperationStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public InvalidOperationStandardScheme getScheme() {
return new InvalidOperationStandardScheme();
}
}
private static class InvalidOperationStandardScheme extends org.apache.thrift.scheme.StandardScheme<InvalidOperation> {
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot, InvalidOperation struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 1: // WHAT_OP
if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
struct.whatOp = iprot.readI32();
struct.setWhatOpIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 2: // WHY
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.why = iprot.readString();
struct.setWhyIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot, InvalidOperation struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
oprot.writeFieldBegin(WHAT_OP_FIELD_DESC);
oprot.writeI32(struct.whatOp);
oprot.writeFieldEnd();
if (struct.why != null) {
oprot.writeFieldBegin(WHY_FIELD_DESC);
oprot.writeString(struct.why);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class InvalidOperationTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public InvalidOperationTupleScheme getScheme() {
return new InvalidOperationTupleScheme();
}
}
private static class InvalidOperationTupleScheme extends org.apache.thrift.scheme.TupleScheme<InvalidOperation> {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, InvalidOperation struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetWhatOp()) {
optionals.set(0);
}
if (struct.isSetWhy()) {
optionals.set(1);
}
oprot.writeBitSet(optionals, 2);
if (struct.isSetWhatOp()) {
oprot.writeI32(struct.whatOp);
}
if (struct.isSetWhy()) {
oprot.writeString(struct.why);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, InvalidOperation struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet incoming = iprot.readBitSet(2);
if (incoming.get(0)) {
struct.whatOp = iprot.readI32();
struct.setWhatOpIsSet(true);
}
if (incoming.get(1)) {
struct.why = iprot.readString();
struct.setWhyIsSet(true);
}
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
}
}

View File

@ -0,0 +1,64 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
public enum Operation implements org.apache.thrift.TEnum {
NOTHING(1),
PREVIOUS(2),
CURRENT(3),
FOR_UPDATE(4),
EXISTS(5),
DELTA(6),
MULTI(7),
CHANGED(8),
PREVIOUS_PRESENCE(9);
private final int value;
private Operation(int value) {
this.value = value;
}
/**
* Get the integer value of this enum value, as defined in the Thrift IDL.
*/
@Override
public int getValue() {
return value;
}
/**
* Find a the enum type by its integer value, as defined in the Thrift IDL.
* @return null if the value is not found.
*/
@org.apache.thrift.annotation.Nullable
public static Operation findByValue(int value) {
switch (value) {
case 1:
return NOTHING;
case 2:
return PREVIOUS;
case 3:
return CURRENT;
case 4:
return FOR_UPDATE;
case 5:
return EXISTS;
case 6:
return DELTA;
case 7:
return MULTI;
case 8:
return CHANGED;
case 9:
return PREVIOUS_PRESENCE;
default:
return null;
}
}
}

View File

@ -0,0 +1,398 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
public class OptionalBinary implements org.apache.thrift.TBase<OptionalBinary, OptionalBinary._Fields>, java.io.Serializable, Cloneable, Comparable<OptionalBinary> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("OptionalBinary");
private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)1);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new OptionalBinaryStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new OptionalBinaryTupleSchemeFactory();
public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer value; // optional
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
VALUE((short)1, "value");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // VALUE
return VALUE;
default:
return null;
}
}
/**
* Find the _Fields constant that matches fieldId, throwing an exception
* if it is not found.
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
return fields;
}
/**
* Find the _Fields constant that matches name, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByName(java.lang.String name) {
return byName.get(name);
}
private final short _thriftId;
private final java.lang.String _fieldName;
_Fields(short thriftId, java.lang.String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
@Override
public short getThriftFieldId() {
return _thriftId;
}
@Override
public java.lang.String getFieldName() {
return _fieldName;
}
}
// isset id assignments
private static final _Fields optionals[] = {_Fields.VALUE};
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(OptionalBinary.class, metaDataMap);
}
public OptionalBinary() {
}
/**
* Performs a deep copy on <i>other</i>.
*/
public OptionalBinary(OptionalBinary other) {
if (other.isSetValue()) {
this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
}
}
@Override
public OptionalBinary deepCopy() {
return new OptionalBinary(this);
}
@Override
public void clear() {
this.value = null;
}
public byte[] getValue() {
setValue(org.apache.thrift.TBaseHelper.rightSize(value));
return value == null ? null : value.array();
}
public java.nio.ByteBuffer bufferForValue() {
return org.apache.thrift.TBaseHelper.copyBinary(value);
}
public OptionalBinary setValue(byte[] value) {
this.value = value == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(value.clone());
return this;
}
public OptionalBinary setValue(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer value) {
this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
return this;
}
public void unsetValue() {
this.value = null;
}
/** Returns true if field value is set (has been assigned a value) and false otherwise */
public boolean isSetValue() {
return this.value != null;
}
public void setValueIsSet(boolean value) {
if (!value) {
this.value = null;
}
}
@Override
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case VALUE:
if (value == null) {
unsetValue();
} else {
if (value instanceof byte[]) {
setValue((byte[])value);
} else {
setValue((java.nio.ByteBuffer)value);
}
}
break;
}
}
@org.apache.thrift.annotation.Nullable
@Override
public java.lang.Object getFieldValue(_Fields field) {
switch (field) {
case VALUE:
return getValue();
}
throw new java.lang.IllegalStateException();
}
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
@Override
public boolean isSet(_Fields field) {
if (field == null) {
throw new java.lang.IllegalArgumentException();
}
switch (field) {
case VALUE:
return isSetValue();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
if (that instanceof OptionalBinary)
return this.equals((OptionalBinary)that);
return false;
}
public boolean equals(OptionalBinary that) {
if (that == null)
return false;
if (this == that)
return true;
boolean this_present_value = true && this.isSetValue();
boolean that_present_value = true && that.isSetValue();
if (this_present_value || that_present_value) {
if (!(this_present_value && that_present_value))
return false;
if (!this.value.equals(that.value))
return false;
}
return true;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
if (isSetValue())
hashCode = hashCode * 8191 + value.hashCode();
return hashCode;
}
@Override
public int compareTo(OptionalBinary other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0;
lastComparison = java.lang.Boolean.compare(isSetValue(), other.isSetValue());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetValue()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@org.apache.thrift.annotation.Nullable
@Override
public _Fields fieldForId(int fieldId) {
return _Fields.findByThriftId(fieldId);
}
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@Override
public java.lang.String toString() {
java.lang.StringBuilder sb = new java.lang.StringBuilder("OptionalBinary(");
boolean first = true;
if (isSetValue()) {
sb.append("value:");
if (this.value == null) {
sb.append("null");
} else {
org.apache.thrift.TBaseHelper.toString(this.value, sb);
}
first = false;
}
sb.append(")");
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
try {
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class OptionalBinaryStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public OptionalBinaryStandardScheme getScheme() {
return new OptionalBinaryStandardScheme();
}
}
private static class OptionalBinaryStandardScheme extends org.apache.thrift.scheme.StandardScheme<OptionalBinary> {
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot, OptionalBinary struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 1: // VALUE
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.value = iprot.readBinary();
struct.setValueIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot, OptionalBinary struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.value != null) {
if (struct.isSetValue()) {
oprot.writeFieldBegin(VALUE_FIELD_DESC);
oprot.writeBinary(struct.value);
oprot.writeFieldEnd();
}
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class OptionalBinaryTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public OptionalBinaryTupleScheme getScheme() {
return new OptionalBinaryTupleScheme();
}
}
private static class OptionalBinaryTupleScheme extends org.apache.thrift.scheme.TupleScheme<OptionalBinary> {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, OptionalBinary struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetValue()) {
optionals.set(0);
}
oprot.writeBitSet(optionals, 1);
if (struct.isSetValue()) {
oprot.writeBinary(struct.value);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, OptionalBinary struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet incoming = iprot.readBitSet(1);
if (incoming.get(0)) {
struct.value = iprot.readBinary();
struct.setValueIsSet(true);
}
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,501 @@
/**
* Autogenerated by Thrift Compiler (0.19.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package it.cavallium.rockserver.core.common.api;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
public class UpdateBegin implements org.apache.thrift.TBase<UpdateBegin, UpdateBegin._Fields>, java.io.Serializable, Cloneable, Comparable<UpdateBegin> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UpdateBegin");
private static final org.apache.thrift.protocol.TField PREVIOUS_FIELD_DESC = new org.apache.thrift.protocol.TField("previous", org.apache.thrift.protocol.TType.STRING, (short)1);
private static final org.apache.thrift.protocol.TField UPDATE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("updateId", org.apache.thrift.protocol.TType.I64, (short)2);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UpdateBeginStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UpdateBeginTupleSchemeFactory();
public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer previous; // optional
public long updateId; // optional
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
PREVIOUS((short)1, "previous"),
UPDATE_ID((short)2, "updateId");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // PREVIOUS
return PREVIOUS;
case 2: // UPDATE_ID
return UPDATE_ID;
default:
return null;
}
}
/**
* Find the _Fields constant that matches fieldId, throwing an exception
* if it is not found.
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
return fields;
}
/**
* Find the _Fields constant that matches name, or null if its not found.
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByName(java.lang.String name) {
return byName.get(name);
}
private final short _thriftId;
private final java.lang.String _fieldName;
_Fields(short thriftId, java.lang.String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
@Override
public short getThriftFieldId() {
return _thriftId;
}
@Override
public java.lang.String getFieldName() {
return _fieldName;
}
}
// isset id assignments
private static final int __UPDATEID_ISSET_ID = 0;
private byte __isset_bitfield = 0;
private static final _Fields optionals[] = {_Fields.PREVIOUS,_Fields.UPDATE_ID};
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.PREVIOUS, new org.apache.thrift.meta_data.FieldMetaData("previous", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)));
tmpMap.put(_Fields.UPDATE_ID, new org.apache.thrift.meta_data.FieldMetaData("updateId", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UpdateBegin.class, metaDataMap);
}
public UpdateBegin() {
}
/**
* Performs a deep copy on <i>other</i>.
*/
public UpdateBegin(UpdateBegin other) {
__isset_bitfield = other.__isset_bitfield;
if (other.isSetPrevious()) {
this.previous = org.apache.thrift.TBaseHelper.copyBinary(other.previous);
}
this.updateId = other.updateId;
}
@Override
public UpdateBegin deepCopy() {
return new UpdateBegin(this);
}
@Override
public void clear() {
this.previous = null;
setUpdateIdIsSet(false);
this.updateId = 0;
}
public byte[] getPrevious() {
setPrevious(org.apache.thrift.TBaseHelper.rightSize(previous));
return previous == null ? null : previous.array();
}
public java.nio.ByteBuffer bufferForPrevious() {
return org.apache.thrift.TBaseHelper.copyBinary(previous);
}
public UpdateBegin setPrevious(byte[] previous) {
this.previous = previous == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(previous.clone());
return this;
}
public UpdateBegin setPrevious(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer previous) {
this.previous = org.apache.thrift.TBaseHelper.copyBinary(previous);
return this;
}
public void unsetPrevious() {
this.previous = null;
}
/** Returns true if field previous is set (has been assigned a value) and false otherwise */
public boolean isSetPrevious() {
return this.previous != null;
}
public void setPreviousIsSet(boolean value) {
if (!value) {
this.previous = null;
}
}
public long getUpdateId() {
return this.updateId;
}
public UpdateBegin setUpdateId(long updateId) {
this.updateId = updateId;
setUpdateIdIsSet(true);
return this;
}
public void unsetUpdateId() {
__isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __UPDATEID_ISSET_ID);
}
/** Returns true if field updateId is set (has been assigned a value) and false otherwise */
public boolean isSetUpdateId() {
return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __UPDATEID_ISSET_ID);
}
public void setUpdateIdIsSet(boolean value) {
__isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __UPDATEID_ISSET_ID, value);
}
@Override
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case PREVIOUS:
if (value == null) {
unsetPrevious();
} else {
if (value instanceof byte[]) {
setPrevious((byte[])value);
} else {
setPrevious((java.nio.ByteBuffer)value);
}
}
break;
case UPDATE_ID:
if (value == null) {
unsetUpdateId();
} else {
setUpdateId((java.lang.Long)value);
}
break;
}
}
@org.apache.thrift.annotation.Nullable
@Override
public java.lang.Object getFieldValue(_Fields field) {
switch (field) {
case PREVIOUS:
return getPrevious();
case UPDATE_ID:
return getUpdateId();
}
throw new java.lang.IllegalStateException();
}
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
@Override
public boolean isSet(_Fields field) {
if (field == null) {
throw new java.lang.IllegalArgumentException();
}
switch (field) {
case PREVIOUS:
return isSetPrevious();
case UPDATE_ID:
return isSetUpdateId();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
if (that instanceof UpdateBegin)
return this.equals((UpdateBegin)that);
return false;
}
public boolean equals(UpdateBegin that) {
if (that == null)
return false;
if (this == that)
return true;
boolean this_present_previous = true && this.isSetPrevious();
boolean that_present_previous = true && that.isSetPrevious();
if (this_present_previous || that_present_previous) {
if (!(this_present_previous && that_present_previous))
return false;
if (!this.previous.equals(that.previous))
return false;
}
boolean this_present_updateId = true && this.isSetUpdateId();
boolean that_present_updateId = true && that.isSetUpdateId();
if (this_present_updateId || that_present_updateId) {
if (!(this_present_updateId && that_present_updateId))
return false;
if (this.updateId != that.updateId)
return false;
}
return true;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = hashCode * 8191 + ((isSetPrevious()) ? 131071 : 524287);
if (isSetPrevious())
hashCode = hashCode * 8191 + previous.hashCode();
hashCode = hashCode * 8191 + ((isSetUpdateId()) ? 131071 : 524287);
if (isSetUpdateId())
hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(updateId);
return hashCode;
}
@Override
public int compareTo(UpdateBegin other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0;
lastComparison = java.lang.Boolean.compare(isSetPrevious(), other.isSetPrevious());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetPrevious()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.previous, other.previous);
if (lastComparison != 0) {
return lastComparison;
}
}
lastComparison = java.lang.Boolean.compare(isSetUpdateId(), other.isSetUpdateId());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetUpdateId()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updateId, other.updateId);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@org.apache.thrift.annotation.Nullable
@Override
public _Fields fieldForId(int fieldId) {
return _Fields.findByThriftId(fieldId);
}
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@Override
public java.lang.String toString() {
java.lang.StringBuilder sb = new java.lang.StringBuilder("UpdateBegin(");
boolean first = true;
if (isSetPrevious()) {
sb.append("previous:");
if (this.previous == null) {
sb.append("null");
} else {
org.apache.thrift.TBaseHelper.toString(this.previous, sb);
}
first = false;
}
if (isSetUpdateId()) {
if (!first) sb.append(", ");
sb.append("updateId:");
sb.append(this.updateId);
first = false;
}
sb.append(")");
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bitfield = 0;
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class UpdateBeginStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public UpdateBeginStandardScheme getScheme() {
return new UpdateBeginStandardScheme();
}
}
private static class UpdateBeginStandardScheme extends org.apache.thrift.scheme.StandardScheme<UpdateBegin> {
@Override
public void read(org.apache.thrift.protocol.TProtocol iprot, UpdateBegin struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 1: // PREVIOUS
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.previous = iprot.readBinary();
struct.setPreviousIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 2: // UPDATE_ID
if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
struct.updateId = iprot.readI64();
struct.setUpdateIdIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}
@Override
public void write(org.apache.thrift.protocol.TProtocol oprot, UpdateBegin struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.previous != null) {
if (struct.isSetPrevious()) {
oprot.writeFieldBegin(PREVIOUS_FIELD_DESC);
oprot.writeBinary(struct.previous);
oprot.writeFieldEnd();
}
}
if (struct.isSetUpdateId()) {
oprot.writeFieldBegin(UPDATE_ID_FIELD_DESC);
oprot.writeI64(struct.updateId);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class UpdateBeginTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
@Override
public UpdateBeginTupleScheme getScheme() {
return new UpdateBeginTupleScheme();
}
}
private static class UpdateBeginTupleScheme extends org.apache.thrift.scheme.TupleScheme<UpdateBegin> {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, UpdateBegin struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetPrevious()) {
optionals.set(0);
}
if (struct.isSetUpdateId()) {
optionals.set(1);
}
oprot.writeBitSet(optionals, 2);
if (struct.isSetPrevious()) {
oprot.writeBinary(struct.previous);
}
if (struct.isSetUpdateId()) {
oprot.writeI64(struct.updateId);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, UpdateBegin struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet incoming = iprot.readBitSet(2);
if (incoming.get(0)) {
struct.previous = iprot.readBinary();
struct.setPreviousIsSet(true);
}
if (incoming.get(1)) {
struct.updateId = iprot.readI64();
struct.setUpdateIdIsSet(true);
}
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
}
}

View File

@ -9,7 +9,7 @@ import org.github.gestalt.config.entity.ValidationError;
import org.github.gestalt.config.node.ConfigNode; import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.reflect.TypeCapture; import org.github.gestalt.config.reflect.TypeCapture;
import org.github.gestalt.config.tag.Tags; import org.github.gestalt.config.tag.Tags;
import org.github.gestalt.config.utils.ValidateOf; import org.github.gestalt.config.utils.GResultOf;
public class DataSizeDecoder implements Decoder<DataSize> { public class DataSizeDecoder implements Decoder<DataSize> {
@ -29,15 +29,19 @@ public class DataSizeDecoder implements Decoder<DataSize> {
} }
@Override @Override
public ValidateOf<DataSize> decode(String path, public GResultOf<DataSize> decode(String path,
Tags tags, Tags tags,
ConfigNode node, ConfigNode node,
TypeCapture<?> type, TypeCapture<?> type,
DecoderContext decoderContext) { DecoderContext decoderContext) {
try { try {
return ValidateOf.validateOf(new DataSize(node.getValue().orElseThrow()), List.of()); return GResultOf.resultOf(new DataSize(node.getValue().orElseThrow()), List.of());
} catch (Exception ex) { } catch (Exception ex) {
return ValidateOf.inValid(new ValidationError.DecodingNumberFormatException(path, node, name())); return GResultOf.errors(new ValidationError.DecodingNumberFormatException(path,
node,
name(),
decoderContext.getSecretConcealer()
));
} }
} }
} }

View File

@ -9,7 +9,7 @@ import org.github.gestalt.config.entity.ValidationError;
import org.github.gestalt.config.node.ConfigNode; import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.reflect.TypeCapture; import org.github.gestalt.config.reflect.TypeCapture;
import org.github.gestalt.config.tag.Tags; import org.github.gestalt.config.tag.Tags;
import org.github.gestalt.config.utils.ValidateOf; import org.github.gestalt.config.utils.GResultOf;
import org.rocksdb.CompressionType; import org.rocksdb.CompressionType;
public class DbCompressionDecoder implements Decoder<CompressionType> { public class DbCompressionDecoder implements Decoder<CompressionType> {
@ -30,15 +30,19 @@ public class DbCompressionDecoder implements Decoder<CompressionType> {
} }
@Override @Override
public ValidateOf<CompressionType> decode(String path, public GResultOf<CompressionType> decode(String path,
Tags tags, Tags tags,
ConfigNode node, ConfigNode node,
TypeCapture<?> type, TypeCapture<?> type,
DecoderContext decoderContext) { DecoderContext decoderContext) {
try { try {
return ValidateOf.validateOf(DatabaseCompression.valueOf(node.getValue().orElseThrow()).compressionType(), List.of()); return GResultOf.resultOf(DatabaseCompression.valueOf(node.getValue().orElseThrow()).compressionType(), List.of());
} catch (Exception ex) { } catch (Exception ex) {
return ValidateOf.inValid(new ValidationError.DecodingNumberFormatException(path, node, name())); return GResultOf.errors(new ValidationError.DecodingNumberFormatException(path,
node,
name(),
decoderContext.getSecretConcealer()
));
} }
} }
} }

View File

@ -5,15 +5,12 @@ import static it.cavallium.rockserver.core.impl.ColumnInstance.BIG_ENDIAN_BYTES;
import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithValue; import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithValue;
import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithoutValue; import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithoutValue;
import it.cavallium.rockserver.core.common.Callback; import it.cavallium.rockserver.core.common.RequestType;
import it.cavallium.rockserver.core.common.Callback.CallbackExists; import it.cavallium.rockserver.core.common.RequestType.RequestGet;
import it.cavallium.rockserver.core.common.Callback.CallbackForUpdate; import it.cavallium.rockserver.core.common.RequestType.RequestPut;
import it.cavallium.rockserver.core.common.Callback.GetCallback;
import it.cavallium.rockserver.core.common.Callback.IteratorCallback;
import it.cavallium.rockserver.core.common.Callback.PutCallback;
import it.cavallium.rockserver.core.common.ColumnSchema; import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.Delta; import it.cavallium.rockserver.core.common.Delta;
import it.cavallium.rockserver.core.common.RocksDBAPI; import it.cavallium.rockserver.core.common.RocksDBSyncAPI;
import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType; import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType;
import it.cavallium.rockserver.core.common.RocksDBRetryException; import it.cavallium.rockserver.core.common.RocksDBRetryException;
import it.cavallium.rockserver.core.common.UpdateContext; import it.cavallium.rockserver.core.common.UpdateContext;
@ -51,10 +48,9 @@ import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException; import org.rocksdb.RocksDBException;
import org.rocksdb.RocksIterator; import org.rocksdb.RocksIterator;
import org.rocksdb.Status.Code; import org.rocksdb.Status.Code;
import org.rocksdb.Transaction;
import org.rocksdb.WriteOptions; import org.rocksdb.WriteOptions;
public class EmbeddedDB implements RocksDBAPI, Closeable { public class EmbeddedDB implements RocksDBSyncAPI, Closeable {
private static final int INITIAL_DIRECT_READ_BYTE_BUF_SIZE_BYTES = 4096; private static final int INITIAL_DIRECT_READ_BYTE_BUF_SIZE_BYTES = 4096;
public static final long MAX_TRANSACTION_DURATION_MS = 10_000L; public static final long MAX_TRANSACTION_DURATION_MS = 10_000L;
@ -308,7 +304,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
long columnId, long columnId,
@NotNull MemorySegment @NotNull [] keys, @NotNull MemorySegment @NotNull [] keys,
@NotNull MemorySegment value, @NotNull MemorySegment value,
PutCallback<? super MemorySegment, T> callback) throws it.cavallium.rockserver.core.common.RocksDBException { RequestPut<? super MemorySegment, T> requestType) throws it.cavallium.rockserver.core.common.RocksDBException {
ops.beginOp(); ops.beginOp();
try { try {
// Column id // Column id
@ -320,7 +316,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
tx = null; tx = null;
} }
long updateId = tx != null && tx.isFromGetForUpdate() ? transactionOrUpdateId : 0L; long updateId = tx != null && tx.isFromGetForUpdate() ? transactionOrUpdateId : 0L;
return put(arena, tx, col, updateId, keys, value, callback); return put(arena, tx, col, updateId, keys, value, requestType);
} catch (it.cavallium.rockserver.core.common.RocksDBException ex) { } catch (it.cavallium.rockserver.core.common.RocksDBException ex) {
throw ex; throw ex;
} catch (Exception ex) { } catch (Exception ex) {
@ -376,12 +372,12 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
long updateId, long updateId,
@NotNull MemorySegment @NotNull[] keys, @NotNull MemorySegment @NotNull[] keys,
@NotNull MemorySegment value, @NotNull MemorySegment value,
PutCallback<? super MemorySegment, U> callback) throws it.cavallium.rockserver.core.common.RocksDBException { RequestPut<? super MemorySegment, U> callback) throws it.cavallium.rockserver.core.common.RocksDBException {
// Check for null value // Check for null value
col.checkNullableValue(value); col.checkNullableValue(value);
try { try {
boolean requirePreviousValue = Callback.requiresGettingPreviousValue(callback); boolean requirePreviousValue = RequestType.requiresGettingPreviousValue(callback);
boolean requirePreviousPresence = Callback.requiresGettingPreviousPresence(callback); boolean requirePreviousPresence = RequestType.requiresGettingPreviousPresence(callback);
boolean needsTx = col.hasBuckets() boolean needsTx = col.hasBuckets()
|| requirePreviousValue || requirePreviousValue
|| requirePreviousPresence; || requirePreviousPresence;
@ -413,7 +409,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_1, e); throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_1, e);
} }
} else { } else {
if (Callback.requiresGettingPreviousValue(callback)) { if (RequestType.requiresGettingPreviousValue(callback)) {
assert tx != null; assert tx != null;
try (var readOptions = new ReadOptions()) { try (var readOptions = new ReadOptions()) {
byte[] previousValueByteArray; byte[] previousValueByteArray;
@ -422,7 +418,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
} catch (RocksDBException e) { } catch (RocksDBException e) {
throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_2, e); throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_2, e);
} }
} else if (Callback.requiresGettingPreviousPresence(callback)) { } else if (RequestType.requiresGettingPreviousPresence(callback)) {
// todo: in the future this should be replaced with just keyExists // todo: in the future this should be replaced with just keyExists
assert tx != null; assert tx != null;
try (var readOptions = new ReadOptions()) { try (var readOptions = new ReadOptions()) {
@ -445,12 +441,12 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
} }
} }
} }
U result = Callback.safeCast(switch (callback) { U result = RequestType.safeCast(switch (callback) {
case Callback.CallbackVoid<?> ignored -> null; case RequestType.RequestNothing<?> ignored -> null;
case Callback.CallbackPrevious<?> ignored -> previousValue; case RequestType.RequestPrevious<?> ignored -> previousValue;
case Callback.CallbackPreviousPresence<?> ignored -> previousValue != null; case RequestType.RequestPreviousPresence<?> ignored -> previousValue != null;
case Callback.CallbackChanged<?> ignored -> !Utils.valueEquals(previousValue, value); case RequestType.RequestChanged<?> ignored -> !Utils.valueEquals(previousValue, value);
case Callback.CallbackDelta<?> ignored -> new Delta<>(previousValue, value); case RequestType.RequestDelta<?> ignored -> new Delta<>(previousValue, value);
}); });
if (updateId != 0L) { if (updateId != 0L) {
@ -484,12 +480,12 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
long transactionOrUpdateId, long transactionOrUpdateId,
long columnId, long columnId,
MemorySegment @NotNull [] keys, MemorySegment @NotNull [] keys,
GetCallback<? super MemorySegment, T> callback) throws it.cavallium.rockserver.core.common.RocksDBException { RequestGet<? super MemorySegment, T> requestType) throws it.cavallium.rockserver.core.common.RocksDBException {
// Column id // Column id
var col = getColumn(columnId); var col = getColumn(columnId);
Tx tx = transactionOrUpdateId != 0 ? getTransaction(transactionOrUpdateId, true) : null; Tx tx = transactionOrUpdateId != 0 ? getTransaction(transactionOrUpdateId, true) : null;
long updateId; long updateId;
if (callback instanceof Callback.CallbackForUpdate<?>) { if (requestType instanceof RequestType.RequestForUpdate<?>) {
if (tx == null) { if (tx == null) {
tx = openTransactionInternal(MAX_TRANSACTION_DURATION_MS, true); tx = openTransactionInternal(MAX_TRANSACTION_DURATION_MS, true);
updateId = allocateTransactionInternal(tx); updateId = allocateTransactionInternal(tx);
@ -501,7 +497,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
} }
try { try {
return get(arena, tx, updateId, col, keys, callback); return get(arena, tx, updateId, col, keys, requestType);
} catch (Throwable ex) { } catch (Throwable ex) {
if (updateId != 0 && tx.isFromGetForUpdate()) { if (updateId != 0 && tx.isFromGetForUpdate()) {
closeTransaction(updateId, false); closeTransaction(updateId, false);
@ -515,10 +511,10 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
long updateId, long updateId,
ColumnInstance col, ColumnInstance col,
MemorySegment @NotNull [] keys, MemorySegment @NotNull [] keys,
GetCallback<? super MemorySegment, T> callback) throws it.cavallium.rockserver.core.common.RocksDBException { RequestGet<? super MemorySegment, T> callback) throws it.cavallium.rockserver.core.common.RocksDBException {
ops.beginOp(); ops.beginOp();
try { try {
if (!col.schema().hasValue() && Callback.requiresGettingCurrentValue(callback)) { if (!col.schema().hasValue() && RequestType.requiresGettingCurrentValue(callback)) {
throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.VALUE_MUST_BE_NULL, throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.VALUE_MUST_BE_NULL,
"The specified callback requires a return value, but this column does not have values!"); "The specified callback requires a return value, but this column does not have values!");
} }
@ -541,8 +537,8 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.GET_1, e); throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.GET_1, e);
} }
} else { } else {
boolean shouldGetCurrent = Callback.requiresGettingCurrentValue(callback) boolean shouldGetCurrent = RequestType.requiresGettingCurrentValue(callback)
|| (tx != null && callback instanceof Callback.CallbackExists<?>); || (tx != null && callback instanceof RequestType.RequestExists<?>);
if (shouldGetCurrent) { if (shouldGetCurrent) {
try (var readOptions = new ReadOptions()) { try (var readOptions = new ReadOptions()) {
foundValue = dbGet(tx, col, arena, readOptions, calculatedKey); foundValue = dbGet(tx, col, arena, readOptions, calculatedKey);
@ -550,7 +546,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
} catch (RocksDBException e) { } catch (RocksDBException e) {
throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_2, e); throw it.cavallium.rockserver.core.common.RocksDBException.of(RocksDBErrorType.PUT_2, e);
} }
} else if (callback instanceof Callback.CallbackExists<?>) { } else if (callback instanceof RequestType.RequestExists<?>) {
// tx is always null here // tx is always null here
//noinspection ConstantValue //noinspection ConstantValue
assert tx == null; assert tx == null;
@ -561,14 +557,14 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
existsValue = false; existsValue = false;
} }
} }
return Callback.safeCast(switch (callback) { return RequestType.safeCast(switch (callback) {
case Callback.CallbackVoid<?> ignored -> null; case RequestType.RequestNothing<?> ignored -> null;
case Callback.CallbackCurrent<?> ignored -> foundValue; case RequestType.RequestCurrent<?> ignored -> foundValue;
case Callback.CallbackForUpdate<?> ignored -> { case RequestType.RequestForUpdate<?> ignored -> {
assert updateId != 0; assert updateId != 0;
yield new UpdateContext<>(foundValue, updateId); yield new UpdateContext<>(foundValue, updateId);
} }
case Callback.CallbackExists<?> ignored -> existsValue; case RequestType.RequestExists<?> ignored -> existsValue;
}); });
} catch (it.cavallium.rockserver.core.common.RocksDBException ex) { } catch (it.cavallium.rockserver.core.common.RocksDBException ex) {
throw ex; throw ex;
@ -634,7 +630,7 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
long iterationId, long iterationId,
long skipCount, long skipCount,
long takeCount, long takeCount,
@NotNull IteratorCallback<? super MemorySegment, T> callback) throws it.cavallium.rockserver.core.common.RocksDBException { @NotNull RequestType.RequestIterate<? super MemorySegment, T> requestType) throws it.cavallium.rockserver.core.common.RocksDBException {
ops.beginOp(); ops.beginOp();
try { try {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -0,0 +1,19 @@
package it.cavallium.rockserver.core.server;
import it.cavallium.rockserver.core.client.RocksDBConnection;
import java.io.Closeable;
import java.io.IOException;
public class Server implements Closeable {
private final RocksDBConnection client;
public Server(RocksDBConnection client) {
this.client = client;
}
@Override
public void close() throws IOException {
}
}

View File

@ -0,0 +1,47 @@
package it.cavallium.rockserver.core.server;
import it.cavallium.rockserver.core.client.ClientBuilder;
import it.cavallium.rockserver.core.client.EmbeddedConnection;
import it.cavallium.rockserver.core.client.RocksDBConnection;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnixDomainSocketAddress;
import java.nio.file.Path;
public class ServerBuilder {
private InetSocketAddress iNetAddress;
private UnixDomainSocketAddress unixAddress;
private String http2Host;
private int http2Port;
private RocksDBConnection client;
public void setUnixSocket(UnixDomainSocketAddress address) {
this.unixAddress = address;
}
public void setAddress(InetSocketAddress address) {
this.iNetAddress = address;
}
public void setHttpAddress(String host, int port) {
this.http2Host = host;
this.http2Port = port;
}
public void setClient(RocksDBConnection client) {
this.client = client;
}
public Server build() throws IOException {
if (http2Host != null) {
return new ThriftServer(client, http2Host, http2Port);
} else if (unixAddress != null) {
throw new UnsupportedOperationException("Not implemented: unix socket");
} else if (iNetAddress != null) {
throw new UnsupportedOperationException("Not implemented: inet address");
} else {
throw new UnsupportedOperationException("Please set a connection type");
}
}
}

View File

@ -0,0 +1,322 @@
package it.cavallium.rockserver.core.server;
import it.cavallium.rockserver.core.client.RocksDBConnection;
import it.cavallium.rockserver.core.common.RequestType;
import it.cavallium.rockserver.core.common.UpdateContext;
import it.cavallium.rockserver.core.common.api.ColumnHashType;
import it.cavallium.rockserver.core.common.api.ColumnSchema;
import it.cavallium.rockserver.core.common.api.Delta;
import it.cavallium.rockserver.core.common.api.OptionalBinary;
import it.cavallium.rockserver.core.common.api.RocksDB;
import it.cavallium.rockserver.core.common.api.RocksDB.AsyncIface;
import it.cavallium.rockserver.core.common.api.RocksDB.AsyncProcessor;
import it.cavallium.rockserver.core.common.api.UpdateBegin;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.io.IOException;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.function.BiConsumer;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TNonblockingServer.Args;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.jetbrains.annotations.NotNull;
public class ThriftServer extends Server {
private final AsyncIface handler;
public ThriftServer(RocksDBConnection client, String http2Host, int http2Port) throws IOException {
super(client);
this.handler = new RocksDB.AsyncIface() {
@Override
public void openTransaction(long timeoutMs, AsyncMethodCallback<Long> resultHandler) {
client.getAsyncApi().openTransactionAsync(timeoutMs).whenComplete(handleResult(resultHandler));
}
@Override
public void closeTransaction(long timeoutMs, boolean commit, AsyncMethodCallback<Boolean> resultHandler) {
client.getAsyncApi().closeTransactionAsync(timeoutMs, commit).whenComplete(handleResult(resultHandler));
}
@Override
public void closeFailedUpdate(long updateId, AsyncMethodCallback<Void> resultHandler) {
client.getAsyncApi().closeFailedUpdateAsync(updateId).whenComplete(handleResult(resultHandler));
}
@Override
public void createColumn(String name, ColumnSchema schema, AsyncMethodCallback<Long> resultHandler) {
client.getAsyncApi().createColumnAsync(name, columnSchemaToRecord(schema))
.whenComplete(handleResult(resultHandler));
}
@Override
public void deleteColumn(long columnId, AsyncMethodCallback<Void> resultHandler) {
client.getAsyncApi().deleteColumnAsync(columnId).whenComplete(handleResult(resultHandler));
}
@Override
public void getColumnId(String name, AsyncMethodCallback<Long> resultHandler) {
client.getAsyncApi().getColumnIdAsync(name).whenComplete(handleResult(resultHandler));
}
@Override
public void put(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
ByteBuffer value,
AsyncMethodCallback<Void> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.putAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), keyToRecord(value), RequestType.none())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void putGetPrevious(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
ByteBuffer value,
AsyncMethodCallback<OptionalBinary> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.putAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), keyToRecord(value), RequestType.previous())
.thenApply(ThriftServer::mapResult)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void putGetDelta(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
ByteBuffer value,
AsyncMethodCallback<Delta> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.putAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), keyToRecord(value), RequestType.delta())
.thenApply(ThriftServer::mapResult)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void putGetChanged(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
ByteBuffer value,
AsyncMethodCallback<Boolean> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.putAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), keyToRecord(value), RequestType.changed())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void putGetPreviousPresence(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
ByteBuffer value,
AsyncMethodCallback<Boolean> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.putAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), keyToRecord(value), RequestType.previousPresence())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void get(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
AsyncMethodCallback<OptionalBinary> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.getAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), RequestType.current())
.thenApply(ThriftServer::mapResult)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void getForUpdate(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
AsyncMethodCallback<UpdateBegin> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.getAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), RequestType.forUpdate())
.thenApply(ThriftServer::mapResult)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void exists(long transactionOrUpdateId,
long columnId,
List<ByteBuffer> keys,
AsyncMethodCallback<Boolean> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.getAsync(arena, transactionOrUpdateId, columnId, keysToRecord(keys), RequestType.exists())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void openIterator(long transactionId,
long columnId,
List<ByteBuffer> startKeysInclusive,
List<ByteBuffer> endKeysExclusive,
boolean reverse,
long timeoutMs,
AsyncMethodCallback<Long> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.openIteratorAsync(arena, transactionId, columnId, keysToRecord(startKeysInclusive), keysToRecord(endKeysExclusive), reverse, timeoutMs)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void closeIterator(long iteratorId, AsyncMethodCallback<Void> resultHandler) {
client.getAsyncApi()
.closeIteratorAsync(iteratorId)
.whenComplete(handleResult(resultHandler));
}
@Override
public void seekTo(long iterationId, List<ByteBuffer> keys, AsyncMethodCallback<Void> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.seekToAsync(arena, iterationId, keysToRecord(keys))
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void subsequent(long iterationId, long skipCount, long takeCount, AsyncMethodCallback<Void> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.subsequentAsync(arena, iterationId, skipCount, takeCount, RequestType.none())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void subsequentExists(long iterationId,
long skipCount,
long takeCount,
AsyncMethodCallback<Boolean> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.subsequentAsync(arena, iterationId, skipCount, takeCount, RequestType.exists())
.whenComplete(handleResultWithArena(arena, resultHandler));
}
@Override
public void subsequentMultiGet(long iterationId,
long skipCount,
long takeCount,
AsyncMethodCallback<List<OptionalBinary>> resultHandler) {
var arena = Arena.ofShared();
client.getAsyncApi()
.subsequentAsync(arena, iterationId, skipCount, takeCount, RequestType.multi())
.thenApply(ThriftServer::mapResult)
.whenComplete(handleResultWithArena(arena, resultHandler));
}
};
try {
var serverTransport = new TNonblockingServerSocket(new InetSocketAddress(http2Host, http2Port));
var server = new TNonblockingServer(new Args(serverTransport).processor(new AsyncProcessor<>(handler)));
server.serve();
} catch (TTransportException e) {
throw new IOException("Can't open server socket", e);
}
}
private @NotNull MemorySegment [] keysToRecord(List<@NotNull ByteBuffer> keys) {
if (keys == null) {
return null;
}
var result = new MemorySegment[keys.size()];
int i = 0;
for (ByteBuffer key : keys) {
result[i] = keyToRecord(key);
i++;
}
return result;
}
private @NotNull MemorySegment keyToRecord(@NotNull ByteBuffer key) {
return MemorySegment.ofBuffer(key);
}
private it.cavallium.rockserver.core.common.ColumnSchema columnSchemaToRecord(ColumnSchema schema) {
return it.cavallium.rockserver.core.common.ColumnSchema.of(new IntArrayList(schema.getFixedKeys()),
hashTypesToRecord(schema.getVariableTailKeys()),
schema.isHasValue()
);
}
private ObjectArrayList<it.cavallium.rockserver.core.common.ColumnHashType> hashTypesToRecord(List<ColumnHashType> variableTailKeys) {
var result = new ObjectArrayList<it.cavallium.rockserver.core.common.ColumnHashType>();
for (ColumnHashType variableTailKey : variableTailKeys) {
result.add(hashTypeToRecord(variableTailKey));
}
return result;
}
private it.cavallium.rockserver.core.common.ColumnHashType hashTypeToRecord(ColumnHashType variableTailKey) {
return it.cavallium.rockserver.core.common.ColumnHashType.valueOf(variableTailKey.name());
}
private static <T> BiConsumer<? super T, ? super Throwable> handleResult(AsyncMethodCallback<T> resultHandler) {
return (result, error) -> {
if (error != null) {
if (error instanceof Exception ex) {
resultHandler.onError(ex);
} else {
resultHandler.onError(new Exception(error));
}
} else {
resultHandler.onComplete(result);
}
};
}
private static <T> BiConsumer<? super T, ? super Throwable> handleResultWithArena(Arena arena,
AsyncMethodCallback<T> resultHandler) {
return (result, error) -> {
arena.close();
if (error != null) {
if (error instanceof Exception ex) {
resultHandler.onError(ex);
} else {
resultHandler.onError(new Exception(error));
}
} else {
resultHandler.onComplete(result);
}
};
}
private static OptionalBinary mapResult(MemorySegment memorySegment) {
return memorySegment != null ? new OptionalBinary().setValue(memorySegment.asByteBuffer()) : null;
}
private static UpdateBegin mapResult(UpdateContext<MemorySegment> context) {
return new UpdateBegin()
.setUpdateId(context.updateId())
.setPrevious(context.previous() != null ? context.previous().asByteBuffer() : null);
}
private static Delta mapResult(it.cavallium.rockserver.core.common.Delta<MemorySegment> delta) {
return new Delta()
.setPrevious(delta.previous() != null ? delta.previous().asByteBuffer() : null)
.setCurrent(delta.current() != null ? delta.current().asByteBuffer() : null);
}
private static List<OptionalBinary> mapResult(List<MemorySegment> multi) {
return multi.stream().map(ThriftServer::mapResult).toList();
}
}

View File

@ -7,7 +7,18 @@ module rockserver.core {
requires high.scale.lib; requires high.scale.lib;
requires org.github.gestalt.core; requires org.github.gestalt.core;
requires org.github.gestalt.hocon; requires org.github.gestalt.hocon;
requires it.unimi.dsi.fastutil.core; requires it.unimi.dsi.fastutil;
requires io.netty5.buffer;
requires io.netty5.codec;
requires io.netty5.codec.http2;
requires io.netty5.common;
requires io.netty5.handler;
requires io.netty5.transport;
requires io.netty5.transport.classes.io_uring;
requires io.netty5.transport.io_uring;
requires io.netty5.transport.unix.common;
requires io.netty5.codec.http;
requires org.apache.thrift;
exports it.cavallium.rockserver.core.client; exports it.cavallium.rockserver.core.client;
exports it.cavallium.rockserver.core.common; exports it.cavallium.rockserver.core.common;

View File

@ -0,0 +1,83 @@
namespace java it.cavallium.rockserver.core.common.api
struct ColumnSchema {
1: list<i32> fixedKeys,
2: list<ColumnHashType> variableTailKeys,
3: bool hasValue
}
enum ColumnHashType {
XXHASH32 = 1,
XXHASH8 = 2,
ALLSAME8 = 3
}
enum Operation {
NOTHING = 1,
PREVIOUS = 2,
CURRENT = 3,
FOR_UPDATE = 4,
EXISTS = 5,
DELTA = 6,
MULTI = 7,
CHANGED = 8,
PREVIOUS_PRESENCE = 9
}
struct Delta {
1: optional binary previous,
2: optional binary current
}
struct OptionalBinary {
1: optional binary value
}
struct UpdateBegin {
1: optional binary previous,
2: optional i64 updateId
}
service RocksDB {
i64 openTransaction(1: required i64 timeoutMs),
bool closeTransaction(1: required i64 timeoutMs, 2: required bool commit),
void closeFailedUpdate(1: required i64 updateId),
i64 createColumn(1: required string name, 2: required ColumnSchema schema),
void deleteColumn(1: required i64 columnId),
i64 getColumnId(1: required string name),
oneway void put(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys, 4: required binary value),
OptionalBinary putGetPrevious(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys, 4: required binary value),
Delta putGetDelta(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys, 4: required binary value),
bool putGetChanged(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys, 4: required binary value),
bool putGetPreviousPresence(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys, 4: required binary value),
OptionalBinary get(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys),
UpdateBegin getForUpdate(1: required i64 transactionOrUpdateId, 2: required i64 columnId, 3: required list<binary> keys),
bool exists(1: required i64 transactionOrUpdateId, 3: required i64 columnId, 4: required list<binary> keys),
i64 openIterator(1: required i64 transactionId, 2: required i64 columnId, 3: required list<binary> startKeysInclusive, 4: list<binary> endKeysExclusive, 5: required bool reverse, 6: required i64 timeoutMs),
void closeIterator(1: required i64 iteratorId),
void seekTo(1: required i64 iterationId, 2: required list<binary> keys),
oneway void subsequent(1: required i64 iterationId, 2: required i64 skipCount, 3: required i64 takeCount),
bool subsequentExists(1: required i64 iterationId, 2: required i64 skipCount, 3: required i64 takeCount),
list<OptionalBinary> subsequentMultiGet(1: required i64 iterationId, 2: required i64 skipCount, 3: required i64 takeCount),
}

View File

@ -3,11 +3,10 @@ package it.cavallium.rockserver.core.impl.test;
import static it.cavallium.rockserver.core.common.Utils.toMemorySegmentSimple; import static it.cavallium.rockserver.core.common.Utils.toMemorySegmentSimple;
import it.cavallium.rockserver.core.client.EmbeddedConnection; import it.cavallium.rockserver.core.client.EmbeddedConnection;
import it.cavallium.rockserver.core.common.Callback; import it.cavallium.rockserver.core.common.RequestType;
import it.cavallium.rockserver.core.common.ColumnHashType; import it.cavallium.rockserver.core.common.ColumnHashType;
import it.cavallium.rockserver.core.common.ColumnSchema; import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.Delta; import it.cavallium.rockserver.core.common.Delta;
import it.cavallium.rockserver.core.common.RocksDBException;
import it.cavallium.rockserver.core.common.RocksDBRetryException; import it.cavallium.rockserver.core.common.RocksDBRetryException;
import it.cavallium.rockserver.core.common.Utils; import it.cavallium.rockserver.core.common.Utils;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
@ -111,13 +110,13 @@ abstract class EmbeddedDBTest {
} }
void fillSomeKeys() { void fillSomeKeys() {
Assertions.assertNull(db.put(arena, 0, colId, key1, value1, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, key1, value1, RequestType.none()));
Assertions.assertNull(db.put(arena, 0, colId, collidingKey1, value2, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, collidingKey1, value2, RequestType.none()));
Assertions.assertNull(db.put(arena, 0, colId, key2, bigValue, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, key2, bigValue, RequestType.none()));
for (int i = 0; i < Byte.MAX_VALUE; i++) { for (int i = 0; i < Byte.MAX_VALUE; i++) {
var keyI = getKeyI(i); var keyI = getKeyI(i);
var valueI = getValueI(i); var valueI = getValueI(i);
Assertions.assertNull(db.put(arena, 0, colId, keyI, valueI, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, keyI, valueI, RequestType.none()));
} }
} }
@ -158,17 +157,17 @@ abstract class EmbeddedDBTest {
var key = getKey1(); var key = getKey1();
if (!getHasValues()) { if (!getHasValues()) {
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, toMemorySegmentSimple(arena, 123), Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, toMemorySegmentSimple(arena, 123), RequestType.delta()));
} else { } else {
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, MemorySegment.NULL, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, MemorySegment.NULL, RequestType.delta()));
} }
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, null, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, null, RequestType.delta()));
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, null, value1, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, null, value1, RequestType.delta()));
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, null, null, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, null, null, RequestType.delta()));
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, value1, null)); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, colId, key, value1, null));
Assertions.assertThrows(Exception.class, () -> db.put(arena, 1, colId, key, value1, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 1, colId, key, value1, RequestType.delta()));
Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, 21203, key, value1, Callback.delta())); Assertions.assertThrows(Exception.class, () -> db.put(arena, 0, 21203, key, value1, RequestType.delta()));
} }
@Test @Test
@ -179,11 +178,11 @@ abstract class EmbeddedDBTest {
Delta<MemorySegment> delta; Delta<MemorySegment> delta;
delta = db.put(arena, 0, colId, key, value1, Callback.delta()); delta = db.put(arena, 0, colId, key, value1, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key, value2, Callback.delta()); delta = db.put(arena, 0, colId, key, value2, RequestType.delta());
assertSegmentEquals(value1, delta.previous()); assertSegmentEquals(value1, delta.previous());
assertSegmentEquals(value2, delta.current()); assertSegmentEquals(value2, delta.current());
} }
@ -203,61 +202,61 @@ abstract class EmbeddedDBTest {
Delta<MemorySegment> delta; Delta<MemorySegment> delta;
Assertions.assertFalse(db.put(arena, 0, colId, getKeyI(3), value2, Callback.previousPresence())); Assertions.assertFalse(db.put(arena, 0, colId, getKeyI(3), value2, RequestType.previousPresence()));
Assertions.assertFalse(db.put(arena, 0, colId, getKeyI(4), value2, Callback.previousPresence())); Assertions.assertFalse(db.put(arena, 0, colId, getKeyI(4), value2, RequestType.previousPresence()));
delta = db.put(arena, 0, colId, key1, value1, Callback.delta()); delta = db.put(arena, 0, colId, key1, value1, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key2, value2, Callback.delta()); delta = db.put(arena, 0, colId, key2, value2, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value2, delta.current()); assertSegmentEquals(value2, delta.current());
delta = db.put(arena, 0, colId, key2, value1, Callback.delta()); delta = db.put(arena, 0, colId, key2, value1, RequestType.delta());
assertSegmentEquals(value2, delta.previous()); assertSegmentEquals(value2, delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key2, value1, Callback.delta()); delta = db.put(arena, 0, colId, key2, value1, RequestType.delta());
assertSegmentEquals(value1, delta.previous()); assertSegmentEquals(value1, delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
Assertions.assertTrue(db.put(arena, 0, colId, key1, value2, Callback.previousPresence())); Assertions.assertTrue(db.put(arena, 0, colId, key1, value2, RequestType.previousPresence()));
Assertions.assertTrue(db.put(arena, 0, colId, key2, value2, Callback.previousPresence())); Assertions.assertTrue(db.put(arena, 0, colId, key2, value2, RequestType.previousPresence()));
delta = db.put(arena, 0, colId, key1, value1, Callback.delta()); delta = db.put(arena, 0, colId, key1, value1, RequestType.delta());
assertSegmentEquals(value2, delta.previous()); assertSegmentEquals(value2, delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key2, value1, Callback.delta()); delta = db.put(arena, 0, colId, key2, value1, RequestType.delta());
assertSegmentEquals(value2, delta.previous()); assertSegmentEquals(value2, delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
Assertions.assertNull(db.put(arena, 0, colId, key1, value2, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, key1, value2, RequestType.none()));
Assertions.assertNull(db.put(arena, 0, colId, key2, value2, Callback.none())); Assertions.assertNull(db.put(arena, 0, colId, key2, value2, RequestType.none()));
assertSegmentEquals(value2, db.put(arena, 0, colId, key1, value1, Callback.previous())); assertSegmentEquals(value2, db.put(arena, 0, colId, key1, value1, RequestType.previous()));
assertSegmentEquals(value2, db.put(arena, 0, colId, key2, value1, Callback.previous())); assertSegmentEquals(value2, db.put(arena, 0, colId, key2, value1, RequestType.previous()));
assertSegmentEquals(value1, db.put(arena, 0, colId, key1, value1, Callback.previous())); assertSegmentEquals(value1, db.put(arena, 0, colId, key1, value1, RequestType.previous()));
assertSegmentEquals(value1, db.put(arena, 0, colId, key2, value1, Callback.previous())); assertSegmentEquals(value1, db.put(arena, 0, colId, key2, value1, RequestType.previous()));
if (!Utils.valueEquals(value1, value2)) { if (!Utils.valueEquals(value1, value2)) {
Assertions.assertTrue(db.put(arena, 0, colId, key1, value2, Callback.changed())); Assertions.assertTrue(db.put(arena, 0, colId, key1, value2, RequestType.changed()));
Assertions.assertTrue(db.put(arena, 0, colId, key2, value2, Callback.changed())); Assertions.assertTrue(db.put(arena, 0, colId, key2, value2, RequestType.changed()));
} }
Assertions.assertFalse(db.put(arena, 0, colId, key1, value2, Callback.changed())); Assertions.assertFalse(db.put(arena, 0, colId, key1, value2, RequestType.changed()));
Assertions.assertFalse(db.put(arena, 0, colId, key2, value2, Callback.changed())); Assertions.assertFalse(db.put(arena, 0, colId, key2, value2, RequestType.changed()));
assertSegmentEquals(value2, db.put(arena, 0, colId, key1, value1, Callback.previous())); assertSegmentEquals(value2, db.put(arena, 0, colId, key1, value1, RequestType.previous()));
assertSegmentEquals(value2, db.put(arena, 0, colId, key2, value1, Callback.previous())); assertSegmentEquals(value2, db.put(arena, 0, colId, key2, value1, RequestType.previous()));
} }
protected ColumnSchema getSchema() { protected ColumnSchema getSchema() {
@ -284,23 +283,23 @@ abstract class EmbeddedDBTest {
var value1 = getValue1(); var value1 = getValue1();
var value2 = getValue2(); var value2 = getValue2();
var delta = db.put(arena, 0, colId, key1, value1, Callback.delta()); var delta = db.put(arena, 0, colId, key1, value1, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, collidingKey1, value2, Callback.delta()); delta = db.put(arena, 0, colId, collidingKey1, value2, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value2, delta.current()); assertSegmentEquals(value2, delta.current());
delta = db.put(arena, 0, colId, collidingKey1, value1, Callback.delta()); delta = db.put(arena, 0, colId, collidingKey1, value1, RequestType.delta());
assertSegmentEquals(value2, delta.previous()); assertSegmentEquals(value2, delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key2, value1, Callback.delta()); delta = db.put(arena, 0, colId, key2, value1, RequestType.delta());
Assertions.assertNull(delta.previous()); Assertions.assertNull(delta.previous());
assertSegmentEquals(value1, delta.current()); assertSegmentEquals(value1, delta.current());
delta = db.put(arena, 0, colId, key2, value2, Callback.delta()); delta = db.put(arena, 0, colId, key2, value2, RequestType.delta());
assertSegmentEquals(value1, delta.previous()); assertSegmentEquals(value1, delta.previous());
assertSegmentEquals(value2, delta.current()); assertSegmentEquals(value2, delta.current());
} }
@ -308,38 +307,38 @@ abstract class EmbeddedDBTest {
@Test @Test
void get() { void get() {
if (getHasValues()) { if (getHasValues()) {
Assertions.assertNull(db.get(arena, 0, colId, key1, Callback.current())); Assertions.assertNull(db.get(arena, 0, colId, key1, RequestType.current()));
Assertions.assertNull(db.get(arena, 0, colId, collidingKey1, Callback.current())); Assertions.assertNull(db.get(arena, 0, colId, collidingKey1, RequestType.current()));
Assertions.assertNull(db.get(arena, 0, colId, key2, Callback.current())); Assertions.assertNull(db.get(arena, 0, colId, key2, RequestType.current()));
} }
Assertions.assertFalse(db.get(arena, 0, colId, key1, Callback.exists())); Assertions.assertFalse(db.get(arena, 0, colId, key1, RequestType.exists()));
Assertions.assertFalse(db.get(arena, 0, colId, collidingKey1, Callback.exists())); Assertions.assertFalse(db.get(arena, 0, colId, collidingKey1, RequestType.exists()));
Assertions.assertFalse(db.get(arena, 0, colId, key2, Callback.exists())); Assertions.assertFalse(db.get(arena, 0, colId, key2, RequestType.exists()));
fillSomeKeys(); fillSomeKeys();
if (getHasValues()) { if (getHasValues()) {
assertSegmentEquals(value1, db.get(arena, 0, colId, key1, Callback.current())); assertSegmentEquals(value1, db.get(arena, 0, colId, key1, RequestType.current()));
Assertions.assertNull(db.get(arena, 0, colId, getNotFoundKeyI(0), Callback.current())); Assertions.assertNull(db.get(arena, 0, colId, getNotFoundKeyI(0), RequestType.current()));
assertSegmentEquals(value2, db.get(arena, 0, colId, collidingKey1, Callback.current())); assertSegmentEquals(value2, db.get(arena, 0, colId, collidingKey1, RequestType.current()));
assertSegmentEquals(bigValue, db.get(arena, 0, colId, key2, Callback.current())); assertSegmentEquals(bigValue, db.get(arena, 0, colId, key2, RequestType.current()));
} }
Assertions.assertTrue(db.get(arena, 0, colId, key1, Callback.exists())); Assertions.assertTrue(db.get(arena, 0, colId, key1, RequestType.exists()));
Assertions.assertFalse(db.get(arena, 0, colId, getNotFoundKeyI(0), Callback.exists())); Assertions.assertFalse(db.get(arena, 0, colId, getNotFoundKeyI(0), RequestType.exists()));
Assertions.assertTrue(db.get(arena, 0, colId, collidingKey1, Callback.exists())); Assertions.assertTrue(db.get(arena, 0, colId, collidingKey1, RequestType.exists()));
Assertions.assertTrue(db.get(arena, 0, colId, key2, Callback.exists())); Assertions.assertTrue(db.get(arena, 0, colId, key2, RequestType.exists()));
} }
@Test @Test
void update() { void update() {
if (getHasValues()) { if (getHasValues()) {
var forUpdate = db.get(arena, 0, colId, key1, Callback.forUpdate()); var forUpdate = db.get(arena, 0, colId, key1, RequestType.forUpdate());
Assertions.assertNull(forUpdate.previous()); Assertions.assertNull(forUpdate.previous());
Assertions.assertTrue(forUpdate.updateId() != 0); Assertions.assertTrue(forUpdate.updateId() != 0);
db.put(arena, forUpdate.updateId(), colId, key1, value1, Callback.none()); db.put(arena, forUpdate.updateId(), colId, key1, value1, RequestType.none());
Assertions.assertThrows(Exception.class, () -> db.put(arena, forUpdate.updateId(), colId, key1, value2, Callback.none())); Assertions.assertThrows(Exception.class, () -> db.put(arena, forUpdate.updateId(), colId, key1, value2, RequestType.none()));
} }
} }
@ -347,17 +346,17 @@ abstract class EmbeddedDBTest {
void concurrentUpdate() { void concurrentUpdate() {
if (getHasValues()) { if (getHasValues()) {
{ {
var forUpdate1 = db.get(arena, 0, colId, key1, Callback.forUpdate()); var forUpdate1 = db.get(arena, 0, colId, key1, RequestType.forUpdate());
try { try {
var forUpdate2 = db.get(arena, 0, colId, key1, Callback.forUpdate()); var forUpdate2 = db.get(arena, 0, colId, key1, RequestType.forUpdate());
try { try {
db.put(arena, forUpdate1.updateId(), colId, key1, value1, Callback.none()); db.put(arena, forUpdate1.updateId(), colId, key1, value1, RequestType.none());
Assertions.assertThrowsExactly(RocksDBRetryException.class, () -> db.put(arena, forUpdate2.updateId(), colId, key1, value2, Callback.none())); Assertions.assertThrowsExactly(RocksDBRetryException.class, () -> db.put(arena, forUpdate2.updateId(), colId, key1, value2, RequestType.none()));
// Retrying // Retrying
var forUpdate3 = db.get(arena, forUpdate2.updateId(), colId, key1, Callback.forUpdate()); var forUpdate3 = db.get(arena, forUpdate2.updateId(), colId, key1, RequestType.forUpdate());
try { try {
assertSegmentEquals(value1, forUpdate3.previous()); assertSegmentEquals(value1, forUpdate3.previous());
db.put(arena, forUpdate3.updateId(), colId, key1, value2, Callback.none()); db.put(arena, forUpdate3.updateId(), colId, key1, value2, RequestType.none());
} catch (Throwable ex3) { } catch (Throwable ex3) {
db.closeFailedUpdate(forUpdate3.updateId()); db.closeFailedUpdate(forUpdate3.updateId());
throw ex3; throw ex3;
@ -386,9 +385,9 @@ abstract class EmbeddedDBTest {
@Test @Test
void getTestError() { void getTestError() {
fillSomeKeys(); fillSomeKeys();
Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, colId, null, Callback.current()))); Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, colId, null, RequestType.current())));
Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, 18239, key1, Callback.current()))); Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, 18239, key1, RequestType.current())));
Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 1, colId, key1, Callback.current()))); Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 1, colId, key1, RequestType.current())));
Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, colId, key1, null))); Assertions.assertThrows(Exception.class, () -> Utils.valueEquals(value1, db.get(arena, 0, colId, key1, null)));
} }
} }

View File

@ -2,7 +2,7 @@ module rockserver.core.test {
requires org.lz4.java; requires org.lz4.java;
requires rockserver.core; requires rockserver.core;
requires org.junit.jupiter.api; requires org.junit.jupiter.api;
requires it.unimi.dsi.fastutil.core; requires it.unimi.dsi.fastutil;
opens it.cavallium.rockserver.core.test; opens it.cavallium.rockserver.core.test;
opens it.cavallium.rockserver.core.impl.test; opens it.cavallium.rockserver.core.impl.test;
} }