diff --git a/pom.xml b/pom.xml
index 39307c1..7418f11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.tidesdb
tidesdb-java
- 0.6.4
+ 0.6.5
jar
TidesDB Java
diff --git a/src/main/c/com_tidesdb_TidesDB.c b/src/main/c/com_tidesdb_TidesDB.c
index 70af321..87a3c89 100644
--- a/src/main/c/com_tidesdb_TidesDB.c
+++ b/src/main/c/com_tidesdb_TidesDB.c
@@ -78,7 +78,8 @@ JNIEXPORT jlong JNICALL Java_com_tidesdb_TidesDB_nativeOpen(JNIEnv *env, jclass
jint numCompactionThreads,
jint logLevel, jlong blockCacheSize,
jlong maxOpenSSTables, jboolean logToFile,
- jlong logTruncationAt)
+ jlong logTruncationAt,
+ jlong maxMemoryUsage)
{
const char *path = (*env)->GetStringUTFChars(env, dbPath, NULL);
if (path == NULL)
@@ -93,6 +94,7 @@ JNIEXPORT jlong JNICALL Java_com_tidesdb_TidesDB_nativeOpen(JNIEnv *env, jclass
.log_level = (tidesdb_log_level_t)logLevel,
.block_cache_size = (size_t)blockCacheSize,
.max_open_sstables = (size_t)maxOpenSSTables,
+ .max_memory_usage = (size_t)maxMemoryUsage,
.log_to_file = logToFile ? 1 : 0,
.log_truncation_at = (size_t)logTruncationAt};
diff --git a/src/main/java/com/tidesdb/Config.java b/src/main/java/com/tidesdb/Config.java
index c686f8d..7fd5c50 100644
--- a/src/main/java/com/tidesdb/Config.java
+++ b/src/main/java/com/tidesdb/Config.java
@@ -31,6 +31,7 @@ public class Config {
private long maxOpenSSTables;
private boolean logToFile;
private long logTruncationAt;
+ private long maxMemoryUsage;
private Config(Builder builder) {
this.dbPath = builder.dbPath;
@@ -41,6 +42,7 @@ private Config(Builder builder) {
this.maxOpenSSTables = builder.maxOpenSSTables;
this.logToFile = builder.logToFile;
this.logTruncationAt = builder.logTruncationAt;
+ this.maxMemoryUsage = builder.maxMemoryUsage;
}
/**
@@ -57,6 +59,7 @@ public static Config defaultConfig() {
.maxOpenSSTables(256)
.logToFile(false)
.logTruncationAt(24 * 1024 * 1024)
+ .maxMemoryUsage(0)
.build();
}
@@ -102,6 +105,10 @@ public long getLogTruncationAt() {
return logTruncationAt;
}
+ public long getMaxMemoryUsage() {
+ return maxMemoryUsage;
+ }
+
/**
* Builder for Config.
*/
@@ -114,6 +121,7 @@ public static class Builder {
private long maxOpenSSTables = 256;
private boolean logToFile = false;
private long logTruncationAt = 24 * 1024 * 1024;
+ private long maxMemoryUsage = 0;
public Builder dbPath(String dbPath) {
this.dbPath = dbPath;
@@ -155,6 +163,11 @@ public Builder logTruncationAt(long logTruncationAt) {
return this;
}
+ public Builder maxMemoryUsage(long maxMemoryUsage) {
+ this.maxMemoryUsage = maxMemoryUsage;
+ return this;
+ }
+
public Config build() {
validate();
return new Config(this);
diff --git a/src/main/java/com/tidesdb/TidesDB.java b/src/main/java/com/tidesdb/TidesDB.java
index 5c0b7ed..c112a49 100644
--- a/src/main/java/com/tidesdb/TidesDB.java
+++ b/src/main/java/com/tidesdb/TidesDB.java
@@ -60,7 +60,8 @@ public static TidesDB open(Config config) throws TidesDBException {
config.getBlockCacheSize(),
config.getMaxOpenSSTables(),
config.isLogToFile(),
- config.getLogTruncationAt()
+ config.getLogTruncationAt(),
+ config.getMaxMemoryUsage()
);
return new TidesDB(handle);
@@ -294,7 +295,8 @@ long getNativeHandle() {
private static native long nativeOpen(String dbPath, int numFlushThreads, int numCompactionThreads,
int logLevel, long blockCacheSize, long maxOpenSSTables,
- boolean logToFile, long logTruncationAt) throws TidesDBException;
+ boolean logToFile, long logTruncationAt,
+ long maxMemoryUsage) throws TidesDBException;
private static native void nativeClose(long handle);
diff --git a/src/test/java/com/tidesdb/TidesDBTest.java b/src/test/java/com/tidesdb/TidesDBTest.java
index d7494ba..3715eec 100644
--- a/src/test/java/com/tidesdb/TidesDBTest.java
+++ b/src/test/java/com/tidesdb/TidesDBTest.java
@@ -1064,6 +1064,78 @@ void testCommitHookNullThrows() throws TidesDBException {
}
}
+ @Test
+ @Order(29)
+ void testMaxMemoryUsageConfig() throws TidesDBException {
+ Config config = Config.builder(tempDir.resolve("testdb27").toString())
+ .numFlushThreads(2)
+ .numCompactionThreads(2)
+ .logLevel(LogLevel.INFO)
+ .blockCacheSize(64 * 1024 * 1024)
+ .maxOpenSSTables(256)
+ .maxMemoryUsage(0)
+ .build();
+
+ assertEquals(0, config.getMaxMemoryUsage());
+
+ try (TidesDB db = TidesDB.open(config)) {
+ ColumnFamilyConfig cfConfig = ColumnFamilyConfig.defaultConfig();
+ db.createColumnFamily("test_cf", cfConfig);
+
+ ColumnFamily cf = db.getColumnFamily("test_cf");
+
+ try (Transaction txn = db.beginTransaction()) {
+ txn.put(cf, "key1".getBytes(), "value1".getBytes());
+ txn.commit();
+ }
+
+ try (Transaction txn = db.beginTransaction()) {
+ byte[] result = txn.get(cf, "key1".getBytes());
+ assertNotNull(result);
+ assertArrayEquals("value1".getBytes(), result);
+ }
+ }
+ }
+
+ @Test
+ @Order(30)
+ void testMultiColumnFamilyTransaction() throws TidesDBException {
+ Config config = Config.builder(tempDir.resolve("testdb28").toString())
+ .numFlushThreads(2)
+ .numCompactionThreads(2)
+ .logLevel(LogLevel.INFO)
+ .blockCacheSize(64 * 1024 * 1024)
+ .maxOpenSSTables(256)
+ .build();
+
+ try (TidesDB db = TidesDB.open(config)) {
+ ColumnFamilyConfig cfConfig = ColumnFamilyConfig.defaultConfig();
+ db.createColumnFamily("users", cfConfig);
+ db.createColumnFamily("orders", cfConfig);
+
+ ColumnFamily usersCf = db.getColumnFamily("users");
+ ColumnFamily ordersCf = db.getColumnFamily("orders");
+
+ // Atomic transaction across multiple column families
+ try (Transaction txn = db.beginTransaction()) {
+ txn.put(usersCf, "user:1000".getBytes(), "John Doe".getBytes());
+ txn.put(ordersCf, "order:5000".getBytes(), "user:1000|product:A".getBytes());
+ txn.commit();
+ }
+
+ // Verify data in both column families
+ try (Transaction txn = db.beginTransaction()) {
+ byte[] user = txn.get(usersCf, "user:1000".getBytes());
+ assertNotNull(user);
+ assertArrayEquals("John Doe".getBytes(), user);
+
+ byte[] order = txn.get(ordersCf, "order:5000".getBytes());
+ assertNotNull(order);
+ assertArrayEquals("user:1000|product:A".getBytes(), order);
+ }
+ }
+ }
+
@Test
@Order(21)
void testTransactionResetNullIsolation() throws TidesDBException {