# HG changeset patch # User mas01mj # Date 1279722427 0 # Node ID 7e1fa27b67eeab2beddaefc1148ef215f83f66fe # Parent 11fd16e1d8b35b3325b3a0009fc826853f3c0a28 * Full status support * Insert support (not fully tested) * Unit tests for create + initial insert diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/build.xml --- a/bindings/java/build.xml Wed Jul 14 17:21:24 2010 +0000 +++ b/bindings/java/build.xml Wed Jul 21 14:27:07 2010 +0000 @@ -6,7 +6,18 @@ + + + + + + + + + + + @@ -14,7 +25,7 @@ - + @@ -32,6 +43,7 @@ + @@ -43,5 +55,28 @@ + + + + + + + + + + + + + + + + + + + + + + + diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/ext/libAudioDB_JNI.c --- a/bindings/java/ext/libAudioDB_JNI.c Wed Jul 14 17:21:24 2010 +0000 +++ b/bindings/java/ext/libAudioDB_JNI.c Wed Jul 21 14:27:07 2010 +0000 @@ -1,8 +1,34 @@ +#include #include "org_omras2_AudioDB.h" #include "org_omras2_AudioDB_Mode.h" #include #include "audioDB_API.h" #include +#include + +// Following Ben's lead here! +#define ADB_HEADER_FLAG_L2NORM 0x1 +#define ADB_HEADER_FLAG_POWER 0x4 +#define ADB_HEADER_FLAG_TIMES 0x20 +#define ADB_HEADER_FLAG_REFERENCES 0x40 + + +adb_t* get_handle(JNIEnv *env, jobject obj) +{ + // Fetch the adb pointer + + adb_t *handle; + + jclass adbClass = (*env)->GetObjectClass(env, obj); + jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J"); + if(fid == NULL) { + return; + } + + handle = (adb_t*)((*env)->GetLongField(env, obj, fid)); + (*env)->DeleteLocalRef(env, adbClass); + return handle; +} JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1create (JNIEnv *env, jobject obj, jstring path, jint datasize, jint ntracks, jint datadim) { @@ -17,6 +43,37 @@ if(!handle) return JNI_FALSE; + (*env)->ReleaseStringUTFChars(env, path, str); + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1open (JNIEnv *env, jobject obj, jstring path, jobject mode) +{ + // TODO: If we have a handle, close the old one. + if(get_handle(env, obj)) + { + return; + } + + jclass modeClass = (*env)->FindClass(env, "org/omras2/AudioDB$Mode"); + jmethodID getNameMethod = (*env)->GetMethodID(env, modeClass, "name", "()Ljava/lang/String;"); + jstring value = (jstring)(*env)->CallObjectMethod(env, mode, getNameMethod); + const char* openMode = (*env)->GetStringUTFChars(env, value, 0); + const char* pathVal = (*env)->GetStringUTFChars(env, path, 0); + int modeVal = 0; + if(strcmp(openMode, "O_RDWR") == 0) + { + modeVal = O_RDWR; + } + else if(strcmp(openMode, "O_RDONLY") == 0) + { + modeVal = O_RDONLY; + } + else + return; + + adb_t *handle; + handle = audiodb_open(pathVal, modeVal); jclass adbClass = (*env)->GetObjectClass(env, obj); jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J"); if(fid == NULL) { @@ -24,22 +81,56 @@ } (*env)->SetLongField(env, obj, fid, (long)handle); (*env)->DeleteLocalRef(env, adbClass); - (*env)->ReleaseStringUTFChars(env, path, str); - return JNI_TRUE; -} - -JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1open (JNIEnv *env, jobject obj, jstring path, jobject mode) -{ - jclass modeClass = (*env)->FindClass(env, "org/omras2/AudioDB$Mode"); - jmethodID getNameMethod = (*env)->GetMethodID(env, modeClass, "name", "()Ljava/lang/String;"); - jstring value = (jstring)(*env)->CallObjectMethod(env, mode, getNameMethod); - const char* openMode = (*env)->GetStringUTFChars(env, value, 0); return JNI_TRUE; } -JNIEXPORT void JNICALL Java_org_omras2_AudioDB_insert(JNIEnv *env, jobject obj) +JNIEXPORT void JNICALL Java_org_omras2_AudioDB_audiodb_1close (JNIEnv *env, jobject obj) { + adb_t *handle = get_handle(env, obj); + if(!handle) + return; + + audiodb_close(handle); + + jclass adbClass = (*env)->GetObjectClass(env, obj); + jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J"); + + if(fid == NULL) { + return; + } + + (*env)->SetLongField(env, obj, fid, 0); + (*env)->DeleteLocalRef(env, adbClass); +} + +JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1insert_1path(JNIEnv *env, jobject obj, jstring key, jstring features, jstring power, jstring times) +{ + adb_t *handle = get_handle(env, obj); + if(!handle) + return JNI_FALSE; + + adb_insert_t* ins = (adb_insert_t *)malloc(sizeof(adb_insert_t)); + ins->key = NULL; + ins->features = NULL; + ins->power = NULL; + ins->times = NULL; + + if(key) + ins->key = (*env)->GetStringUTFChars(env, key, 0); + if(features) + ins->features = (*env)->GetStringUTFChars(env, features, 0); + if(power) + ins->power = (*env)->GetStringUTFChars(env, power, 0); + if(times) + ins->times = (*env)->GetStringUTFChars(env, times, 0); + + int result = audiodb_insert(handle, ins); + + if(result) + return JNI_FALSE; + + return JNI_TRUE; } JNIEXPORT void JNICALL Java_org_omras2_AudioDB_query(JNIEnv *env, jobject obj) @@ -48,20 +139,9 @@ JNIEXPORT jobject JNICALL Java_org_omras2_AudioDB_audiodb_1status(JNIEnv *env, jobject obj) { - - // Fetch the adb pointer - - adb_t *handle; - - jclass adbClass = (*env)->GetObjectClass(env, obj); - jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J"); - if(fid == NULL) { - return; - } - - handle = (adb_t*)((*env)->GetLongField(env, obj, fid)); - (*env)->DeleteLocalRef(env, adbClass); - + adb_t *handle = get_handle(env, obj); + if(!handle) + return NULL; adb_status_t *status; status = (adb_status_t *)malloc(sizeof(adb_status_t)); int flags = audiodb_status(handle, status); @@ -77,11 +157,48 @@ jobject result = (*env)->NewObject(env, statusClass, cid); - fid = (*env)->GetFieldID(env, statusClass, "numFiles", "I"); - if(fid == NULL) { - return; - } + // This needs a macro! + jfieldID fid = (*env)->GetFieldID(env, statusClass, "numFiles", "I"); + if(fid == NULL) return; (*env)->SetIntField(env, result, fid, status->numFiles); + + fid = (*env)->GetFieldID(env, statusClass, "dim", "I"); + if(fid == NULL) return; + (*env)->SetIntField(env, result, fid, status->dim); + + fid = (*env)->GetFieldID(env, statusClass, "dudCount", "I"); + if(fid == NULL) return; + (*env)->SetIntField(env, result, fid, status->dudCount); + + fid = (*env)->GetFieldID(env, statusClass, "nullCount", "I"); + if(fid == NULL) return; + (*env)->SetIntField(env, result, fid, status->nullCount); + + fid = (*env)->GetFieldID(env, statusClass, "length", "I"); + if(fid == NULL) return; + (*env)->SetIntField(env, result, fid, status->length); + + fid = (*env)->GetFieldID(env, statusClass, "dataRegionSize", "I"); + if(fid == NULL) return; + (*env)->SetIntField(env, result, fid, status->data_region_size); + + // Flags + + fid = (*env)->GetFieldID(env, statusClass, "isL2Normed", "Z"); + if(fid == NULL) return; + (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_L2NORM)); + + fid = (*env)->GetFieldID(env, statusClass, "hasPower", "Z"); + if(fid == NULL) return; + (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_POWER)); + + fid = (*env)->GetFieldID(env, statusClass, "hasTimes", "Z"); + if(fid == NULL) return; + (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_TIMES)); + + fid = (*env)->GetFieldID(env, statusClass, "hasReferences", "Z"); + if(fid == NULL) return; + (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_REFERENCES)); (*env)->DeleteLocalRef(env, statusClass); diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/lib/junit.jar Binary file bindings/java/lib/junit.jar has changed diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/src/org/omras2/AudioDB.java --- a/bindings/java/src/org/omras2/AudioDB.java Wed Jul 14 17:21:24 2010 +0000 +++ b/bindings/java/src/org/omras2/AudioDB.java Wed Jul 21 14:27:07 2010 +0000 @@ -6,12 +6,12 @@ { public native boolean audiodb_create(String path, int datasize, int ntracks, int datadim); public native boolean audiodb_open(String path, Mode mode); + public native void audiodb_close(); public native Status audiodb_status(); - -// public native void insert(); + public native boolean audiodb_insert_path(String key, String features, String power, String times); // public native void query(); - public enum Mode { O_RDONLY, O_RDRW } + public enum Mode { O_RDONLY, O_RDWR } private File path; private long adbHandle; @@ -21,6 +21,27 @@ this.path = path; } + public void close() + { + audiodb_close(); + } + + public boolean insert(File features) + { + return audiodb_insert_path(null, features.getPath(), null, null); + } + + public boolean insert(String key, File features) + { + return audiodb_insert_path(key, features.getPath(), null, null); + } + + public boolean insert(String key, File features, File power, File times) + { + return audiodb_insert_path(key, features.getPath(), (power == null ? null : power.getPath()), (times == null ? null : times.getPath())); + } + + public boolean create(int datasize, int ntracks, int datadim) { return audiodb_create(path.toString(), datasize, ntracks, datadim); @@ -45,9 +66,11 @@ { AudioDB testDB = new AudioDB(new File("test.adb")); testDB.create(5, 5, 12); -// testDB.open(Mode.O_RDRW); + testDB.open(Mode.O_RDWR); + testDB.insert(new File("testfiles/testfeature")); Status status = testDB.getStatus(); System.out.println("Num files: "+status.getNumFiles()); + testDB.close(); } } diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/src/org/omras2/Status.java --- a/bindings/java/src/org/omras2/Status.java Wed Jul 14 17:21:24 2010 +0000 +++ b/bindings/java/src/org/omras2/Status.java Wed Jul 21 14:27:07 2010 +0000 @@ -4,14 +4,14 @@ public class Status { - @Getter @Setter private int numFiles; - @Getter @Setter private int dims; - @Getter @Setter private int dudCount; - @Getter @Setter private int nullCount; - @Getter @Setter private int length; - @Getter @Setter private int dataRegionSize; - @Getter @Setter private boolean isL2Normed; - @Getter @Setter private boolean hasPower; - @Getter @Setter private boolean hasTimes; - @Getter @Setter private boolean hasRefs; + @Getter private int numFiles; + @Getter private int dim; + @Getter private int dudCount; + @Getter private int nullCount; + @Getter private int length; + @Getter private int dataRegionSize; + @Getter private boolean isL2Normed; + @Getter private boolean hasPower; + @Getter private boolean hasTimes; + @Getter private boolean hasReferences; } diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/test/TestCreate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bindings/java/test/TestCreate.java Wed Jul 21 14:27:07 2010 +0000 @@ -0,0 +1,35 @@ +import junit.framework.*; +import java.io.File; +import org.omras2.*; + +public class TestCreate extends TestCase +{ + File testDBFile; + + protected void setUp() + { + testDBFile = new File("testfiles/test.adb"); + if(testDBFile.exists()) + testDBFile.delete(); + } + + public void testCreateNew() + { + AudioDB testDB = new AudioDB(testDBFile); + assertTrue("DB created", testDB.create(5, 5, 12)); + assertTrue("Test DB created on FS", testDBFile.exists()); + assertTrue("Test DB has length > 0", testDBFile.length() > 0); + } + + public void testReplaceExisting() + { + AudioDB testDB = new AudioDB(testDBFile); + assertTrue("DB created", testDB.create(5, 5, 12)); + + // Try to create again + testDB = new AudioDB(testDBFile); + assertFalse("DB not created", testDB.create(5, 5, 12)); + assertTrue("Test DB still exists on FS", testDBFile.exists()); + assertTrue("Test DB still has length > 0", testDBFile.length() > 0); + } +} diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/test/TestInsert.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bindings/java/test/TestInsert.java Wed Jul 21 14:27:07 2010 +0000 @@ -0,0 +1,39 @@ +import junit.framework.*; +import java.io.File; +import org.omras2.*; + +public class TestInsert extends TestCase +{ + File testDBFile; + File testFeatureFile; + protected void setUp() + { + testDBFile = new File("testfiles/test.adb"); + testFeatureFile = new File("testfiles/testfeature"); + if(testDBFile.exists()) + testDBFile.delete(); + } + + public void testInsertFile() + { + AudioDB testDB = new AudioDB(testDBFile); + assertTrue("DB created", testDB.create(1, 1, 1)); + testDB.open(AudioDB.Mode.O_RDWR); + assertTrue("Insert feature file", testDB.insert(testFeatureFile)); + Status status = testDB.getStatus(); + assertEquals("One feature in db", 1, status.getNumFiles()); + assertEquals("1D Feature", 1, status.getDim()); + System.out.println(status.hasReferences()); + System.out.println(status.isL2Normed()); + System.out.println(status.hasPower()); + System.out.println(status.hasTimes()); + } + + public void testInsertFileReadOnly() + { + AudioDB testDB = new AudioDB(testDBFile); + assertTrue("DB created", testDB.create(1, 1, 1)); + testDB.open(AudioDB.Mode.O_RDONLY); + assertFalse("Insert feature file", testDB.insert(testFeatureFile)); + } +} diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/test/TestQuery.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bindings/java/test/TestQuery.java Wed Jul 21 14:27:07 2010 +0000 @@ -0,0 +1,32 @@ +import junit.framework.*; +import java.io.File; +import org.omras2.*; + +public class TestQuery extends TestCase +{ + File testDBFile; + File testFeatureFile; + protected void setUp() + { + testDBFile = new File("testfiles/test.adb"); + testFeatureFile = new File("testfiles/testfeature"); + if(testDBFile.exists()) + testDBFile.delete(); + } + + public void testQuery() + { + // Insert the same feature twice + AudioDB testDB = new AudioDB(testDBFile); + assertTrue("DB created", testDB.create(1, 2, 1)); + testDB.open(AudioDB.Mode.O_RDWR); + assertTrue("Insert feature file", testDB.insert("feat1", testFeatureFile)); + assertTrue("Insert feature file again", testDB.insert("feat2", testFeatureFile)); + testDB.close(); + + testDB.open(AudioDB.Mode.O_RDONLY); + Status status = testDB.getStatus(); + assertEquals("Two features", 2, status.getNumFiles()); + } + +} diff -r 11fd16e1d8b3 -r 7e1fa27b67ee bindings/java/testfiles/testfeature Binary file bindings/java/testfiles/testfeature has changed