changeset 580:633614461994

API for retrieving a track's data. A new function, audiodb_retrieve_datum() fills a provided adb_datum_t structure with the data corresponding to a given database key; the companion audiodb_free_datum() function frees the data in a given datum appropriately. Just in case, I continue to require passing in the adb_t * as the first argument to audiodb_free_datum(), even though it's not currently used: I couldn't convince myself that _all_ possible implementations could free a datum without reference to the adb_t. This meant rewriting the internal code to use a new internal audiodb_really_free_datum() function, which audiodb_free_datum() also calls. Sanity-checked by implementing a binding in sb-alien to this function, lightly-tested. All this fixes ticket:20 in Trac.
author mas01cr
date Tue, 14 Jul 2009 15:35:36 +0000
parents 81053b8bdb51
children 361f3bda6694
files Makefile audioDB-internals.h audioDB_API.h bindings/sb-alien/interface.lisp bindings/sb-alien/library.lisp insert.cpp query.cpp
diffstat 7 files changed, 60 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Mon Jul 06 17:13:49 2009 +0000
+++ b/Makefile	Tue Jul 14 15:35:36 2009 +0000
@@ -8,7 +8,7 @@
 
 SHARED_LIB_FLAGS=-shared -Wl,-soname,
 
-LIBOBJS=lock.o pointpair.o create.o open.o power.o l2norm.o insert.o status.o query.o dump.o close.o lshlib.o index-utils.o query-indexed.o liszt.o
+LIBOBJS=lock.o pointpair.o create.o open.o power.o l2norm.o insert.o status.o query.o dump.o close.o lshlib.o index-utils.o query-indexed.o liszt.o retrieve.o
 OBJS=$(LIBOBJS) index.o soap.o sample.o cmdline.o audioDB.o common.o
 
 EXECUTABLE=audioDB
--- a/audioDB-internals.h	Mon Jul 06 17:13:49 2009 +0000
+++ b/audioDB-internals.h	Tue Jul 14 15:35:36 2009 +0000
@@ -298,7 +298,7 @@
 int audiodb_read_data(adb_t *, int, int, double **, size_t *);
 int audiodb_insert_create_datum(adb_insert_t *, adb_datum_t *);
 int audiodb_track_id_datum(adb_t *, uint32_t, adb_datum_t *);
-int audiodb_free_datum(adb_datum_t *);
+int audiodb_really_free_datum(adb_datum_t *);
 int audiodb_datum_qpointers(adb_datum_t *, uint32_t, double **, double **, adb_qpointers_internal_t *);
 int audiodb_query_spec_qpointers(adb_t *, const adb_query_spec_t *, double **, double **, adb_qpointers_internal_t *);
 int audiodb_query_queue_loop(adb_t *, const adb_query_spec_t *, adb_qstate_internal_t *, double *, adb_qpointers_internal_t *);
--- a/audioDB_API.h	Mon Jul 06 17:13:49 2009 +0000
+++ b/audioDB_API.h	Tue Jul 14 15:35:36 2009 +0000
@@ -205,7 +205,11 @@
 /* database status */  
 int audiodb_status(adb_ptr mydb, adb_status_ptr status);
 
-/* varoius dump formats */
+/* retrieval of inserted data */
+int audiodb_retrieve_datum(adb_t *, const char *, adb_datum_t *);
+int audiodb_free_datum(adb_t *, adb_datum_t *);
+
+/* various dump formats */
 int audiodb_dump(adb_ptr mydb, const char *outputdir);
 
 /* liszt */
--- a/bindings/sb-alien/interface.lisp	Mon Jul 06 17:13:49 2009 +0000
+++ b/bindings/sb-alien/interface.lisp	Tue Jul 14 15:35:36 2009 +0000
@@ -99,6 +99,40 @@
             (setf (slot d 'power) nil))
         (sb-int:with-float-traps-masked (:invalid)
           (%insert-datum (slot-value db 'alien) (addr d)))))))
+
+(defgeneric retrieve (key db))
+
+(defmethod retrieve ((key string) (db adb))
+  ;; KLUDGE: this does multiple copies of the floating point data:
+  ;; once within audiodb_retrieve_datum(), and once from the alien to
+  ;; the lisp arrays.  Oh well.
+  (with-alien ((d adb-datum-t))
+    (setf (slot d 'times) nil
+          (slot d 'power) nil)
+    (%retrieve-datum (slot-value db 'alien) key (addr d))
+    (let* ((dim (slot d 'dim))
+           (nvectors (slot d 'nvectors))
+           (data (make-array (list nvectors dim) :element-type 'double-float))
+           (vector (sb-ext:array-storage-vector data))
+           ;; FIXME: this shares KEY
+           (datum (%make-datum :key key :data data)))
+      (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'data)) 0
+                                       (sb-sys:vector-sap vector) 0
+                                       (* dim nvectors))
+      (unless (null-alien (slot d 'times))
+        (let ((times (make-array nvectors :element-type 'double-float)))
+          (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'times)) 0
+                                           (sb-sys:vector-sap times) 0
+                                           nvectors)
+          (setf (datum-times datum) times)))
+      (unless (null-alien (slot d 'power))
+        (let ((power (make-array nvectors :element-type 'double-float)))
+          (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'power)) 0
+                                           (sb-sys:vector-sap power) 0
+                                           nvectors)
+          (setf (datum-power datum) power)))
+      (%free-datum (slot-value db 'alien) (addr d))
+      datum)))
 
 (defstruct result
   (key "" :type string)
--- a/bindings/sb-alien/library.lisp	Mon Jul 06 17:13:49 2009 +0000
+++ b/bindings/sb-alien/library.lisp	Tue Jul 14 15:35:36 2009 +0000
@@ -51,6 +51,17 @@
   (datum (* adb-datum-t)))
 (define-int-checking-function %insert-datum (adb datum) %%insert-datum)
 
+(define-alien-routine ("audiodb_retrieve_datum" %%retrieve-datum) int
+  (adb (* adb-t))
+  (key c-string)
+  (datum (* adb-datum-t)))
+(define-int-checking-function %retrieve-datum (adb key datum) %%retrieve-datum)
+
+(define-alien-routine ("audiodb_free_datum" %%free-datum) int
+  (adb (* adb-t))
+  (datum (* adb-datum-t)))
+(define-int-checking-function %free-datum (adb datum) %%free-datum)
+
 (define-alien-type adb-status-t
   (struct adb-status
     (nfiles (unsigned 32))
--- a/insert.cpp	Mon Jul 06 17:13:49 2009 +0000
+++ b/insert.cpp	Tue Jul 14 15:35:36 2009 +0000
@@ -272,7 +272,7 @@
   }
 }
 
-int audiodb_free_datum(adb_datum_t *datum) {
+int audiodb_really_free_datum(adb_datum_t *datum) {
   if(datum->data) {
     free(datum->data);
     datum->data = NULL;
@@ -398,7 +398,7 @@
   if(file) {
     fclose(file);
   }
-  audiodb_free_datum(datum);
+  audiodb_really_free_datum(datum);
   return 1;
 }
 
@@ -421,7 +421,7 @@
       return 1;
     }
     err = audiodb_insert_datum(adb, &datum);
-    audiodb_free_datum(&datum);
+    audiodb_really_free_datum(&datum);
 
     if(err == 2) {
       return 0;
--- a/query.cpp	Mon Jul 06 17:13:49 2009 +0000
+++ b/query.cpp	Tue Jul 14 15:35:36 2009 +0000
@@ -240,7 +240,7 @@
     return 0;
   }
  error:
-  audiodb_free_datum(d);
+  audiodb_really_free_datum(d);
   return 1;
 }
 
@@ -310,7 +310,7 @@
   /* FIXME: check the overflow logic here */
   if(sequence_start + sequence_length > d.nvectors) {
     if(datum != &d) {
-      audiodb_free_datum(&d);
+      audiodb_really_free_datum(&d);
     }
     return 1;
   }
@@ -333,7 +333,7 @@
   /* Clean up: free any bits of datum that we have ourselves
    * allocated. */
   if(datum != &d) {
-    audiodb_free_datum(&d);
+    audiodb_really_free_datum(&d);
   }
 
   return 0;
@@ -464,10 +464,10 @@
       }
       if(audiodb_datum_qpointers(&d, sequence_length, &dbdata, &dbdata_pointer, &dbpointers)) {
         delete qstate->exact_evaluation_queue;
-        audiodb_free_datum(&d);
+        audiodb_really_free_datum(&d);
         return 1;
       }
-      audiodb_free_datum(&d);
+      audiodb_really_free_datum(&d);
     }
     Uns32T qPos = (spec->qid.flags & ADB_QID_FLAG_EXHAUSTIVE) ? pp.qpos : 0;
     Uns32T sPos = pp.spos; // index into l2norm table