Mercurial > hg > audiodb
changeset 458:913a95f06998 api-inversion
Start using the query state structure.
Actually using it means moving it around in the source code a little
bit, thanks to entanglements. It'll all be alright on the night. Now
the accumulator, allowed_keys and exact_evaluation_queue are all part of
the query state, and can therefore be passed around with minimal effort
(and deleted in the appropriate place).
Now a whole bunch of static methods (the callbacks, basically) in
index.cpp can be rewritten as plain old C functions. The callbacks need
both an adb_t and a query state structure to function (the adb_t to get
at things like lsh_n_point_bits and the track->key table; the qstate to
get at the accumulator and allowed_keys list).
Rearrange audioDB::query a little bit, and mark the beginning and the
end of the putative audiodb_query_spec() API function implementation.
author | mas01cr |
---|---|
date | Sun, 28 Dec 2008 18:44:08 +0000 |
parents | 823bca1e10f5 |
children | fcc6f7c4856b |
files | audioDB-internals.h audioDB.cpp audioDB.h common.cpp create.cpp index.cpp query.cpp |
diffstat | 7 files changed, 141 insertions(+), 149 deletions(-) [+] |
line wrap: on
line diff
--- a/audioDB-internals.h Wed Dec 24 10:57:30 2008 +0000 +++ b/audioDB-internals.h Sun Dec 28 18:44:08 2008 +0000 @@ -24,12 +24,7 @@ * using adb->fd, but changing to use pread() might win us * threadsafety eventually. */ -typedef struct adb_qstate_internal { - Accumulator *accumulator; - adb_qpointers_internal_t *qpointers; - adb_qpointers_internal_t *dbpointers; - std::set<std::string> *allowed_keys; -} adb_qstate_internal_t; +// FIXME moved to audioDB.h for now struct adb { char *path; @@ -207,6 +202,24 @@ } } +/************************* LSH point index to audioDB conversion *****************/ +static inline uint32_t audiodb_index_to_track_id(uint32_t lshid, uint32_t n_point_bits) { + return (lshid >> n_point_bits); +} + +static inline uint32_t audiodb_index_to_track_pos(uint32_t lshid, uint32_t n_point_bits) { + return (lshid & ((1 << n_point_bits) - 1)); +} + +static inline uint32_t audiodb_index_from_trackinfo(uint32_t track_id, uint32_t track_pos, uint32_t n_point_bits) { + return ((track_id << n_point_bits) | track_pos); +} + +static inline uint32_t audiodb_lsh_n_point_bits(adb_t *adb) { + uint32_t nbits = adb->header->flags >> 28; + return (nbits ? nbits : O2_DEFAULT_LSH_N_POINT_BITS); +} + int audiodb_read_data(adb_t *, int, int, double **, size_t *); int audiodb_insert_create_datum(adb_insert_t *, adb_datum_t *); int audiodb_free_datum(adb_datum_t *);
--- a/audioDB.cpp Wed Dec 24 10:57:30 2008 +0000 +++ b/audioDB.cpp Sun Dec 28 18:44:08 2008 +0000 @@ -217,10 +217,6 @@ munmap(powerFileNameTable, fileTableLength); if(reporter) delete reporter; - if(accumulator) - delete accumulator; - if(exact_evaluation_queue) - delete exact_evaluation_queue; if(rng) gsl_rng_free(rng); if(vv)
--- a/audioDB.h Wed Dec 24 10:57:30 2008 +0000 +++ b/audioDB.h Sun Dec 28 18:44:08 2008 +0000 @@ -32,6 +32,16 @@ #include "soapH.h" #include "cmdline.h" +// should probably be rewritten +class PointPair{ + public: + Uns32T trackID; + Uns32T qpos; + Uns32T spos; + PointPair(Uns32T a, Uns32T b, Uns32T c); +}; +bool operator<(const PointPair& a, const PointPair& b); + // should be in -internals.h typedef struct adb_qpointers_internal { uint32_t nvectors; @@ -42,6 +52,12 @@ double *mean_duration; } adb_qpointers_internal_t; +typedef struct adb_qstate_internal { + Accumulator *accumulator; + std::set<std::string> *allowed_keys; + std::priority_queue<PointPair> *exact_evaluation_queue; +} adb_qstate_internal_t; + #define MAXSTR 512 // Databse PRIMARY commands @@ -219,16 +235,6 @@ off_t dbSize; } dbTableHeaderT, *dbTableHeaderPtr; -class PointPair{ - public: - Uns32T trackID; - Uns32T qpos; - Uns32T spos; - PointPair(Uns32T a, Uns32T b, Uns32T c); -}; - -bool operator<(const PointPair& a, const PointPair& b); - class audioDB{ private: gengetopt_args_info args_info; @@ -309,8 +315,6 @@ double relative_threshold; ReporterBase* reporter; // track/point reporter - Accumulator *accumulator; - priority_queue<PointPair, std::vector<PointPair>, std::less<PointPair> >* exact_evaluation_queue; // LISZT parameters unsigned lisztOffset; @@ -324,8 +328,8 @@ void error(const char* a, const char* b = "", const char *sysFunc = 0); void insertTimeStamps(unsigned n, std::ifstream* timesFile, double* timesdata); - int query_loop(adb_t *adb, adb_query_spec_t *spec); - void query_loop_points(adb_t *adb, adb_query_spec_t *spec, double* query, adb_qpointers_internal_t *qpointers); + int query_loop(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate); + void query_loop_points(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate, double *query, adb_qpointers_internal_t *qpointers); void initRNG(); void initDBHeader(const char *dbName); void initInputFile(const char *inFile); @@ -371,7 +375,6 @@ Uns32T lsh_param_N; // Number of rows per hash table Uns32T lsh_param_b; // Batch size, in number of tracks, per indexing iteration Uns32T lsh_param_ncols; // Maximum number of collision in a hash-table row - Uns32T lsh_n_point_bits; // How many bits to use to encode point ID within a track // LSH vector<> containers for one in-core copy of a set of feature vectors @@ -384,18 +387,11 @@ int index_insert_track(Uns32T trackID, double** fvpp, double** snpp, double** sppp); Uns32T index_insert_shingles(vector<vector<float> >*, Uns32T trackID, double* spp); int index_norm_shingles(vector<vector<float> >*, double* snp, double* spp); - int index_query_loop(adb_t *adb, adb_query_spec_t *spec); + int index_query_loop(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate); 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); char* index_get_name(const char*dbName, double radius, Uns32T sequenceLength); - static void index_add_point_approximate(void* instance, Uns32T pointID, Uns32T qpos, float dist); // static point reporter callback method - static void index_add_point_exact(void* instance, Uns32T pointID, Uns32T qpos, float dist); // static point reporter callback method - static Uns32T index_to_trackID(Uns32T lshID, Uns32T nPntBits); // Convert lsh point index to audioDB trackID - static Uns32T index_to_trackPos(Uns32T lshID, Uns32T nPntBits); // Convert lsh point index to audioDB trackPos (spos) - static Uns32T index_from_trackInfo(Uns32T trackID, Uns32T pntID, Uns32T nPntBits); // Convert audioDB trackID and trackPos to an lsh point index - void initialize_exact_evalutation_queue(); - void index_insert_exact_evaluation_queue(Uns32T trackID, Uns32T qpos, Uns32T spos); LSH* index_allocate(char* indexName, bool load_hashTables); void insertPowerData(unsigned n, int powerfd, double *powerdata); void init_track_aux_data(Uns32T trackID, double* fvp, double** sNormpp,double** snPtrp, double** sPowerp, double** spPtrp); @@ -474,8 +470,6 @@ use_relative_threshold(false), \ relative_threshold(0.0), \ reporter(0), \ - accumulator(0), \ - exact_evaluation_queue(0), \ lisztOffset(0), \ lisztLength(0), \ apierrortemp(0), \ @@ -490,6 +484,5 @@ lsh_param_N(0), \ lsh_param_b(0), \ lsh_param_ncols(0), \ - lsh_n_point_bits(0), \ vv(0) #endif
--- a/common.cpp Wed Dec 24 10:57:30 2008 +0000 +++ b/common.cpp Sun Dec 28 18:44:08 2008 +0000 @@ -145,11 +145,6 @@ CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength); } } - - // Assign correct number of point bits per track in LSH indexing / retrieval - lsh_n_point_bits = dbH->flags >> 28; - if( !lsh_n_point_bits ) - lsh_n_point_bits = O2_DEFAULT_LSH_N_POINT_BITS; } void audioDB::initInputFile (const char *inFile) {
--- a/create.cpp Wed Dec 24 10:57:30 2008 +0000 +++ b/create.cpp Sun Dec 28 18:44:08 2008 +0000 @@ -70,14 +70,14 @@ databytes = ((off_t) datasize) * 1024 * 1024; auxbytes = databytes / datadim; - /* FIXME: what's going on here? There are two distinct - preprocessor constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS); - a third is presumably some default - (O2_DEFAULT_LSH_N_POINT_BITS), and then there's this magic 28 - bits. Should this really be part of the flags structure at - all? Putting it elsewhere will of course break backwards - compatibility, unless 14 is the only value that's been used - anywhere... */ + /* FIXME: what's going on here? There are two distinct preprocessor + constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS); a third is + presumably some default (O2_DEFAULT_LSH_N_POINT_BITS), and then + there's this magic 28 bits [which needs to be the same as the 28 + in audiodb_lsh_n_point_bits()]. Should this really be part of + the flags structure at all? Putting it elsewhere will of course + break backwards compatibility, unless 14 is the only value that's + been used anywhere... */ // For backward-compatibility, Record the point-encoding parameter for LSH indexing in the adb header // If this value is 0 then it will be set to 14
--- a/index.cpp Wed Dec 24 10:57:30 2008 +0000 +++ b/index.cpp Sun Dec 28 18:44:08 2008 +0000 @@ -14,21 +14,10 @@ #include "audioDB.h" #include "audioDB-internals.h" -/************************* LSH point index to audioDB conversion *****************/ -Uns32T audioDB::index_to_trackID(Uns32T lshID, Uns32T nPntBits){ - assert(nPntBits); - return lshID>>nPntBits; -} - -Uns32T audioDB::index_to_trackPos(Uns32T lshID, Uns32T nPntBits){ - assert(nPntBits); - return lshID&((1<<nPntBits)-1); -} - -Uns32T audioDB::index_from_trackInfo(Uns32T trackID, Uns32T spos, Uns32T nPntBits){ - assert(nPntBits); - return (trackID << nPntBits) | spos; -} +typedef struct adb_qcallback { + adb_t *adb; + adb_qstate_internal_t *qstate; +} adb_qcallback_t; /************************* LSH indexing and query initialization *****************/ @@ -266,7 +255,7 @@ // Get the lsh header info and find how many tracks are inserted already lsh = new LSH(mergeIndexName, false); // lshInCore=false to avoid loading hashTables here assert(lsh); - Uns32T maxs = index_to_trackID(lsh->get_maxp(), lsh_n_point_bits)+1; + Uns32T maxs = audiodb_index_to_track_id(lsh->get_maxp(), audiodb_lsh_n_point_bits(adb))+1; delete lsh; lsh = 0; @@ -483,7 +472,7 @@ cout << "[" << trackID << "]" << fileTable+trackID*O2_FILETABLE_ENTRY_SIZE; for( Uns32T pointID=0 ; pointID < (*vv).size(); pointID+=sequenceHop){ if(!use_absolute_threshold || (use_absolute_threshold && (*spp >= absolute_threshold))) - collisionCount += lsh->insert_point((*vv)[pointID], index_from_trackInfo(trackID, pointID, lsh_n_point_bits)); + collisionCount += lsh->insert_point((*vv)[pointID], audiodb_index_from_trackinfo(trackID, pointID, audiodb_lsh_n_point_bits(adb))); spp+=sequenceHop; } return collisionCount; @@ -519,7 +508,7 @@ VERB_LOG(1,"INDEX: k %d\n", lsh->get_lshHeader()->get_numFuns()); VERB_LOG(1,"INDEX: L (m*(m-1))/2 %d\n", lsh->get_lshHeader()->get_numTables()); VERB_LOG(1,"INDEX: N %d\n", lsh->get_lshHeader()->get_numRows()); - VERB_LOG(1,"INDEX: s %d\n", index_to_trackID(lsh->get_maxp(), lsh_n_point_bits)); + VERB_LOG(1,"INDEX: s %d\n", audiodb_index_to_track_id(lsh->get_maxp(), audiodb_lsh_n_point_bits(adb))); VERB_LOG(1,"INDEX: Opened LSH index file %s\n", indexName); } @@ -536,65 +525,63 @@ return true; } -// *Static* approximate NN point reporter callback method for lshlib -void audioDB::index_add_point_approximate(void* instancePtr, Uns32T pointID, Uns32T qpos, float dist){ - assert(instancePtr); // We need an instance for this callback - audioDB* myself = (audioDB*) instancePtr; // Use explicit cast to recover "this" instance - Uns32T trackID = index_to_trackID(pointID, myself->lsh_n_point_bits); - Uns32T spos = index_to_trackPos(pointID, myself->lsh_n_point_bits); - // Skip identity in query_from_key - if( !myself->query_from_key || (myself->query_from_key && ( trackID != myself->query_from_key_index )) ) { +void audiodb_index_add_point_approximate(void *user_data, Uns32T pointID, Uns32T qpos, float dist) { + adb_qcallback_t *data = (adb_qcallback_t *) user_data; + adb_t *adb = data->adb; + adb_qstate_internal_t *qstate = data->qstate; + uint32_t nbits = audiodb_lsh_n_point_bits(adb); + uint32_t trackID = audiodb_index_to_track_id(pointID, nbits); + uint32_t spos = audiodb_index_to_track_pos(pointID, nbits); + std::set<std::string>::iterator keys_end = qstate->allowed_keys->end(); + if(qstate->allowed_keys->find((*adb->keys)[trackID]) != keys_end) { adb_result_t r; - r.key = myself->fileTable + trackID * O2_FILETABLE_ENTRY_SIZE; + r.key = (*adb->keys)[trackID].c_str(); r.dist = dist; r.qpos = qpos; r.ipos = spos; - myself->accumulator->add_point(&r); + qstate->accumulator->add_point(&r); } } -// *Static* exact NN point reporter callback method for lshlib -// Maintain a queue of points to pass to query_points() for exact evaluation -void audioDB::index_add_point_exact(void* instancePtr, Uns32T pointID, Uns32T qpos, float dist){ - assert(instancePtr); // We need an instance for this callback - audioDB* myself = (audioDB*) instancePtr; // Use explicit cast to recover "this" instance - Uns32T trackID = index_to_trackID(pointID, myself->lsh_n_point_bits); - Uns32T spos = index_to_trackPos(pointID, myself->lsh_n_point_bits); - // Skip identity in query_from_key - if( !myself->query_from_key || (myself->query_from_key && ( trackID != myself->query_from_key_index )) ) - myself->index_insert_exact_evaluation_queue(trackID, qpos, spos); -} - -void audioDB::initialize_exact_evalutation_queue(){ - if(exact_evaluation_queue) - delete exact_evaluation_queue; - exact_evaluation_queue = new priority_queue<PointPair, std::vector<PointPair>, std::less<PointPair> >; -} - -void audioDB::index_insert_exact_evaluation_queue(Uns32T trackID, Uns32T qpos, Uns32T spos){ - PointPair p(trackID, qpos, spos); - exact_evaluation_queue->push(p); +// Maintain a queue of points to pass to query_loop_points() for exact +// evaluation +void audiodb_index_add_point_exact(void *user_data, Uns32T pointID, Uns32T qpos, float dist) { + adb_qcallback_t *data = (adb_qcallback_t *) user_data; + adb_t *adb = data->adb; + adb_qstate_internal_t *qstate = data->qstate; + uint32_t nbits = audiodb_lsh_n_point_bits(adb); + uint32_t trackID = audiodb_index_to_track_id(pointID, nbits); + uint32_t spos = audiodb_index_to_track_pos(pointID, nbits); + std::set<std::string>::iterator keys_end = qstate->allowed_keys->end(); + if(qstate->allowed_keys->find((*adb->keys)[trackID]) != keys_end) { + PointPair p(trackID, qpos, spos); + qstate->exact_evaluation_queue->push(p); + } } // return 0: if index does not exist // return nqv: if index exists -int audioDB::index_query_loop(adb_t *adb, adb_query_spec_t *spec) { +int audioDB::index_query_loop(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate) { double *query = 0, *query_data = 0; adb_qpointers_internal_t qpointers = {0}; + adb_qcallback_t callback_data; + callback_data.adb = adb; + callback_data.qstate = qstate; + void (*add_point_func)(void*,Uns32T,Uns32T,float); sequenceLength = spec->qid.sequence_length; normalizedDistance = (spec->params.distance == ADB_DISTANCE_EUCLIDEAN_NORMED); // Set the point-reporter callback based on the value of lsh_exact - if(lsh_exact){ - initialize_exact_evalutation_queue(); - add_point_func = &index_add_point_exact; + if(lsh_exact) { + qstate->exact_evaluation_queue = new std::priority_queue<PointPair>; + add_point_func = &audiodb_index_add_point_exact; + } else { + add_point_func = &audiodb_index_add_point_approximate; } - else - add_point_func = &index_add_point_approximate; if(!index_init_query(adb->path)) // sets-up LSH index structures for querying return 0; @@ -621,23 +608,23 @@ double* qpp = qpointers.power; // Keep original qpPtr for possible exact evaluation if(usingQueryPoint && numVecsAboveThreshold){ if((lsh->get_lshHeader()->flags&O2_SERIAL_FILEFORMAT2) || lsh_in_core) - lsh->retrieve_point((*vv)[0], queryPoint, add_point_func, (void*)this); + lsh->retrieve_point((*vv)[0], queryPoint, add_point_func, &callback_data); else - lsh->serial_retrieve_point(database, (*vv)[0], queryPoint, add_point_func, (void*)this); + lsh->serial_retrieve_point(database, (*vv)[0], queryPoint, add_point_func, &callback_data); } else if(numVecsAboveThreshold) for( Uns32T pointID = 0 ; pointID < Nq; pointID++ ) if(!use_absolute_threshold || (use_absolute_threshold && (*qpp++ >= absolute_threshold))) { if((lsh->get_lshHeader()->flags&O2_SERIAL_FILEFORMAT2) || lsh_in_core) { - lsh->retrieve_point((*vv)[pointID], pointID, add_point_func, (void*)this); + lsh->retrieve_point((*vv)[pointID], pointID, add_point_func, &callback_data); } else { - lsh->serial_retrieve_point(database, (*vv)[pointID], pointID, add_point_func, (void*)this); + lsh->serial_retrieve_point(database, (*vv)[pointID], pointID, add_point_func, &callback_data); } } if(lsh_exact) // Perform exact distance computation on point pairs in exact_evaluation_queue - query_loop_points(adb, spec, query, &qpointers); + query_loop_points(adb, spec, qstate, query, &qpointers); // Close the index file close(lshfid);
--- a/query.cpp Wed Dec 24 10:57:30 2008 +0000 +++ b/query.cpp Sun Dec 28 18:44:08 2008 +0000 @@ -149,7 +149,7 @@ } 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); + reporter = new trackSequenceQueryRadReporter(trackNN, audiodb_index_to_track_id(lsh->get_maxp(), audiodb_lsh_n_point_bits(adb))+1); delete[] indexName; } else { reporter = new trackSequenceQueryRadReporter(trackNN, dbH->numFiles); @@ -161,7 +161,7 @@ } 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); + reporter = new trackSequenceQueryRadNNReporter(pointNN,trackNN, audiodb_index_to_track_id(lsh->get_maxp(), audiodb_lsh_n_point_bits(adb))+1); delete[] indexName; } else { reporter = new trackSequenceQueryRadNNReporter(pointNN,trackNN, dbH->numFiles); @@ -179,21 +179,37 @@ error("unrecognized queryType"); } - // keyKeyPos requires dbH to be initialized - if(query_from_key && (!key || (query_from_key_index = audiodb_key_index(adb, key)) == (uint32_t) -1)) - error("Query key not found", key); + /* Somewhere around here is where the implementation of + * audiodb_query_spec() starts. */ + + adb_qstate_internal_t qstate; + qstate.allowed_keys = new std::set<std::string>; + if(qspec.refine.flags & ADB_REFINE_INCLUDE_KEYLIST) { + for(unsigned int k = 0; k < qspec.refine.include.nkeys; k++) { + qstate.allowed_keys->insert(qspec.refine.include.keys[k]); + } + } else { + for(unsigned int k = 0; k < adb->header->numFiles; k++) { + qstate.allowed_keys->insert((*adb->keys)[k]); + } + } + if(qspec.refine.flags & ADB_REFINE_EXCLUDE_KEYLIST) { + for(unsigned int k = 0; k < qspec.refine.exclude.nkeys; k++) { + qstate.allowed_keys->erase(qspec.refine.exclude.keys[k]); + } + } switch(qspec.params.distance) { case ADB_DISTANCE_DOT_PRODUCT: switch(qspec.params.accumulation) { case ADB_ACCUMULATION_DB: - accumulator = new DBAccumulator<adb_result_dist_gt>(qspec.params.npoints); + qstate.accumulator = new DBAccumulator<adb_result_dist_gt>(qspec.params.npoints); break; case ADB_ACCUMULATION_PER_TRACK: - accumulator = new PerTrackAccumulator<adb_result_dist_gt>(qspec.params.npoints, qspec.params.ntracks); + qstate.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>(); + qstate.accumulator = new NearestAccumulator<adb_result_dist_gt>(); break; default: error("unknown accumulation"); @@ -203,13 +219,13 @@ case ADB_DISTANCE_EUCLIDEAN: switch(qspec.params.accumulation) { case ADB_ACCUMULATION_DB: - accumulator = new DBAccumulator<adb_result_dist_lt>(qspec.params.npoints); + qstate.accumulator = new DBAccumulator<adb_result_dist_lt>(qspec.params.npoints); break; case ADB_ACCUMULATION_PER_TRACK: - accumulator = new PerTrackAccumulator<adb_result_dist_lt>(qspec.params.npoints, qspec.params.ntracks); + qstate.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>(); + qstate.accumulator = new NearestAccumulator<adb_result_dist_lt>(); break; default: error("unknown accumulation"); @@ -222,16 +238,22 @@ // Test for index (again) here if((qspec.refine.flags & ADB_REFINE_RADIUS) && index_exists(adb->path, qspec.refine.radius, qspec.qid.sequence_length)){ VERB_LOG(1, "Calling indexed query on database %s, radius=%f, sequence_length=%d\n", adb->path, qspec.refine.radius, qspec.qid.sequence_length); - index_query_loop(adb, &qspec); + index_query_loop(adb, &qspec, &qstate); } else{ VERB_LOG(1, "Calling brute-force query on database %s\n", dbName); - if(query_loop(adb, &qspec)) { + if(query_loop(adb, &qspec, &qstate)) { error("query_loop failed"); } } - adb_query_results_t *rs = accumulator->get_points(); + adb_query_results_t *rs = qstate.accumulator->get_points(); + + delete qstate.accumulator; + delete qstate.allowed_keys; + + /* End of audiodb_query_spec() function */ + for(unsigned int k = 0; k < rs->nresults; k++) { adb_result_t r = rs->results[k]; reporter->add_point(audiodb_key_index(adb, r.key), r.qpos, r.ipos, r.dist); @@ -606,13 +628,13 @@ // Postconditions: // reporter contains the points and distances that meet the reporter constraints -void audioDB::query_loop_points(adb_t *adb, adb_query_spec_t *spec, double* query, adb_qpointers_internal_t *qpointers) { +void audioDB::query_loop_points(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate, double *query, adb_qpointers_internal_t *qpointers) { adb_qpointers_internal_t dbpointers = {0}; uint32_t sequence_length = spec->qid.sequence_length; bool power_refine = spec->refine.flags & (ADB_REFINE_ABSOLUTE_THRESHOLD|ADB_REFINE_RELATIVE_THRESHOLD); - if(exact_evaluation_queue->size() == 0) { + if(qstate->exact_evaluation_queue->size() == 0) { return; } @@ -638,9 +660,9 @@ Uns32T trackOffset = 0; Uns32T trackIndexOffset = 0; Uns32T currentTrack = 0x80000000; // Initialize with a value outside of track index range - Uns32T npairs = exact_evaluation_queue->size(); + Uns32T npairs = qstate->exact_evaluation_queue->size(); while(npairs--){ - PointPair pp = exact_evaluation_queue->top(); + PointPair pp = qstate->exact_evaluation_queue->top(); // Large ADB track data must be loaded here for sPower if(adb->header->flags & O2_FLAG_LARGE_ADB) { trackOffset=0; @@ -703,40 +725,25 @@ r.dist = dist; r.qpos = pp.qpos; r.ipos = pp.spos; - accumulator->add_point(&r); + qstate->accumulator->add_point(&r); } } - exact_evaluation_queue->pop(); + qstate->exact_evaluation_queue->pop(); } // Cleanup SAFE_DELETE_ARRAY(dbpointers.l2norm_data); SAFE_DELETE_ARRAY(dbpointers.power_data); SAFE_DELETE_ARRAY(dbpointers.mean_duration); + delete qstate->exact_evaluation_queue; } -int audioDB::query_loop(adb_t *adb, adb_query_spec_t *spec) { +int audioDB::query_loop(adb_t *adb, adb_query_spec_t *spec, adb_qstate_internal_t *qstate) { double *query, *query_data; adb_qpointers_internal_t qpointers = {0}, dbpointers = {0}; bool power_refine = spec->refine.flags & (ADB_REFINE_ABSOLUTE_THRESHOLD|ADB_REFINE_RELATIVE_THRESHOLD); - std::set<std::string> keys; - if(spec->refine.flags & ADB_REFINE_INCLUDE_KEYLIST) { - for(unsigned int k = 0; k < spec->refine.include.nkeys; k++) { - keys.insert(spec->refine.include.keys[k]); - } - } else { - for(unsigned int k = 0; k < adb->header->numFiles; k++) { - keys.insert((*adb->keys)[k]); - } - } - if(spec->refine.flags & ADB_REFINE_EXCLUDE_KEYLIST) { - for(unsigned int k = 0; k < spec->refine.exclude.nkeys; k++) { - keys.erase(spec->refine.exclude.keys[k]); - } - } - if(adb->header->flags & O2_FLAG_LARGE_ADB) { /* FIXME: actually it would be nice to support this mode of * operation, but for now... */ @@ -766,10 +773,11 @@ double *data_buffer = 0; lseek(adb->fd, adb->header->dataOffset, SEEK_SET); + std::set<std::string>::iterator keys_end = qstate->allowed_keys->end(); for(track = 0; track < adb->header->numFiles; track++) { unsigned t = track; - - while (keys.find((*adb->keys)[track]) == keys.end()) { + + while (qstate->allowed_keys->find((*adb->keys)[track]) == keys_end) { track++; if(track == adb->header->numFiles) { goto loop_finish; @@ -822,7 +830,7 @@ r.qpos = spec->qid.sequence_start; } r.ipos = k; - accumulator->add_point(&r); + qstate->accumulator->add_point(&r); } } }