+ * Provides a java interface to the C++ leveldb::Comparator class. + *
+ * + * @author Hiram Chirino + */ +public abstract class NativeComparator extends NativeObject { + + @JniClass(name="JNIComparator", flags={STRUCT, CPP}) + static public class ComparatorJNI { + + static { + NativeDB.LIBRARY.load(); + init(); + } + + @JniMethod(flags={CPP_NEW}) + public static final native long create(); + @JniMethod(flags={CPP_DELETE}) + public static final native void delete(long ptr); + + public static final native void memmove ( + @JniArg(cast="void *") long dest, + @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) ComparatorJNI src, + @JniArg(cast="size_t") long size); + + public static final native void memmove ( + @JniArg(cast="void *", flags={NO_IN, CRITICAL}) ComparatorJNI dest, + @JniArg(cast="const void *") long src, + @JniArg(cast="size_t") long size); + + @JniField(cast="jobject", flags={POINTER_FIELD}) + long target; + + @JniField(cast="jmethodID", flags={POINTER_FIELD}) + long compare_method; + + @JniField(cast="const char *") + long name; + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, accessor="sizeof(struct JNIComparator)") + static int SIZEOF; + + @JniField(flags={CONSTANT}, cast="const Comparator*", accessor="leveldb::BytewiseComparator()") + private static long BYTEWISE_COMPARATOR; + + } + + private NativeBuffer name_buffer; + private long globalRef; + + public NativeComparator() { + super(ComparatorJNI.create()); + try { + name_buffer = NativeBuffer.create(name()); + globalRef = NativeDB.DBJNI.NewGlobalRef(this); + if( globalRef==0 ) { + throw new RuntimeException("jni call failed: NewGlobalRef"); + } + ComparatorJNI struct = new ComparatorJNI(); + struct.compare_method = NativeDB.DBJNI.GetMethodID(this.getClass(), "compare", "(JJ)I"); + if( struct.compare_method==0 ) { + throw new RuntimeException("jni call failed: GetMethodID"); + } + struct.target = globalRef; + struct.name = name_buffer.pointer(); + ComparatorJNI.memmove(self, struct, ComparatorJNI.SIZEOF); + + } catch (RuntimeException e) { + delete(); + throw e; + } + } + + public static final NativeComparator BYTEWISE_COMPARATOR = new NativeComparator(ComparatorJNI.BYTEWISE_COMPARATOR) { + @Override + public void delete() { + // we won't really delete this one since it's static. + } + @Override + public int compare(byte[] key1, byte[] key2) { + throw new UnsupportedOperationException(); + } + @Override + public String name() { + throw new UnsupportedOperationException(); + } + }; + + NativeComparator(long ptr) { + super(ptr); + } + + public void delete() { + if( name_buffer!=null ) { + name_buffer.delete(); + name_buffer = null; + } + if( globalRef!=0 ) { + NativeDB.DBJNI.DeleteGlobalRef(globalRef); + globalRef = 0; + } + } + + private int compare(long ptr1, long ptr2) { + NativeSlice s1 = new NativeSlice(); + s1.read(ptr1, 0); + NativeSlice s2 = new NativeSlice(); + s2.read(ptr2, 0); + return compare(s1.toByteArray(), s2.toByteArray()); + } + + public abstract int compare(byte[] key1, byte[] key2); + public abstract String name(); + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeCompressionType.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeCompressionType.java new file mode 100644 index 000000000..2c8b97b96 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeCompressionType.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +/** + * Provides a java interface to the C++ leveldb::CompressionType enum. + * + * @author Hiram Chirino + */ +public enum NativeCompressionType { + kNoCompression(0x0), kSnappyCompression(0x1); + + static final int t = kNoCompression.value; + final int value; + + NativeCompressionType(int value) { + this.value = value; + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java new file mode 100644 index 000000000..f6afb4da9 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniArg; +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniMethod; +import org.fusesource.hawtjni.runtime.Library; + +import java.io.File; +import java.io.IOException; + +import static org.fusesource.hawtjni.runtime.ArgFlag.*; +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.MethodFlag.*; + +/** + * The DB object provides the main interface to acessing LevelDB + * + * @author Hiram Chirino + */ +public class NativeDB extends NativeObject { + + public static final Library LIBRARY = new Library("leveldbjni", NativeDB.class); + + @JniClass(name="leveldb::DB", flags={CPP}) + static class DBJNI { + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(flags={JNI, POINTER_RETURN}, cast="jobject") + public static final native long NewGlobalRef( + Object target); + + @JniMethod(flags={JNI}, cast="jobject") + public static final native void DeleteGlobalRef( + @JniArg(cast="jobject", flags={POINTER_ARG}) + long target); + + @JniMethod(flags={JNI, POINTER_RETURN}, cast="jmethodID") + public static final native long GetMethodID( + @JniArg(cast="jclass", flags={POINTER_ARG}) + Class clazz, + String name, + String signature); + + @JniMethod(flags={CPP_DELETE}) + static final native void delete( + long self + ); + + @JniMethod(copy="leveldb::Status", accessor = "leveldb::DB::Open") + static final native long Open( + @JniArg(flags={BY_VALUE, NO_OUT}) NativeOptions options, + @JniArg(cast="const char*") String path, + @JniArg(cast="leveldb::DB**") long[] self); + + @JniMethod(copy="leveldb::Status", flags={CPP_METHOD}) + static final native long Put( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeWriteOptions options, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice key, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice value + ); + + @JniMethod(copy="leveldb::Status", flags={CPP_METHOD}) + static final native long Delete( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeWriteOptions options, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice key + ); + + @JniMethod(copy="leveldb::Status", flags={CPP_METHOD}) + static final native long Write( + long self, + @JniArg(flags={BY_VALUE}) NativeWriteOptions options, + @JniArg(cast="leveldb::WriteBatch *") long updates + ); + + @JniMethod(copy="leveldb::Status", flags={CPP_METHOD}) + static final native long Get( + long self, + @JniArg(flags={NO_OUT, BY_VALUE}) NativeReadOptions options, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice key, + @JniArg(cast="std::string *") long value + ); + + @JniMethod(cast="leveldb::Iterator *", flags={CPP_METHOD}) + static final native long NewIterator( + long self, + @JniArg(flags={NO_OUT, BY_VALUE}) NativeReadOptions options + ); + + @JniMethod(cast="leveldb::Snapshot *", flags={CPP_METHOD}) + static final native long GetSnapshot( + long self); + + @JniMethod(flags={CPP_METHOD}) + static final native void ReleaseSnapshot( + long self, + @JniArg(cast="const leveldb::Snapshot *") long snapshot + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void GetApproximateSizes( + long self, + @JniArg(cast="const leveldb::Range *") long range, + int n, + @JniArg(cast="uint64_t*") long[] sizes + ); + + @JniMethod(flags={CPP_METHOD}) + static final native boolean GetProperty( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice property, + @JniArg(cast="std::string *") long value + ); + + @JniMethod(copy="leveldb::Status", accessor = "leveldb::DestroyDB") + static final native long DestroyDB( + @JniArg(cast="const char*") String path, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeOptions options); + + @JniMethod(copy="leveldb::Status", accessor = "leveldb::RepairDB") + 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() { + assertAllocated(); + DBJNI.delete(self); + self = 0; + } + + private NativeDB(long self) { + super(self); + } + + public static class DBException extends IOException { + private final boolean notFound; + + DBException(String s, boolean notFound) { + super(s); + this.notFound = notFound; + } + + public boolean isNotFound() { + return notFound; + } + } + + static void checkStatus(long s) throws DBException { + NativeStatus status = new NativeStatus(s); + try { + if( !status.isOk() ) { + throw new DBException(status.toString(), status.isNotFound()); + } + } finally { + status.delete(); + } + } + + static void checkArgNotNull(Object value, String name) { + if(value==null) { + throw new IllegalArgumentException("The "+name+" argument cannot be null"); + } + } + + public static NativeDB open(NativeOptions options, File path) throws IOException, DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(path, "path"); + long rc[] = new long[1]; + try { + checkStatus(DBJNI.Open(options, path.getCanonicalPath(), rc)); + } catch (IOException e) { + if( rc[0]!=0 ) { + DBJNI.delete(rc[0]); + } + throw e; + } + return new NativeDB(rc[0]); + } + + public void put(NativeWriteOptions options, byte[] key, byte[] value) throws DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(key, "key"); + checkArgNotNull(value, "value"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + NativeBuffer valueBuffer = NativeBuffer.create(value); + try { + put(options, keyBuffer, valueBuffer); + } finally { + valueBuffer.delete(); + } + } finally { + keyBuffer.delete(); + } + } + + private void put(NativeWriteOptions options, NativeBuffer keyBuffer, NativeBuffer valueBuffer) throws DBException { + put(options, new NativeSlice(keyBuffer), new NativeSlice(valueBuffer)); + } + + private void put(NativeWriteOptions options, NativeSlice keySlice, NativeSlice valueSlice) throws DBException { + assertAllocated(); + checkStatus(DBJNI.Put(self, options, keySlice, valueSlice)); + } + + public void delete(NativeWriteOptions options, byte[] key) throws DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(key, "key"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + delete(options, keyBuffer); + } finally { + keyBuffer.delete(); + } + } + + private void delete(NativeWriteOptions options, NativeBuffer keyBuffer) throws DBException { + delete(options, new NativeSlice(keyBuffer)); + } + + private void delete(NativeWriteOptions options, NativeSlice keySlice) throws DBException { + assertAllocated(); + checkStatus(DBJNI.Delete(self, options, keySlice)); + } + + public void write(NativeWriteOptions options, NativeWriteBatch updates) throws DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(updates, "updates"); + checkStatus(DBJNI.Write(self, options, updates.pointer())); + } + + public byte[] get(NativeReadOptions options, byte[] key) throws DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(key, "key"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + return get(options, keyBuffer); + } finally { + keyBuffer.delete(); + } + } + + private byte[] get(NativeReadOptions options, NativeBuffer keyBuffer) throws DBException { + return get(options, new NativeSlice(keyBuffer)); + } + + private byte[] get(NativeReadOptions options, NativeSlice keySlice) throws DBException { + assertAllocated(); + NativeStdString result = new NativeStdString(); + try { + checkStatus(DBJNI.Get(self, options, keySlice, result.pointer())); + return result.toByteArray(); + } finally { + result.delete(); + } + } + + public NativeSnapshot getSnapshot() { + return new NativeSnapshot(DBJNI.GetSnapshot(self)); + } + + public void releaseSnapshot(NativeSnapshot snapshot) { + checkArgNotNull(snapshot, "snapshot"); + DBJNI.ReleaseSnapshot(self, snapshot.pointer()); + } + + public NativeIterator iterator(NativeReadOptions options) { + checkArgNotNull(options, "options"); + return new NativeIterator(DBJNI.NewIterator(self, options)); + } + + public long[] getApproximateSizes(NativeRange... ranges) { + if( ranges==null ) { + return null; + } + + long rc[] = new long[ranges.length]; + NativeRange.RangeJNI structs[] = new NativeRange.RangeJNI[ranges.length]; + if( rc.length> 0 ) { + NativeBuffer range_array = NativeRange.RangeJNI.arrayCreate(ranges.length); + try { + for(int i=0; i < ranges.length; i++) { + structs[i] = new NativeRange.RangeJNI(ranges[i]); + structs[i].arrayWrite(range_array.pointer(), i); + } + DBJNI.GetApproximateSizes(self,range_array.pointer(), ranges.length, rc); + } finally { + for(int i=0; i < ranges.length; i++) { + if( structs[i] != null ) { + structs[i].delete(); + } + } + range_array.delete(); + } + } + return rc; + } + + public String getProperty(String name) { + checkArgNotNull(name, "name"); + NativeBuffer keyBuffer = NativeBuffer.create(name.getBytes()); + try { + byte[] property = getProperty(keyBuffer); + if( property==null ) { + return null; + } else { + return new String(property); + } + } finally { + keyBuffer.delete(); + } + } + + private byte[] getProperty(NativeBuffer nameBuffer) { + return getProperty(new NativeSlice(nameBuffer)); + } + + private byte[] getProperty(NativeSlice nameSlice) { + assertAllocated(); + NativeStdString result = new NativeStdString(); + try { + if( DBJNI.GetProperty(self, nameSlice, result.pointer()) ) { + return result.toByteArray(); + } else { + return null; + } + } finally { + result.delete(); + } + } + + 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"); + checkStatus(DBJNI.DestroyDB(path.getCanonicalPath(), options)); + } + + static public void repair(File path, NativeOptions options) throws IOException, DBException { + checkArgNotNull(options, "options"); + checkArgNotNull(path, "path"); + checkStatus(DBJNI.RepairDB(path.getCanonicalPath(), options)); + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeIterator.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeIterator.java new file mode 100644 index 000000000..bf40b1901 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeIterator.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.*; + +import static org.fusesource.hawtjni.runtime.MethodFlag.*; +import static org.fusesource.hawtjni.runtime.ArgFlag.*; +import static org.fusesource.hawtjni.runtime.ClassFlag.*; + +/** + * Provides a java interface to the C++ leveldb::Iterator class. + * + * @author Hiram Chirino + */ +public class NativeIterator extends NativeObject { + + @JniClass(name="leveldb::Iterator", flags={CPP}) + private static class IteratorJNI { + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(flags={CPP_DELETE}) + public static final native void delete( + long self + ); + + @JniMethod(flags={CPP_METHOD}) + static final native boolean Valid( + long self + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void SeekToFirst( + long self + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void SeekToLast( + long self + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void Seek( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice target + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void Next( + long self + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void Prev( + long self + ); + + @JniMethod(copy="leveldb::Slice", flags={CPP_METHOD}) + static final native long key( + long self + ); + + @JniMethod(copy="leveldb::Slice", flags={CPP_METHOD}) + static final native long value( + long self + ); + + @JniMethod(copy="leveldb::Status", flags={CPP_METHOD}) + static final native long status( + long self + ); + } + + NativeIterator(long self) { + super(self); + } + + public void delete() { + assertAllocated(); + IteratorJNI.delete(self); + self = 0; + } + + public boolean isValid() { + assertAllocated(); + return IteratorJNI.Valid(self); + } + + private void checkStatus() throws NativeDB.DBException { + NativeDB.checkStatus(IteratorJNI.status(self)); + } + + public void seekToFirst() { + assertAllocated(); + IteratorJNI.SeekToFirst(self); + } + + public void seekToLast() { + assertAllocated(); + IteratorJNI.SeekToLast(self); + } + + public void seek(byte[] key) throws NativeDB.DBException { + NativeDB.checkArgNotNull(key, "key"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + seek(keyBuffer); + } finally { + keyBuffer.delete(); + } + } + + private void seek(NativeBuffer keyBuffer) throws NativeDB.DBException { + seek(new NativeSlice(keyBuffer)); + } + + private void seek(NativeSlice keySlice) throws NativeDB.DBException { + assertAllocated(); + IteratorJNI.Seek(self, keySlice); + checkStatus(); + } + + public void next() throws NativeDB.DBException { + assertAllocated(); + IteratorJNI.Next(self); + checkStatus(); + } + + public void prev() throws NativeDB.DBException { + assertAllocated(); + IteratorJNI.Prev(self); + checkStatus(); + } + + public byte[] key() throws NativeDB.DBException { + assertAllocated(); + long slice_ptr = IteratorJNI.key(self); + checkStatus(); + try { + NativeSlice slice = new NativeSlice(); + slice.read(slice_ptr, 0); + return slice.toByteArray(); + } finally { + NativeSlice.SliceJNI.delete(slice_ptr); + } + } + + public byte[] value() throws NativeDB.DBException { + assertAllocated(); + long slice_ptr = IteratorJNI.value(self); + checkStatus(); + try { + NativeSlice slice = new NativeSlice(); + slice.read(slice_ptr, 0); + return slice.toByteArray(); + } finally { + NativeSlice.SliceJNI.delete(slice_ptr); + } + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeLogger.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeLogger.java new file mode 100644 index 000000000..10f83e44a --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeLogger.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniArg; +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniField; +import org.fusesource.hawtjni.runtime.JniMethod; + +import static org.fusesource.hawtjni.runtime.ArgFlag.CRITICAL; +import static org.fusesource.hawtjni.runtime.ArgFlag.NO_OUT; +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; +import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT; +import static org.fusesource.hawtjni.runtime.FieldFlag.POINTER_FIELD; +import static org.fusesource.hawtjni.runtime.MethodFlag.*; + +/** + *+ * Provides a java interface to the C++ leveldb::Logger class. + *
+ * + * @author Hiram Chirino + */ +public abstract class NativeLogger extends NativeObject { + + @JniClass(name="JNILogger", flags={STRUCT, CPP}) + static public class LoggerJNI { + + static { + NativeDB.LIBRARY.load(); + init(); + } + + @JniMethod(flags={CPP_NEW}) + public static final native long create(); + + @JniMethod(flags={CPP_DELETE}) + public static final native void delete( + long self + ); + + public static final native void memmove ( + @JniArg(cast="void *") long dest, + @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) LoggerJNI src, + @JniArg(cast="size_t") long size); + + @JniField(cast="jobject", flags={POINTER_FIELD}) + long target; + + @JniField(cast="jmethodID", flags={POINTER_FIELD}) + long log_method; + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, accessor="sizeof(struct JNILogger)") + static int SIZEOF; + } + + private long globalRef; + + public NativeLogger() { + super(LoggerJNI.create()); + try { + globalRef = NativeDB.DBJNI.NewGlobalRef(this); + if( globalRef==0 ) { + throw new RuntimeException("jni call failed: NewGlobalRef"); + } + LoggerJNI struct = new LoggerJNI(); + struct.log_method = NativeDB.DBJNI.GetMethodID(this.getClass(), "log", "(Ljava/lang/String;)V"); + if( struct.log_method ==0 ) { + throw new RuntimeException("jni call failed: GetMethodID"); + } + struct.target = globalRef; + LoggerJNI.memmove(self, struct, LoggerJNI.SIZEOF); + + } catch (RuntimeException e) { + delete(); + throw e; + } + } + + NativeLogger(long ptr) { + super(ptr); + } + + public void delete() { + if( globalRef!=0 ) { + NativeDB.DBJNI.DeleteGlobalRef(globalRef); + globalRef = 0; + } + } + + public abstract void log(String message); + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeObject.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeObject.java new file mode 100644 index 000000000..af2fb84ae --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeObject.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +/** + * A helper base class which is used to track a pointer to a native + * structure or class. + * + * @author Hiram Chirino + */ +class NativeObject { + + protected long self; + + protected NativeObject(long self) { + this.self = self; + if( self ==0 ) { + throw new OutOfMemoryError("Failure allocating native heap memory"); + } + } + + long pointer() { + return self; + } + + public boolean isAllocated() { + return self !=0; + } + + protected void assertAllocated() { + assert isAllocated() : "This object has been deleted"; + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeOptions.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeOptions.java new file mode 100644 index 000000000..71ce0e29d --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeOptions.java @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniField; +import org.fusesource.hawtjni.runtime.JniMethod; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; +import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT; +import static org.fusesource.hawtjni.runtime.FieldFlag.FIELD_SKIP; +import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER; + +/** + * Provides a java interface to the C++ leveldb::Options class. + * + * @author Hiram Chirino + */ +@JniClass(name="leveldb::Options", flags={STRUCT, CPP}) +public class NativeOptions { + + static { + NativeDB.LIBRARY.load(); + init(); + } + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, cast="Env*", accessor="leveldb::Env::Default()") + private static long DEFAULT_ENV; + + private boolean create_if_missing = false; + private boolean error_if_exists = false; + private boolean paranoid_checks = false; + @JniField(cast="size_t") + private long write_buffer_size = 4 << 20; + @JniField(cast="size_t") + private long block_size = 4086; + private int max_open_files = 1000; + private int block_restart_interval = 16; + + @JniField(flags={FIELD_SKIP}) + private NativeComparator comparatorObject = NativeComparator.BYTEWISE_COMPARATOR; + @JniField(cast="const leveldb::Comparator*") + private long comparator = comparatorObject.pointer(); + + @JniField(flags={FIELD_SKIP}) + private NativeLogger infoLogObject = null; + @JniField(cast="leveldb::Logger*") + private long info_log = 0; + + @JniField(cast="leveldb::Env*") + private long env = DEFAULT_ENV; + @JniField(cast="leveldb::Cache*") + private long block_cache = 0; + @JniField(flags={FIELD_SKIP}) + private NativeCache cache; + + @JniField(cast="leveldb::CompressionType") + private int compression = NativeCompressionType.kSnappyCompression.value; + + public NativeOptions createIfMissing(boolean value) { + this.create_if_missing = value; + return this; + } + public boolean createIfMissing() { + return create_if_missing; + } + + public NativeOptions errorIfExists(boolean value) { + this.error_if_exists = value; + return this; + } + public boolean errorIfExists() { + return error_if_exists; + } + + public NativeOptions paranoidChecks(boolean value) { + this.paranoid_checks = value; + return this; + } + public boolean paranoidChecks() { + return paranoid_checks; + } + + public NativeOptions writeBufferSize(long value) { + this.write_buffer_size = value; + return this; + } + public long writeBufferSize() { + return write_buffer_size; + } + + public NativeOptions maxOpenFiles(int value) { + this.max_open_files = value; + return this; + } + public int maxOpenFiles() { + return max_open_files; + } + + public NativeOptions blockRestartInterval(int value) { + this.block_restart_interval = value; + return this; + } + public int blockRestartInterval() { + return block_restart_interval; + } + + public NativeOptions blockSize(long value) { + this.block_size = value; + return this; + } + public long blockSize() { + return block_size; + } + +// @JniField(cast="Env*") +// private long env = DEFAULT_ENV; + + public NativeComparator comparator() { + return comparatorObject; + } + + public NativeOptions comparator(NativeComparator comparator) { + if( comparator==null ) { + throw new IllegalArgumentException("comparator cannot be null"); + } + this.comparatorObject = comparator; + this.comparator = comparator.pointer(); + return this; + } + + public NativeLogger infoLog() { + return infoLogObject; + } + + public NativeOptions infoLog(NativeLogger logger) { + this.infoLogObject = logger; + if( logger ==null ) { + this.info_log = 0; + } else { + this.info_log = logger.pointer(); + } + return this; + } + + public NativeCompressionType compression() { + if(compression == NativeCompressionType.kNoCompression.value) { + return NativeCompressionType.kNoCompression; + } else if(compression == NativeCompressionType.kSnappyCompression.value) { + return NativeCompressionType.kSnappyCompression; + } else { + return NativeCompressionType.kSnappyCompression; + } + } + + public NativeOptions compression(NativeCompressionType compression) { + this.compression = compression.value; + return this; + } + + public NativeCache cache() { + return cache; + } + + public NativeOptions cache(NativeCache cache) { + this.cache = cache; + if( cache!=null ) { + this.block_cache = cache.pointer(); + } else { + this.block_cache = 0; + } + return this; + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeRange.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeRange.java new file mode 100644 index 000000000..953d37e78 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeRange.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.*; + +import static org.fusesource.hawtjni.runtime.ArgFlag.*; +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; +import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT; +import static org.fusesource.hawtjni.runtime.FieldFlag.FIELD_SKIP; +import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER; + +/** + * Provides a java interface to the C++ leveldb::ReadOptions class. + * + * @author Hiram Chirino + */ +public class NativeRange { + + @JniClass(name="leveldb::Range", flags={STRUCT, CPP}) + static public class RangeJNI { + + static { + NativeDB.LIBRARY.load(); + init(); + } + + public static final native void memmove ( + @JniArg(cast="void *") long dest, + @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) RangeJNI src, + @JniArg(cast="size_t") long size); + + public static final native void memmove ( + @JniArg(cast="void *", flags={NO_IN, CRITICAL}) RangeJNI dest, + @JniArg(cast="const void *") long src, + @JniArg(cast="size_t") long size); + + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, accessor="sizeof(struct leveldb::Range)") + static int SIZEOF; + + @JniField + NativeSlice start = new NativeSlice(); + @JniField(flags={FIELD_SKIP}) + NativeBuffer start_buffer; + + @JniField + NativeSlice limit = new NativeSlice(); + @JniField(flags={FIELD_SKIP}) + NativeBuffer limit_buffer; + + public RangeJNI(NativeRange range) { + start_buffer = NativeBuffer.create(range.start()); + start.set(start_buffer); + try { + limit_buffer = NativeBuffer.create(range.limit()); + } catch (OutOfMemoryError e) { + start_buffer.delete(); + throw e; + } + limit.set(limit_buffer); + } + + public void delete() { + start_buffer.delete(); + limit_buffer.delete(); + } + + static NativeBuffer arrayCreate(int dimension) { + return NativeBuffer.create(dimension*SIZEOF); + } + + void arrayWrite(long buffer, int index) { + RangeJNI.memmove(PointerMath.add(buffer, SIZEOF * index), this, SIZEOF); + } + + void arrayRead(long buffer, int index) { + RangeJNI.memmove(this, PointerMath.add(buffer, SIZEOF * index), SIZEOF); + } + + } + + final private byte[] start; + final private byte[] limit; + + public byte[] limit() { + return limit; + } + + public byte[] start() { + return start; + } + + public NativeRange(byte[] start, byte[] limit) { + NativeDB.checkArgNotNull(start, "start"); + NativeDB.checkArgNotNull(limit, "limit"); + this.limit = limit; + this.start = start; + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeReadOptions.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeReadOptions.java new file mode 100644 index 000000000..85e76a3dd --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeReadOptions.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniField; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; + +/** + * Provides a java interface to the C++ leveldb::ReadOptions class. + * + * @author Hiram Chirino + */ +@JniClass(name="leveldb::ReadOptions", flags={STRUCT, CPP}) +public class NativeReadOptions { + + @JniField + private boolean verify_checksums = false; + + @JniField + private boolean fill_cache = true; + + @JniField(cast="const leveldb::Snapshot*") + private long snapshot=0; + + public boolean fillCache() { + return fill_cache; + } + + public NativeReadOptions fillCache(boolean fill_cache) { + this.fill_cache = fill_cache; + return this; + } + + public NativeSnapshot snapshot() { + if( snapshot == 0 ) { + return null; + } else { + return new NativeSnapshot(snapshot); + } + } + + public NativeReadOptions snapshot(NativeSnapshot snapshot) { + if( snapshot==null ) { + this.snapshot = 0; + } else { + this.snapshot = snapshot.pointer(); + } + return this; + } + + public boolean verifyChecksums() { + return verify_checksums; + } + + public NativeReadOptions verifyChecksums(boolean verify_checksums) { + this.verify_checksums = verify_checksums; + return this; + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSlice.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSlice.java new file mode 100644 index 000000000..a2e2d60b5 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSlice.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.*; + +import static org.fusesource.hawtjni.runtime.ArgFlag.*; +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; +import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT; +import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER; +import static org.fusesource.hawtjni.runtime.MethodFlag.CPP_DELETE; + +/** + * Provides a java interface to the C++ leveldb::Slice class. + * + * @author Hiram Chirino + */ +@JniClass(name="leveldb::Slice", flags={STRUCT, CPP}) +class NativeSlice { + + @JniClass(name="leveldb::Slice", flags={CPP}) + static class SliceJNI { + static { + NativeDB.LIBRARY.load(); + init(); + } + + @JniMethod(flags={CPP_DELETE}) + public static final native void delete( + long self + ); + + public static final native void memmove ( + @JniArg(cast="void *") long dest, + @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) NativeSlice src, + @JniArg(cast="size_t") long size); + + public static final native void memmove ( + @JniArg(cast="void *", flags={NO_IN, CRITICAL}) NativeSlice dest, + @JniArg(cast="const void *") long src, + @JniArg(cast="size_t") long size); + + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, accessor="sizeof(struct leveldb::Slice)") + static int SIZEOF; + + } + + + @JniField(cast="const char*") + private long data_; + @JniField(cast="size_t") + private long size_; + + public NativeSlice() { + } + + public NativeSlice(long data, long length) { + this.data_ = data; + this.size_ = length; + } + + 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_; + } + + public NativeSlice data(long data) { + this.data_ = data; + return this; + } + + public long size() { + return size_; + } + + public NativeSlice size(long size) { + this.size_ = size; + return this; + } + + public NativeSlice set(NativeSlice buffer) { + this.size_ = buffer.size_; + this.data_ = buffer.data_; + return this; + } + + public NativeSlice set(NativeBuffer buffer) { + this.size_ = buffer.capacity(); + this.data_ = buffer.pointer(); + return this; + } + + public byte[] toByteArray() { + if( size_ > Integer.MAX_VALUE ) { + throw new ArrayIndexOutOfBoundsException("Native slice is larger than the maximum Java array"); + } + byte []rc = new byte[(int) size_]; + NativeBuffer.NativeBufferJNI.buffer_copy(data_, 0, rc, 0, rc.length); + return rc; + } + + static NativeBuffer arrayCreate(int dimension) { + return NativeBuffer.create(dimension*SliceJNI.SIZEOF); + } + + void write(long buffer, int index) { + SliceJNI.memmove(PointerMath.add(buffer, SliceJNI.SIZEOF*index), this, SliceJNI.SIZEOF); + } + + void read(long buffer, int index) { + SliceJNI.memmove(this, PointerMath.add(buffer, SliceJNI.SIZEOF*index), SliceJNI.SIZEOF); + } + + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSnapshot.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSnapshot.java new file mode 100644 index 000000000..69403e198 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSnapshot.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +/** + * Provides a java interface to the C++ leveldb::Snapshot class. + * + * @author Hiram Chirino + */ +public class NativeSnapshot extends NativeObject { + + NativeSnapshot(long self) { + super(self); + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStatus.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStatus.java new file mode 100644 index 000000000..2950066b9 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStatus.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniMethod; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.MethodFlag.CPP_DELETE; +import static org.fusesource.hawtjni.runtime.MethodFlag.CPP_METHOD; + +/** + * Provides a java interface to the C++ leveldb::Status class. + * + * @author Hiram Chirino + */ +class NativeStatus extends NativeObject{ + + @JniClass(name="leveldb::Status", flags={CPP}) + static class StatusJNI { + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(flags={CPP_DELETE}) + public static final native void delete( + long self); + + @JniMethod(flags={CPP_METHOD}) + public static final native boolean ok( + long self); + + @JniMethod(flags={CPP_METHOD}) + public static final native boolean IsNotFound( + long self); + + @JniMethod(copy="std::string", flags={CPP_METHOD}) + public static final native long ToString( + long self); + } + + public NativeStatus(long self) { + super(self); + } + + public void delete() { + assertAllocated(); + StatusJNI.delete(self); + self = 0; + } + + public boolean isOk() { + assertAllocated(); + return StatusJNI.ok(self); + } + + public boolean isNotFound() { + assertAllocated(); + return StatusJNI.IsNotFound(self); + } + + public String toString() { + assertAllocated(); + long strptr = StatusJNI.ToString(self); + if( strptr==0 ) { + return null; + } else { + NativeStdString rc = new NativeStdString(strptr); + try { + return rc.toString(); + } finally { + rc.delete(); + } + } + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStdString.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStdString.java new file mode 100644 index 000000000..85a51c2b2 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStdString.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniMethod; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.MethodFlag.*; + +/** + * Provides a java interface to the C++ std::string class. + * + * @author Hiram Chirino + */ +class NativeStdString extends NativeObject { + + @JniClass(name="std::string", flags={CPP}) + private static class StdStringJNI { + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(flags={CPP_NEW}) + public static final native long create(); + + @JniMethod(flags={CPP_NEW}) + public static final native long create(String value); + + @JniMethod(flags={CPP_DELETE}) + static final native void delete( + long self); + + @JniMethod(flags={CPP_METHOD}, accessor = "c_str", cast="const char*") + public static final native long c_str_ptr ( + long self); + + @JniMethod(flags={CPP_METHOD},cast = "size_t") + public static final native long length ( + long self); + + } + + public NativeStdString(long self) { + super(self); + } + + public NativeStdString() { + super(StdStringJNI.create()); + } + + public void delete() { + assertAllocated(); + StdStringJNI.delete(self); + self = 0; + } + + public String toString() { + return new String(toByteArray()); + } + + public long length() { + assertAllocated(); + return StdStringJNI.length(self); + } + + public byte[] toByteArray() { + long l = length(); + if( l > Integer.MAX_VALUE ) { + throw new ArrayIndexOutOfBoundsException("Native string is larger than the maximum Java array"); + } + byte []rc = new byte[(int) l]; + NativeBuffer.NativeBufferJNI.buffer_copy(StdStringJNI.c_str_ptr(self), 0, rc, 0, rc.length); + return rc; + } +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteBatch.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteBatch.java new file mode 100644 index 000000000..bac8f21f3 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteBatch.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniArg; +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniMethod; + +import static org.fusesource.hawtjni.runtime.ArgFlag.BY_VALUE; +import static org.fusesource.hawtjni.runtime.ArgFlag.NO_OUT; +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.MethodFlag.*; + +/** + * Provides a java interface to the C++ leveldb::WriteBatch class. + * + * @author Hiram Chirino + */ +public class NativeWriteBatch extends NativeObject { + + @JniClass(name="leveldb::WriteBatch", flags={CPP}) + private static class WriteBatchJNI { + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(flags={CPP_NEW}) + public static final native long create(); + @JniMethod(flags={CPP_DELETE}) + public static final native void delete( + long self); + + @JniMethod(flags={CPP_METHOD}) + static final native void Put( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice key, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice value + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void Delete( + long self, + @JniArg(flags={BY_VALUE, NO_OUT}) NativeSlice key + ); + + @JniMethod(flags={CPP_METHOD}) + static final native void Clear( + long self + ); + + } + + public NativeWriteBatch() { + super(WriteBatchJNI.create()); + } + + public void delete() { + assertAllocated(); + WriteBatchJNI.delete(self); + self = 0; + } + + public void put(byte[] key, byte[] value) { + NativeDB.checkArgNotNull(key, "key"); + NativeDB.checkArgNotNull(value, "value"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + NativeBuffer valueBuffer = NativeBuffer.create(value); + try { + put(keyBuffer, valueBuffer); + } finally { + valueBuffer.delete(); + } + } finally { + keyBuffer.delete(); + } + } + + private void put(NativeBuffer keyBuffer, NativeBuffer valueBuffer) { + put(new NativeSlice(keyBuffer), new NativeSlice(valueBuffer)); + } + + private void put(NativeSlice keySlice, NativeSlice valueSlice) { + assertAllocated(); + WriteBatchJNI.Put(self, keySlice, valueSlice); + } + + + public void delete(byte[] key) { + NativeDB.checkArgNotNull(key, "key"); + NativeBuffer keyBuffer = NativeBuffer.create(key); + try { + delete(keyBuffer); + } finally { + keyBuffer.delete(); + } + } + + private void delete(NativeBuffer keyBuffer) { + delete(new NativeSlice(keyBuffer)); + } + + private void delete(NativeSlice keySlice) { + assertAllocated(); + WriteBatchJNI.Delete(self, keySlice); + } + + public void clear() { + assertAllocated(); + WriteBatchJNI.Clear(self); + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteOptions.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteOptions.java new file mode 100644 index 000000000..81c76fea1 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteOptions.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniField; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.ClassFlag.STRUCT; + +/** + * Provides a java interface to the C++ leveldb::WriteOptions class. + * + * @author Hiram Chirino + */ +@JniClass(name="leveldb::WriteOptions", flags={STRUCT, CPP}) +public class NativeWriteOptions { + + @JniField + boolean sync; + + public boolean sync() { + return sync; + } + + public NativeWriteOptions sync(boolean sync) { + this.sync = sync; + return this; + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/Util.java b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/Util.java new file mode 100644 index 000000000..55258ad4f --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/Util.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2011, FuseSource Corp. All rights reserved. + * + * http://fusesource.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of FuseSource Corp. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.fusesource.leveldbjni.internal; + +import org.fusesource.hawtjni.runtime.JniArg; +import org.fusesource.hawtjni.runtime.JniClass; +import org.fusesource.hawtjni.runtime.JniField; +import org.fusesource.hawtjni.runtime.JniMethod; + +import java.io.File; +import java.io.IOException; + +import static org.fusesource.hawtjni.runtime.ClassFlag.CPP; +import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT; +import static org.fusesource.hawtjni.runtime.MethodFlag.*; +import static org.fusesource.hawtjni.runtime.ArgFlag.*; + +/** + * Some miscellaneous utility functions. + * + * @author Hiram Chirino + */ +public class Util { + + @JniClass(name="leveldb::Env", flags={CPP}) + static class EnvJNI { + + static { + NativeDB.LIBRARY.load(); + } + + @JniMethod(cast = "leveldb::Env *", accessor = "leveldb::Env::Default") + public static final native long Default(); + + @JniMethod(flags = {CPP_METHOD}) + public static final native void Schedule( + long self, + @JniArg(cast = "void (*)(void*)") long fp, + @JniArg(cast = "void *") long arg); + + } + + @JniClass(flags={CPP}) + static class UtilJNI { + + static { + NativeDB.LIBRARY.load(); + init(); + } + + @JniMethod(flags={CONSTANT_INITIALIZER}) + private static final native void init(); + + @JniField(flags={CONSTANT}, accessor="1", conditional="defined(_WIN32) || defined(_WIN64)") + static int ON_WINDOWS; + + + @JniMethod(conditional="!defined(_WIN32) && !defined(_WIN64)") + static final native int link( + @JniArg(cast="const char*") String source, + @JniArg(cast="const char*") String target); + + @JniMethod(conditional="defined(_WIN32) || defined(_WIN64)") + static final native int CreateHardLinkW( + @JniArg(cast="LPCTSTR", flags={POINTER_ARG, UNICODE}) String target, + @JniArg(cast="LPCTSTR", flags={POINTER_ARG, UNICODE}) String source, + @JniArg(cast="LPSECURITY_ATTRIBUTES", flags={POINTER_ARG}) long lpSecurityAttributes); + + @JniMethod(flags={CONSTANT_GETTER}) + public static final native int errno(); + + @JniMethod(cast="char *") + public static final native long strerror(int errnum); + + public static final native int strlen( + @JniArg(cast="const char *")long s); + + } + + /** + * Creates a hard link from source to target. + * @param source + * @param target + * @return + */ + public static void link(File source, File target) throws IOException { + if( UtilJNI.ON_WINDOWS == 1 ) { + if( UtilJNI.CreateHardLinkW(target.getCanonicalPath(), source.getCanonicalPath(), 0) == 0) { + throw new IOException("link failed"); + } + } else { + if( UtilJNI.link(source.getCanonicalPath(), target.getCanonicalPath()) != 0 ) { + throw new IOException("link failed: "+strerror()); + } + } + } + + static int errno() { + return UtilJNI.errno(); + } + + static String strerror() { + return string(UtilJNI.strerror(errno())); + } + + static String string(long ptr) { + if( ptr == 0 ) + return null; + return new String(new NativeSlice(ptr, UtilJNI.strlen(ptr)).toByteArray()); + } + +} diff --git a/java/leveldbjni/leveldbjni/src/main/native-package/license.txt b/java/leveldbjni/leveldbjni/src/main/native-package/license.txt new file mode 100644 index 000000000..8edd37590 --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/native-package/license.txt @@ -0,0 +1,27 @@ +Copyright (c) 2011 FuseSource Corp. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of FuseSource Corp. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/java/leveldbjni/leveldbjni/src/main/native-package/m4/custom.m4 b/java/leveldbjni/leveldbjni/src/main/native-package/m4/custom.m4 new file mode 100644 index 000000000..f29e5805c --- /dev/null +++ b/java/leveldbjni/leveldbjni/src/main/native-package/m4/custom.m4 @@ -0,0 +1,63 @@ +dnl --------------------------------------------------------------------------- +dnl Copyright (C) 2011, FuseSource Corp. All rights reserved. +dnl +dnl http://fusesource.com +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that the following conditions are +dnl met: +dnl +dnl * Redistributions of source code must retain the above copyright +dnl notice, this list of conditions and the following disclaimer. +dnl * Redistributions in binary form must reproduce the above +dnl copyright notice, this list of conditions and the following disclaimer +dnl in the documentation and/or other materials provided with the +dnl distribution. +dnl * Neither the name of FuseSource Corp. nor the names of its +dnl contributors may be used to endorse or promote products derived from +dnl this software without specific prior written permission. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +dnl --------------------------------------------------------------------------- + +AC_DEFUN([CUSTOM_M4_SETUP], +[ + AC_LANG_PUSH(C++) + + AC_CHECK_HEADER([pthread.h],[AC_DEFINE([HAVE_PTHREAD_H], [1], [Define to 1 if you have the