Add LevelDb's JNI wrapper

Summary: This implement the Java interface by using JNI

Test Plan: compile test

Reviewers: dhruba

Reviewed By: dhruba

Differential Revision: https://reviews.facebook.net/D5925
main
Thawan Kooburat 12 years ago
parent fc23714f27
commit 696b290821
  1. 13
      java/leveldbjni/.gitignore
  2. 42
      java/leveldbjni/changelog.md
  3. 29
      java/leveldbjni/leveldb.patch
  4. 95
      java/leveldbjni/leveldbjni-all/pom.xml
  5. 4
      java/leveldbjni/leveldbjni-all/src/main/java/org/fusesource/leveldbjni/All.java
  6. 100
      java/leveldbjni/leveldbjni-linux32/pom.xml
  7. 99
      java/leveldbjni/leveldbjni-linux64/pom.xml
  8. 110
      java/leveldbjni/leveldbjni-osx/pom.xml
  9. 97
      java/leveldbjni/leveldbjni-win32/pom.xml
  10. 96
      java/leveldbjni/leveldbjni-win64/pom.xml
  11. 180
      java/leveldbjni/leveldbjni/pom.xml
  12. 212
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/JniDBFactory.java
  13. 228
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/JniDB.java
  14. 146
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/JniDBIterator.java
  15. 57
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/JniSnapshot.java
  16. 65
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/JniWriteBatch.java
  17. 285
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeBuffer.java
  18. 72
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeCache.java
  19. 160
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeComparator.java
  20. 48
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeCompressionType.java
  21. 414
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeDB.java
  22. 191
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeIterator.java
  23. 126
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeLogger.java
  24. 63
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeObject.java
  25. 207
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeOptions.java
  26. 133
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeRange.java
  27. 91
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeReadOptions.java
  28. 160
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSlice.java
  29. 45
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeSnapshot.java
  30. 106
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStatus.java
  31. 105
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeStdString.java
  32. 142
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteBatch.java
  33. 60
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/NativeWriteOptions.java
  34. 141
      java/leveldbjni/leveldbjni/src/main/java/org/fusesource/leveldbjni/internal/Util.java
  35. 27
      java/leveldbjni/leveldbjni/src/main/native-package/license.txt
  36. 63
      java/leveldbjni/leveldbjni/src/main/native-package/m4/custom.m4
  37. 36
      java/leveldbjni/leveldbjni/src/main/native-package/src/buffer.c
  38. 142
      java/leveldbjni/leveldbjni/src/main/native-package/src/leveldbjni.h
  39. 194
      java/leveldbjni/leveldbjni/src/main/native-package/vs2010.vcxproj
  40. 1
      java/leveldbjni/leveldbjni/src/main/resources/org/fusesource/leveldbjni/version.txt
  41. 422
      java/leveldbjni/leveldbjni/src/test/java/org/fusesource/leveldbjni/test/DBTest.java
  42. 27
      java/leveldbjni/license.txt
  43. 303
      java/leveldbjni/pom.xml
  44. 242
      java/leveldbjni/readme.md
  45. 30
      java/leveldbjni/releasing.md

@ -0,0 +1,13 @@
*~
*.swp
.idea
.idea/*
*.iml
*.ipr
*.iws
target
.DS_Store
.project
.classpath
.settings
eclipse-classes

@ -0,0 +1,42 @@
# [LevelDBJNI](https://github.com/fusesource/leveldbjni)
## [leveldbjni 1.3][1_3], released 2012-09-24
[1_3]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/leveldbjni/leveldbjni/1.3
* Make Util.link work on windows too.
* Expose the CreateHardLinkW windows API call.
* Added Windows LevelDB Support
* Update to hawtjni 1.6.
* Support the db.compactRange method to force compaction of the leveldb files.
* Fixed bug need to get leveldbjni workin on the Zing JVM
## [leveldbjni 1.2][1_2], released 2012-02-27
[1_2]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/leveldbjni/leveldbjni/1.2
* Document how to use the memory pools.
* Fixes issue #6 Support using a memory pool to reduce native memory allocation overhead.
* Update leveldb, hawtjni, and leveldb-api versions.
* Store the version in the factory class.
* Added a release guide.
## [leveldbjni 1.1][1_1], released 2011-09-29
[1_1]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/leveldbjni/leveldbjni/1.1
* the all module needs at least one java file so that it produces a javadoc and src.zip
* Try to load the native lib when the JniDBFactory class is loaded.
* Fixes issue #1 : Bug on NativeBuffer offset
* Switch the license from CDDL to the New BSD license to match the license used in the leveldb project.
* Add the sonatype snapshot repo since that's where the leveldb-api is at currently.
* Pickup updates in the api module.
* Updating build instructions.
* implement repair and destroy.
* api updated
* Cleaner java package structure. We only need to expose one public class now since we are using the org.iq80.leveldb abstract api.
* Refactored so that the main user API is the abstract API defined in 'org.iq80.leveldb.api' package.
## [leveldbjni 1.0][1_0], released 2011-08-08
[1_0]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/leveldbjni/leveldbjni/1.0
* Initial Release
* OS X Intel 32 and 64 bit support
* Linux Intel 32 and 64 bit support

@ -0,0 +1,29 @@
diff --git a/build_detect_platform b/build_detect_platform
index 959a7d6..388d225 100755
--- a/build_detect_platform
+++ b/build_detect_platform
@@ -171,9 +171,9 @@ echo "CC=$CC" >> $OUTPUT
echo "CXX=$CXX" >> $OUTPUT
echo "PLATFORM=$PLATFORM" >> $OUTPUT
echo "PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS" >> $OUTPUT
-echo "PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS" >> $OUTPUT
-echo "PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS" >> $OUTPUT
-echo "PLATFORM_SHARED_CFLAGS=$PLATFORM_SHARED_CFLAGS" >> $OUTPUT
+echo "PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS $PLATFORM_SHARED_CFLAGS" >> $OUTPUT
+echo "PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS $PLATFORM_SHARED_CFLAGS" >> $OUTPUT
+echo "PLATFORM_SHARED_CFLAGS=" >> $OUTPUT
echo "PLATFORM_SHARED_EXT=$PLATFORM_SHARED_EXT" >> $OUTPUT
echo "PLATFORM_SHARED_LDFLAGS=$PLATFORM_SHARED_LDFLAGS" >> $OUTPUT
echo "PLATFORM_SHARED_VERSIONED=$PLATFORM_SHARED_VERSIONED" >> $OUTPUT
diff --git a/include/leveldb/slice.h b/include/leveldb/slice.h
index 74ea8fa..135bbd7 100644
--- a/include/leveldb/slice.h
+++ b/include/leveldb/slice.h
@@ -77,7 +77,6 @@ class Slice {
(memcmp(data_, x.data_, x.size_) == 0));
}
- private:
const char* data_;
size_t size_;

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-all</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>An uber jar which contains all the leveldbjni platform libraries and dependencies</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-osx</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-linux32</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-linux64</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-win32</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-win64</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.fusesource.mvnplugins</groupId>
<artifactId>maven-uberize-plugin</artifactId>
<version>1.15</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>uberize</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,4 @@
package org.fusesource.leveldbjni;
public class All {
}

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-linux32</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>The leveldbjni linux 32 native libraries</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${basedir}/../leveldbjni/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${basedir}/target/generated-sources/hawtjni/lib</classesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<name>leveldbjni</name>
<classified>false</classified>
<nativeSrcDependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>${project.version}</version>
<classifier>native-src</classifier>
<type>zip</type>
</nativeSrcDependency>
<configureArgs>
<arg>--with-leveldb=${env.LEVELDB_HOME}</arg>
<arg>--with-snappy=${env.SNAPPY_HOME}</arg>
</configureArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-linux64</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>The leveldbjni linux 64 native libraries</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${basedir}/../leveldbjni/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${basedir}/target/generated-sources/hawtjni/lib</classesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<name>leveldbjni</name>
<classified>false</classified>
<nativeSrcDependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>${project.version}</version>
<classifier>native-src</classifier>
<type>zip</type>
</nativeSrcDependency>
<configureArgs>
<arg>--with-leveldb=${env.LEVELDB_HOME}</arg>
<arg>--with-snappy=${env.SNAPPY_HOME}</arg>
</configureArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-osx</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>The leveldbjni OS X universal native libraries</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${basedir}/../leveldbjni/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${basedir}/target/generated-sources/hawtjni/lib</classesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<name>leveldbjni</name>
<classified>false</classified>
<nativeSrcDependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>${project.version}</version>
<classifier>native-src</classifier>
<type>zip</type>
</nativeSrcDependency>
<platform>osx</platform>
<configureArgs>
<arg>--with-leveldb=${env.LEVELDB_HOME}</arg>
<arg>--with-snappy=${env.SNAPPY_HOME}</arg>
<arg>--with-universal</arg>
</configureArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-win32</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>The leveldbjni Windows 32 bit native libraries</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${basedir}/../leveldbjni/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${basedir}/target/generated-sources/hawtjni/lib</classesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<name>leveldbjni</name>
<classified>false</classified>
<nativeSrcDependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>${project.version}</version>
<classifier>native-src</classifier>
<type>zip</type>
</nativeSrcDependency>
<packageDirectory>${basedir}/../leveldbjni/target/generated-sources/hawtjni/native-package</packageDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-win64</artifactId>
<version>99-master-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>The leveldbjni Windows 64 bit native libraries</description>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${basedir}/../leveldbjni/src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${basedir}/target/generated-sources/hawtjni/lib</classesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<name>leveldbjni</name>
<classified>false</classified>
<nativeSrcDependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>${project.version}</version>
<classifier>native-src</classifier>
<type>zip</type>
</nativeSrcDependency>
<packageDirectory>${basedir}/../leveldbjni/target/generated-sources/hawtjni/native-package</packageDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni</artifactId>
<version>99-master-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>leveldbjni is a jni library for acessing leveldb.</description>
<properties>
<skipAutogen>false</skipAutogen>
</properties>
<dependencies>
<dependency>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>hawtjni-runtime</artifactId>
<version>${hawtjni-version}</version>
</dependency>
<dependency>
<groupId>org.iq80.leveldb</groupId>
<artifactId>leveldb-api</artifactId>
<version>${leveldb-api-version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.fusesource.hawtjni</groupId>
<artifactId>maven-hawtjni-plugin</artifactId>
<version>${hawtjni-version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
<goal>package-source</goal>
</goals>
</execution>
</executions>
<configuration>
<skipAutogen>${skipAutogen}</skipAutogen>
<name>leveldbjni</name>
<callbacks>true</callbacks>
<copyright><![CDATA[
/*******************************************************************************
* Copyright (C) 2011, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* The software in this package is published under the terms of the
* CDDL license a copy of which has been included with this distribution
* in the license.txt file.
*******************************************************************************/
]]></copyright>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<forkMode>once</forkMode>
<argLine>-ea</argLine>
<failIfNoTests>false</failIfNoTests>
<workingDirectory>${project.build.directory}</workingDirectory>
<excludes>
<exclude>**/*</exclude>
</excludes>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.1</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>!org.fusesource.leveldbjni*,!org.fusesource.hawtjni*,sun.reflect;resolution:=optional,*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,212 @@
/*
* 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;
import org.fusesource.leveldbjni.internal.*;
import org.iq80.leveldb.*;
import java.io.*;
import java.net.URL;
import java.util.concurrent.Callable;
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class JniDBFactory implements DBFactory {
public static final JniDBFactory factory = new JniDBFactory();
static {
NativeDB.LIBRARY.load();
}
public static final String VERSION;
static {
String v="unknown";
InputStream is = JniDBFactory.class.getResourceAsStream("version.txt");
try {
v = new BufferedReader(new InputStreamReader(is, "UTF-8")).readLine();
} catch (Throwable e) {
} finally {
try {
is.close();
} catch (Throwable e) {
}
}
VERSION = v;
}
public static byte[] bytes(String value) {
if( value == null) {
return null;
}
try {
return value.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static String asString(byte value[]) {
if( value == null) {
return null;
}
try {
return new String(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
static private class OptionsResourceHolder {
NativeCache cache = null;
NativeComparator comparator=null;
NativeLogger logger=null;
NativeOptions options;
public void init(Options value) {
options = new NativeOptions();
options.blockRestartInterval(value.blockRestartInterval());
options.blockSize(value.blockSize());
options.createIfMissing(value.createIfMissing());
options.errorIfExists(value.errorIfExists());
options.maxOpenFiles(value.maxOpenFiles());
options.paranoidChecks(value.paranoidChecks());
options.writeBufferSize(value.writeBufferSize());
switch(value.compressionType()) {
case NONE:
options.compression(NativeCompressionType.kNoCompression);
break;
case SNAPPY:
options.compression(NativeCompressionType.kSnappyCompression);
break;
}
if(value.cacheSize()>0 ) {
cache = new NativeCache(value.cacheSize());
options.cache(cache);
}
final DBComparator userComparator = value.comparator();
if(userComparator!=null) {
comparator = new NativeComparator() {
@Override
public int compare(byte[] key1, byte[] key2) {
return userComparator.compare(key1, key2);
}
@Override
public String name() {
return userComparator.name();
}
};
options.comparator(comparator);
}
final Logger userLogger = value.logger();
if(userLogger!=null) {
logger = new NativeLogger() {
@Override
public void log(String message) {
userLogger.log(message);
}
};
options.infoLog(logger);
}
}
public void close() {
if(cache!=null) {
cache.delete();
}
if(comparator!=null){
comparator.delete();
}
if(logger!=null) {
logger.delete();
}
}
}
public DB open(File path, Options options) throws IOException {
NativeDB db=null;
OptionsResourceHolder holder = new OptionsResourceHolder();
try {
holder.init(options);
db = NativeDB.open(holder.options, path);
} finally {
// if we could not open up the DB, then clean up the
// other allocated native resouces..
if(db==null) {
holder.close();
}
}
return new JniDB(db, holder.cache, holder.comparator, holder.logger);
}
public void destroy(File path, Options options) throws IOException {
OptionsResourceHolder holder = new OptionsResourceHolder();
try {
holder.init(options);
NativeDB.destroy(path, holder.options);
} finally {
holder.close();
}
}
public void repair(File path, Options options) throws IOException {
OptionsResourceHolder holder = new OptionsResourceHolder();
try {
holder.init(options);
NativeDB.repair(path, holder.options);
} finally {
holder.close();
}
}
@Override
public String toString() {
return String.format("leveldbjni version %s", VERSION);
}
public static void pushMemoryPool(int size) {
NativeBuffer.pushMemoryPool(size);
}
public static void popMemoryPool() {
NativeBuffer.popMemoryPool();
}
}

@ -0,0 +1,228 @@
/*
* 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.Callback;
import org.iq80.leveldb.*;
import java.util.concurrent.CountDownLatch;
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class JniDB implements DB {
private final NativeDB db;
private final NativeCache cache;
private final NativeComparator comparator;
private final NativeLogger logger;
public JniDB(NativeDB db, NativeCache cache, NativeComparator comparator, NativeLogger logger) {
this.db = db;
this.cache = cache;
this.comparator = comparator;
this.logger = logger;
}
public void close() {
db.delete();
if(cache!=null) {
cache.delete();
}
if(comparator!=null){
comparator.delete();
}
if(logger!=null) {
logger.delete();
}
}
public byte[] get(byte[] key) throws DBException {
return get(key, new ReadOptions());
}
public byte[] get(byte[] key, ReadOptions options) throws DBException {
try {
return db.get(convert(options), key);
} catch (NativeDB.DBException e) {
if(e.isNotFound()) {
return null;
}
throw new DBException(e.getMessage(), e);
}
}
public DBIterator iterator() {
return iterator(new ReadOptions());
}
public DBIterator iterator(ReadOptions options) {
return new JniDBIterator(db.iterator(convert(options)));
}
public void put(byte[] key, byte[] value) throws DBException {
put(key, value, new WriteOptions());
}
public void delete(byte[] key) throws DBException {
delete(key, new WriteOptions());
}
public void write(WriteBatch updates) throws DBException {
write(updates, new WriteOptions());
}
public WriteBatch createWriteBatch() {
return new JniWriteBatch(new NativeWriteBatch());
}
public Snapshot put(byte[] key, byte[] value, WriteOptions options) throws DBException {
try {
db.put(convert(options), key, value);
return null;
} catch (NativeDB.DBException e) {
throw new DBException(e.getMessage(), e);
}
}
public Snapshot delete(byte[] key, WriteOptions options) throws DBException {
try {
db.delete(convert(options), key);
return null;
} catch (NativeDB.DBException e) {
throw new DBException(e.getMessage(), e);
}
}
public Snapshot write(WriteBatch updates, WriteOptions options) throws DBException {
try {
db.write(convert(options), ((JniWriteBatch) updates).writeBatch());
return null;
} catch (NativeDB.DBException e) {
throw new DBException(e.getMessage(), e);
}
}
public Snapshot getSnapshot() {
return new JniSnapshot(db, db.getSnapshot());
}
public long[] getApproximateSizes(Range... ranges) {
NativeRange args[] = new NativeRange[ranges.length];
for (int i = 0; i < args.length; i++) {
args[i] = new NativeRange(ranges[i].start(), ranges[i].limit());
}
return db.getApproximateSizes(args);
}
public String getProperty(String name) {
return db.getProperty(name);
}
private NativeReadOptions convert(ReadOptions options) {
if(options==null) {
return null;
}
NativeReadOptions rc = new NativeReadOptions();
rc.fillCache(options.fillCache());
rc.verifyChecksums(options.verifyChecksums());
if(options.snapshot()!=null) {
rc.snapshot(((JniSnapshot) options.snapshot()).snapshot());
}
return rc;
}
private NativeWriteOptions convert(WriteOptions options) {
if(options==null) {
return null;
}
NativeWriteOptions rc = new NativeWriteOptions();
rc.sync(options.sync());
if(options.snapshot()) {
throw new UnsupportedOperationException("WriteOptions snapshot not supported");
}
return rc;
}
public void compactRange(byte[] begin, byte[] end) throws DBException {
db.compactRange(begin, end);
}
private static class Suspension {
static long env = Util.EnvJNI.Default();
CountDownLatch suspended = new CountDownLatch(1);
CountDownLatch resumed = new CountDownLatch(1);
Callback callback = new Callback(this, "suspended", 1);
public Suspension() {
Util.EnvJNI.Schedule(env, callback.getAddress(), 0);
}
private long suspended(long arg) {
suspended.countDown();
try {
resumed.await();
} catch (InterruptedException e) {
} finally {
callback.dispose();
}
return 0;
}
}
int suspendCounter = 0;
Suspension suspension = null;
public void suspendCompactions() throws InterruptedException {
Suspension s = null;
synchronized (this) {
suspendCounter++;
if( suspendCounter==1 ) {
suspension = new Suspension();
}
s = suspension;
}
// Don't return until the compactions have suspended.
s.suspended.await();
}
synchronized public void resumeCompactions() {
suspendCounter--;
if( suspendCounter==0 ) {
suspension.resumed.countDown();
suspension = null;
}
}
}

@ -0,0 +1,146 @@
/*
* 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.leveldbjni.internal.NativeDB;
import org.fusesource.leveldbjni.internal.NativeIterator;
import org.iq80.leveldb.DBIterator;
import java.util.AbstractMap;
import java.util.Map;
import java.util.NoSuchElementException;
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class JniDBIterator implements DBIterator {
private final NativeIterator iterator;
JniDBIterator(NativeIterator iterator) {
this.iterator = iterator;
}
public void close() {
iterator.delete();
}
public void remove() {
throw new UnsupportedOperationException();
}
public void seek(byte[] key) {
try {
iterator.seek(key);
} catch (NativeDB.DBException e) {
if( e.isNotFound() ) {
throw new NoSuchElementException();
} else {
throw new RuntimeException(e);
}
}
}
public void seekToFirst() {
iterator.seekToFirst();
}
public void seekToLast() {
iterator.seekToLast();
}
public Map.Entry<byte[], byte[]> peekNext() {
if(!iterator.isValid()) {
throw new NoSuchElementException();
}
try {
return new AbstractMap.SimpleImmutableEntry<byte[],byte[]>(iterator.key(), iterator.value());
} catch (NativeDB.DBException e) {
throw new RuntimeException(e);
}
}
public boolean hasNext() {
return iterator.isValid();
}
public Map.Entry<byte[], byte[]> next() {
Map.Entry<byte[], byte[]> rc = peekNext();
try {
iterator.next();
} catch (NativeDB.DBException e) {
throw new RuntimeException(e);
}
return rc;
}
public boolean hasPrev() {
if( !iterator.isValid() )
return false;
try {
iterator.prev();
try {
return iterator.isValid();
} finally {
iterator.next();
}
} catch (NativeDB.DBException e) {
throw new RuntimeException(e);
}
}
public Map.Entry<byte[], byte[]> peekPrev() {
try {
iterator.prev();
try {
return peekNext();
} finally {
iterator.next();
}
} catch (NativeDB.DBException e) {
throw new RuntimeException(e);
}
}
public Map.Entry<byte[], byte[]> prev() {
Map.Entry<byte[], byte[]> rc = peekPrev();
try {
iterator.prev();
} catch (NativeDB.DBException e) {
throw new RuntimeException(e);
}
return rc;
}
}

@ -0,0 +1,57 @@
/*
* 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.leveldbjni.internal.*;
import org.iq80.leveldb.Snapshot;
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class JniSnapshot implements Snapshot {
private final NativeDB db;
private final NativeSnapshot snapshot;
JniSnapshot(NativeDB db, NativeSnapshot snapshot) {
this.db = db;
this.snapshot = snapshot;
}
public void close() {
db.releaseSnapshot(snapshot);
}
NativeSnapshot snapshot() {
return snapshot;
}
}

@ -0,0 +1,65 @@
/*
* 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.leveldbjni.internal.NativeWriteBatch;
import org.iq80.leveldb.WriteBatch;
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class JniWriteBatch implements WriteBatch {
private final NativeWriteBatch writeBatch;
JniWriteBatch(NativeWriteBatch writeBatch) {
this.writeBatch = writeBatch;
}
public void close() {
writeBatch.delete();
}
public WriteBatch put(byte[] key, byte[] value) {
writeBatch.put(key, value);
return this;
}
public WriteBatch delete(byte[] key) {
writeBatch.delete(key);
return this;
}
public NativeWriteBatch writeBatch() {
return writeBatch;
}
}

@ -0,0 +1,285 @@
/*
* 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.PointerMath;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
import static org.fusesource.hawtjni.runtime.ArgFlag.*;
/**
* A NativeBuffer allocates a native buffer on the heap. It supports
* creating sub slices/views of that buffer and manages reference tracking
* so that the the native buffer is freed once all NativeBuffer views
* are deleted.
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class NativeBuffer extends NativeObject {
@JniClass
static class NativeBufferJNI {
static {
NativeDB.LIBRARY.load();
}
@JniMethod(cast="void *")
public static final native long malloc(
@JniArg(cast="size_t") long size);
public static final native void free(
@JniArg(cast="void *") long self);
// public static final native void buffer_copy (
// @JniArg(cast="const void *") long src,
// @JniArg(cast="size_t") long srcPos,
// @JniArg(cast="void *") long dest,
// @JniArg(cast="size_t") long destPos,
// @JniArg(cast="size_t") long length);
public static final native void buffer_copy (
@JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src,
@JniArg(cast="size_t") long srcPos,
@JniArg(cast="void *") long dest,
@JniArg(cast="size_t") long destPos,
@JniArg(cast="size_t") long length);
public static final native void buffer_copy (
@JniArg(cast="const void *") long src,
@JniArg(cast="size_t") long srcPos,
@JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest,
@JniArg(cast="size_t") long destPos,
@JniArg(cast="size_t") long length);
// @JniMethod(cast="void *")
// public static final native long memset (
// @JniArg(cast="void *") long buffer,
// int c,
// @JniArg(cast="size_t") long num);
}
private static class Allocation extends NativeObject {
private final AtomicInteger retained = new AtomicInteger(0);
private Allocation(long size) {
super(NativeBufferJNI.malloc(size));
}
void retain() {
assertAllocated();
retained.incrementAndGet();
}
void release() {
assertAllocated();
int r = retained.decrementAndGet();
if( r < 0 ) {
throw new Error("The object has already been deleted.");
} else if( r==0 ) {
NativeBufferJNI.free(self);
}
self = 0;
}
}
private static class Pool {
private final NativeBuffer.Pool prev;
Allocation allocation;
long pos;
long remaining;
int chunk;
public Pool(int chunk, Pool prev) {
this.chunk = chunk;
this.prev = prev;
}
NativeBuffer create(long size) {
if( size >= chunk ) {
Allocation allocation = new Allocation(size);
return new NativeBuffer(allocation, allocation.self, size);
}
if( remaining < size ) {
delete();
}
if( allocation == null ) {
allocate();
}
NativeBuffer rc = new NativeBuffer(allocation, pos, size);
pos = PointerMath.add(pos, size);
remaining -= size;
return rc;
}
private void allocate() {
allocation = new NativeBuffer.Allocation(chunk);
allocation.retain();
remaining = chunk;
pos = allocation.self;
}
public void delete() {
if( allocation!=null ) {
allocation.release();
allocation = null;
}
}
}
private final Allocation allocation;
private final long capacity;
static final private ThreadLocal<Pool> CURRENT_POOL = new ThreadLocal<Pool>();
static public NativeBuffer create(long capacity) {
Pool pool = CURRENT_POOL.get();
if( pool == null ) {
Allocation allocation = new Allocation(capacity);
return new NativeBuffer(allocation, allocation.self, capacity);
} else {
return pool.create(capacity);
}
}
public static void pushMemoryPool(int size) {
Pool original = CURRENT_POOL.get();
Pool next = new Pool(size, original);
CURRENT_POOL.set(next);
}
public static void popMemoryPool() {
Pool next = CURRENT_POOL.get();
next.delete();
if( next.prev == null ) {
CURRENT_POOL.remove();
} else {
CURRENT_POOL.set(next.prev);
}
}
static public NativeBuffer create(byte[] data) {
if( data == null ) {
return null;
} else {
return create(data, 0 , data.length);
}
}
static public NativeBuffer create(String data) {
return create(cbytes(data));
}
static public NativeBuffer create(byte[] data, int offset, int length) {
NativeBuffer rc = create(length);
rc.write(0, data, offset, length);
return rc;
}
private NativeBuffer(Allocation allocation, long self, long capacity) {
super(self);
this.capacity = capacity;
this.allocation = allocation;
this.allocation.retain();
}
public NativeBuffer slice(long offset, long length) {
assertAllocated();
if( length < 0 ) throw new IllegalArgumentException("length cannot be negative");
if( offset < 0 ) throw new IllegalArgumentException("offset cannot be negative");
if( offset+length >= capacity) throw new ArrayIndexOutOfBoundsException("offset + length exceed the length of this buffer");
return new NativeBuffer(allocation, PointerMath.add(self, offset), length);
}
static byte[] cbytes(String strvalue) {
byte[] value = strvalue.getBytes();
// expand by 1 so we get a null at the end.
byte[] rc = new byte[value.length+1];
System.arraycopy(value, 0, rc, 0, value.length);
return rc;
}
public NativeBuffer head(long length) {
return slice(0, length);
}
public NativeBuffer tail(long length) {
if( capacity-length < 0) throw new ArrayIndexOutOfBoundsException("capacity-length cannot be less than zero");
return slice(capacity-length, length);
}
public void delete() {
allocation.release();
}
public long capacity() {
return capacity;
}
public void write(long at, byte []source, int offset, int length) {
assertAllocated();
if( length < 0 ) throw new IllegalArgumentException("length cannot be negative");
if( offset < 0 ) throw new IllegalArgumentException("offset cannot be negative");
if( at < 0 ) throw new IllegalArgumentException("at cannot be negative");
if( at+length > capacity ) throw new ArrayIndexOutOfBoundsException("at + length exceeds the capacity of this object");
if( offset+length > source.length) throw new ArrayIndexOutOfBoundsException("offset + length exceed the length of the source buffer");
NativeBufferJNI.buffer_copy(source, offset, self, at, length);
}
public void read(long at, byte []target, int offset, int length) {
assertAllocated();
if( length < 0 ) throw new IllegalArgumentException("length cannot be negative");
if( offset < 0 ) throw new IllegalArgumentException("offset cannot be negative");
if( at < 0 ) throw new IllegalArgumentException("at cannot be negative");
if( at+length > capacity ) throw new ArrayIndexOutOfBoundsException("at + length exceeds the capacity of this object");
if( offset+length > target.length) throw new ArrayIndexOutOfBoundsException("offset + length exceed the length of the target buffer");
NativeBufferJNI.buffer_copy(self, at, target, offset, length);
}
public byte[] toByteArray() {
if( capacity > Integer.MAX_VALUE ) {
throw new OutOfMemoryError("Native buffer larger than the largest allowed Java byte[]");
}
byte [] rc = new byte[(int) capacity];
read(0, rc, 0, rc.length);
return rc;
}
}

@ -0,0 +1,72 @@
/*
* 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.ClassFlag.CPP;
import static org.fusesource.hawtjni.runtime.MethodFlag.CPP_DELETE;
/**
* Provides a java interface to the C++ leveldb::Cache class.
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class NativeCache extends NativeObject {
@JniClass(name="leveldb::Cache", flags={CPP})
private static class CacheJNI {
static {
NativeDB.LIBRARY.load();
}
@JniMethod(cast="leveldb::Cache *", accessor="leveldb::NewLRUCache")
public static final native long NewLRUCache(
@JniArg(cast="size_t") long capacity);
@JniMethod(flags={CPP_DELETE})
public static final native void delete(long self);
}
public NativeCache(long capacity) {
super(CacheJNI.NewLRUCache(capacity));
}
public void delete() {
assertAllocated();
CacheJNI.delete(self);
self = 0;
}
}

@ -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.FieldFlag.*;
import static org.fusesource.hawtjni.runtime.MethodFlag.*;
import static org.fusesource.hawtjni.runtime.ArgFlag.*;
import static org.fusesource.hawtjni.runtime.ClassFlag.*;
/**
* <p>
* Provides a java interface to the C++ leveldb::Comparator class.
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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();
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public enum NativeCompressionType {
kNoCompression(0x0), kSnappyCompression(0x1);
static final int t = kNoCompression.value;
final int value;
NativeCompressionType(int value) {
this.value = value;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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));
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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);
}
}
}

@ -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.*;
/**
* <p>
* Provides a java interface to the C++ leveldb::Logger class.
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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);
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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";
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
@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;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
@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;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
@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);
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class NativeSnapshot extends NativeObject {
NativeSnapshot(long self) {
super(self);
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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();
}
}
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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);
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
@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;
}
}

@ -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 <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
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());
}
}

@ -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.

@ -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 <pthread.h> header file.])])
AC_ARG_WITH([leveldb],
[AS_HELP_STRING([--with-leveldb@<:@=PATH@:>@],
[Directory where leveldb was built. Example: --with-leveldb=/opt/leveldb])],
[
CFLAGS="$CFLAGS -I${withval}/include"
CXXFLAGS="$CXXFLAGS -I${withval}/include"
AC_SUBST(CXXFLAGS)
LDFLAGS="$LDFLAGS -lleveldb -L${withval}"
AC_SUBST(LDFLAGS)
])
AC_CHECK_HEADER([leveldb/db.h],,AC_MSG_ERROR([cannot find headers for leveldb]))
AC_ARG_WITH([snappy],
[AS_HELP_STRING([--with-snappy@<:@=PATH@:>@],
[Directory where snappy was built. Example: --with-snappy=/opt/snappy])],
[
LDFLAGS="$LDFLAGS -lsnappy -L${withval}"
AC_SUBST(LDFLAGS)
])
AC_CHECK_HEADER([sys/errno.h],[AC_DEFINE([HAVE_SYS_ERRNO_H], [1], [Define to 1 if you have the <sys/errno.h> header file.])])
AC_LANG_POP()
])

@ -0,0 +1,36 @@
/*******************************************************************************
* 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.
*******************************************************************************/
#include "leveldbjni.h"
void buffer_copy(const void *source, size_t source_pos, void *dest, size_t dest_pos, size_t length) {
memmove(((char *)dest)+dest_pos, ((const char *)source)+source_pos, length);
}

@ -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.
*******************************************************************************/
#ifndef LEVELDBJNI_H
#define LEVELDBJNI_H
#ifdef HAVE_CONFIG_H
/* configure based build.. we will use what it discovered about the platform */
#include "config.h"
#else
#if defined(_WIN32) || defined(_WIN64)
/* Windows based build */
#define HAVE_STDLIB_H 1
#define HAVE_STRINGS_H 1
#include <windows.h>
#endif
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRINGS_H
#include <string.h>
#endif
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include "hawtjni.h"
#include <stdint.h>
#include <stdarg.h>
#ifdef __cplusplus
#include "leveldb/db.h"
#include "leveldb/options.h"
#include "leveldb/write_batch.h"
#include "leveldb/cache.h"
#include "leveldb/comparator.h"
#include "leveldb/env.h"
#include "leveldb/slice.h"
struct JNIComparator : public leveldb::Comparator {
jobject target;
jmethodID compare_method;
const char *name;
int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {
JNIEnv *env;
if ( hawtjni_attach_thread(&env, "leveldb") ) {
return 0;
}
int rc = env->CallIntMethod(target, compare_method, (jlong)(intptr_t)&a, (jlong)(intptr_t)&b);
hawtjni_detach_thread();
return rc;
}
const char* Name() const {
return name;
}
void FindShortestSeparator(std::string*, const leveldb::Slice&) const { }
void FindShortSuccessor(std::string*) const { }
};
struct JNILogger : public leveldb::Logger {
jobject target;
jmethodID log_method;
void Logv(const char* format, va_list ap) {
JNIEnv *env;
if ( hawtjni_attach_thread(&env, "leveldb") ) {
return;
}
char buffer[1024];
vsnprintf(buffer, sizeof(buffer), format, ap);
jstring message = env->NewStringUTF(buffer);
if( message ) {
env->CallVoidMethod(target, log_method, message);
env->DeleteLocalRef(message);
}
if (env->ExceptionOccurred() ) {
env->ExceptionDescribe();
env->ExceptionClear();
}
hawtjni_detach_thread();
}
};
#endif
#ifdef __cplusplus
extern "C" {
#endif
void buffer_copy(const void *source, size_t source_pos, void *dest, size_t dest_pos, size_t length);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LEVELDBJNI_H */

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- msbuild vs2008.vcxproj -->
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|Win32">
<Configuration>debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release|Win32">
<Configuration>release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release|x64">
<Configuration>release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>leveldbjni</ProjectName>
<RootNamespace>leveldbjni</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='release|Win32'">$(ProjectDir)/target/$(Platform)-$(Configuration)/lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='release|Win32'">$(ProjectDir)/target/$(Platform)-$(Configuration)/obj\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(ProjectDir)/target/$(Platform)-$(Configuration)/lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(ProjectDir)/target/$(Platform)-$(Configuration)/obj\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)/target/$(Platform)-$(Configuration)/lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)/target/$(Platform)-$(Configuration)/obj\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(ProjectDir)/target/$(Platform)-$(Configuration)/lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(ProjectDir)/target/$(Platform)-$(Configuration)/obj\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='debug|x64'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include=".\src\leveldbjni.cpp"/>
<ClCompile Include=".\src\leveldbjni_stats.cpp"/>
<ClCompile Include=".\src\leveldbjni_structs.cpp"/>
<ClCompile Include=".\src\buffer.c"/>
<ClCompile Include=".\src\hawtjni.c"/>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>SNAPPY;LEVELDB_PLATFORM_WINDOWS;OS_WIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(LEVELDB_HOME);$(LEVELDB_HOME)\include;$(LEVELDB_HOME)\port\win;$(SNAPPY_HOME);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
<Link>
<AdditionalDependencies>shlwapi.lib;$(LEVELDB_HOME)\Release\leveldb.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
<Link>
<AdditionalDependencies>shlwapi.lib;$(LEVELDB_HOME)\x64\Release\leveldb.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,422 @@
/*
* 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.test;
import junit.framework.TestCase;
import org.fusesource.leveldbjni.JniDBFactory;
import org.fusesource.leveldbjni.internal.JniDB;
import org.iq80.leveldb.*;
import org.junit.Test;
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;
/**
* A Unit test for the DB class implementation.
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class DBTest extends TestCase {
DBFactory factory = JniDBFactory.factory;
File getTestDirectory(String name) throws IOException {
File rc = new File(new File("test-data"), name);
factory.destroy(rc, new Options().createIfMissing(true));
rc.mkdirs();
return rc;
}
@Test
public void testOpen() throws IOException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
db.close();
// Try again.. this time we expect a failure since it exists.
options = new Options().errorIfExists(true);
try {
factory.open(path, options);
fail("Expected exception.");
} catch (IOException e) {
}
}
@Test
public void testRepair() throws IOException, DBException {
testCRUD();
factory.repair(new File(new File("test-data"), getName()), new Options());
}
@Test
public void testCRUD() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
WriteOptions wo = new WriteOptions().sync(false);
ReadOptions ro = new ReadOptions().fillCache(true).verifyChecksums(true);
db.put(bytes("Tampa"), bytes("green"));
db.put(bytes("London"), bytes("red"));
db.put(bytes("New York"), bytes("blue"));
assertEquals(db.get(bytes("Tampa"), ro), bytes("green"));
assertEquals(db.get(bytes("London"), ro), bytes("red"));
assertEquals(db.get(bytes("New York"), ro), bytes("blue"));
db.delete(bytes("New York"), wo);
assertNull(db.get(bytes("New York"), ro));
// leveldb does not consider deleting something that does not exist an error.
db.delete(bytes("New York"), wo);
db.close();
}
@Test
public void testIterator() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
db.put(bytes("Tampa"), bytes("green"));
db.put(bytes("London"), bytes("red"));
db.put(bytes("New York"), bytes("blue"));
ArrayList<String> expecting = new ArrayList<String>();
expecting.add("London");
expecting.add("New York");
expecting.add("Tampa");
ArrayList<String> actual = new ArrayList<String>();
DBIterator iterator = db.iterator();
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
actual.add(asString(iterator.peekNext().getKey()));
}
iterator.close();
assertEquals(expecting, actual);
db.close();
}
@Test
public void testSnapshot() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
db.put(bytes("Tampa"), bytes("green"));
db.put(bytes("London"), bytes("red"));
db.delete(bytes("New York"));
ReadOptions ro = new ReadOptions().snapshot(db.getSnapshot());
db.put(bytes("New York"), bytes("blue"));
assertEquals(db.get(bytes("Tampa"), ro), bytes("green"));
assertEquals(db.get(bytes("London"), ro), bytes("red"));
// Should not be able to get "New York" since it was added
// after the snapshot
assertNull(db.get(bytes("New York"), ro));
ro.snapshot().close();
// Now try again without the snapshot..
ro.snapshot(null);
assertEquals(db.get(bytes("New York"), ro), bytes("blue"));
db.close();
}
@Test
public void testWriteBatch() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
db.put(bytes("NA"), bytes("Na"));
WriteBatch batch = db.createWriteBatch();
batch.delete(bytes("NA"));
batch.put(bytes("Tampa"), bytes("green"));
batch.put(bytes("London"), bytes("red"));
batch.put(bytes("New York"), bytes("blue"));
db.write(batch);
batch.close();
ArrayList<String> expecting = new ArrayList<String>();
expecting.add("London");
expecting.add("New York");
expecting.add("Tampa");
ArrayList<String> actual = new ArrayList<String>();
DBIterator iterator = db.iterator();
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
actual.add(asString(iterator.peekNext().getKey()));
}
iterator.close();
assertEquals(expecting, actual);
db.close();
}
@Test
public void testApproximateSizes() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
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));
}
long[] approximateSizes = db.getApproximateSizes(new Range(bytes("row"), bytes("s")));
assertNotNull(approximateSizes);
assertEquals(1, approximateSizes.length);
assertTrue("Wrong size", approximateSizes[0] > 0);
db.close();
}
@Test
public void testGetProperty() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
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));
}
String stats = db.getProperty("leveldb.stats");
assertNotNull(stats);
assertTrue(stats.contains("Compactions"));
db.close();
}
@Test
public void testCustomComparator1() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
options.comparator(new DBComparator() {
public int compare(byte[] key1, byte[] key2) {
return new String(key1).compareTo(new String(key2));
}
public String name() {
return getName();
}
public byte[] findShortestSeparator(byte[] start, byte[] limit) {
return start;
}
public byte[] findShortSuccessor(byte[] key) {
return key;
}
});
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
ArrayList<String> expecting = new ArrayList<String>();
for(int i=0; i < 26; i++) {
String t = ""+ ((char) ('a' + i));
expecting.add(t);
db.put(bytes(t), bytes(t));
}
ArrayList<String> actual = new ArrayList<String>();
DBIterator iterator = db.iterator();
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
actual.add(asString(iterator.peekNext().getKey()));
}
iterator.close();
assertEquals(expecting, actual);
db.close();
}
@Test
public void testCustomComparator2() throws IOException, DBException {
Options options = new Options().createIfMissing(true);
options.comparator(new DBComparator() {
public int compare(byte[] key1, byte[] key2) {
return new String(key1).compareTo(new String(key2)) * -1;
}
public String name() {
return getName();
}
public byte[] findShortestSeparator(byte[] start, byte[] limit) {
return start;
}
public byte[] findShortSuccessor(byte[] key) {
return key;
}
});
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
ArrayList<String> expecting = new ArrayList<String>();
for(int i=0; i < 26; i++) {
String t = ""+ ((char) ('a' + i));
expecting.add(t);
db.put(bytes(t), bytes(t));
}
Collections.reverse(expecting);
ArrayList<String> actual = new ArrayList<String>();
DBIterator iterator = db.iterator();
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
actual.add(asString(iterator.peekNext().getKey()));
}
iterator.close();
assertEquals(expecting, actual);
db.close();
}
@Test
public void testLogger() throws IOException, InterruptedException, DBException {
final List<String> messages = Collections.synchronizedList(new ArrayList<String>());
Options options = new Options().createIfMissing(true);
options.logger(new Logger() {
public void log(String message) {
messages.add(message);
}
});
File path = getTestDirectory(getName());
DB db = factory.open(path, options);
for( int j=0; j < 5; j++) {
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));
}
Thread.sleep(100);
}
db.close();
assertFalse(messages.isEmpty());
}
@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");
System.out.println(stats);
// Compactions
// Level Files Size(MB) Time(sec) Read(MB) Write(MB)
// --------------------------------------------------
assertFalse(stats.contains("1 0 0 0"));
assertFalse(stats.contains("2 0 0 0"));
// After the compaction, level 1 and 2 should not have any files in it..
((JniDB) db).compactRange(null, null);
stats = db.getProperty("leveldb.stats");
System.out.println(stats);
assertTrue(stats.contains("1 0 0 0"));
assertTrue(stats.contains("2 0 0 0"));
}
db.close();
}
public void assertEquals(byte[] arg1, byte[] arg2) {
assertTrue(Arrays.equals(arg1, arg2));
}
}

@ -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.

@ -0,0 +1,303 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fusesource</groupId>
<artifactId>fusesource-pom</artifactId>
<version>1.9</version>
</parent>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-project</artifactId>
<version>99-master-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>leveldbjni is a jni library for accessing leveldb.</description>
<properties>
<forge-project-id>leveldbjni</forge-project-id>
<forge-project-id-uc>LEVELDBJNI</forge-project-id-uc>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hawtjni-version>1.6</hawtjni-version>
<leveldb-api-version>0.2</leveldb-api-version>
</properties>
<modules>
<module>leveldbjni</module>
</modules>
<url>http://${forge-project-id}.fusesource.org</url>
<inceptionYear>2009</inceptionYear>
<issueManagement>
<system>github</system>
<url>https://github.com/fusesource/leveldbjni/issues</url>
</issueManagement>
<mailingLists>
<mailingList>
<name>${forge-project-id} dev</name>
<post>${forge-project-id}-dev@fusesource.org</post>
<subscribe>${forge-project-id}-dev-subscribe@fusesource.org</subscribe>
</mailingList>
<mailingList>
<name>${forge-project-id} commits</name>
<post>${forge-project-id}-commits@fusesource.org</post>
<subscribe>${forge-project-id}-commits-subscribe@fusesource.org</subscribe>
</mailingList>
</mailingLists>
<licenses>
<license>
<name>The BSD 3-Clause License</name>
<url>http://www.opensource.org/licenses/BSD-3-Clause</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:git://github.com/fusesource/leveldbjni.git</connection>
<developerConnection>scm:git:git@github.com:fusesource/leveldbjni.git</developerConnection>
<url>https://github.com/fusesource/leveldbjni</url>
</scm>
<distributionManagement>
<site>
<id>website.fusesource.org</id>
<name>website</name>
<url>dav:http://fusesource.com/forge/dav/${forge-project-id}/maven/${project.version}</url>
</site>
</distributionManagement>
<developers>
<developer>
<id>chirino</id>
<name>Hiram Chirino</name>
<email>hiram@hiramchirino.com</email>
<url>http://hiramchirino.com</url>
<timezone>GMT-5</timezone>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- the older clean plugin has trouble deleting directories with symlinks in them -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<forkMode>once</forkMode>
<argLine>-ea</argLine>
<failIfNoTests>false</failIfNoTests>
<workingDirectory>${project.build.directory}</workingDirectory>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.6</version>
<configuration>
<excludePackageNames>*.internal</excludePackageNames>
<linksource>true</linksource>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api</link>
</links>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.1.1</version>
<reportSets>
<reportSet>
<reports>
<report>index</report>
<report>sumary</report>
<report>plugins</report>
<report>dependencies</report>
<report>mailing-list</report>
<report>issue-tracking</report>
<report>license</report>
<report>scm</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>surefire-report-maven-plugin</artifactId>
<version>2.0-beta-1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>download</id>
<repositories>
<repository>
<id>fusesource.nexus.snapshot</id>
<name>FuseSource Community Snapshot Repository</name>
<url>http://repo.fusesource.com/nexus/content/groups/public-snapshots</url>
</repository>
<repository>
<id>sonatype-nexus</id>
<name>Sonatype Nexus</name>
<url>https://oss.sonatype.org/content/repositories/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>fusesource.nexus.snapshot</id>
<name>FuseSource Community Snapshot Repository</name>
<url>http://repo.fusesource.com/nexus/content/groups/public-snapshots</url>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>full</id>
<modules>
<module>leveldbjni-osx</module>
<module>leveldbjni-linux32</module>
<module>leveldbjni-linux64</module>
<module>leveldbjni-win32</module>
<module>leveldbjni-win64</module>
<module>leveldbjni-all</module>
</modules>
</profile>
<profile>
<id>all</id>
<modules>
<module>leveldbjni-all</module>
</modules>
</profile>
<profile>
<id>osx</id>
<modules>
<module>leveldbjni-osx</module>
</modules>
</profile>
<profile>
<id>linux32</id>
<modules>
<module>leveldbjni-linux32</module>
</modules>
</profile>
<profile>
<id>linux64</id>
<modules>
<module>leveldbjni-linux64</module>
</modules>
</profile>
<profile>
<id>win32</id>
<properties>
<skipAutogen>true</skipAutogen>
</properties>
<modules>
<module>leveldbjni-win32</module>
</modules>
</profile>
<profile>
<id>win64</id>
<properties>
<skipAutogen>true</skipAutogen>
</properties>
<modules>
<module>leveldbjni-win64</module>
</modules>
</profile>
</profiles>
</project>

@ -0,0 +1,242 @@
# LevelDB JNI
## Description
LevelDB JNI gives you a Java interface to the
[LevelDB](http://code.google.com/p/leveldb/) C++ library
which is a fast key-value storage library written at Google
that provides an ordered mapping from string keys to string values..
## Using as a Maven Dependency
You just nee to add the following repositories and dependencies to your Maven pom.
<repositories>
<repository>
<id>fusesource.nexus.snapshot</id>
<name>FuseSource Community Snapshot Repository</name>
<url>http://repo.fusesource.com/nexus/content/groups/public-snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-all</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
## API Usage:
Recommended Package imports:
import org.iq80.leveldb.*;
import static org.fusesource.leveldbjni.JniDBFactory.*;
import java.io.*;
Opening and closing the database.
Options options = new Options();
options.createIfMissing(true);
DB db = factory.open(new File("example"), options);
try {
// Use the db in here....
} finally {
// Make sure you close the db to shutdown the
// database and avoid resource leaks.
db.close();
}
Putting, Getting, and Deleting key/values.
db.put(bytes("Tampa"), bytes("rocks"));
String value = asString(db.get(bytes("Tampa")));
db.delete(wo, bytes("Tampa"));
Performing Batch/Bulk/Atomic Updates.
WriteBatch batch = db.createWriteBatch();
try {
batch.delete(bytes("Denver"));
batch.put(bytes("Tampa"), bytes("green"));
batch.put(bytes("London"), bytes("red"));
db.write(batch);
} finally {
// Make sure you close the batch to avoid resource leaks.
batch.close();
}
Iterating key/values.
DBIterator iterator = db.iterator();
try {
for(iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
String key = asString(iterator.peekNext().getKey());
String value = asString(iterator.peekNext().getValue());
System.out.println(key+" = "+value);
}
} finally {
// Make sure you close the iterator to avoid resource leaks.
iterator.close();
}
Working against a Snapshot view of the Database.
ReadOptions ro = new ReadOptions();
ro.snapshot(db.getSnapshot());
try {
// All read operations will now use the same
// consistent view of the data.
... = db.iterator(ro);
... = db.get(bytes("Tampa"), ro);
} finally {
// Make sure you close the snapshot to avoid resource leaks.
ro.snapshot().close();
}
Using a custom Comparator.
DBComparator comparator = new DBComparator(){
public int compare(byte[] key1, byte[] key2) {
return new String(key1).compareTo(new String(key2));
}
public String name() {
return "simple";
}
public byte[] findShortestSeparator(byte[] start, byte[] limit) {
return start;
}
public byte[] findShortSuccessor(byte[] key) {
return key;
}
};
Options options = new Options();
options.comparator(comparator);
DB db = factory.open(new File("example"), options);
Disabling Compression
Options options = new Options();
options.compressionType(CompressionType.NONE);
DB db = factory.open(new File("example"), options);
Configuring the Cache
Options options = new Options();
options.cacheSize(100 * 1048576); // 100MB cache
DB db = factory.open(new File("example"), options);
Getting approximate sizes.
long[] sizes = db.getApproximateSizes(new Range(bytes("a"), bytes("k")), new Range(bytes("k"), bytes("z")));
System.out.println("Size: "+sizes[0]+", "+sizes[1]);
Getting database status.
String stats = db.getProperty("leveldb.stats");
System.out.println(stats);
Getting informational log messages.
Logger logger = new Logger() {
public void log(String message) {
System.out.println(message);
}
};
Options options = new Options();
options.logger(logger);
DB db = factory.open(new File("example"), options);
Destroying a database.
Options options = new Options();
factory.destroy(new File("example"), options);
Repairing a database.
Options options = new Options();
factory.repair(new File("example"), options);
Using a memory pool to make native memory allocations more efficient:
JniDBFactory.pushMemoryPool(1024 * 512);
try {
// .. work with the DB in here,
} finally {
JniDBFactory.popMemoryPool();
}
## Building
### Prerequisites
* GNU compiler toolchain
* [Maven 3](http://maven.apache.org/download.html)
### Supported Platforms
The following worked for me on:
* OS X Lion with X Code 4
* CentOS 5.6 (32 and 64 bit)
* Ubuntu 12.04 (32 and 64 bit)
* apt-get install autoconf libtool
### Build Procedure
Then download the snappy, leveldb, and leveldbjni project source code:
wget http://snappy.googlecode.com/files/snappy-1.0.5.tar.gz
tar -zxvf snappy-1.0.5.tar.gz
git clone git://github.com/chirino/leveldb.git
git clone git://github.com/fusesource/leveldbjni.git
export SNAPPY_HOME=`cd snappy-1.0.5; pwd`
export LEVELDB_HOME=`cd leveldb; pwd`
export LEVELDBJNI_HOME=`cd leveldbjni; pwd`
Compile the snappy project. This produces a static library.
cd ${SNAPPY_HOME}
./configure --disable-shared --with-pic
make
Patch and Compile the leveldb project. This produces a static library.
cd ${LEVELDB_HOME}
export LIBRARY_PATH=${SNAPPY_HOME}
export C_INCLUDE_PATH=${LIBRARY_PATH}
export CPLUS_INCLUDE_PATH=${LIBRARY_PATH}
git apply ../leveldbjni/leveldb.patch
make libleveldb.a
Now use maven to build the leveldbjni project.
cd ${LEVELDBJNI_HOME}
mvn clean install -P download -P ${platform}
Replace ${platform} with one of the following platform identifiers (depending on the platform your building on):
* osx
* linux32
* linux64
* win32
* win64
If your platform does not have the right auto-tools levels available
just copy the `leveldbjni-${version}-SNAPSHOT-native-src.zip` artifact
from a platform the does have the tools available then add the
following argument to your maven build:
-Dnative-src-url=file:leveldbjni-${verision}-SNAPSHOT-native-src.zip
### Build Results
* `leveldbjni/target/leveldbjni-${version}.jar` : The java class file to the library.
* `leveldbjni/target/leveldbjni-${version}-native-src.zip` : A GNU style source project which you can use to build the native library on other systems.
* `leveldbjni-${platform}/target/leveldbjni-${platform}-${version}.jar` : A jar file containing the built native library using your currently platform.

@ -0,0 +1,30 @@
# How To Release
Since levedbjni has to be build against multiple platforms, the standard maven release plugin will not work to do the release.
Once you ready to do the release, create a branch for the release using:
git co -b ${version}.x
Update the version number in the poms using:
mvn -P all org.codehaus.mojo:versions-maven-plugin:1.2:set org.codehaus.mojo:versions-maven-plugin:1.2:commit -DnewVersion="${version}"
git commit -am "Preping for a the ${version} release"
git tag "leveldbjni-${version}"
git push origin "leveldbjni-${version}"
Now release the non-platform specific artifacts using:
mvn clean deploy -P release -P download
Then for each platform, shell into the box check out the "leveldbjni-${version}" tag and then:
cd $platform
mvn clean deploy -Dleveldb=`cd ../../leveldb; pwd` -Dsnappy=`cd ../../snappy-1.0.3; pwd` -P release -P download
Finally release the `leveldbjni-all` which uber jars all the previously released artifacts.
cd leveldbjni-all
mvn clean deploy -P release -P download
Congrats your done. Make sure your releasing the artifacts in Nexus after each step.
Loading…
Cancel
Save