Mercurial > hg > audiodb
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 |