Browse files

Support the db.compactRange method to force compaction of the leveldb…

… files.
  • Loading branch information...
1 parent 0fbd001 commit 440ccd6569d71f063b4e1d8c08264bad3bc3db94 @chirino chirino committed Aug 21, 2012
View
5 leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/JniDB.java
@@ -170,4 +170,9 @@ private NativeWriteOptions convert(WriteOptions options) {
}
return rc;
}
+
+ public void compactRange(byte[] begin, byte[] end) throws DBException {
+ db.compactRange(begin, end);
+ }
+
}
View
6 leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeBuffer.java
@@ -197,7 +197,11 @@ public static void popMemoryPool() {
}
static public NativeBuffer create(byte[] data) {
- return create(data, 0 , data.length);
+ if( data == null ) {
+ return null;
+ } else {
+ return create(data, 0 , data.length);
+ }
}
static public NativeBuffer create(String data) {
View
36 leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java
@@ -155,6 +155,14 @@ static final native long DestroyDB(
static final native long RepairDB(
@JniArg(cast="const char*") String path,
@JniArg(flags={BY_VALUE, NO_OUT}) NativeOptions options);
+
+ @JniMethod(flags={CPP_METHOD})
+ static final native void CompactRange(
+ long self,
+ @JniArg(flags={NO_OUT}) NativeSlice begin,
+ @JniArg(flags={NO_OUT}) NativeSlice end
+ );
+
}
public void delete() {
@@ -364,6 +372,34 @@ public String getProperty(String name) {
}
}
+ public void compactRange(byte[] begin, byte[] end) {
+ NativeBuffer keyBuffer = NativeBuffer.create(begin);
+ try {
+ NativeBuffer valueBuffer = NativeBuffer.create(end);
+ try {
+ compactRange(keyBuffer, valueBuffer);
+ } finally {
+ if( valueBuffer!=null ) {
+ valueBuffer.delete();
+ }
+ }
+ } finally {
+ if( keyBuffer!=null ) {
+ keyBuffer.delete();
+ }
+ }
+ }
+
+ private void compactRange( NativeBuffer beginBuffer, NativeBuffer endBuffer) {
+ compactRange(NativeSlice.create(beginBuffer), NativeSlice.create(endBuffer));
+ }
+
+ private void compactRange( NativeSlice beginSlice, NativeSlice endSlice) {
+ assertAllocated();
+ DBJNI.CompactRange(self, beginSlice, endSlice);
+ }
+
+
static public void destroy(File path, NativeOptions options) throws IOException, DBException {
checkArgNotNull(options, "options");
checkArgNotNull(path, "path");
View
8 leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSlice.java
@@ -97,6 +97,14 @@ public NativeSlice(NativeBuffer buffer) {
this(buffer.pointer(), buffer.capacity());
}
+ public static NativeSlice create(NativeBuffer buffer) {
+ if(buffer == null ) {
+ return null;
+ } else {
+ return new NativeSlice(buffer);
+ }
+ }
+
public long data() {
return data_;
}
View
38 leveldbjni/src/test/java/org/fusesource/leveldbjni/test/DBTest.java
@@ -33,6 +33,7 @@
import junit.framework.TestCase;
import org.fusesource.leveldbjni.JniDBFactory;
+import org.fusesource.leveldbjni.internal.JniDB;
import org.iq80.leveldb.*;
import org.junit.Test;
@@ -376,6 +377,43 @@ public void log(String message) {
}
+ @Test
+ public void testCompactRanges() throws IOException, InterruptedException, DBException {
+ Options options = new Options().createIfMissing(true);
+ File path = getTestDirectory(getName());
+ DB db = factory.open(path, options);
+ if( db instanceof JniDB) {
+ Random r = new Random(0);
+ String data="";
+ for(int i=0; i < 1024; i++) {
+ data+= 'a'+r.nextInt(26);
+ }
+ for(int i=0; i < 5*1024; i++) {
+ db.put(bytes("row"+i), bytes(data));
+ }
+ for(int i=0; i < 5*1024; i++) {
+ db.delete(bytes("row" + i));
+ }
+
+ String stats = db.getProperty("leveldb.stats");
+
+ // Compactions
+ // Level Files Size(MB) Time(sec) Read(MB) Write(MB)
+ // --------------------------------------------------
+ assertTrue(stats.contains("1 2 2 0 0 2"));
+ assertTrue(stats.contains("2 1 1 0 0 1"));
+
+ // After the compaction, level 1 and 2 should not have any files in it..
+ ((JniDB) db).compactRange(null, null);
+
+ stats = db.getProperty("leveldb.stats");
+ assertTrue(stats.contains("1 0 0 0 3 2"));
+ assertTrue(stats.contains("2 0 0 0 1 1"));
+
+ }
+ db.close();
+ }
+
public void assertEquals(byte[] arg1, byte[] arg2) {
assertTrue(Arrays.equals(arg1, arg2));
}

0 comments on commit 440ccd6

Please sign in to comment.