Mercurial > hg > audiodb
view reporter.h @ 770:c54bc2ffbf92 tip
update tags
author | convert-repo |
---|---|
date | Fri, 16 Dec 2011 11:34:01 +0000 |
parents | 23c47e118bc6 |
children |
line wrap: on
line source
#ifndef __REPORTER_H #define __REPORTER_H #include <utility> #include <queue> #include <set> #include <functional> #include <iostream> #include "ReporterBase.h" #include "audioDB.h" typedef struct nnresult { unsigned int trackID; double dist; unsigned int qpos; unsigned int spos; } NNresult; typedef struct radresult { unsigned int trackID; unsigned int count; } Radresult; bool operator< (const NNresult &a, const NNresult &b) { return a.dist < b.dist; } bool operator> (const NNresult &a, const NNresult &b) { return a.dist > b.dist; } bool operator< (const Radresult &a, const Radresult &b) { return a.count < b.count; } bool operator> (const Radresult &a, const Radresult &b) { return a.count > b.count; } class Reporter : public ReporterBase { public: virtual ~Reporter() {}; virtual void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) = 0; // FIXME: this interface is a bit wacky: a relic of previous, more // confused times. Really it might make sense to have separate // reporter classes for WS and for stdout, rather than passing this // adbQueryResponse thing everywhere; the adb argument is there // solely for converting trackIDs into names. -- CSR, 2007-12-10. virtual void report(adb_t *adb, struct soap *soap, void* adbQueryResponse) = 0; }; template <class T> class pointQueryReporter : public Reporter { public: pointQueryReporter(unsigned int pointNN); ~pointQueryReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(adb_t *adb, struct soap *soap, void* adbQueryResponse); private: unsigned int pointNN; std::priority_queue< NNresult, std::vector< NNresult >, T> *queue; }; template <class T> pointQueryReporter<T>::pointQueryReporter(unsigned int pointNN) : pointNN(pointNN) { queue = new std::priority_queue< NNresult, std::vector< NNresult >, T>; } template <class T> pointQueryReporter<T>::~pointQueryReporter() { delete queue; } template <class T> void pointQueryReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { if (!isnan(dist)) { NNresult r; r.trackID = trackID; r.qpos = qpos; r.spos = spos; r.dist = dist; queue->push(r); if(queue->size() > pointNN) { queue->pop(); } } } template <class T> void pointQueryReporter<T>::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { NNresult r; std::vector<NNresult> v; unsigned int size = queue->size(); for(unsigned int k = 0; k < size; k++) { r = queue->top(); v.push_back(r); queue->pop(); } std::vector<NNresult>::reverse_iterator rit; if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; if(adb) std::cout << audiodb_index_key(adb, r.trackID) << " "; else std::cout << r.trackID << " "; std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; } } else { adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse; response->result.__sizeRlist=size; response->result.__sizeDist=size; response->result.__sizeQpos=size; response->result.__sizeSpos=size; response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *)); response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double)); response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); unsigned int k = 0; for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { r = *rit; response->result.Rlist[k] = (char *) soap_malloc(soap, O2_MAXFILESTR); response->result.Dist[k] = r.dist; response->result.Qpos[k] = r.qpos; response->result.Spos[k] = r.spos; if(adb) snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID)); else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID); } } } template <class T> class trackAveragingReporter : public Reporter { public: trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); ~trackAveragingReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(adb_t *adb, struct soap *soap, void *adbQueryResponse); protected: unsigned int pointNN; unsigned int trackNN; unsigned int numFiles; std::priority_queue< NNresult, std::vector< NNresult>, T > *queues; }; template <class T> trackAveragingReporter<T>::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles) : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles]; } template <class T> trackAveragingReporter<T>::~trackAveragingReporter() { delete [] queues; } template <class T> void trackAveragingReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { if (!isnan(dist)) { NNresult r; r.trackID = trackID; r.qpos = qpos; r.spos = spos; r.dist = dist; queues[trackID].push(r); if(queues[trackID].size() > pointNN) { queues[trackID].pop(); } } } template <class T> void trackAveragingReporter<T>::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { std::priority_queue < NNresult, std::vector< NNresult>, T> result; for (int i = numFiles-1; i >= 0; i--) { unsigned int size = queues[i].size(); if (size > 0) { NNresult r; double dist = 0; NNresult oldr = queues[i].top(); for (unsigned int j = 0; j < size; j++) { r = queues[i].top(); dist += r.dist; queues[i].pop(); if (r.dist == oldr.dist) { r.qpos = oldr.qpos; r.spos = oldr.spos; } else { oldr = r; } } dist /= size; r.dist = dist; // trackID, qpos and spos are magically right already. result.push(r); if (result.size() > trackNN) { result.pop(); } } } NNresult r; std::vector<NNresult> v; unsigned int size = result.size(); for(unsigned int k = 0; k < size; k++) { r = result.top(); v.push_back(r); result.pop(); } std::vector<NNresult>::reverse_iterator rit; if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; if(adb) std::cout << audiodb_index_key(adb, r.trackID) << " "; else std::cout << r.trackID << " "; std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; } } else { adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse; response->result.__sizeRlist=size; response->result.__sizeDist=size; response->result.__sizeQpos=size; response->result.__sizeSpos=size; response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *)); response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double)); response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); unsigned int k = 0; for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { r = *rit; response->result.Rlist[k] = (char *) soap_malloc(soap, O2_MAXFILESTR); response->result.Dist[k] = r.dist; response->result.Qpos[k] = r.qpos; response->result.Spos[k] = r.spos; if(adb) snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID)); else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID); } } } // Another type of trackAveragingReporter that reports all pointNN nearest neighbours template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> { protected: using trackAveragingReporter<T>::numFiles; using trackAveragingReporter<T>::queues; using trackAveragingReporter<T>::trackNN; using trackAveragingReporter<T>::pointNN; public: trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); void report(adb_t *adb, struct soap *soap, void *adbQueryResponse); }; template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles) :trackAveragingReporter<T>(pointNN, trackNN, numFiles){} template <class T> void trackSequenceQueryNNReporter<T>::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { std::priority_queue < NNresult, std::vector< NNresult>, T> result; std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles]; for (int i = numFiles-1; i >= 0; i--) { unsigned int size = queues[i].size(); if (size > 0) { NNresult r; double dist = 0; NNresult oldr = queues[i].top(); for (unsigned int j = 0; j < size; j++) { r = queues[i].top(); dist += r.dist; point_queues[i].push(r); queues[i].pop(); if (r.dist == oldr.dist) { r.qpos = oldr.qpos; r.spos = oldr.spos; } else { oldr = r; } } dist /= size; r.dist = dist; // trackID, qpos and spos are magically right already. result.push(r); if (result.size() > trackNN) { result.pop(); } } } NNresult r; std::vector<NNresult> v; unsigned int size = result.size(); for(unsigned int k = 0; k < size; k++) { r = result.top(); v.push_back(r); result.pop(); } std::vector<NNresult>::reverse_iterator rit; std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue; NNresult rk; if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; if(adb) std::cout << audiodb_index_key(adb, r.trackID) << " "; else std::cout << r.trackID << " "; std::cout << r.dist << std::endl; unsigned int qsize = point_queues[r.trackID].size(); // Reverse the order of the points stored in point_queues for(unsigned int k=0; k < qsize; k++){ point_queue.push( point_queues[r.trackID].top() ); point_queues[r.trackID].pop(); } for(unsigned int k = 0; k < qsize; k++) { rk = point_queue.top(); std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl; point_queue.pop(); } } } else { adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse; response->result.__sizeRlist=size*pointNN; response->result.__sizeDist=size*pointNN; response->result.__sizeQpos=size*pointNN; response->result.__sizeSpos=size*pointNN; response->result.Rlist= (char **) soap_malloc(soap, size * pointNN * sizeof(char *)); response->result.Dist = (double *) soap_malloc(soap, size * pointNN * sizeof(double)); response->result.Qpos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int)); response->result.Spos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int)); unsigned int k = 0; // Loop over returned tracks for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; // Reverse the order of the points stored in point_queues unsigned int qsize=point_queues[r.trackID].size(); while(qsize--){ point_queue.push(point_queues[r.trackID].top()); point_queues[r.trackID].pop(); } qsize=point_queue.size(); unsigned int numReports = pointNN; while(numReports--){ // pop the rest of the points if(qsize) rk = point_queue.top(); // Take one point from the top of the queue else{ rk.dist = 1000000000.0; rk.qpos = 0xFFFFFFFF; rk.spos = 0xFFFFFFFF; } response->result.Rlist[k] = (char *) soap_malloc(soap, O2_MAXFILESTR); response->result.Dist[k] = rk.dist; response->result.Qpos[k] = rk.qpos; response->result.Spos[k] = rk.spos; if(qsize){ if(adb) snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID)); else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID); point_queue.pop(); qsize--; } else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL"); k++; } } } // clean up delete[] point_queues; } /********************** Radius Reporters **************************/ class triple{ public: unsigned int a; unsigned int b; unsigned int c; triple(void); triple(unsigned int, unsigned int, unsigned int); unsigned int first(); unsigned int second(); unsigned int third(); }; triple& make_triple(unsigned int, unsigned int, unsigned int); triple::triple(unsigned int a, unsigned int b, unsigned int c):a(a),b(b),c(c){} unsigned int triple::first(){return a;} unsigned int triple::second(){return b;} unsigned int triple::third(){return c;} triple::triple():a(0),b(0),c(0){} bool operator< (const triple &t1, const triple &t2) { return ((t1.a < t2.a) || ((t1.a == t2.a) && ((t1.b < t2.b) || ((t1.b == t2.b) && (t1.c < t2.c))))); } bool operator== (const triple &t1, const triple &t2) { return ((t1.a == t2.a) && (t1.b == t2.b) && (t1.c == t2.c)); } triple& make_triple(unsigned int a, unsigned int b, unsigned int c){ triple* t = new triple(a,b,c); return *t; } // track Sequence Query Radius Reporter // only return tracks and retrieved point counts class trackSequenceQueryRadReporter : public Reporter { public: trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles); ~trackSequenceQueryRadReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(adb_t *adb, struct soap *soap, void *adbQueryResponse); protected: unsigned int trackNN; unsigned int numFiles; std::set<std::pair<unsigned int, unsigned int> > *set; std::set< triple > *set_triple; unsigned int *count; }; trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles): trackNN(trackNN), numFiles(numFiles) { set = new std::set<std::pair<unsigned int, unsigned int> >; set_triple = new std::set<triple, std::less<triple> >; count = new unsigned int[numFiles]; for (unsigned i = 0; i < numFiles; i++) { count[i] = 0; } } trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() { delete set; delete set_triple; delete [] count; } void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { std::set<std::pair<unsigned int, unsigned int> >::iterator it; std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once std::set<triple>::iterator it2; triple triple; triple = make_triple(trackID, qpos, spos); // only count this once // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables) it2 = set_triple->find(triple); if(it2 == set_triple->end()){ set_triple->insert(triple); it = set->find(pair); if (it == set->end()) { set->insert(pair); count[trackID]++; // only count if <tackID,qpos> pair is unique } } } void trackSequenceQueryRadReporter::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result; // KLUDGE: doing this backwards in an attempt to get the same // tiebreak behaviour as before. for (int i = numFiles-1; i >= 0; i--) { Radresult r; r.trackID = i; r.count = count[i]; if(r.count > 0) { result.push(r); if (result.size() > trackNN) { result.pop(); } } } Radresult r; std::vector<Radresult> v; unsigned int size = result.size(); for(unsigned int k = 0; k < size; k++) { r = result.top(); v.push_back(r); result.pop(); } std::vector<Radresult>::reverse_iterator rit; if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; if(adb) std::cout << audiodb_index_key(adb, r.trackID) << " "; else std::cout << r.trackID << " "; std::cout << r.count << std::endl; } } else { adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse; response->result.__sizeRlist=size; response->result.__sizeDist=size; response->result.__sizeQpos=size; response->result.__sizeSpos=size; response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *)); response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double)); response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int)); unsigned int k = 0; for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { r = *rit; response->result.Rlist[k] = (char *) soap_malloc(soap, O2_MAXFILESTR); response->result.Dist[k] = 0; response->result.Qpos[k] = 0; response->result.Spos[k] = r.count; if(adb) snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID)); else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID); } } } // track Sequence Query Radius NN Reporter // retrieve tracks ordered by query-point matches (one per track per query point) // // as well as sorted n-NN points per retrieved track class trackSequenceQueryRadNNReporter : public Reporter { public: trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); ~trackSequenceQueryRadNNReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(adb_t *adb, struct soap *soap, void *adbQueryResponse); protected: unsigned int pointNN; unsigned int trackNN; unsigned int numFiles; std::set<std::pair<unsigned int, unsigned int> > *set; std::set< triple > *set_triple; std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues; unsigned int *count; }; trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles): pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { // Where to count Radius track matches (one-to-one) set = new std::set<std::pair<unsigned int, unsigned int> >; set_triple = new std::set<triple, std::less<triple> >; // Where to insert individual point matches (one-to-many) point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles]; count = new unsigned int[numFiles]; for (unsigned i = 0; i < numFiles; i++) { count[i] = 0; } } trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() { delete set; delete set_triple; delete [] count; } void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { std::set<std::pair<unsigned int, unsigned int> >::iterator it; std::set<triple>::iterator it2; std::pair<unsigned int, unsigned int> pair; triple triple; NNresult r; pair = std::make_pair(trackID, qpos); // only count this once triple = make_triple(trackID, qpos, spos); // only count this once // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables) it2 = set_triple->find(triple); if(it2 == set_triple->end()){ set_triple->insert(triple); // Record all matching points (within radius) // Record counts of <trackID,qpos> pairs it = set->find(pair); if (it == set->end()) { set->insert(pair); count[trackID]++; } if (!isnan(dist)) { r.trackID = trackID; r.qpos = qpos; r.dist = dist; r.spos = spos; point_queues[trackID].push(r); if(point_queues[trackID].size() > pointNN) point_queues[trackID].pop(); } } } void trackSequenceQueryRadNNReporter::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result; // KLUDGE: doing this backwards in an attempt to get the same // tiebreak behaviour as before. Radresult r; NNresult rk; std::vector<Radresult> v; unsigned int size; if(pointNN>1){ for (int i = numFiles-1; i >= 0; i--) { r.trackID = i; r.count = count[i]; if(r.count > 0) { cout.flush(); result.push(r); if (result.size() > trackNN) { result.pop(); } } } size = result.size(); for(unsigned int k = 0; k < size; k++) { r = result.top(); v.push_back(r); result.pop(); } } else{ // Instantiate a 1-NN trackAveragingNN reporter trackSequenceQueryNNReporter<std::less <NNresult> >* rep = new trackSequenceQueryNNReporter<std::less <NNresult> >(1, trackNN, numFiles); // Add all the points we've got to the reporter for(unsigned int i=0; i<numFiles; i++){ int qsize = point_queues[i].size(); while(qsize--){ rk = point_queues[i].top(); rep->add_point(i, rk.qpos, rk.spos, rk.dist); point_queues[i].pop(); } } // Report rep->report(adb, soap, adbQueryResponse); // Exit delete[] point_queues; return; } // Traverse tracks in descending order of count cardinality std::vector<Radresult>::reverse_iterator rit; std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue; if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; if(adb) std::cout << audiodb_index_key(adb, r.trackID) << " "; else std::cout << r.trackID << " "; std::cout << r.count << std::endl; // Reverse the order of the points stored in point_queues unsigned int qsize=point_queues[r.trackID].size(); for(unsigned int k=0; k < qsize; k++){ point_queue.push(point_queues[r.trackID].top()); point_queues[r.trackID].pop(); } for(unsigned int k=0; k < qsize; k++){ rk = point_queue.top(); std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl; point_queue.pop(); } } } else { adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse; response->result.__sizeRlist=size*pointNN; response->result.__sizeDist=size*pointNN; response->result.__sizeQpos=size*pointNN; response->result.__sizeSpos=size*pointNN; response->result.Rlist= (char **) soap_malloc(soap, size * pointNN * sizeof(char *)); response->result.Dist = (double *) soap_malloc(soap, size * pointNN * sizeof(double)); response->result.Qpos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int)); response->result.Spos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int)); unsigned int k = 0; // Loop over returned tracks for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; // Reverse the order of the points stored in point_queues unsigned int qsize=point_queues[r.trackID].size(); while(qsize--){ point_queue.push(point_queues[r.trackID].top()); point_queues[r.trackID].pop(); } qsize=point_queue.size(); unsigned int numReports = pointNN; while(numReports--){ // pop the rest of the points if(qsize) rk = point_queue.top(); // Take one point from the top of the queue else{ rk.dist = 1000000000.0; rk.qpos = 0xFFFFFFFF; rk.spos = 0xFFFFFFFF; } response->result.Rlist[k] = (char *) soap_malloc(soap, O2_MAXFILESTR); response->result.Dist[k] = rk.dist; response->result.Qpos[k] = rk.qpos; response->result.Spos[k] = rk.spos; if(qsize){ if(adb) snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID)); else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID); point_queue.pop(); qsize--; } else snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL"); k++; } } } delete[] point_queues; } /********** ONE-TO-ONE REPORTERS *****************/ // track Sequence Query Radius NN Reporter One-to-One // for each query point find the single best matching target point in all database // report qpos, spos and trackID class trackSequenceQueryRadNNReporterOneToOne : public Reporter { public: trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); ~trackSequenceQueryRadNNReporterOneToOne(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(adb_t *adb, struct soap *soap, void *adbQueryResponse); protected: unsigned int pointNN; unsigned int trackNN; unsigned int numFiles; std::set< NNresult > *set; std::vector< NNresult> *point_queue; unsigned int *count; }; trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles): pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { // Where to count Radius track matches (one-to-one) set = new std::set< NNresult >; // Where to insert individual point matches (one-to-many) point_queue = new std::vector< NNresult >; count = new unsigned int[numFiles]; for (unsigned i = 0; i < numFiles; i++) { count[i] = 0; } } trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() { delete set; delete [] count; } void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { std::set< NNresult >::iterator it; NNresult r; r.qpos = qpos; r.trackID = trackID; r.spos = spos; r.dist = dist; if(point_queue->size() < r.qpos + 1){ point_queue->resize( r.qpos + 1 ); (*point_queue)[r.qpos].dist = 1e6; } if (r.dist < (*point_queue)[r.qpos].dist) (*point_queue)[r.qpos] = r; } void trackSequenceQueryRadNNReporterOneToOne::report(adb_t *adb, struct soap *soap, void *adbQueryResponse) { if(adbQueryResponse==0) { std::vector< NNresult >::iterator vit; NNresult rk; for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){ rk = *vit; std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << " "; if(adb) std::cout << audiodb_index_key(adb, rk.trackID) << " "; else std::cout << rk.trackID << " "; std::cout << std::endl; } } else { // FIXME } } #endif