mas01cr@416
|
1 #include <string>
|
mas01cr@416
|
2 #include <set>
|
mas01cr@416
|
3 #include <queue>
|
mas01cr@416
|
4 #include <map>
|
mas01cr@416
|
5 #include <functional>
|
mas01cr@416
|
6 #include "audioDB.h"
|
mas01cr@416
|
7 extern "C" {
|
mas01cr@416
|
8 #include "audioDB_API.h"
|
mas01cr@416
|
9 }
|
mas01cr@416
|
10 #include "audioDB-internals.h"
|
mas01cr@416
|
11
|
mas01cr@416
|
12 #ifndef ACCUMULATOR_H
|
mas01cr@416
|
13 #define ACCUMULATOR_H
|
mas01cr@416
|
14
|
mas01cr@416
|
15 class Accumulator {
|
mas01cr@416
|
16 public:
|
mas01cr@416
|
17 virtual ~Accumulator() {};
|
mas01cr@416
|
18 virtual void add_point(adb_result_t *r) = 0;
|
mas01cr@416
|
19 virtual adb_query_results_t *get_points() = 0;
|
mas01cr@416
|
20 };
|
mas01cr@416
|
21
|
mas01cr@416
|
22 template <class T> class DBAccumulator : public Accumulator {
|
mas01cr@416
|
23 public:
|
mas01cr@416
|
24 DBAccumulator(unsigned int pointNN);
|
mas01cr@416
|
25 ~DBAccumulator();
|
mas01cr@416
|
26 void add_point(adb_result_t *r);
|
mas01cr@416
|
27 adb_query_results_t *get_points();
|
mas01cr@416
|
28 private:
|
mas01cr@416
|
29 unsigned int pointNN;
|
mas01cr@416
|
30 std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *queue;
|
mas01cr@416
|
31 std::set< adb_result_t, adb_result_triple_lt > *set;
|
mas01cr@416
|
32 };
|
mas01cr@416
|
33
|
mas01cr@416
|
34 template <class T> DBAccumulator<T>::DBAccumulator(unsigned int pointNN)
|
mas01cr@416
|
35 : pointNN(pointNN), queue(0), set(0) {
|
mas01cr@416
|
36 queue = new std::priority_queue< adb_result_t, std::vector<adb_result_t>, T>;
|
mas01cr@416
|
37 set = new std::set<adb_result_t, adb_result_triple_lt>;
|
mas01cr@416
|
38 }
|
mas01cr@416
|
39
|
mas01cr@416
|
40 template <class T> DBAccumulator<T>::~DBAccumulator() {
|
mas01cr@416
|
41 if(queue) {
|
mas01cr@416
|
42 delete queue;
|
mas01cr@416
|
43 }
|
mas01cr@416
|
44 if(set) {
|
mas01cr@416
|
45 delete set;
|
mas01cr@416
|
46 }
|
mas01cr@416
|
47 }
|
mas01cr@416
|
48
|
mas01cr@416
|
49 template <class T> void DBAccumulator<T>::add_point(adb_result_t *r) {
|
mas01cr@416
|
50 if(!isnan(r->dist)) {
|
mas01cr@416
|
51 if(set->find(*r) == set->end()) {
|
mas01cr@416
|
52 set->insert(*r);
|
mas01cr@416
|
53 queue->push(*r);
|
mas01cr@416
|
54 if(queue->size() > pointNN) {
|
mas01cr@416
|
55 queue->pop();
|
mas01cr@416
|
56 }
|
mas01cr@416
|
57 }
|
mas01cr@416
|
58 }
|
mas01cr@416
|
59 }
|
mas01cr@416
|
60
|
mas01cr@416
|
61 template <class T> adb_query_results_t *DBAccumulator<T>::get_points() {
|
mas01cr@416
|
62 unsigned int size = queue->size();
|
mas01cr@416
|
63 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
|
mas01cr@416
|
64 adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t));
|
mas01cr@416
|
65 r->nresults = size;
|
mas01cr@416
|
66 r->results = rs;
|
mas01cr@416
|
67
|
mas01cr@416
|
68 for(unsigned int k = 0; k < size; k++) {
|
mas01cr@416
|
69 rs[k] = queue->top();
|
mas01cr@416
|
70 queue->pop();
|
mas01cr@416
|
71 }
|
mas01cr@416
|
72 return r;
|
mas01cr@416
|
73 }
|
mas01cr@416
|
74
|
mas01cr@416
|
75 template <class T> class PerTrackAccumulator : public Accumulator {
|
mas01cr@416
|
76 public:
|
mas01cr@416
|
77 PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN);
|
mas01cr@416
|
78 ~PerTrackAccumulator();
|
mas01cr@416
|
79 void add_point(adb_result_t *r);
|
mas01cr@416
|
80 adb_query_results_t *get_points();
|
mas01cr@416
|
81 private:
|
mas01cr@416
|
82 unsigned int pointNN;
|
mas01cr@416
|
83 unsigned int trackNN;
|
mas01cr@416
|
84 std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt> *queues;
|
mas01cr@416
|
85 std::set< adb_result_t, adb_result_triple_lt > *set;
|
mas01cr@416
|
86 };
|
mas01cr@416
|
87
|
mas01cr@416
|
88 template <class T> PerTrackAccumulator<T>::PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN)
|
mas01cr@416
|
89 : pointNN(pointNN), trackNN(trackNN), queues(0), set(0) {
|
mas01cr@416
|
90 queues = new std::map<adb_result_t, std::priority_queue< adb_result_t, std::vector<adb_result_t>, T > *, adb_result_key_lt>;
|
mas01cr@416
|
91 set = new std::set< adb_result_t, adb_result_triple_lt >;
|
mas01cr@416
|
92 }
|
mas01cr@416
|
93
|
mas01cr@416
|
94 template <class T> PerTrackAccumulator<T>::~PerTrackAccumulator() {
|
mas01cr@416
|
95 if(queues) {
|
mas01cr@416
|
96 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@416
|
97 for(it = queues->begin(); it != queues->end(); it++) {
|
mas01cr@416
|
98 delete (*it).second;
|
mas01cr@416
|
99 }
|
mas01cr@416
|
100 delete queues;
|
mas01cr@416
|
101 }
|
mas01cr@416
|
102 if(set) {
|
mas01cr@416
|
103 delete set;
|
mas01cr@416
|
104 }
|
mas01cr@416
|
105 }
|
mas01cr@416
|
106
|
mas01cr@416
|
107 template <class T> void PerTrackAccumulator<T>::add_point(adb_result_t *r) {
|
mas01cr@416
|
108 if(!isnan(r->dist)) {
|
mas01cr@416
|
109 if(set->find(*r) == set->end()) {
|
mas01cr@416
|
110 set->insert(*r);
|
mas01cr@416
|
111
|
mas01cr@416
|
112 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@416
|
113 std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *queue;
|
mas01cr@416
|
114 it = queues->find(*r);
|
mas01cr@416
|
115 if(it == queues->end()) {
|
mas01cr@416
|
116 queue = new std::priority_queue< adb_result_t, std::vector< adb_result_t >, T >;
|
mas01cr@416
|
117 (*queues)[*r] = queue;
|
mas01cr@416
|
118 } else {
|
mas01cr@416
|
119 queue = (*it).second;
|
mas01cr@416
|
120 }
|
mas01cr@416
|
121
|
mas01cr@416
|
122 queue->push(*r);
|
mas01cr@416
|
123 if(queue->size() > pointNN) {
|
mas01cr@416
|
124 queue->pop();
|
mas01cr@416
|
125 }
|
mas01cr@416
|
126 }
|
mas01cr@416
|
127 }
|
mas01cr@416
|
128 }
|
mas01cr@416
|
129
|
mas01cr@416
|
130 template <class T> adb_query_results_t *PerTrackAccumulator<T>::get_points() {
|
mas01cr@416
|
131 typename std::map< adb_result_t, std::vector< adb_result_t >, adb_result_key_lt> points;
|
mas01cr@416
|
132 typename std::priority_queue< adb_result_t, std::vector< adb_result_t >, T> queue;
|
mas01cr@416
|
133 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@416
|
134
|
mas01cr@416
|
135 unsigned int size = 0;
|
mas01cr@416
|
136 for(it = queues->begin(); it != queues->end(); it++) {
|
mas01cr@416
|
137 unsigned int n = ((*it).second)->size();
|
mas01cr@416
|
138 std::vector<adb_result_t> v;
|
mas01cr@416
|
139 adb_result_t r;
|
mas01cr@416
|
140 double dist = 0;
|
mas01cr@416
|
141 for(unsigned int k = 0; k < n; k++) {
|
mas01cr@416
|
142 r = ((*it).second)->top();
|
mas01cr@416
|
143 dist += r.dist;
|
mas01cr@416
|
144 v.push_back(r);
|
mas01cr@416
|
145 ((*it).second)->pop();
|
mas01cr@416
|
146 }
|
mas01cr@416
|
147 points[r] = v;
|
mas01cr@416
|
148 dist /= n;
|
mas01cr@416
|
149 size += n;
|
mas01cr@416
|
150 r.dist = dist;
|
mas01cr@416
|
151 /* I will burn in hell */
|
mas01cr@416
|
152 r.ipos = n;
|
mas01cr@416
|
153 queue.push(r);
|
mas01cr@416
|
154 if(queue.size() > trackNN) {
|
mas01cr@416
|
155 size -= queue.top().ipos;
|
mas01cr@416
|
156 queue.pop();
|
mas01cr@416
|
157 }
|
mas01cr@416
|
158 }
|
mas01cr@416
|
159
|
mas01cr@416
|
160 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
|
mas01cr@416
|
161 adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t));
|
mas01cr@416
|
162 r->nresults = size;
|
mas01cr@416
|
163 r->results = rs;
|
mas01cr@416
|
164
|
mas01cr@416
|
165 unsigned int k = 0;
|
mas01cr@416
|
166 while(queue.size() > 0) {
|
mas01cr@416
|
167 std::vector<adb_result_t> v = points[queue.top()];
|
mas01cr@416
|
168 queue.pop();
|
mas01cr@416
|
169 while(v.size() > 0) {
|
mas01cr@416
|
170 rs[k++] = v.back();
|
mas01cr@416
|
171 v.pop_back();
|
mas01cr@416
|
172 }
|
mas01cr@416
|
173 }
|
mas01cr@416
|
174 return r;
|
mas01cr@416
|
175 }
|
mas01cr@416
|
176
|
mas01cr@416
|
177 template <class T> class NearestAccumulator : public Accumulator {
|
mas01cr@416
|
178 public:
|
mas01cr@416
|
179 NearestAccumulator();
|
mas01cr@416
|
180 ~NearestAccumulator();
|
mas01cr@416
|
181 void add_point(adb_result_t *r);
|
mas01cr@416
|
182 adb_query_results_t *get_points();
|
mas01cr@416
|
183 private:
|
mas01cr@416
|
184 std::set< adb_result_t, adb_result_triple_lt > *set;
|
mas01cr@416
|
185 std::set< adb_result_t, adb_result_qpos_lt > *points;
|
mas01cr@416
|
186 };
|
mas01cr@416
|
187
|
mas01cr@416
|
188 template <class T> NearestAccumulator<T>::NearestAccumulator()
|
mas01cr@416
|
189 : set(0), points(0) {
|
mas01cr@416
|
190 set = new std::set< adb_result_t, adb_result_triple_lt >;
|
mas01cr@416
|
191 points = new std::set< adb_result_t, adb_result_qpos_lt >;
|
mas01cr@416
|
192 }
|
mas01cr@416
|
193
|
mas01cr@416
|
194 template <class T> NearestAccumulator<T>::~NearestAccumulator() {
|
mas01cr@416
|
195 if(set) {
|
mas01cr@416
|
196 delete set;
|
mas01cr@416
|
197 }
|
mas01cr@416
|
198 if(points) {
|
mas01cr@416
|
199 delete points;
|
mas01cr@416
|
200 }
|
mas01cr@416
|
201 }
|
mas01cr@416
|
202
|
mas01cr@416
|
203 template <class T> void NearestAccumulator<T>::add_point(adb_result_t *r) {
|
mas01cr@416
|
204 if(!isnan(r->dist)) {
|
mas01cr@416
|
205 if(set->find(*r) == set->end()) {
|
mas01cr@416
|
206 set->insert(*r);
|
mas01cr@416
|
207
|
mas01cr@416
|
208 std::set< adb_result_t, adb_result_qpos_lt >::iterator it;
|
mas01cr@416
|
209 it = points->find(*r);
|
mas01cr@416
|
210 if(it == points->end()) {
|
mas01cr@416
|
211 points->insert(*r);
|
mas01cr@416
|
212 } else if(T()(*(const adb_result_t *)r,(*it))) {
|
mas01cr@416
|
213 points->erase(it);
|
mas01cr@416
|
214 points->insert(*r);
|
mas01cr@416
|
215 }
|
mas01cr@416
|
216 }
|
mas01cr@416
|
217 }
|
mas01cr@416
|
218 }
|
mas01cr@416
|
219
|
mas01cr@416
|
220 template <class T> adb_query_results_t *NearestAccumulator<T>::get_points() {
|
mas01cr@416
|
221 unsigned int nresults = points->size();
|
mas01cr@416
|
222 adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t));
|
mas01cr@416
|
223 adb_result_t *rs = (adb_result_t *) calloc(nresults, sizeof(adb_result_t));
|
mas01cr@416
|
224 r->nresults = nresults;
|
mas01cr@416
|
225 r->results = rs;
|
mas01cr@416
|
226 std::set< adb_result_t, adb_result_qpos_lt >::iterator it;
|
mas01cr@416
|
227 unsigned int k = 0;
|
mas01cr@416
|
228 for(it = points->begin(); it != points->end(); it++) {
|
mas01cr@416
|
229 rs[k++] = *it;
|
mas01cr@416
|
230 }
|
mas01cr@416
|
231 return r;
|
mas01cr@416
|
232 }
|
mas01cr@416
|
233
|
mas01cr@416
|
234 #endif
|