diff --git a/pom.xml b/pom.xml
index c39aac8..5be551e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.tidesdb
tidesdb-java
- 0.3.0
+ 0.3.1
jar
TidesDB Java
diff --git a/src/main/c/com_tidesdb_TidesDB.c b/src/main/c/com_tidesdb_TidesDB.c
index 8238273..e0b5030 100644
--- a/src/main/c/com_tidesdb_TidesDB.c
+++ b/src/main/c/com_tidesdb_TidesDB.c
@@ -431,13 +431,27 @@ JNIEXPORT jobject JNICALL Java_com_tidesdb_ColumnFamily_nativeGetStats(JNIEnv *e
free(nums);
}
- jclass statsClass = (*env)->FindClass(env, "com/tidesdb/Stats");
- jmethodID constructor =
- (*env)->GetMethodID(env, statsClass, "", "(IJ[J[ILcom/tidesdb/ColumnFamilyConfig;)V");
+ jlongArray levelKeyCounts = (*env)->NewLongArray(env, stats->num_levels);
+ if (stats->level_key_counts != NULL)
+ {
+ jlong *counts = malloc(stats->num_levels * sizeof(jlong));
+ for (int i = 0; i < stats->num_levels; i++)
+ {
+ counts[i] = (jlong)stats->level_key_counts[i];
+ }
+ (*env)->SetLongArrayRegion(env, levelKeyCounts, 0, stats->num_levels, counts);
+ free(counts);
+ }
- jobject statsObj =
- (*env)->NewObject(env, statsClass, constructor, stats->num_levels,
- (jlong)stats->memtable_size, levelSizes, levelNumSSTables, NULL);
+ jclass statsClass = (*env)->FindClass(env, "com/tidesdb/Stats");
+ jmethodID constructor = (*env)->GetMethodID(env, statsClass, "",
+ "(IJ[J[ILcom/tidesdb/ColumnFamilyConfig;JJDD[JDD)V");
+
+ jobject statsObj = (*env)->NewObject(env, statsClass, constructor, stats->num_levels,
+ (jlong)stats->memtable_size, levelSizes, levelNumSSTables,
+ NULL, (jlong)stats->total_keys, (jlong)stats->total_data_size,
+ stats->avg_key_size, stats->avg_value_size, levelKeyCounts,
+ stats->read_amp, stats->hit_rate);
tidesdb_free_stats(stats);
diff --git a/src/main/java/com/tidesdb/Stats.java b/src/main/java/com/tidesdb/Stats.java
index 221ee99..eb98a31 100644
--- a/src/main/java/com/tidesdb/Stats.java
+++ b/src/main/java/com/tidesdb/Stats.java
@@ -28,13 +28,30 @@ public class Stats {
private final long[] levelSizes;
private final int[] levelNumSSTables;
private final ColumnFamilyConfig config;
+ private final long totalKeys;
+ private final long totalDataSize;
+ private final double avgKeySize;
+ private final double avgValueSize;
+ private final long[] levelKeyCounts;
+ private final double readAmp;
+ private final double hitRate;
- public Stats(int numLevels, long memtableSize, long[] levelSizes, int[] levelNumSSTables, ColumnFamilyConfig config) {
+ public Stats(int numLevels, long memtableSize, long[] levelSizes, int[] levelNumSSTables,
+ ColumnFamilyConfig config, long totalKeys, long totalDataSize,
+ double avgKeySize, double avgValueSize, long[] levelKeyCounts,
+ double readAmp, double hitRate) {
this.numLevels = numLevels;
this.memtableSize = memtableSize;
this.levelSizes = levelSizes;
this.levelNumSSTables = levelNumSSTables;
this.config = config;
+ this.totalKeys = totalKeys;
+ this.totalDataSize = totalDataSize;
+ this.avgKeySize = avgKeySize;
+ this.avgValueSize = avgValueSize;
+ this.levelKeyCounts = levelKeyCounts;
+ this.readAmp = readAmp;
+ this.hitRate = hitRate;
}
/**
@@ -82,11 +99,80 @@ public ColumnFamilyConfig getConfig() {
return config;
}
+ /**
+ * Gets the total number of keys across memtable and all SSTables.
+ *
+ * @return total key count
+ */
+ public long getTotalKeys() {
+ return totalKeys;
+ }
+
+ /**
+ * Gets the total data size (klog + vlog) across all SSTables.
+ *
+ * @return total data size in bytes
+ */
+ public long getTotalDataSize() {
+ return totalDataSize;
+ }
+
+ /**
+ * Gets the average key size in bytes.
+ *
+ * @return average key size
+ */
+ public double getAvgKeySize() {
+ return avgKeySize;
+ }
+
+ /**
+ * Gets the average value size in bytes.
+ *
+ * @return average value size
+ */
+ public double getAvgValueSize() {
+ return avgValueSize;
+ }
+
+ /**
+ * Gets the number of keys per level.
+ *
+ * @return array of key counts per level
+ */
+ public long[] getLevelKeyCounts() {
+ return levelKeyCounts;
+ }
+
+ /**
+ * Gets the read amplification (point lookup cost multiplier).
+ *
+ * @return read amplification factor
+ */
+ public double getReadAmp() {
+ return readAmp;
+ }
+
+ /**
+ * Gets the cache hit rate for this column family.
+ *
+ * @return hit rate (0.0 to 1.0), or 0.0 if cache is disabled
+ */
+ public double getHitRate() {
+ return hitRate;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Stats{numLevels=").append(numLevels);
sb.append(", memtableSize=").append(memtableSize);
+ sb.append(", totalKeys=").append(totalKeys);
+ sb.append(", totalDataSize=").append(totalDataSize);
+ sb.append(", avgKeySize=").append(avgKeySize);
+ sb.append(", avgValueSize=").append(avgValueSize);
+ sb.append(", readAmp=").append(readAmp);
+ sb.append(", hitRate=").append(hitRate);
if (levelSizes != null) {
sb.append(", levelSizes=[");
for (int i = 0; i < levelSizes.length; i++) {
@@ -103,6 +189,14 @@ public String toString() {
}
sb.append("]");
}
+ if (levelKeyCounts != null) {
+ sb.append(", levelKeyCounts=[");
+ for (int i = 0; i < levelKeyCounts.length; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(levelKeyCounts[i]);
+ }
+ sb.append("]");
+ }
sb.append("}");
return sb.toString();
}