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
|