changeset 435:53c487885b2c api-inversion

begin pushing an adb_query_spec_t * all the way through query. Almost all of the query specification data is in there now; missing are the key list refinement and the query datum. Mostly eliminate uses of the audioDB::sequenceLength member variable throughout query.cpp. It's still used in functions in index.cpp, though, so make sure that a correct value is installed before calling audioDB::index_query_loop()
author mas01cr
date Wed, 24 Dec 2008 10:55:56 +0000
parents 7af140bf8a0a
children e43f8a7aca93
files Makefile audioDB.h audioDB_API.h index.cpp query.cpp
diffstat 5 files changed, 117 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Dec 24 10:55:52 2008 +0000
+++ b/Makefile	Wed Dec 24 10:55:56 2008 +0000
@@ -8,7 +8,7 @@
 
 SHARED_LIB_FLAGS=-shared -Wl,-soname,
 
-LIBOBJS=insert.o create.o common.o open.o close.o status.o dump.o power.o l2norm.o liszt.o query.o sample.o index.o lshlib.o cmdline.o
+LIBOBJS=query.o index.o insert.o create.o common.o open.o close.o status.o dump.o power.o l2norm.o liszt.o sample.o lshlib.o cmdline.o
 OBJS=$(LIBOBJS) soap.o audioDB.o
 
 
--- a/audioDB.h	Wed Dec 24 10:55:52 2008 +0000
+++ b/audioDB.h	Wed Dec 24 10:55:56 2008 +0000
@@ -319,13 +319,13 @@
   // private methods
   void error(const char* a, const char* b = "", const char *sysFunc = 0);
 
-  void initialize_arrays(adb_t *adb, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD);
+  void initialize_arrays(adb_t *adb, adb_query_spec_t *spec, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD);
   void insertTimeStamps(unsigned n, std::ifstream* timesFile, double* timesdata);
-  void set_up_query(double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned int *nvp);
-  void set_up_query_from_key(double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp, Uns32T queryIndex);
-  int set_up_db(adb_t *adb, double **snp, double **vsnp, double **spp, double **vspp, double **mddp, unsigned int *dvp);
-  void query_loop(adb_query_parameters_t *params, adb_query_refine_t *refine, Uns32T queryIndex);
-  void query_loop_points(double* query, double* qnPtr, double* qpPtr, double meanQdur, Uns32T numVectors, adb_query_parameters_t *params, adb_query_refine_t *refine);
+  void set_up_query(adb_query_spec_t *spec, double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned int *nvp);
+  void set_up_query_from_key(adb_query_spec_t *spec, double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp, Uns32T queryIndex);
+  int set_up_db(adb_t *adb, adb_query_spec_t *spec, double **snp, double **vsnp, double **spp, double **vspp, double **mddp, unsigned int *dvp);
+  void query_loop(adb_query_spec_t *spec, Uns32T queryIndex);
+  void query_loop_points(adb_query_spec_t *spec, double* query, double* qnPtr, double* qpPtr, double meanQdur, Uns32T numVectors);
   void initRNG();
   void initDBHeader(const char *dbName);
   void initInputFile(const char *inFile, bool loadData = true);
@@ -386,7 +386,7 @@
   Uns32T index_insert_shingles(vector<vector<float> >*, Uns32T trackID, double* spp);
   void index_make_shingle(vector<vector<float> >*, Uns32T idx, double* fvp, Uns32T dim, Uns32T seqLen);
   int index_norm_shingles(vector<vector<float> >*, double* snp, double* spp);
-  int index_query_loop(adb_query_parameters_t *params, adb_query_refine_t *refine, const char* dbName, Uns32T queryIndex);
+  int index_query_loop(adb_query_spec_t *spec, const char* dbName, Uns32T queryIndex);
   vector<vector<float> >* index_initialize_shingles(Uns32T sz);
   int index_init_query(const char* dbName);
   int index_exists(const char* dbName, double radius, Uns32T sequenceLength);
--- a/audioDB_API.h	Wed Dec 24 10:55:52 2008 +0000
+++ b/audioDB_API.h	Wed Dec 24 10:55:56 2008 +0000
@@ -151,8 +151,8 @@
 
 typedef struct adbqueryspec {
   adb_query_id_t qid;
-  adb_query_parameters_t qparms;
-  adb_query_refine_t qrefines;
+  adb_query_parameters_t params;
+  adb_query_refine_t refine;
 } adb_query_spec_t;
 
 /*******************************************************************/
--- a/index.cpp	Wed Dec 24 10:55:52 2008 +0000
+++ b/index.cpp	Wed Dec 24 10:55:56 2008 +0000
@@ -576,7 +576,7 @@
 
 // return 0: if index does not exist
 // return nqv: if index exists
-int audioDB::index_query_loop(adb_query_parameters_t *params, adb_query_refine_t *refine, const char* dbName, Uns32T queryIndex) {
+int audioDB::index_query_loop(adb_query_spec_t *spec, const char* dbName, Uns32T queryIndex) {
   
   unsigned int numVectors = 0;
   double *query = 0, *query_data = 0;
@@ -584,7 +584,7 @@
   double meanQdur = 0;
   void (*add_point_func)(void*,Uns32T,Uns32T,float);
 
-  normalizedDistance = (params->distance == ADB_DISTANCE_EUCLIDEAN_NORMED);
+  normalizedDistance = (spec->params.distance == ADB_DISTANCE_EUCLIDEAN_NORMED);
 
   // Set the point-reporter callback based on the value of lsh_exact
   if(lsh_exact){
@@ -600,9 +600,9 @@
   char* database = index_get_name(dbName, radius, sequenceLength);
 
   if(query_from_key)
-    set_up_query_from_key(&query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors, queryIndex);
+    set_up_query_from_key(spec, &query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors, queryIndex);
   else
-    set_up_query(&query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors); // get query vectors
+    set_up_query(spec, &query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors); // get query vectors
 
   VERB_LOG(1, "retrieving tracks...");
   
@@ -640,7 +640,7 @@
 
   if(lsh_exact)
     // Perform exact distance computation on point pairs in exact_evaluation_queue
-    query_loop_points(query, qnPtr, qpPtr, meanQdur, numVectors, params, refine); 
+    query_loop_points(spec, query, qnPtr, qpPtr, meanQdur, numVectors); 
   
   gettimeofday(&tv2,NULL);
   VERB_LOG(1,"elapsed time: %ld msec\n",
--- a/query.cpp	Wed Dec 24 10:55:52 2008 +0000
+++ b/query.cpp	Wed Dec 24 10:55:56 2008 +0000
@@ -26,61 +26,66 @@
   else
     initTables(dbName, inFile);
 
-  adb_query_refine_t refine;
-  adb_query_parameters_t params;
-  refine.flags = 0;
+  adb_query_spec_t qspec;
+
+  qspec.refine.flags = 0;
   /* FIXME: trackFile / ADB_REFINE_KEYLIST */
   if(radius) {
-    refine.flags |= ADB_REFINE_RADIUS;
-    refine.radius = radius;
+    qspec.refine.flags |= ADB_REFINE_RADIUS;
+    qspec.refine.radius = radius;
   }
   if(use_absolute_threshold) {
-    refine.flags |= ADB_REFINE_ABSOLUTE_THRESHOLD;
-    refine.absolute_threshold = absolute_threshold;
+    qspec.refine.flags |= ADB_REFINE_ABSOLUTE_THRESHOLD;
+    qspec.refine.absolute_threshold = absolute_threshold;
   }
   if(use_relative_threshold) {
-    refine.flags |= ADB_REFINE_RELATIVE_THRESHOLD;
-    refine.relative_threshold = relative_threshold;
+    qspec.refine.flags |= ADB_REFINE_RELATIVE_THRESHOLD;
+    qspec.refine.relative_threshold = relative_threshold;
   }
   if(usingTimes) {
-    refine.flags |= ADB_REFINE_DURATION_RATIO;
-    refine.duration_ratio = timesTol;
+    qspec.refine.flags |= ADB_REFINE_DURATION_RATIO;
+    qspec.refine.duration_ratio = timesTol;
   }
   /* FIXME: not sure about this any more; maybe it belongs in query_id */
   if(sequenceHop != 1) {
-    refine.flags |= ADB_REFINE_HOP_SIZE;
-    refine.hopsize = sequenceHop;
+    qspec.refine.flags |= ADB_REFINE_HOP_SIZE;
+    qspec.refine.hopsize = sequenceHop;
   }
 
+  /* FIXME qspec.qid.datum */
+  qspec.qid.sequence_length = sequenceLength;
+  qspec.qid.flags = usingQueryPoint ? 0 : ADB_QUERY_ID_FLAG_EXHAUSTIVE;
+  qspec.qid.sequence_start = queryPoint;
+
   switch(queryType) {
   case O2_POINT_QUERY:
-    sequenceLength = 1;
-    params.accumulation = ADB_ACCUMULATION_DB;
-    params.distance = ADB_DISTANCE_DOT_PRODUCT;
-    params.npoints = pointNN;
-    params.ntracks = 0;
+    qspec.qid.sequence_length = 1;
+    qspec.params.accumulation = ADB_ACCUMULATION_DB;
+    qspec.params.distance = ADB_DISTANCE_DOT_PRODUCT;
+    qspec.params.npoints = pointNN;
+    qspec.params.ntracks = 0;
     reporter = new pointQueryReporter< std::greater < NNresult > >(pointNN);
     break;
   case O2_TRACK_QUERY:
-    sequenceLength = 1;
-    params.accumulation = ADB_ACCUMULATION_PER_TRACK;
-    params.distance = ADB_DISTANCE_DOT_PRODUCT;
-    params.npoints = pointNN;
-    params.ntracks = trackNN;
+    qspec.qid.sequence_length = 1;
+    qspec.params.accumulation = ADB_ACCUMULATION_PER_TRACK;
+    qspec.params.distance = ADB_DISTANCE_DOT_PRODUCT;
+    qspec.params.npoints = pointNN;
+    qspec.params.ntracks = trackNN;
     reporter = new trackAveragingReporter< std::greater< NNresult > >(pointNN, trackNN, dbH->numFiles);
     break;
   case O2_SEQUENCE_QUERY:
   case O2_N_SEQUENCE_QUERY:
-    params.accumulation = ADB_ACCUMULATION_PER_TRACK;
-    params.distance = no_unit_norming ? ADB_DISTANCE_EUCLIDEAN : ADB_DISTANCE_EUCLIDEAN_NORMED;
-    params.npoints = pointNN;
-    params.ntracks = trackNN;
+    qspec.params.accumulation = ADB_ACCUMULATION_PER_TRACK;
+    qspec.params.distance = no_unit_norming ? ADB_DISTANCE_EUCLIDEAN : ADB_DISTANCE_EUCLIDEAN_NORMED;
+    qspec.params.npoints = pointNN;
+    qspec.params.ntracks = trackNN;
     switch(queryType) {
     case O2_SEQUENCE_QUERY:
-      if(!(refine.flags & ADB_REFINE_RADIUS)) {
+      if(!(qspec.refine.flags & ADB_REFINE_RADIUS)) {
         reporter = new trackAveragingReporter< std::less< NNresult > >(pointNN, trackNN, dbH->numFiles);
-      } else if (index_exists(dbName, radius, sequenceLength)) {
-	char* indexName = index_get_name(dbName, radius, sequenceLength);
+      } else if (index_exists(adb->path, qspec.refine.radius, qspec.qid.sequence_length)) {
+	char* indexName = index_get_name(adb->path, qspec.refine.radius, qspec.qid.sequence_length);
 	lsh = index_allocate(indexName, false);
 	reporter = new trackSequenceQueryRadReporter(trackNN, index_to_trackID(lsh->get_maxp(), lsh_n_point_bits)+1);
 	delete[] indexName;
@@ -89,10 +94,10 @@
       }
       break;
     case O2_N_SEQUENCE_QUERY:
-      if(!(refine.flags & ADB_REFINE_RADIUS)) {
+      if(!(qspec.refine.flags & ADB_REFINE_RADIUS)) {
         reporter = new trackSequenceQueryNNReporter< std::less < NNresult > >(pointNN, trackNN, dbH->numFiles);
-      } else if (index_exists(dbName, radius, sequenceLength)){
-	char* indexName = index_get_name(dbName, radius, sequenceLength);
+      } else if (index_exists(adb->path, qspec.refine.radius, qspec.qid.sequence_length)){
+	char* indexName = index_get_name(adb->path, qspec.refine.radius, qspec.qid.sequence_length);
 	lsh = index_allocate(indexName, false);
 	reporter = new trackSequenceQueryRadNNReporter(pointNN,trackNN, index_to_trackID(lsh->get_maxp(), lsh_n_point_bits)+1);
 	delete[] indexName;
@@ -103,10 +108,10 @@
     }
     break;
   case O2_ONE_TO_ONE_N_SEQUENCE_QUERY:
-    params.accumulation = ADB_ACCUMULATION_ONE_TO_ONE;
-    params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED;
-    params.npoints = 0;
-    params.ntracks = 0;
+    qspec.params.accumulation = ADB_ACCUMULATION_ONE_TO_ONE;
+    qspec.params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED;
+    qspec.params.npoints = 0;
+    qspec.params.ntracks = 0;
     break;
   default:
     error("unrecognized queryType");
@@ -116,14 +121,14 @@
   if(query_from_key && (!key || (query_from_key_index = audiodb_key_index(adb, key)) == (uint32_t) -1)) 
     error("Query key not found", key);  
 
-  switch(params.distance) {
+  switch(qspec.params.distance) {
   case ADB_DISTANCE_DOT_PRODUCT:
-    switch(params.accumulation) {
+    switch(qspec.params.accumulation) {
     case ADB_ACCUMULATION_DB:
-      accumulator = new DBAccumulator<adb_result_dist_gt>(params.npoints);
+      accumulator = new DBAccumulator<adb_result_dist_gt>(qspec.params.npoints);
       break;
     case ADB_ACCUMULATION_PER_TRACK:
-      accumulator = new PerTrackAccumulator<adb_result_dist_gt>(params.npoints, params.ntracks);
+      accumulator = new PerTrackAccumulator<adb_result_dist_gt>(qspec.params.npoints, qspec.params.ntracks);
       break;
     case ADB_ACCUMULATION_ONE_TO_ONE:
       accumulator = new NearestAccumulator<adb_result_dist_gt>();
@@ -134,12 +139,12 @@
     break;
   case ADB_DISTANCE_EUCLIDEAN_NORMED:
   case ADB_DISTANCE_EUCLIDEAN:
-    switch(params.accumulation) {
+    switch(qspec.params.accumulation) {
     case ADB_ACCUMULATION_DB:
-      accumulator = new DBAccumulator<adb_result_dist_lt>(params.npoints);
+      accumulator = new DBAccumulator<adb_result_dist_lt>(qspec.params.npoints);
       break;
     case ADB_ACCUMULATION_PER_TRACK:
-      accumulator = new PerTrackAccumulator<adb_result_dist_lt>(params.npoints, params.ntracks);
+      accumulator = new PerTrackAccumulator<adb_result_dist_lt>(qspec.params.npoints, qspec.params.ntracks);
       break;
     case ADB_ACCUMULATION_ONE_TO_ONE:
       accumulator = new NearestAccumulator<adb_result_dist_lt>();
@@ -153,13 +158,15 @@
   }
   
   // Test for index (again) here
-  if((refine.flags & ADB_REFINE_RADIUS) && index_exists(dbName, radius, sequenceLength)){ 
-    VERB_LOG(1, "Calling indexed query on database %s, radius=%f, sequenceLength=%d\n", dbName, radius, sequenceLength);
-    index_query_loop(&params, &refine, dbName, query_from_key_index);
+  if((qspec.refine.flags & ADB_REFINE_RADIUS) && index_exists(adb->path, qspec.refine.radius, qspec.qid.sequence_length)){ 
+    /* FIXME: remaining use of sequenceLength */
+    sequenceLength = qspec.qid.sequence_length;
+    VERB_LOG(1, "Calling indexed query on database %s, radius=%f, sequenceLength=%d\n", adb->path, qspec.refine.radius, sequenceLength);
+    index_query_loop(&qspec, dbName, query_from_key_index);
   }
   else{
     VERB_LOG(1, "Calling brute-force query on database %s\n", dbName);
-    query_loop(&params, &refine, query_from_key_index);
+    query_loop(&qspec, query_from_key_index);
   }
 
   adb_query_results_t *rs = accumulator->get_points();
@@ -171,12 +178,12 @@
   reporter->report(fileTable, adbQueryResponse);
 }
 
-void audioDB::initialize_arrays(adb_t *adb, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD) {
+void audioDB::initialize_arrays(adb_t *adb, adb_query_spec_t *spec, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD) {
   unsigned int j, k, l, w;
   double *dp, *qp, *sp;
 
   const unsigned HOP_SIZE = sequenceHop;
-  const unsigned wL = sequenceLength;
+  const unsigned wL = spec->qid.sequence_length;
 
   for(j = 0; j < numVectors; j++) {
     // Sum products matrix
@@ -305,14 +312,15 @@
 // are pointers to the query, norm and power vectors; the names
 // starting with "v" are things that will end up pointing to the
 // actual query point's information.  -- CSR, 2007-12-05
-void audioDB::set_up_query(double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp) {
+void audioDB::set_up_query(adb_query_spec_t *spec, double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp) {
   *nvp = (statbuf.st_size - sizeof(int)) / (dbH->dim * sizeof(double));
 
+  uint32_t sequence_length = spec->qid.sequence_length;
   if(!(dbH->flags & O2_FLAG_L2NORM)) {
     error("Database must be L2 normed for sequence query","use -L2NORM");
   }
 
-  if(*nvp < sequenceLength) {
+  if(*nvp < sequence_length) {
     error("Query shorter than requested sequence length", "maybe use -l");
   }
   
@@ -323,8 +331,8 @@
   *qnp = new double[*nvp];
   audiodb_l2norm_buffer(*qp, dbH->dim, *nvp, *qnp);
 
-  audiodb_sequence_sum(*qnp, *nvp, sequenceLength);
-  audiodb_sequence_sqrt(*qnp, *nvp, sequenceLength);
+  audiodb_sequence_sum(*qnp, *nvp, sequence_length);
+  audiodb_sequence_sqrt(*qnp, *nvp, sequence_length);
 
   if (usingPower) {
     *qpp = new double[*nvp];
@@ -339,8 +347,8 @@
       error("short read", powerFileName);
     }
 
-    audiodb_sequence_sum(*qpp, *nvp, sequenceLength);
-    audiodb_sequence_average(*qpp, *nvp, sequenceLength);
+    audiodb_sequence_sum(*qpp, *nvp, sequence_length);
+    audiodb_sequence_average(*qpp, *nvp, sequence_length);
   }
 
   if (usingTimes) {
@@ -367,7 +375,7 @@
   *vqpp = *qpp;
 
   if(usingQueryPoint) {
-    if( !(queryPoint < *nvp && queryPoint < *nvp - sequenceLength + 1) ) {
+    if( !(queryPoint < *nvp && queryPoint < *nvp - sequence_length + 1) ) {
       error("queryPoint >= numVectors-sequenceLength+1 in query");
     } else {
       VERB_LOG(1, "query point: %u\n", queryPoint);
@@ -376,14 +384,15 @@
       if (usingPower) {
         *vqpp = *qpp + queryPoint;
       }
-      *nvp = sequenceLength;
+      *nvp = sequence_length;
     }
   }
 }
 
 // Does the same as set_up_query(...) but from database features instead of from a file
 // Constructs the same outputs as set_up_query
-void audioDB::set_up_query_from_key(double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp, Uns32T queryIndex) {
+void audioDB::set_up_query_from_key(adb_query_spec_t *spec, double **qp, double **vqp, double **qnp, double **vqnp, double **qpp, double **vqpp, double *mqdp, unsigned *nvp, Uns32T queryIndex) {
+  uint32_t sequence_length = spec->qid.sequence_length;
   if(!trackTable)
     error("trackTable not initialized","set_up_query_from_key");
 
@@ -398,7 +407,7 @@
     usingTimes = true;
 
   *nvp = trackTable[queryIndex];  
-  if(*nvp < sequenceLength) {
+  if(*nvp < sequence_length) {
     error("Query shorter than requested sequence length", "maybe use -l");
   }
   
@@ -439,15 +448,15 @@
     // Copy L2 norm partial-sum coefficients
     assert(*qnp = new double[*nvp]);
     memcpy(*qnp, l2normTable+trackIndexOffset, *nvp*sizeof(double));
-    audiodb_sequence_sum(*qnp, *nvp, sequenceLength);
-    audiodb_sequence_sqrt(*qnp, *nvp, sequenceLength);
+    audiodb_sequence_sum(*qnp, *nvp, sequence_length);
+    audiodb_sequence_sqrt(*qnp, *nvp, sequence_length);
     
     if( usingPower ){
       // Copy Power partial-sum coefficients
       assert(*qpp = new double[*nvp]);
       memcpy(*qpp, powerTable+trackIndexOffset, *nvp*sizeof(double));
-      audiodb_sequence_sum(*qpp, *nvp, sequenceLength);
-      audiodb_sequence_average(*qpp, *nvp, sequenceLength);
+      audiodb_sequence_sum(*qpp, *nvp, sequence_length);
+      audiodb_sequence_average(*qpp, *nvp, sequence_length);
     }
     
     if (usingTimes) {
@@ -476,7 +485,7 @@
   *vqpp = *qpp;
 
   if(usingQueryPoint) {
-    if( !(queryPoint < *nvp && queryPoint < *nvp - sequenceLength + 1) ) {
+    if( !(queryPoint < *nvp && queryPoint < *nvp - sequence_length + 1) ) {
       error("queryPoint >= numVectors-sequenceLength+1 in query");
     } else {
       VERB_LOG(1, "query point: %u\n", queryPoint);
@@ -485,7 +494,7 @@
       if (usingPower) {
         *vqpp = *qpp + queryPoint;
       }
-      *nvp = sequenceLength;
+      *nvp = sequence_length;
     }
   }
 }
@@ -494,7 +503,9 @@
 // FIXME: this is not the right name; we're not actually setting up
 // the database, but copying various bits of it out of mmap()ed tables
 // in order to reduce seeks.
-int audioDB::set_up_db(adb_t *adb, double **snp, double **vsnp, double **spp, double **vspp, double **mddp, unsigned int *dvp) {
+int audioDB::set_up_db(adb_t *adb, adb_query_spec_t *spec, double **snp, double **vsnp, double **spp, double **vspp, double **mddp, unsigned int *dvp) {
+  uint32_t sequence_length = spec->qid.sequence_length;
+
   *dvp = adb->header->length / (adb->header->dim * sizeof(double));
   *snp = new double[*dvp];
 
@@ -514,12 +525,12 @@
 
   for(unsigned int i = 0; i < adb->header->numFiles; i++){
     size_t track_length = (*adb->track_lengths)[i];
-    if(track_length >= sequenceLength) {
-      audiodb_sequence_sum(snpp, track_length, sequenceLength);
-      audiodb_sequence_sqrt(snpp, track_length, sequenceLength);
+    if(track_length >= sequence_length) {
+      audiodb_sequence_sum(snpp, track_length, sequence_length);
+      audiodb_sequence_sqrt(snpp, track_length, sequence_length);
       if (usingPower) {
-	audiodb_sequence_sum(sppp, track_length, sequenceLength);
-        audiodb_sequence_average(sppp, track_length, sequenceLength);
+	audiodb_sequence_sum(sppp, track_length, sequence_length);
+        audiodb_sequence_average(sppp, track_length, sequence_length);
       }
     }
     snpp += track_length;
@@ -578,7 +589,7 @@
 // Postconditions:
 // reporter contains the points and distances that meet the reporter constraints 
 
-void audioDB::query_loop_points(double* query, double* qnPtr, double* qpPtr, double meanQdur, Uns32T numVectors, adb_query_parameters_t *params, adb_query_refine_t *refine){ 
+void audioDB::query_loop_points(adb_query_spec_t *spec, double* query, double* qnPtr, double* qpPtr, double meanQdur, Uns32T numVectors){ 
   unsigned int dbVectors;
   double *sNorm = 0, *snPtr, *sPower = 0, *spPtr = 0;
   double *meanDBdur = 0;
@@ -592,7 +603,7 @@
   // FIXME: we more than likely don't need very much of the database
   // so make a new method to build these values per-track or, even better, per-point
   if( !( dbH->flags & O2_FLAG_LARGE_ADB) )
-    if(set_up_db(adb, &sNorm, &snPtr, &sPower, &spPtr, &meanDBdur, &dbVectors)) {
+    if(set_up_db(adb, spec, &sNorm, &snPtr, &sPower, &spPtr, &meanDBdur, &dbVectors)) {
       error("failed to set up db");
     }
 
@@ -647,7 +658,7 @@
     Uns32T qPos = usingQueryPoint?0:pp.qpos;// index for query point
     Uns32T sPos = trackIndexOffset+pp.spos; // index into l2norm table
     // Test power thresholds before computing distance
-    if( ( !usingPower || audiodb_powers_acceptable(refine, qpPtr[qPos], sPower[sPos])) &&
+    if( ( !usingPower || audiodb_powers_acceptable(&spec->refine, qpPtr[qPos], sPower[sPos])) &&
 	( qPos<numVectors-sequenceLength+1 && pp.spos<trackTable[pp.trackID]-sequenceLength+1 ) ){
       // Non-large ADB track data is loaded inside power test for efficiency
       if( !(dbH->flags & O2_FLAG_LARGE_ADB) && (currentTrack!=pp.trackID) ){
@@ -661,7 +672,7 @@
       dist = audiodb_dot_product(query+qPos*dbH->dim, data_buffer+pp.spos*dbH->dim, dbH->dim*sequenceLength);
       double qn = qnPtr[qPos];
       double sn = sNorm[sPos];
-      switch(params->distance) {
+      switch(spec->params.distance) {
       case ADB_DISTANCE_EUCLIDEAN_NORMED:
 	dist = 2 - (2/(qn*sn))*dist;
         break;
@@ -686,7 +697,7 @@
   SAFE_DELETE_ARRAY(meanDBdur);
 }
 
-void audioDB::query_loop(adb_query_parameters_t *params, adb_query_refine_t *refine, Uns32T queryIndex) {
+void audioDB::query_loop(adb_query_spec_t *spec, Uns32T queryIndex) {
   
   unsigned int numVectors;
   double *query, *query_data;
@@ -697,21 +708,22 @@
     error("error: LARGE_ADB requires indexed query");
 
   if(query_from_key)
-    set_up_query_from_key(&query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors, queryIndex);
+    set_up_query_from_key(spec, &query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors, queryIndex);
   else
-    set_up_query(&query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors);
+    set_up_query(spec, &query_data, &query, &qNorm, &qnPtr, &qPower, &qpPtr, &meanQdur, &numVectors);
 
   unsigned int dbVectors;
   double *sNorm, *snPtr, *sPower = 0, *spPtr = 0;
   double *meanDBdur = 0;
 
-  if(set_up_db(adb, &sNorm, &snPtr, &sPower, &spPtr, &meanDBdur, &dbVectors)) {
+  if(set_up_db(adb, spec, &sNorm, &snPtr, &sPower, &spPtr, &meanDBdur, &dbVectors)) {
     error("failed to set up db");
   }
 
   VERB_LOG(1, "matching tracks...");
   
-  unsigned j,k,track,trackOffset=0, HOP_SIZE=sequenceHop, wL=sequenceLength;
+  unsigned j,k,track,trackOffset=0, HOP_SIZE=sequenceHop;
+  unsigned wL = spec->qid.sequence_length;
   double **D = 0;    // Differences query and target 
   double **DD = 0;   // Matched filter distance
 
@@ -763,18 +775,18 @@
 
     if(audiodb_read_data(adb, dbfid, track, &data_buffer, &data_buffer_size))
       error("failed to read data");
-    if(sequenceLength <= trackTable[track]) {  // test for short sequences
+    if(wL <= trackTable[track]) {  // test for short sequences
       
       VERB_LOG(7,"%u.%jd.%u | ", track, (intmax_t) trackIndexOffset, trackTable[track]);
       
-      initialize_arrays(adb, track, numVectors, query, data_buffer, D, DD);
+      initialize_arrays(adb, spec, track, numVectors, query, data_buffer, D, DD);
 
-      if(refine->flags & ADB_REFINE_DURATION_RATIO) {
+      if(spec->refine.flags & ADB_REFINE_DURATION_RATIO) {
         VERB_LOG(3,"meanQdur=%f meanDBdur=%f\n", meanQdur, meanDBdur[track]);
       }
 
-      if((!(refine->flags & ADB_REFINE_DURATION_RATIO)) || fabs(meanDBdur[track]-meanQdur) < meanQdur*refine->duration_ratio) {
-        if(refine->flags & ADB_REFINE_DURATION_RATIO) {
+      if((!(spec->refine.flags & ADB_REFINE_DURATION_RATIO)) || fabs(meanDBdur[track]-meanQdur) < meanQdur*spec->refine.duration_ratio) {
+        if(spec->refine.flags & ADB_REFINE_DURATION_RATIO) {
           VERB_LOG(3,"within duration tolerance.\n");
         }
 
@@ -782,7 +794,7 @@
 	for(j = 0; j <= numVectors - wL; j += HOP_SIZE) {
 	  for(k = 0; k <= trackTable[track] - wL; k += HOP_SIZE) {
             double thisDist = 0;
-            switch(params->distance) {
+            switch(spec->params.distance) {
             case ADB_DISTANCE_EUCLIDEAN_NORMED:
               thisDist = 2-(2/(qnPtr[j]*sNorm[trackIndexOffset+k]))*DD[j][k];
               break;
@@ -794,10 +806,10 @@
               break;
             }
 	    // Power test
-	    if ((!usingPower) || audiodb_powers_acceptable(refine, qpPtr[j], sPower[trackIndexOffset + k])) {
+	    if ((!usingPower) || audiodb_powers_acceptable(&spec->refine, qpPtr[j], sPower[trackIndexOffset + k])) {
               // radius test
-              if((!(refine->flags & ADB_REFINE_RADIUS)) || 
-                 thisDist <= (refine->radius+O2_DISTANCE_TOLERANCE)) {
+              if((!(spec->refine.flags & ADB_REFINE_RADIUS)) || 
+                 thisDist <= (spec->refine.radius+O2_DISTANCE_TOLERANCE)) {
                 adb_result_t r;
                 r.key = fileTable + track * O2_FILETABLE_ENTRY_SIZE;
                 r.dist = thisDist;