diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ea22d9..8944201 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,10 @@ CHECK_FUNCTION_EXISTS(posix_fallocate HAVE_POSIX_FALLOCATE) CHECK_FUNCTION_EXISTS(fdatasync HAVE_FDATASYNC) CHECK_FUNCTION_EXISTS(tdestroy HAVE_TDESTROY) +FIND_PACKAGE(JNI) +FIND_PACKAGE(PERL) +FIND_PACKAGE(RUBY) + FIND_LIBRARY(DBUG_TEST dbug-stubs /home/sears/local/dbug/lib/) if(NOT DBUG_TEST) message(STATUS "dbug not found. proceeding with normal build") diff --git a/lang/CMakeLists.txt b/lang/CMakeLists.txt index fa23e0d..c630cfe 100644 --- a/lang/CMakeLists.txt +++ b/lang/CMakeLists.txt @@ -1,2 +1,3 @@ SUBDIRS(perl) SUBDIRS(ruby) +SUBDIRS(java) \ No newline at end of file diff --git a/lang/java/CMakeLists.txt b/lang/java/CMakeLists.txt new file mode 100644 index 0000000..0b18ebb --- /dev/null +++ b/lang/java/CMakeLists.txt @@ -0,0 +1,17 @@ +IF(JNI_FOUND) + ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/org/stasis/Stasis.class + COMMAND javac -d ${CMAKE_CURRENT_BINARY_DIR} + -sourcepath ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/org/stasis/Stasis.java + ) + ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/org_stasis_Stasis.h + COMMAND javah -classpath ${CMAKE_CURRENT_BINARY_DIR} -jni + -d ${CMAKE_CURRENT_BINARY_DIR} org.stasis.Stasis + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/org/stasis/Stasis.class + ) +#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} /usr/lib/jvm/java-6-openjdk/include/ ${INCLUDE_DIRECTORIES}) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${JAVA_INCLUDE_PATH} ${INCLUDE_DIRECTORIES}) + ADD_LIBRARY(stasisjni ${CMAKE_CURRENT_SOURCE_DIR}/org_stasis_Stasis.c) +ENDIF(JNI_FOUND) \ No newline at end of file diff --git a/lang/java/build.xml b/lang/java/build.xml new file mode 100644 index 0000000..9dde4e6 --- /dev/null +++ b/lang/java/build.xml @@ -0,0 +1,4 @@ + + + + diff --git a/lang/java/org/stasis/LinearHashNTA.java b/lang/java/org/stasis/LinearHashNTA.java new file mode 100644 index 0000000..b32b484 --- /dev/null +++ b/lang/java/org/stasis/LinearHashNTA.java @@ -0,0 +1,193 @@ +package stasis.jni; + +import java.util.Arrays; +import java.util.Iterator; + +import jol.core.Runtime; +import jol.types.basic.Tuple; +import jol.types.basic.TupleSet; +import jol.types.exception.BadKeyException; +import jol.types.exception.UpdateException; +import jol.types.table.Key; +import jol.types.table.StasisTable; +import jol.types.table.TableName; + +public class LinearHashNTA extends StasisTable { + static LinearHashNTA catalog = null; + + protected final Tuple header; + private final long[] rid; + + protected Tuple registerTable(TableName name, Key key, Class[] type) throws UpdateException { + Tuple header = new Tuple(rid[0], rid[1], key, attributeTypes); + Tuple nameTup = new Tuple(name); + + Tuple row = catalog.key().reconstruct(nameTup, header); + catalog.insert(row); + + return row; + + } + protected LinearHashNTA(Runtime context) throws UpdateException { + super(context, CATALOG_NAME, CATALOG_KEY, CATALOG_COLTYPES); + key = new Key(0); + long[] rootRid = Stasis.root_record(); + synchronized (xactTable) { + long type = Stasis.record_type(ts.xid, rootRid); + if(type == -1) { + ts.dirty = true; + rid = Stasis.hash_create(ts.xid); + if(rid[0] != rootRid[0] || rid[1] != rootRid[1]) { + throw new IllegalStateException(); + } + } else { + rid = new long[3]; + rid[0] = rootRid[0]; + rid[1] = rootRid[1]; + } + header = CATALOG_SCHEMA; + } + } + public LinearHashNTA(Runtime context, TableName name, Key key, + Class[] attributeTypes) throws UpdateException { + super(context, name, key, attributeTypes); + int port = context.getPort(); + if(catalog == null) { + catalog = new LinearHashNTA(context); // open catalog based on recordid + catalog.registerTable(CATALOG_NAME, CATALOG_KEY, CATALOG_COLTYPES); + } + TableName n = new TableName(port + ":" + name.scope, name.name); + TupleSet headerSet; + try { + headerSet = catalog.primary().lookupByKey(n); + } catch (BadKeyException e) { + throw new IllegalStateException(e); + } + + Tuple catalogEntry; + synchronized (xactTable) { + if(headerSet.isEmpty()) { + ts.dirty = true; + rid = Stasis.hash_create(ts.xid); +// System.out.println("Alloced stasis table: " + n + ", " + key); + catalogEntry = registerTable(n, key, attributeTypes); + } else { + catalogEntry = headerSet.iterator().next(); + rid = new long[3]; + } + } + header = catalog.primary().key().projectValue(catalogEntry); + rid[0] = (Long)header.value(0); + rid[1] = (Long)header.value(1); + } + + @Override + protected boolean add(byte[] keybytes, byte[] valbytes) + throws UpdateException { + synchronized (xactTable) { + ts.dirty = true; + byte[] oldvalbytes = Stasis.hash_insert(ts.xid, rid, keybytes, valbytes); + if(oldvalbytes != null) { + return (!Arrays.equals(valbytes, oldvalbytes)); + } + return oldvalbytes == null; + } + } + + @Override + public Long cardinality() { + return Stasis.hash_cardinality(-1, rid); + } + + @Override + protected boolean remove(byte[] keybytes, byte[] valbytes) + throws UpdateException { + synchronized (xactTable) { + // 'bug for bug' compatible w/ BasicTable + byte[] oldvalbytes = lookup(keybytes); + if(oldvalbytes == null || ! Arrays.equals(oldvalbytes, valbytes)) { + return false; + } else { + Stasis.hash_remove(ts.xid, rid, keybytes); + ts.dirty = true; + return true; + } + // preferred implementation follows. + /*byte[] oldvalbytes = Stasis.hash_remove(ts.xid, rid, keybytes); + if(oldvalbytes != null && ! Arrays.equals(valbytes, oldvalbytes)) { + throw new UpdateException("attempt to remove non-existant tuple"); + } + ts.dirty = true; + + return oldvalbytes != null; */ + } + } + + @Override + protected byte[] lookup(byte[] keybytes) { + if(keybytes == null) throw new NullPointerException("keybytes is null!"); + if(rid == null) throw new NullPointerException("rid is null!"); + return Stasis.hash_lookup(-1, rid, keybytes); + } + + @Override + protected Iterator tupleBytes() { + return new Iterator() { + private byte[] it = Stasis.hash_iterator(-1, rid); + + private byte[][] current = new byte[2][]; + private byte[][] next = new byte[2][]; + + private boolean hadNext = true; + Iterator init() { + hadNext = Stasis.iterator_next(-1, it); + if(hadNext) { + next[0] = Stasis.iterator_key(-1,it); + next[1] = Stasis.iterator_value(-1, it); + Stasis.iterator_tuple_done(-1, it); + } else { + Stasis.iterator_close(-1, it); + } + return this; + } + + public boolean hasNext() { + return hadNext; + } + + public byte[][] next() { + if(hadNext) { + current = next; + next = new byte[2][]; + + hadNext = Stasis.iterator_next(-1,it); + if(hadNext) { + next[0] = Stasis.iterator_key(-1,it); + next[1] = Stasis.iterator_value(-1,it); + Stasis.iterator_tuple_done(-1,it); + } else { + Stasis.iterator_close(-1, it); + } + return current; + } else { + throw new IllegalStateException("next() called after end of iterator"); + } + } + + public void remove() { + throw new UnsupportedOperationException("No support for removal via table iterators yet..."); + } + + @Override + protected void finalize() throws Throwable { + try { + if(hadNext) + throw new IllegalStateException("detected non-exhausted iterator in finalize()"); + } finally { + super.finalize(); + } + } + }.init(); + } + +} diff --git a/lang/java/org/stasis/Stasis.java b/lang/java/org/stasis/Stasis.java new file mode 100644 index 0000000..4ad478e --- /dev/null +++ b/lang/java/org/stasis/Stasis.java @@ -0,0 +1,65 @@ +package org.stasis; + +public class Stasis { + // Stasis operations + public static native int init(); + public static native void deinit(); + + public static native long[] root_record(); + + public static boolean recordid_equals(long[] a, long[] b) { return a[0]==b[0]&&a[1]==b[1]; } + + // Transaction initiation + public static native long begin(); + public static native void commit(long xid); + public static native void abort(long xid); + public static native void prepare(long xid); + + // Record operations + public static native long record_type(long xid, long[] rid); + + // LinearHashNTA + public static native long[] hash_create(long xid); + public static native void hash_delete(long xid, long[] rid); // TODO need way to drop tables from lincoln... + public static native long hash_cardinality(long xid, long[] rid); + public static native byte[] hash_insert(long xid, long[] rid, byte[] keybytes, byte[] valbytes); + public static native byte[] hash_remove(long xid, long[] rid, byte[] keybytes); + public static native byte[] hash_lookup(long xid, long[] rid, byte[] keybytes); + public static native byte[] hash_iterator(long xid, long[] rid); + + // Generic iterator interface + public static native void iterator_close(long xid, byte[] it); + public static native boolean iterator_next(long xid, byte[] it); + public static native byte[] iterator_key(long xid, byte[] it); + public static native byte[] iterator_value(long xid, byte[] it); + public static native void iterator_tuple_done(long xid, byte[] it); + + public static void loadLibrary() { + System.loadLibrary("stasisjni"); + } + + public static void main(String[] arg) { + loadLibrary(); + System.out.println("Tinit()"); + init(); + System.out.println("Stasis is running"); + System.out.println("Tbegin()"); + long xid = begin(); + long[] root = root_record(); + long rootType = record_type(xid,root); + System.out.println("Root record (page: " + root[0] + ", slot: " + root[1] + ") type is " + rootType); + if(rootType == -1) { + System.out.println("Uninitialized store"); + System.out.println("Creating root record"); + long[] hashRec = hash_create(xid); + if(!recordid_equals(hashRec,root)) { + throw new IllegalStateException("Bootstrapping didn't set the root record!!"); + } + } + + System.out.println("Tcommit()"); + commit(xid); + deinit(); + System.out.println("Successfully shut down. Exiting."); + } +} diff --git a/lang/java/org_stasis_Stasis.c b/lang/java/org_stasis_Stasis.c new file mode 100644 index 0000000..596abc8 --- /dev/null +++ b/lang/java/org_stasis_Stasis.c @@ -0,0 +1,211 @@ +#include "org_stasis_Stasis.h" +#include +#include + +static jlongArray jlongArray_recordid(JNIEnv *e, recordid rid) { + jlong l[3] = {rid.page, rid.slot, rid.size}; + jlongArray jla = (*e)->NewLongArray(e, 3); + if((*e)->ExceptionOccurred(e)) return 0; + (*e)->SetLongArrayRegion(e, jla, 0, 3, (jlong*)&l); + if((*e)->ExceptionOccurred(e)) return 0; + return jla; +} + +static recordid recordid_jlongArray(JNIEnv *e, jlongArray jla) { + jlong l[3]; + (*e)->GetLongArrayRegion(e, jla, 0, 3, (jlong*)&l); + if((*e)->ExceptionOccurred(e)) + return NULLRID; + recordid ret = {l[0], l[1], l[2]}; + return ret; +} + +static byte * bytes_jbyteArray(JNIEnv *e, jbyteArray jba, size_t * sz) { + *sz = (*e)->GetArrayLength(e, jba) * sizeof(byte); + if((*e)->ExceptionOccurred(e)) return 0; + assert(sizeof(jbyte) == 1); + jbyte * ret = malloc(*sz); + (*e)->GetByteArrayRegion(e, jba, 0, *sz, (jbyte*)ret); + if((*e)->ExceptionOccurred(e)) return 0; + return (byte*)ret; +} +static jbyteArray jbyteArray_bytes(JNIEnv *e, byte* b, size_t sz) { + jbyteArray jba = (*e)->NewByteArray(e, sz); + (*e)->SetByteArrayRegion(e, jba, 0, sz, (jbyte*)b); + if((*e)->ExceptionOccurred(e)) return 0; + return jba; +} +static int initted = 0; +JNIEXPORT jint JNICALL Java_stasis_jni_Stasis_init + (JNIEnv *e, jclass c) { + if(!initted) { + Tinit(); + } + initted++; + return initted; +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_deinit + (JNIEnv *e, jclass c) { + initted--; + if(!initted) { + Tdeinit(); + } +} +JNIEXPORT jlongArray JNICALL Java_stasis_jni_Stasis_root_1record + (JNIEnv *e, jclass c) { + return jlongArray_recordid(e, ROOT_RECORD); +} +JNIEXPORT jlong JNICALL Java_stasis_jni_Stasis_begin + (JNIEnv *e, jclass c) { + assert(initted); + jlong xid = (jlong) Tbegin(); + return xid; +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_commit + (JNIEnv *e, jclass c, jlong xid) { + printf("commiting %d\n", xid); + Tcommit((int)xid); +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_abort + (JNIEnv *e, jclass c, jlong xid) { + Tabort((int)xid); +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_prepare + (JNIEnv *e, jclass c, jlong xid) { + Tprepare((int)xid); +} +JNIEXPORT jlong JNICALL Java_stasis_jni_Stasis_record_1type + (JNIEnv *e, jclass c, jlong xid, jlongArray jlaRid) { + recordid rid = recordid_jlongArray(e, jlaRid); + if((*e)->ExceptionOccurred(e)) return 0; + return (jlong)TrecordType(xid, rid); +} +JNIEXPORT jlongArray JNICALL Java_stasis_jni_Stasis_hash_1create + (JNIEnv *e, jclass c, jlong xid) { + return jlongArray_recordid(e,ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH)); +} +/* // ThashDelete is unimplemented... +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_hash_1delete + (JNIEnv *e, jclass c, jlong xid, jlongArray jlaRid) { + ThashDelete(xid, recordid_jlongArray(e, jlaRid)); + } */ +/* // no equivalent call in stasis api +JNIEXPORT jlong JNICALL Java_stasis_jni_Stasis_hash_1cardinality + (JNIEnv *, jclass, jlong, jlongArray); +*/ +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_hash_1insert + (JNIEnv *e, jclass c, jlong xid, jlongArray jbarid, jbyteArray jbakey, jbyteArray jbaval) { + recordid rid = recordid_jlongArray(e,jbarid); + if((*e)->ExceptionOccurred(e)) return 0; + size_t keylen; + byte * key = bytes_jbyteArray(e,jbakey, &keylen); + if((*e)->ExceptionOccurred(e)) return 0; + size_t vallen; + byte * val = bytes_jbyteArray(e,jbaval, &vallen); + if((*e)->ExceptionOccurred(e)) return 0; + byte * ret; + int retsize = ThashLookup((int)xid,rid,key,keylen,&ret); + jbyteArray jbaret; + if(retsize == -1) { + jbaret = 0; + } else { + jbaret = jbyteArray_bytes(e,ret,retsize); + } + if((*e)->ExceptionOccurred(e)) return 0; + // printf("Calling insert %lld %lld %lld %lx %lld %lx %lld (retsize %lld)", (long long)xid, (long long)rid.page, (long long)rid.slot, (unsigned long)key, (long long) keylen, (unsigned long)val, (long long) keylen, (long long)retsize); fflush(0); + ThashInsert((int)xid, rid, key, keylen, val, vallen); + // printf("Returned from insert"); fflush(0); + return jbaret; +} + +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_hash_1remove + (JNIEnv *e, jclass c, jlong xid, jlongArray jbarid, jbyteArray jbakey) { + + recordid rid = recordid_jlongArray(e, jbarid); + if((*e)->ExceptionOccurred(e)) return 0; + + size_t keylen; + byte * key = bytes_jbyteArray(e,jbakey,&keylen); + if((*e)->ExceptionOccurred(e)) return 0; + + byte * ret; + int retsize = ThashLookup((int)xid,rid,key,keylen,&ret); + + jbyteArray jbaret; + if(retsize == -1) { + jbaret = 0; + } else { + jbaret = jbyteArray_bytes(e,ret,retsize); + } + if((*e)->ExceptionOccurred(e)) return 0; + ThashRemove((int)xid,rid,key,keylen); + return jbaret; +} + +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_hash_1lookup + (JNIEnv *e, jclass c, jlong xid, jlongArray jbarid, jbyteArray jbakey) { + // printf("in lookup"); + recordid rid = recordid_jlongArray(e, jbarid); + if((*e)->ExceptionOccurred(e)) return 0; + size_t keylen; + byte * key = bytes_jbyteArray(e,jbakey,&keylen); + if((*e)->ExceptionOccurred(e)) return 0; + + + byte * ret; + // printf("calling thashlookup"); + int retsize = ThashLookup((int)xid,rid,key,keylen,&ret); + // printf("returned thashlookup"); + jbyteArray jbaret; + if(retsize == -1) { + jbaret = 0; + } else { + jbaret = jbyteArray_bytes(e,ret,retsize); + } + if((*e)->ExceptionOccurred(e)) return 0; + return jbaret; +} +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_hash_1iterator + (JNIEnv *e, jclass c, jlong xid, jlongArray rid) { + lladdIterator_t * it = ThashGenericIterator(xid, recordid_jlongArray(e,rid)); + return jbyteArray_bytes(e,(byte*)&it,sizeof(it)); +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_iterator_1close + (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { + size_t sz; + lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); + Titerator_close(xid,*it); +} +JNIEXPORT jboolean JNICALL Java_stasis_jni_Stasis_iterator_1next + (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { + size_t sz; + lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); + return (jboolean)Titerator_next((int)xid, *it); +} +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_iterator_1key + (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { + size_t sz; + lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); + + byte * key; + sz = Titerator_key(xid, *it, &key); + + return jbyteArray_bytes(e,key,sz); +} +JNIEXPORT jbyteArray JNICALL Java_stasis_jni_Stasis_iterator_1value + (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { + size_t sz; + lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); + + byte * val; + sz = Titerator_value(xid, *it, &val); + + return jbyteArray_bytes(e,val,sz); +} +JNIEXPORT void JNICALL Java_stasis_jni_Stasis_iterator_1tuple_1done + (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { + size_t sz; + lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); + + Titerator_tupleDone(xid, *it); +} diff --git a/lang/java/org_stasis_Stasis.h b/lang/java/org_stasis_Stasis.h new file mode 100644 index 0000000..58031b5 --- /dev/null +++ b/lang/java/org_stasis_Stasis.h @@ -0,0 +1,173 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_stasis_Stasis */ + +#ifndef _Included_org_stasis_Stasis +#define _Included_org_stasis_Stasis +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_stasis_Stasis + * Method: init + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_stasis_Stasis_init + (JNIEnv *, jclass); + +/* + * Class: org_stasis_Stasis + * Method: deinit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_deinit + (JNIEnv *, jclass); + +/* + * Class: org_stasis_Stasis + * Method: root_record + * Signature: ()[J + */ +JNIEXPORT jlongArray JNICALL Java_org_stasis_Stasis_root_1record + (JNIEnv *, jclass); + +/* + * Class: org_stasis_Stasis + * Method: begin + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_stasis_Stasis_begin + (JNIEnv *, jclass); + +/* + * Class: org_stasis_Stasis + * Method: commit + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_commit + (JNIEnv *, jclass, jlong); + +/* + * Class: org_stasis_Stasis + * Method: abort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_abort + (JNIEnv *, jclass, jlong); + +/* + * Class: org_stasis_Stasis + * Method: prepare + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_prepare + (JNIEnv *, jclass, jlong); + +/* + * Class: org_stasis_Stasis + * Method: record_type + * Signature: (J[J)J + */ +JNIEXPORT jlong JNICALL Java_org_stasis_Stasis_record_1type + (JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_create + * Signature: (J)[J + */ +JNIEXPORT jlongArray JNICALL Java_org_stasis_Stasis_hash_1create + (JNIEnv *, jclass, jlong); + +/* + * Class: org_stasis_Stasis + * Method: hash_delete + * Signature: (J[J)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_hash_1delete + (JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_cardinality + * Signature: (J[J)J + */ +JNIEXPORT jlong JNICALL Java_org_stasis_Stasis_hash_1cardinality + (JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_insert + * Signature: (J[J[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_hash_1insert + (JNIEnv *, jclass, jlong, jlongArray, jbyteArray, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_remove + * Signature: (J[J[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_hash_1remove + (JNIEnv *, jclass, jlong, jlongArray, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_lookup + * Signature: (J[J[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_hash_1lookup + (JNIEnv *, jclass, jlong, jlongArray, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: hash_iterator + * Signature: (J[J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_hash_1iterator + (JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: org_stasis_Stasis + * Method: iterator_close + * Signature: (J[B)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_iterator_1close + (JNIEnv *, jclass, jlong, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: iterator_next + * Signature: (J[B)Z + */ +JNIEXPORT jboolean JNICALL Java_org_stasis_Stasis_iterator_1next + (JNIEnv *, jclass, jlong, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: iterator_key + * Signature: (J[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_iterator_1key + (JNIEnv *, jclass, jlong, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: iterator_value + * Signature: (J[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_stasis_Stasis_iterator_1value + (JNIEnv *, jclass, jlong, jbyteArray); + +/* + * Class: org_stasis_Stasis + * Method: iterator_tuple_done + * Signature: (J[B)V + */ +JNIEXPORT void JNICALL Java_org_stasis_Stasis_iterator_1tuple_1done + (JNIEnv *, jclass, jlong, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif