get() on a nonexistent key works through exception #7

Closed
aluht opened this Issue Mar 2, 2012 · 1 comment

Comments

Projects
None yet
2 participants

aluht commented Mar 2, 2012

I'm trying to work with leveldbjni-linux64-1.2-SNAPSHOT and found that get() on a nonexistent value works through

checkStatus(DBJNI.Get(self, options, keySlice, result.pointer()));

that throws exception if value was not found. Exceptions are usually not too good for performance and get() miss in my case is not an exceptional case.

The following test works 2700 ms with exceptions and 600ms after exceptions were removed in case of missed get():

import org.fusesource.leveldbjni.JniDBFactory;
import org.fusesource.leveldbjni.*;
import org.iq80.leveldb.*;

import java.io.File;
import java.io.IOException;
import java.util.*;

import static org.fusesource.leveldbjni.JniDBFactory.asString;
import static org.fusesource.leveldbjni.JniDBFactory.bytes;

public class Test {
    static final DBFactory factory = JniDBFactory.factory;

    public static void main(String[] args) throws Exception {
        Options options = new Options().createIfMissing(true);

        options.cacheSize(120 * 1024 * 1024);
        options.writeBufferSize(8 * 1024 * 1024);
        options.paranoidChecks(false);
        options.verifyChecksums(false);
        options.blockSize(4096);

        DB db = factory.open(new File("gagaga"), options);

        byte[] key = new byte[] {0, 0, 0, 0, -84, -19, 0, 5, 116, 0, 4, 107, 101, 121, 48};

        long start = System.currentTimeMillis();

        for(int i = 0; i < 1000000; i++) {
            db.get(key);
        }

        long time = System.currentTimeMillis() - start;

        System.out.println("test tool " + time + "ms");

        db.close();

    }
}

The "patch" is:

--- a/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java
+++ b/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java
@@ -287,8 +287,22 @@ public class NativeDB extends NativeObject {
         assertAllocated();
         NativeStdString result = new NativeStdString();
         try {
-            checkStatus(DBJNI.Get(self, options, keySlice, result.pointer()));
-            return result.toByteArray();
+            long s = DBJNI.Get(self, options, keySlice, result.pointer());
+
+            NativeStatus status = new NativeStatus(s);
+            try {
+                if(status.isOk()) {
+                    return result.toByteArray();
+                }
+
+                if(status.isNotFound()) {
+                    return null;
+                }
+                
+                throw new DBException(status.toString(), status.isNotFound());
+            } finally {
+                status.delete();
+            }
Owner

chirino commented Feb 6, 2013

Patch applied. Many thanks!

chirino closed this Feb 6, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment