annotate reporter.h @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 23c47e118bc6
children
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@508 49 virtual void report(adb_t *adb, struct soap *soap, 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@508 57 void report(adb_t *adb, struct soap *soap, 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@508 86 template <class T> void pointQueryReporter<T>::report(adb_t *adb, struct soap *soap, 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@508 112 response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *));
mas01cr@508 113 response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double));
mas01cr@508 114 response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
mas01cr@508 115 response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
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@508 119 response->result.Rlist[k] = (char *) soap_malloc(soap, 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@508 136 void report(adb_t *adb, struct soap *soap, 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@508 167 template <class T> void trackAveragingReporter<T>::report(adb_t *adb, struct soap *soap, 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@508 220 response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *));
mas01cr@508 221 response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double));
mas01cr@508 222 response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
mas01cr@508 223 response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
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@508 227 response->result.Rlist[k] = (char *) soap_malloc(soap, 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@508 248 void report(adb_t *adb, struct soap *soap, 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@508 254 template <class T> void trackSequenceQueryNNReporter<T>::report(adb_t *adb, struct soap *soap, 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@508 325 response->result.Rlist= (char **) soap_malloc(soap, size * pointNN * sizeof(char *));
mas01cr@508 326 response->result.Dist = (double *) soap_malloc(soap, size * pointNN * sizeof(double));
mas01cr@508 327 response->result.Qpos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int));
mas01cr@508 328 response->result.Spos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int));
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@508 350 response->result.Rlist[k] = (char *) soap_malloc(soap, 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@508 418 void report(adb_t *adb, struct soap *soap, 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@508 465 void trackSequenceQueryRadReporter::report(adb_t *adb, struct soap *soap, 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@508 506 response->result.Rlist= (char **) soap_malloc(soap, size * sizeof(char *));
mas01cr@508 507 response->result.Dist = (double *) soap_malloc(soap, size * sizeof(double));
mas01cr@508 508 response->result.Qpos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
mas01cr@508 509 response->result.Spos = (unsigned int *) soap_malloc(soap, size * sizeof(unsigned int));
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@508 513 response->result.Rlist[k] = (char *) soap_malloc(soap, 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@508 534 void report(adb_t *adb, struct soap *soap, 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@508 597 void trackSequenceQueryRadNNReporter::report(adb_t *adb, struct soap *soap, 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@508 639 rep->report(adb, soap, 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@508 677 response->result.Rlist= (char **) soap_malloc(soap, size * pointNN * sizeof(char *));
mas01cr@508 678 response->result.Dist = (double *) soap_malloc(soap, size * pointNN * sizeof(double));
mas01cr@508 679 response->result.Qpos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int));
mas01cr@508 680 response->result.Spos = (unsigned int *) soap_malloc(soap, size * pointNN * sizeof(unsigned int));
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@508 702 response->result.Rlist[k] = (char *) soap_malloc(soap, 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@508 733 void report(adb_t *adb, struct soap *soap, 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@508 781 void trackSequenceQueryRadNNReporterOneToOne::report(adb_t *adb, struct soap *soap, 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