annotate pertrackaccumulator.h @ 497:9d8aee621afb api-inversion

More libtests fixups. Include audiodb_close() calls everywhere (whoops). Add the facility to run tests under valgrind. Unfortunately the error-exitcode flag doesn't actually cause an error exit if the only thing wrong is memory leaks, but it will if there are actual memory errors, which is a start.
author mas01cr
date Sat, 10 Jan 2009 16:07:43 +0000
parents 580f696c817c
children e21a3db643af
rev   line source
mas01cr@420 1 template <class T> class PerTrackAccumulator : public Accumulator {
mas01cr@420 2 public:
mas01cr@420 3 PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN);
mas01cr@420 4 ~PerTrackAccumulator();
mas01cr@420 5 void add_point(adb_result_t *r);
mas01cr@420 6 adb_query_results_t *get_points();
mas01cr@420 7 private:
mas01cr@420 8 unsigned int pointNN;
mas01cr@420 9 unsigned int trackNN;
mas01cr@420 10 std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt> *queues;
mas01cr@420 11 std::set< adb_result_t, adb_result_triple_lt > *set;
mas01cr@420 12 };
mas01cr@420 13
mas01cr@420 14 template <class T> PerTrackAccumulator<T>::PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN)
mas01cr@420 15 : pointNN(pointNN), trackNN(trackNN), queues(0), set(0) {
mas01cr@420 16 queues = new std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt>;
mas01cr@420 17 set = new std::set< adb_result_t, adb_result_triple_lt >;
mas01cr@420 18 }
mas01cr@420 19
mas01cr@420 20 template <class T> PerTrackAccumulator<T>::~PerTrackAccumulator() {
mas01cr@420 21 if(queues) {
mas01cr@420 22 typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_key_lt>::iterator it;
mas01cr@420 23 for(it = queues->begin(); it != queues->end(); it++) {
mas01cr@420 24 delete (*it).second;
mas01cr@420 25 }
mas01cr@420 26 delete queues;
mas01cr@420 27 }
mas01cr@420 28 if(set) {
mas01cr@420 29 delete set;
mas01cr@420 30 }
mas01cr@420 31 }
mas01cr@420 32
mas01cr@420 33 template <class T> void PerTrackAccumulator<T>::add_point(adb_result_t *r) {
mas01cr@420 34 if(!isnan(r->dist)) {
mas01cr@420 35 if(set->find(*r) == set->end()) {
mas01cr@420 36 set->insert(*r);
mas01cr@420 37
mas01cr@420 38 typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_key_lt>::iterator it;
mas01cr@420 39 std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *queue;
mas01cr@420 40 it = queues->find(*r);
mas01cr@420 41 if(it == queues->end()) {
mas01cr@420 42 queue = new std::priority_queue< adb_result_t, std::vector< adb_result_t >, T >;
mas01cr@420 43 (*queues)[*r] = queue;
mas01cr@420 44 } else {
mas01cr@420 45 queue = (*it).second;
mas01cr@420 46 }
mas01cr@420 47
mas01cr@420 48 queue->push(*r);
mas01cr@420 49 if(queue->size() > pointNN) {
mas01cr@420 50 queue->pop();
mas01cr@420 51 }
mas01cr@420 52 }
mas01cr@420 53 }
mas01cr@420 54 }
mas01cr@420 55
mas01cr@420 56 template <class T> adb_query_results_t *PerTrackAccumulator<T>::get_points() {
mas01cr@420 57 typename std::map< adb_result_t, std::vector< adb_result_t >, adb_result_key_lt> points;
mas01cr@420 58 typename std::priority_queue< adb_result_t, std::vector< adb_result_t >, T> queue;
mas01cr@420 59 typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_key_lt>::iterator it;
mas01cr@420 60
mas01cr@420 61 unsigned int size = 0;
mas01cr@420 62 for(it = queues->begin(); it != queues->end(); it++) {
mas01cr@420 63 unsigned int n = ((*it).second)->size();
mas01cr@420 64 std::vector<adb_result_t> v;
mas01cr@420 65 adb_result_t r;
mas01cr@420 66 double dist = 0;
mas01cr@420 67 for(unsigned int k = 0; k < n; k++) {
mas01cr@420 68 r = ((*it).second)->top();
mas01cr@420 69 dist += r.dist;
mas01cr@420 70 v.push_back(r);
mas01cr@420 71 ((*it).second)->pop();
mas01cr@420 72 }
mas01cr@420 73 points[r] = v;
mas01cr@420 74 dist /= n;
mas01cr@420 75 size += n;
mas01cr@420 76 r.dist = dist;
mas01cr@420 77 /* I will burn in hell */
mas01cr@420 78 r.ipos = n;
mas01cr@420 79 queue.push(r);
mas01cr@420 80 if(queue.size() > trackNN) {
mas01cr@420 81 size -= queue.top().ipos;
mas01cr@420 82 queue.pop();
mas01cr@420 83 }
mas01cr@420 84 }
mas01cr@420 85
mas01cr@420 86 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
mas01cr@420 87 adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t));
mas01cr@420 88 r->nresults = size;
mas01cr@420 89 r->results = rs;
mas01cr@420 90
mas01cr@420 91 unsigned int k = 0;
mas01cr@420 92 while(queue.size() > 0) {
mas01cr@420 93 std::vector<adb_result_t> v = points[queue.top()];
mas01cr@420 94 queue.pop();
mas01cr@420 95 while(v.size() > 0) {
mas01cr@420 96 rs[k++] = v.back();
mas01cr@420 97 v.pop_back();
mas01cr@420 98 }
mas01cr@420 99 }
mas01cr@420 100 return r;
mas01cr@420 101 }
mas01cr@420 102