annotate reporter.h @ 507:e7fd50483311

Free bits of the datum constructed in audioDB::query. We're not quite safe: error calls between allocation of some of these bits and pieces and their use will cause failure... but not freeing things here is definitely wrong.
author mas01cr
date Tue, 13 Jan 2009 21:37:10 +0000
parents 342822c2d49a
children 23c47e118bc6
rev   line source
mas01mc@292 1 #ifndef __REPORTER_H
mas01mc@292 2 #define __REPORTER_H
mas01mc@292 3
mas01cr@239 4 #include <utility>
mas01cr@239 5 #include <queue>
mas01cr@239 6 #include <set>
mas01cr@239 7 #include <functional>
mas01mc@292 8 #include <iostream>
mas01mc@292 9 #include "ReporterBase.h"
mas01mc@292 10 #include "audioDB.h"
mas01cr@239 11
mas01cr@239 12 typedef struct nnresult {
mas01cr@239 13 unsigned int trackID;
mas01cr@239 14 double dist;
mas01cr@239 15 unsigned int qpos;
mas01cr@239 16 unsigned int spos;
mas01cr@239 17 } NNresult;
mas01cr@239 18
mas01cr@239 19 typedef struct radresult {
mas01cr@239 20 unsigned int trackID;
mas01cr@239 21 unsigned int count;
mas01cr@239 22 } Radresult;
mas01cr@239 23
mas01cr@239 24 bool operator< (const NNresult &a, const NNresult &b) {
mas01cr@239 25 return a.dist < b.dist;
mas01cr@239 26 }
mas01cr@239 27
mas01cr@239 28 bool operator> (const NNresult &a, const NNresult &b) {
mas01cr@239 29 return a.dist > b.dist;
mas01cr@239 30 }
mas01cr@239 31
mas01cr@239 32 bool operator< (const Radresult &a, const Radresult &b) {
mas01cr@239 33 return a.count < b.count;
mas01cr@239 34 }
mas01cr@239 35
mas01mc@275 36 bool operator> (const Radresult &a, const Radresult &b) {
mas01mc@275 37 return a.count > b.count;
mas01mc@275 38 }
mas01mc@275 39
mas01mc@292 40 class Reporter : public ReporterBase {
mas01cr@239 41 public:
mas01cr@239 42 virtual ~Reporter() {};
mas01cr@239 43 virtual void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) = 0;
mas01cr@239 44 // FIXME: this interface is a bit wacky: a relic of previous, more
mas01cr@239 45 // confused times. Really it might make sense to have separate
mas01cr@239 46 // reporter classes for WS and for stdout, rather than passing this
mas01cr@498 47 // adbQueryResponse thing everywhere; the adb argument is there
mas01cr@498 48 // solely for converting trackIDs into names. -- CSR, 2007-12-10.
mas01cr@498 49 virtual void report(adb_t *adb, void* adbQueryResponse) = 0;
mas01cr@239 50 };
mas01cr@239 51
mas01cr@239 52 template <class T> class pointQueryReporter : public Reporter {
mas01cr@239 53 public:
mas01cr@239 54 pointQueryReporter(unsigned int pointNN);
mas01cr@239 55 ~pointQueryReporter();
mas01cr@239 56 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@498 57 void report(adb_t *adb, void* adbQueryResponse);
mas01cr@239 58 private:
mas01cr@239 59 unsigned int pointNN;
mas01cr@239 60 std::priority_queue< NNresult, std::vector< NNresult >, T> *queue;
mas01cr@239 61 };
mas01cr@239 62
mas01cr@239 63 template <class T> pointQueryReporter<T>::pointQueryReporter(unsigned int pointNN)
mas01cr@239 64 : pointNN(pointNN) {
mas01cr@239 65 queue = new std::priority_queue< NNresult, std::vector< NNresult >, T>;
mas01cr@239 66 }
mas01cr@239 67
mas01cr@239 68 template <class T> pointQueryReporter<T>::~pointQueryReporter() {
mas01cr@239 69 delete queue;
mas01cr@239 70 }
mas01cr@239 71
mas01cr@239 72 template <class T> void pointQueryReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 73 if (!isnan(dist)) {
mas01cr@242 74 NNresult r;
mas01cr@242 75 r.trackID = trackID;
mas01cr@242 76 r.qpos = qpos;
mas01cr@242 77 r.spos = spos;
mas01cr@242 78 r.dist = dist;
mas01cr@242 79 queue->push(r);
mas01cr@242 80 if(queue->size() > pointNN) {
mas01cr@242 81 queue->pop();
mas01cr@242 82 }
mas01cr@239 83 }
mas01cr@239 84 }
mas01cr@239 85
mas01cr@498 86 template <class T> void pointQueryReporter<T>::report(adb_t *adb, void *adbQueryResponse) {
mas01cr@239 87 NNresult r;
mas01cr@239 88 std::vector<NNresult> v;
mas01cr@239 89 unsigned int size = queue->size();
mas01cr@239 90 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 91 r = queue->top();
mas01cr@239 92 v.push_back(r);
mas01cr@239 93 queue->pop();
mas01cr@239 94 }
mas01cr@239 95 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 96
mas01cr@239 97 if(adbQueryResponse==0) {
mas01cr@239 98 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 99 r = *rit;
mas01cr@498 100 if(adb)
mas01cr@498 101 std::cout << audiodb_index_key(adb, r.trackID) << " ";
mas01mc@292 102 else
mas01mc@292 103 std::cout << r.trackID << " ";
mas01cr@239 104 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 105 }
mas01cr@239 106 } else {
mas01cr@498 107 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@498 108 response->result.__sizeRlist=size;
mas01cr@498 109 response->result.__sizeDist=size;
mas01cr@498 110 response->result.__sizeQpos=size;
mas01cr@498 111 response->result.__sizeSpos=size;
mas01cr@498 112 response->result.Rlist= new char*[size];
mas01cr@498 113 response->result.Dist = new double[size];
mas01cr@498 114 response->result.Qpos = new unsigned int[size];
mas01cr@498 115 response->result.Spos = new unsigned int[size];
mas01cr@239 116 unsigned int k = 0;
mas01cr@239 117 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 118 r = *rit;
mas01cr@498 119 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@498 120 response->result.Dist[k] = r.dist;
mas01cr@498 121 response->result.Qpos[k] = r.qpos;
mas01cr@498 122 response->result.Spos[k] = r.spos;
mas01cr@498 123 if(adb)
mas01cr@498 124 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID));
mas01mc@292 125 else
mas01cr@498 126 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 127 }
mas01cr@239 128 }
mas01cr@239 129 }
mas01cr@239 130
mas01cr@239 131 template <class T> class trackAveragingReporter : public Reporter {
mas01cr@239 132 public:
mas01cr@239 133 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01cr@239 134 ~trackAveragingReporter();
mas01cr@239 135 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@498 136 void report(adb_t *adb, void *adbQueryResponse);
mas01mc@249 137 protected:
mas01cr@239 138 unsigned int pointNN;
mas01cr@239 139 unsigned int trackNN;
mas01cr@239 140 unsigned int numFiles;
mas01cr@239 141 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues;
mas01cr@239 142 };
mas01cr@239 143
mas01cr@239 144 template <class T> trackAveragingReporter<T>::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01cr@239 145 : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01cr@239 146 queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles];
mas01cr@239 147 }
mas01cr@239 148
mas01cr@239 149 template <class T> trackAveragingReporter<T>::~trackAveragingReporter() {
mas01cr@239 150 delete [] queues;
mas01cr@239 151 }
mas01cr@239 152
mas01cr@239 153 template <class T> void trackAveragingReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 154 if (!isnan(dist)) {
mas01cr@242 155 NNresult r;
mas01cr@242 156 r.trackID = trackID;
mas01cr@242 157 r.qpos = qpos;
mas01cr@242 158 r.spos = spos;
mas01cr@242 159 r.dist = dist;
mas01cr@242 160 queues[trackID].push(r);
mas01cr@242 161 if(queues[trackID].size() > pointNN) {
mas01cr@242 162 queues[trackID].pop();
mas01cr@242 163 }
mas01cr@239 164 }
mas01cr@239 165 }
mas01cr@239 166
mas01cr@498 167 template <class T> void trackAveragingReporter<T>::report(adb_t *adb, void *adbQueryResponse) {
mas01cr@239 168 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01cr@239 169 for (int i = numFiles-1; i >= 0; i--) {
mas01cr@239 170 unsigned int size = queues[i].size();
mas01cr@239 171 if (size > 0) {
mas01cr@239 172 NNresult r;
mas01cr@239 173 double dist = 0;
mas01cr@239 174 NNresult oldr = queues[i].top();
mas01cr@239 175 for (unsigned int j = 0; j < size; j++) {
mas01cr@239 176 r = queues[i].top();
mas01cr@239 177 dist += r.dist;
mas01cr@239 178 queues[i].pop();
mas01cr@239 179 if (r.dist == oldr.dist) {
mas01cr@239 180 r.qpos = oldr.qpos;
mas01cr@239 181 r.spos = oldr.spos;
mas01cr@239 182 } else {
mas01cr@239 183 oldr = r;
mas01cr@239 184 }
mas01cr@239 185 }
mas01cr@239 186 dist /= size;
mas01cr@239 187 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01cr@239 188 result.push(r);
mas01cr@239 189 if (result.size() > trackNN) {
mas01cr@239 190 result.pop();
mas01cr@239 191 }
mas01cr@239 192 }
mas01cr@239 193 }
mas01cr@239 194
mas01cr@239 195 NNresult r;
mas01cr@239 196 std::vector<NNresult> v;
mas01cr@239 197 unsigned int size = result.size();
mas01cr@239 198 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 199 r = result.top();
mas01cr@239 200 v.push_back(r);
mas01cr@239 201 result.pop();
mas01cr@239 202 }
mas01cr@239 203 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 204
mas01cr@239 205 if(adbQueryResponse==0) {
mas01cr@239 206 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 207 r = *rit;
mas01cr@498 208 if(adb)
mas01cr@498 209 std::cout << audiodb_index_key(adb, r.trackID) << " ";
mas01mc@292 210 else
mas01mc@292 211 std::cout << r.trackID << " ";
mas01cr@239 212 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 213 }
mas01cr@239 214 } else {
mas01cr@498 215 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@498 216 response->result.__sizeRlist=size;
mas01cr@498 217 response->result.__sizeDist=size;
mas01cr@498 218 response->result.__sizeQpos=size;
mas01cr@498 219 response->result.__sizeSpos=size;
mas01cr@498 220 response->result.Rlist= new char*[size];
mas01cr@498 221 response->result.Dist = new double[size];
mas01cr@498 222 response->result.Qpos = new unsigned int[size];
mas01cr@498 223 response->result.Spos = new unsigned int[size];
mas01cr@239 224 unsigned int k = 0;
mas01cr@239 225 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 226 r = *rit;
mas01cr@498 227 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@498 228 response->result.Dist[k] = r.dist;
mas01cr@498 229 response->result.Qpos[k] = r.qpos;
mas01cr@498 230 response->result.Spos[k] = r.spos;
mas01cr@498 231 if(adb)
mas01cr@498 232 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID));
mas01mc@292 233 else
mas01cr@498 234 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 235 }
mas01cr@239 236 }
mas01cr@239 237 }
mas01cr@239 238
mas01mc@249 239 // Another type of trackAveragingReporter that reports all pointNN nearest neighbours
mas01mc@249 240 template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> {
mas01mc@249 241 protected:
mas01mc@249 242 using trackAveragingReporter<T>::numFiles;
mas01mc@249 243 using trackAveragingReporter<T>::queues;
mas01mc@249 244 using trackAveragingReporter<T>::trackNN;
mas01mc@249 245 using trackAveragingReporter<T>::pointNN;
mas01mc@248 246 public:
mas01mc@248 247 trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01cr@498 248 void report(adb_t *adb, void *adbQueryResponse);
mas01mc@248 249 };
mas01mc@248 250
mas01mc@249 251 template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01mc@249 252 :trackAveragingReporter<T>(pointNN, trackNN, numFiles){}
mas01mc@248 253
mas01cr@498 254 template <class T> void trackSequenceQueryNNReporter<T>::report(adb_t *adb, void *adbQueryResponse) {
mas01mc@248 255 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01mc@292 256 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues
mas01mc@292 257 = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@249 258
mas01mc@248 259 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@248 260 unsigned int size = queues[i].size();
mas01mc@248 261 if (size > 0) {
mas01mc@248 262 NNresult r;
mas01mc@248 263 double dist = 0;
mas01mc@248 264 NNresult oldr = queues[i].top();
mas01mc@248 265 for (unsigned int j = 0; j < size; j++) {
mas01mc@248 266 r = queues[i].top();
mas01mc@248 267 dist += r.dist;
mas01mc@248 268 point_queues[i].push(r);
mas01mc@249 269 queues[i].pop();
mas01mc@248 270 if (r.dist == oldr.dist) {
mas01mc@248 271 r.qpos = oldr.qpos;
mas01mc@248 272 r.spos = oldr.spos;
mas01mc@248 273 } else {
mas01mc@248 274 oldr = r;
mas01mc@248 275 }
mas01mc@248 276 }
mas01mc@248 277 dist /= size;
mas01mc@248 278 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01mc@248 279 result.push(r);
mas01mc@248 280 if (result.size() > trackNN) {
mas01mc@248 281 result.pop();
mas01mc@248 282 }
mas01mc@248 283 }
mas01mc@248 284 }
mas01mc@248 285
mas01mc@248 286 NNresult r;
mas01mc@248 287 std::vector<NNresult> v;
mas01mc@248 288 unsigned int size = result.size();
mas01mc@248 289 for(unsigned int k = 0; k < size; k++) {
mas01mc@248 290 r = result.top();
mas01mc@248 291 v.push_back(r);
mas01mc@248 292 result.pop();
mas01mc@248 293 }
mas01mc@248 294 std::vector<NNresult>::reverse_iterator rit;
mas01mc@264 295 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@324 296 NNresult rk;
mas01mc@264 297
mas01mc@248 298 if(adbQueryResponse==0) {
mas01mc@248 299 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 300 r = *rit;
mas01cr@498 301 if(adb)
mas01cr@498 302 std::cout << audiodb_index_key(adb, r.trackID) << " ";
mas01mc@292 303 else
mas01mc@292 304 std::cout << r.trackID << " ";
mas01cr@498 305 std::cout << r.dist << std::endl;
mas01mc@264 306 unsigned int qsize = point_queues[r.trackID].size();
mas01mc@264 307 // Reverse the order of the points stored in point_queues
mas01mc@264 308 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 309 point_queue.push( point_queues[r.trackID].top() );
mas01mc@264 310 point_queues[r.trackID].pop();
mas01mc@264 311 }
mas01mc@264 312
mas01mc@264 313 for(unsigned int k = 0; k < qsize; k++) {
mas01mc@324 314 rk = point_queue.top();
mas01mc@248 315 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 316 point_queue.pop();
mas01mc@248 317 }
mas01mc@248 318 }
mas01mc@248 319 } else {
mas01cr@498 320 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@498 321 response->result.__sizeRlist=size*pointNN;
mas01cr@498 322 response->result.__sizeDist=size*pointNN;
mas01cr@498 323 response->result.__sizeQpos=size*pointNN;
mas01cr@498 324 response->result.__sizeSpos=size*pointNN;
mas01cr@498 325 response->result.Rlist= new char*[size*pointNN];
mas01cr@498 326 response->result.Dist = new double[size*pointNN];
mas01cr@498 327 response->result.Qpos = new unsigned int[size*pointNN];
mas01cr@498 328 response->result.Spos = new unsigned int[size*pointNN];
mas01mc@248 329 unsigned int k = 0;
mas01mc@324 330 // Loop over returned tracks
mas01mc@324 331 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 332 r = *rit;
mas01mc@324 333 // Reverse the order of the points stored in point_queues
mas01mc@324 334 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@324 335 while(qsize--){
mas01mc@324 336 point_queue.push(point_queues[r.trackID].top());
mas01mc@324 337 point_queues[r.trackID].pop();
mas01mc@324 338 }
mas01mc@324 339 qsize=point_queue.size();
mas01mc@324 340 unsigned int numReports = pointNN;
mas01mc@324 341 while(numReports--){ // pop the rest of the points
mas01mc@324 342 if(qsize)
mas01mc@324 343 rk = point_queue.top(); // Take one point from the top of the queue
mas01mc@324 344 else{
mas01mc@324 345 rk.dist = 1000000000.0;
mas01mc@324 346 rk.qpos = 0xFFFFFFFF;
mas01mc@324 347 rk.spos = 0xFFFFFFFF;
mas01mc@324 348 }
mas01mc@324 349
mas01cr@498 350 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@498 351 response->result.Dist[k] = rk.dist;
mas01cr@498 352 response->result.Qpos[k] = rk.qpos;
mas01cr@498 353 response->result.Spos[k] = rk.spos;
mas01mc@324 354 if(qsize){
mas01cr@498 355 if(adb)
mas01cr@498 356 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID));
mas01mc@324 357 else
mas01cr@498 358 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@324 359 point_queue.pop();
mas01mc@324 360 qsize--;
mas01mc@324 361 }
mas01mc@324 362 else
mas01cr@498 363 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL");
mas01mc@324 364 k++;
mas01mc@324 365 }
mas01mc@248 366 }
mas01mc@248 367 }
mas01mc@248 368 // clean up
mas01mc@248 369 delete[] point_queues;
mas01mc@248 370 }
mas01mc@250 371
mas01mc@292 372 /********************** Radius Reporters **************************/
mas01mc@250 373
mas01mc@292 374 class triple{
mas01mc@292 375 public:
mas01mc@292 376 unsigned int a;
mas01mc@292 377 unsigned int b;
mas01mc@292 378 unsigned int c;
mas01mc@292 379
mas01mc@292 380 triple(void);
mas01mc@292 381 triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 382 unsigned int first();
mas01mc@292 383 unsigned int second();
mas01mc@292 384 unsigned int third();
mas01mc@292 385 };
mas01mc@292 386
mas01mc@292 387 triple& make_triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 388
mas01mc@292 389 triple::triple(unsigned int a, unsigned int b, unsigned int c):a(a),b(b),c(c){}
mas01mc@292 390
mas01mc@292 391 unsigned int triple::first(){return a;}
mas01mc@292 392 unsigned int triple::second(){return b;}
mas01mc@292 393 unsigned int triple::third(){return c;}
mas01mc@292 394
mas01mc@292 395 triple::triple():a(0),b(0),c(0){}
mas01mc@292 396
mas01mc@292 397 bool operator< (const triple &t1, const triple &t2) {
mas01mc@292 398 return ((t1.a < t2.a) ||
mas01mc@292 399 ((t1.a == t2.a) && ((t1.b < t2.b) ||
mas01mc@292 400 ((t1.b == t2.b) && (t1.c < t2.c)))));
mas01mc@292 401 }
mas01mc@292 402 bool operator== (const triple &t1, const triple &t2) {
mas01mc@292 403 return ((t1.a == t2.a) && (t1.b == t2.b) && (t1.c == t2.c));
mas01mc@292 404 }
mas01mc@292 405
mas01mc@292 406 triple& make_triple(unsigned int a, unsigned int b, unsigned int c){
mas01mc@292 407 triple* t = new triple(a,b,c);
mas01mc@292 408 return *t;
mas01mc@292 409 }
mas01mc@292 410
mas01mc@292 411 // track Sequence Query Radius Reporter
mas01mc@292 412 // only return tracks and retrieved point counts
mas01mc@292 413 class trackSequenceQueryRadReporter : public Reporter {
mas01mc@250 414 public:
mas01mc@292 415 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles);
mas01mc@292 416 ~trackSequenceQueryRadReporter();
mas01mc@250 417 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@498 418 void report(adb_t *adb, void *adbQueryResponse);
mas01mc@250 419 protected:
mas01mc@250 420 unsigned int trackNN;
mas01mc@250 421 unsigned int numFiles;
mas01mc@292 422 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 423 std::set< triple > *set_triple;
mas01mc@250 424 unsigned int *count;
mas01mc@250 425 };
mas01mc@250 426
mas01mc@292 427 trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles):
mas01mc@292 428 trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 429 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 430 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@250 431 count = new unsigned int[numFiles];
mas01mc@250 432 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@250 433 count[i] = 0;
mas01mc@250 434 }
mas01mc@250 435 }
mas01mc@250 436
mas01mc@292 437 trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() {
mas01mc@250 438 delete set;
mas01mc@292 439 delete set_triple;
mas01mc@250 440 delete [] count;
mas01mc@250 441 }
mas01mc@250 442
mas01mc@292 443 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 444 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 445 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 446 std::set<triple>::iterator it2;
mas01mc@292 447 triple triple;
mas01mc@250 448
mas01mc@292 449 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 450
mas01mc@292 451 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 452 it2 = set_triple->find(triple);
mas01mc@250 453
mas01mc@292 454 if(it2 == set_triple->end()){
mas01mc@292 455 set_triple->insert(triple);
mas01mc@292 456
mas01mc@292 457 it = set->find(pair);
mas01mc@292 458 if (it == set->end()) {
mas01mc@292 459 set->insert(pair);
mas01mc@292 460 count[trackID]++; // only count if <tackID,qpos> pair is unique
mas01mc@292 461 }
mas01mc@250 462 }
mas01mc@250 463 }
mas01mc@250 464
mas01cr@498 465 void trackSequenceQueryRadReporter::report(adb_t *adb, void *adbQueryResponse) {
mas01mc@275 466 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@250 467 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@250 468 // tiebreak behaviour as before.
mas01mc@250 469 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@250 470 Radresult r;
mas01mc@250 471 r.trackID = i;
mas01mc@250 472 r.count = count[i];
mas01mc@250 473 if(r.count > 0) {
mas01mc@250 474 result.push(r);
mas01mc@250 475 if (result.size() > trackNN) {
mas01mc@250 476 result.pop();
mas01mc@250 477 }
mas01mc@250 478 }
mas01mc@250 479 }
mas01mc@250 480
mas01mc@250 481 Radresult r;
mas01mc@250 482 std::vector<Radresult> v;
mas01mc@250 483 unsigned int size = result.size();
mas01mc@250 484 for(unsigned int k = 0; k < size; k++) {
mas01mc@250 485 r = result.top();
mas01mc@250 486 v.push_back(r);
mas01mc@250 487 result.pop();
mas01mc@250 488 }
mas01mc@292 489 std::vector<Radresult>::reverse_iterator rit;
mas01mc@292 490
mas01mc@292 491 if(adbQueryResponse==0) {
mas01mc@292 492 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@292 493 r = *rit;
mas01cr@498 494 if(adb)
mas01cr@498 495 std::cout << audiodb_index_key(adb, r.trackID) << " ";
mas01mc@292 496 else
mas01mc@292 497 std::cout << r.trackID << " ";
mas01mc@292 498 std::cout << r.count << std::endl;
mas01mc@292 499 }
mas01cr@498 500 } else {
mas01cr@498 501 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@498 502 response->result.__sizeRlist=size;
mas01cr@498 503 response->result.__sizeDist=size;
mas01cr@498 504 response->result.__sizeQpos=size;
mas01cr@498 505 response->result.__sizeSpos=size;
mas01cr@498 506 response->result.Rlist= new char*[size];
mas01cr@498 507 response->result.Dist = new double[size];
mas01cr@498 508 response->result.Qpos = new unsigned int[size];
mas01cr@498 509 response->result.Spos = new unsigned int[size];
mas01mc@307 510 unsigned int k = 0;
mas01mc@307 511 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@307 512 r = *rit;
mas01cr@498 513 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@498 514 response->result.Dist[k] = 0;
mas01cr@498 515 response->result.Qpos[k] = 0;
mas01cr@498 516 response->result.Spos[k] = r.count;
mas01cr@498 517 if(adb)
mas01cr@498 518 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID));
mas01mc@307 519 else
mas01cr@498 520 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@307 521 }
mas01mc@292 522 }
mas01mc@292 523 }
mas01mc@292 524
mas01mc@292 525 // track Sequence Query Radius NN Reporter
mas01mc@292 526 // retrieve tracks ordered by query-point matches (one per track per query point)
mas01mc@292 527 //
mas01mc@292 528 // as well as sorted n-NN points per retrieved track
mas01mc@292 529 class trackSequenceQueryRadNNReporter : public Reporter {
mas01mc@292 530 public:
mas01mc@292 531 trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@292 532 ~trackSequenceQueryRadNNReporter();
mas01mc@292 533 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@498 534 void report(adb_t *adb, void *adbQueryResponse);
mas01mc@292 535 protected:
mas01mc@292 536 unsigned int pointNN;
mas01mc@292 537 unsigned int trackNN;
mas01mc@292 538 unsigned int numFiles;
mas01mc@292 539 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 540 std::set< triple > *set_triple;
mas01mc@292 541 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues;
mas01mc@292 542 unsigned int *count;
mas01mc@292 543 };
mas01mc@292 544
mas01mc@292 545 trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@292 546 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 547 // Where to count Radius track matches (one-to-one)
mas01mc@292 548 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 549 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@292 550 // Where to insert individual point matches (one-to-many)
mas01mc@292 551 point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@292 552
mas01mc@292 553 count = new unsigned int[numFiles];
mas01mc@292 554 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@292 555 count[i] = 0;
mas01mc@292 556 }
mas01mc@292 557 }
mas01mc@292 558
mas01mc@292 559 trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() {
mas01mc@292 560 delete set;
mas01mc@292 561 delete set_triple;
mas01mc@292 562 delete [] count;
mas01mc@292 563 }
mas01mc@292 564
mas01mc@292 565 void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 566 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 567 std::set<triple>::iterator it2;
mas01mc@292 568 std::pair<unsigned int, unsigned int> pair;
mas01mc@292 569 triple triple;
mas01mc@292 570 NNresult r;
mas01mc@292 571
mas01mc@292 572 pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 573 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 574 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 575 it2 = set_triple->find(triple);
mas01mc@292 576 if(it2 == set_triple->end()){
mas01mc@292 577 set_triple->insert(triple);
mas01mc@292 578 // Record all matching points (within radius)
mas01mc@292 579 // Record counts of <trackID,qpos> pairs
mas01mc@292 580 it = set->find(pair);
mas01mc@292 581 if (it == set->end()) {
mas01mc@292 582 set->insert(pair);
mas01mc@292 583 count[trackID]++;
mas01mc@307 584 }
mas01mc@307 585 if (!isnan(dist)) {
mas01mc@307 586 r.trackID = trackID;
mas01mc@307 587 r.qpos = qpos;
mas01mc@307 588 r.dist = dist;
mas01mc@307 589 r.spos = spos;
mas01mc@307 590 point_queues[trackID].push(r);
mas01mc@307 591 if(point_queues[trackID].size() > pointNN)
mas01mc@307 592 point_queues[trackID].pop();
mas01mc@292 593 }
mas01mc@292 594 }
mas01mc@292 595 }
mas01mc@292 596
mas01cr@498 597 void trackSequenceQueryRadNNReporter::report(adb_t *adb, void *adbQueryResponse) {
mas01mc@292 598 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@292 599 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@292 600 // tiebreak behaviour as before.
mas01mc@292 601 Radresult r;
mas01mc@292 602 NNresult rk;
mas01mc@307 603 std::vector<Radresult> v;
mas01mc@307 604 unsigned int size;
mas01mc@292 605
mas01mc@307 606 if(pointNN>1){
mas01mc@307 607 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@307 608 r.trackID = i;
mas01mc@307 609 r.count = count[i];
mas01mc@307 610 if(r.count > 0) {
mas01mc@307 611 cout.flush();
mas01mc@307 612 result.push(r);
mas01mc@307 613 if (result.size() > trackNN) {
mas01mc@307 614 result.pop();
mas01mc@307 615 }
mas01mc@292 616 }
mas01mc@292 617 }
mas01mc@307 618
mas01mc@307 619 size = result.size();
mas01mc@307 620 for(unsigned int k = 0; k < size; k++) {
mas01mc@307 621 r = result.top();
mas01mc@307 622 v.push_back(r);
mas01mc@307 623 result.pop();
mas01mc@307 624 }
mas01mc@292 625 }
mas01mc@307 626 else{
mas01mc@307 627 // Instantiate a 1-NN trackAveragingNN reporter
mas01mc@307 628 trackSequenceQueryNNReporter<std::less <NNresult> >* rep = new trackSequenceQueryNNReporter<std::less <NNresult> >(1, trackNN, numFiles);
mas01mc@307 629 // Add all the points we've got to the reporter
mas01mc@307 630 for(unsigned int i=0; i<numFiles; i++){
mas01mc@307 631 int qsize = point_queues[i].size();
mas01mc@307 632 while(qsize--){
mas01mc@307 633 rk = point_queues[i].top();
mas01mc@307 634 rep->add_point(i, rk.qpos, rk.spos, rk.dist);
mas01mc@307 635 point_queues[i].pop();
mas01mc@307 636 }
mas01mc@307 637 }
mas01mc@307 638 // Report
mas01cr@498 639 rep->report(adb, adbQueryResponse);
mas01mc@307 640 // Exit
mas01mc@307 641 delete[] point_queues;
mas01mc@307 642 return;
mas01mc@292 643 }
mas01mc@264 644
mas01mc@264 645
mas01mc@264 646 // Traverse tracks in descending order of count cardinality
mas01mc@250 647 std::vector<Radresult>::reverse_iterator rit;
mas01mc@264 648 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@264 649
mas01mc@250 650 if(adbQueryResponse==0) {
mas01mc@250 651 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@250 652 r = *rit;
mas01cr@498 653 if(adb)
mas01cr@498 654 std::cout << audiodb_index_key(adb, r.trackID) << " ";
mas01mc@292 655 else
mas01mc@292 656 std::cout << r.trackID << " ";
mas01mc@292 657 std::cout << r.count << std::endl;
mas01mc@264 658
mas01mc@264 659 // Reverse the order of the points stored in point_queues
mas01mc@264 660 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@264 661 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 662 point_queue.push(point_queues[r.trackID].top());
mas01mc@264 663 point_queues[r.trackID].pop();
mas01mc@264 664 }
mas01mc@264 665 for(unsigned int k=0; k < qsize; k++){
mas01mc@292 666 rk = point_queue.top();
mas01mc@250 667 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 668 point_queue.pop();
mas01mc@250 669 }
mas01mc@250 670 }
mas01cr@498 671 } else {
mas01cr@498 672 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@498 673 response->result.__sizeRlist=size*pointNN;
mas01cr@498 674 response->result.__sizeDist=size*pointNN;
mas01cr@498 675 response->result.__sizeQpos=size*pointNN;
mas01cr@498 676 response->result.__sizeSpos=size*pointNN;
mas01cr@498 677 response->result.Rlist= new char*[size*pointNN];
mas01cr@498 678 response->result.Dist = new double[size*pointNN];
mas01cr@498 679 response->result.Qpos = new unsigned int[size*pointNN];
mas01cr@498 680 response->result.Spos = new unsigned int[size*pointNN];
mas01mc@307 681 unsigned int k = 0;
mas01mc@307 682 // Loop over returned tracks
mas01mc@324 683 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@307 684 r = *rit;
mas01mc@307 685 // Reverse the order of the points stored in point_queues
mas01mc@307 686 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@307 687 while(qsize--){
mas01mc@307 688 point_queue.push(point_queues[r.trackID].top());
mas01mc@307 689 point_queues[r.trackID].pop();
mas01mc@307 690 }
mas01mc@307 691 qsize=point_queue.size();
mas01mc@324 692 unsigned int numReports = pointNN;
mas01mc@324 693 while(numReports--){ // pop the rest of the points
mas01mc@324 694 if(qsize)
mas01mc@324 695 rk = point_queue.top(); // Take one point from the top of the queue
mas01mc@324 696 else{
mas01mc@324 697 rk.dist = 1000000000.0;
mas01mc@324 698 rk.qpos = 0xFFFFFFFF;
mas01mc@324 699 rk.spos = 0xFFFFFFFF;
mas01mc@324 700 }
mas01mc@324 701
mas01cr@498 702 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@498 703 response->result.Dist[k] = rk.dist;
mas01cr@498 704 response->result.Qpos[k] = rk.qpos;
mas01cr@498 705 response->result.Spos[k] = rk.spos;
mas01mc@324 706 if(qsize){
mas01cr@498 707 if(adb)
mas01cr@498 708 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", audiodb_index_key(adb, r.trackID));
mas01mc@324 709 else
mas01cr@498 710 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@324 711 point_queue.pop();
mas01mc@324 712 qsize--;
mas01mc@324 713 }
mas01mc@324 714 else
mas01cr@498 715 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL");
mas01mc@324 716 k++;
mas01mc@324 717 }
mas01mc@307 718 }
mas01mc@307 719 }
mas01mc@264 720 delete[] point_queues;
mas01mc@250 721 }
mas01mc@263 722
mas01mc@264 723 /********** ONE-TO-ONE REPORTERS *****************/
mas01mc@263 724
mas01mc@264 725 // track Sequence Query Radius NN Reporter One-to-One
mas01mc@264 726 // for each query point find the single best matching target point in all database
mas01mc@264 727 // report qpos, spos and trackID
mas01mc@263 728 class trackSequenceQueryRadNNReporterOneToOne : public Reporter {
mas01mc@263 729 public:
mas01mc@263 730 trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@263 731 ~trackSequenceQueryRadNNReporterOneToOne();
mas01mc@263 732 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@498 733 void report(adb_t *adb, void *adbQueryResponse);
mas01mc@263 734 protected:
mas01mc@263 735 unsigned int pointNN;
mas01mc@263 736 unsigned int trackNN;
mas01mc@263 737 unsigned int numFiles;
mas01mc@263 738 std::set< NNresult > *set;
mas01mc@263 739 std::vector< NNresult> *point_queue;
mas01mc@263 740 unsigned int *count;
mas01mc@263 741
mas01mc@263 742 };
mas01mc@263 743
mas01mc@263 744 trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@263 745 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@263 746 // Where to count Radius track matches (one-to-one)
mas01mc@263 747 set = new std::set< NNresult >;
mas01mc@263 748 // Where to insert individual point matches (one-to-many)
mas01mc@263 749 point_queue = new std::vector< NNresult >;
mas01mc@263 750
mas01mc@263 751 count = new unsigned int[numFiles];
mas01mc@263 752 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@263 753 count[i] = 0;
mas01mc@263 754 }
mas01mc@263 755 }
mas01mc@263 756
mas01mc@263 757 trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() {
mas01mc@263 758 delete set;
mas01mc@263 759 delete [] count;
mas01mc@263 760 }
mas01mc@263 761
mas01mc@263 762 void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@263 763 std::set< NNresult >::iterator it;
mas01mc@263 764 NNresult r;
mas01mc@264 765
mas01mc@263 766 r.qpos = qpos;
mas01mc@263 767 r.trackID = trackID;
mas01mc@263 768 r.spos = spos;
mas01mc@263 769 r.dist = dist;
mas01mc@263 770
mas01mc@263 771 if(point_queue->size() < r.qpos + 1){
mas01mc@263 772 point_queue->resize( r.qpos + 1 );
mas01mc@263 773 (*point_queue)[r.qpos].dist = 1e6;
mas01mc@263 774 }
mas01mc@263 775
mas01mc@263 776 if (r.dist < (*point_queue)[r.qpos].dist)
mas01mc@263 777 (*point_queue)[r.qpos] = r;
mas01mc@263 778
mas01mc@263 779 }
mas01mc@263 780
mas01cr@498 781 void trackSequenceQueryRadNNReporterOneToOne::report(adb_t *adb, void *adbQueryResponse) {
mas01mc@263 782 if(adbQueryResponse==0) {
mas01mc@263 783 std::vector< NNresult >::iterator vit;
mas01mc@263 784 NNresult rk;
mas01mc@263 785 for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){
mas01mc@263 786 rk = *vit;
mas01mc@263 787 std::cout << rk.dist << " "
mas01mc@263 788 << rk.qpos << " "
mas01mc@292 789 << rk.spos << " ";
mas01cr@498 790 if(adb)
mas01cr@498 791 std::cout << audiodb_index_key(adb, rk.trackID) << " ";
mas01mc@292 792 else
mas01mc@292 793 std::cout << rk.trackID << " ";
mas01mc@292 794 std::cout << std::endl;
mas01mc@263 795 }
mas01mc@263 796 } else {
mas01mc@263 797 // FIXME
mas01mc@263 798 }
mas01mc@263 799 }
mas01mc@292 800
mas01mc@292 801 #endif