annotate accumulator.h @ 419:f3b5d8aebd17 api-inversion

Map out "new" audiodb_query() API.
author mas01cr
date Wed, 24 Dec 2008 10:54:51 +0000
parents 6e6f4c1cc14d
children 580f696c817c
rev   line source
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