comparison pertrackaccumulator.h @ 420:580f696c817c api-inversion

Split up accumulator.h into multiple files One benefit is the sanity-preserving side-effect of only one class per file; the main reason, though, is so that we can include accumulator.h (the abstract base class) in more than one project file.
author mas01cr
date Wed, 24 Dec 2008 10:54:55 +0000
parents
children e21a3db643af
comparison
equal deleted inserted replaced
419:f3b5d8aebd17 420:580f696c817c
1 template <class T> class PerTrackAccumulator : public Accumulator {
2 public:
3 PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN);
4 ~PerTrackAccumulator();
5 void add_point(adb_result_t *r);
6 adb_query_results_t *get_points();
7 private:
8 unsigned int pointNN;
9 unsigned int trackNN;
10 std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt> *queues;
11 std::set< adb_result_t, adb_result_triple_lt > *set;
12 };
13
14 template <class T> PerTrackAccumulator<T>::PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN)
15 : pointNN(pointNN), trackNN(trackNN), queues(0), set(0) {
16 queues = new std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt>;
17 set = new std::set< adb_result_t, adb_result_triple_lt >;
18 }
19
20 template <class T> PerTrackAccumulator<T>::~PerTrackAccumulator() {
21 if(queues) {
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;
23 for(it = queues->begin(); it != queues->end(); it++) {
24 delete (*it).second;
25 }
26 delete queues;
27 }
28 if(set) {
29 delete set;
30 }
31 }
32
33 template <class T> void PerTrackAccumulator<T>::add_point(adb_result_t *r) {
34 if(!isnan(r->dist)) {
35 if(set->find(*r) == set->end()) {
36 set->insert(*r);
37
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;
39 std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *queue;
40 it = queues->find(*r);
41 if(it == queues->end()) {
42 queue = new std::priority_queue< adb_result_t, std::vector< adb_result_t >, T >;
43 (*queues)[*r] = queue;
44 } else {
45 queue = (*it).second;
46 }
47
48 queue->push(*r);
49 if(queue->size() > pointNN) {
50 queue->pop();
51 }
52 }
53 }
54 }
55
56 template <class T> adb_query_results_t *PerTrackAccumulator<T>::get_points() {
57 typename std::map< adb_result_t, std::vector< adb_result_t >, adb_result_key_lt> points;
58 typename std::priority_queue< adb_result_t, std::vector< adb_result_t >, T> queue;
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;
60
61 unsigned int size = 0;
62 for(it = queues->begin(); it != queues->end(); it++) {
63 unsigned int n = ((*it).second)->size();
64 std::vector<adb_result_t> v;
65 adb_result_t r;
66 double dist = 0;
67 for(unsigned int k = 0; k < n; k++) {
68 r = ((*it).second)->top();
69 dist += r.dist;
70 v.push_back(r);
71 ((*it).second)->pop();
72 }
73 points[r] = v;
74 dist /= n;
75 size += n;
76 r.dist = dist;
77 /* I will burn in hell */
78 r.ipos = n;
79 queue.push(r);
80 if(queue.size() > trackNN) {
81 size -= queue.top().ipos;
82 queue.pop();
83 }
84 }
85
86 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
87 adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t));
88 r->nresults = size;
89 r->results = rs;
90
91 unsigned int k = 0;
92 while(queue.size() > 0) {
93 std::vector<adb_result_t> v = points[queue.top()];
94 queue.pop();
95 while(v.size() > 0) {
96 rs[k++] = v.back();
97 v.pop_back();
98 }
99 }
100 return r;
101 }
102