annotate pertrackaccumulator.h @ 601:82d23418d867

Fix some fd leaks in the command-line binary Strictly speaking, they're not really leaks, because the only codepath that suffers from these leaks exits immediately afterwards. On the other hand, this fix makes valgrind on e.g. tests/0025 happier, going from 5 errors to none.
author mas01cr
date Fri, 14 Aug 2009 16:39:32 +0000
parents 342822c2d49a
children e21a3db643af
rev   line source
mas01cr@498 1 template <class T> class PerTrackAccumulator : public Accumulator {
mas01cr@498 2 public:
mas01cr@498 3 PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN);
mas01cr@498 4 ~PerTrackAccumulator();
mas01cr@498 5 void add_point(adb_result_t *r);
mas01cr@498 6 adb_query_results_t *get_points();
mas01cr@498 7 private:
mas01cr@498 8 unsigned int pointNN;
mas01cr@498 9 unsigned int trackNN;
mas01cr@498 10 std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt> *queues;
mas01cr@498 11 std::set< adb_result_t, adb_result_triple_lt > *set;
mas01cr@498 12 };
mas01cr@498 13
mas01cr@498 14 template <class T> PerTrackAccumulator<T>::PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN)
mas01cr@498 15 : pointNN(pointNN), trackNN(trackNN), queues(0), set(0) {
mas01cr@498 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@498 17 set = new std::set< adb_result_t, adb_result_triple_lt >;
mas01cr@498 18 }
mas01cr@498 19
mas01cr@498 20 template <class T> PerTrackAccumulator<T>::~PerTrackAccumulator() {
mas01cr@498 21 if(queues) {
mas01cr@498 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@498 23 for(it = queues->begin(); it != queues->end(); it++) {
mas01cr@498 24 delete (*it).second;
mas01cr@498 25 }
mas01cr@498 26 delete queues;
mas01cr@498 27 }
mas01cr@498 28 if(set) {
mas01cr@498 29 delete set;
mas01cr@498 30 }
mas01cr@498 31 }
mas01cr@498 32
mas01cr@498 33 template <class T> void PerTrackAccumulator<T>::add_point(adb_result_t *r) {
mas01cr@498 34 if(!isnan(r->dist)) {
mas01cr@498 35 if(set->find(*r) == set->end()) {
mas01cr@498 36 set->insert(*r);
mas01cr@498 37
mas01cr@498 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@498 39 std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *queue;
mas01cr@498 40 it = queues->find(*r);
mas01cr@498 41 if(it == queues->end()) {
mas01cr@498 42 queue = new std::priority_queue< adb_result_t, std::vector< adb_result_t >, T >;
mas01cr@498 43 (*queues)[*r] = queue;
mas01cr@498 44 } else {
mas01cr@498 45 queue = (*it).second;
mas01cr@498 46 }
mas01cr@498 47
mas01cr@498 48 queue->push(*r);
mas01cr@498 49 if(queue->size() > pointNN) {
mas01cr@498 50 queue->pop();
mas01cr@498 51 }
mas01cr@498 52 }
mas01cr@498 53 }
mas01cr@498 54 }
mas01cr@498 55
mas01cr@498 56 template <class T> adb_query_results_t *PerTrackAccumulator<T>::get_points() {
mas01cr@498 57 typename std::map< adb_result_t, std::vector< adb_result_t >, adb_result_key_lt> points;
mas01cr@498 58 typename std::priority_queue< adb_result_t, std::vector< adb_result_t >, T> queue;
mas01cr@498 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@498 60
mas01cr@498 61 unsigned int size = 0;
mas01cr@498 62 for(it = queues->begin(); it != queues->end(); it++) {
mas01cr@498 63 unsigned int n = ((*it).second)->size();
mas01cr@498 64 std::vector<adb_result_t> v;
mas01cr@498 65 adb_result_t r;
mas01cr@498 66 double dist = 0;
mas01cr@498 67 for(unsigned int k = 0; k < n; k++) {
mas01cr@498 68 r = ((*it).second)->top();
mas01cr@498 69 dist += r.dist;
mas01cr@498 70 v.push_back(r);
mas01cr@498 71 ((*it).second)->pop();
mas01cr@498 72 }
mas01cr@498 73 points[r] = v;
mas01cr@498 74 dist /= n;
mas01cr@498 75 size += n;
mas01cr@498 76 r.dist = dist;
mas01cr@498 77 /* I will burn in hell */
mas01cr@498 78 r.ipos = n;
mas01cr@498 79 queue.push(r);
mas01cr@498 80 if(queue.size() > trackNN) {
mas01cr@498 81 size -= queue.top().ipos;
mas01cr@498 82 queue.pop();
mas01cr@498 83 }
mas01cr@498 84 }
mas01cr@498 85
mas01cr@498 86 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
mas01cr@498 87 adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t));
mas01cr@498 88 r->nresults = size;
mas01cr@498 89 r->results = rs;
mas01cr@498 90
mas01cr@498 91 unsigned int k = 0;
mas01cr@498 92 while(queue.size() > 0) {
mas01cr@498 93 std::vector<adb_result_t> v = points[queue.top()];
mas01cr@498 94 queue.pop();
mas01cr@498 95 while(v.size() > 0) {
mas01cr@498 96 rs[k++] = v.back();
mas01cr@498 97 v.pop_back();
mas01cr@498 98 }
mas01cr@498 99 }
mas01cr@498 100 return r;
mas01cr@498 101 }
mas01cr@498 102