mas01cr@498: template class PerTrackAccumulator : public Accumulator { mas01cr@498: public: mas01cr@498: PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN); mas01cr@498: ~PerTrackAccumulator(); mas01cr@498: void add_point(adb_result_t *r); mas01cr@498: adb_query_results_t *get_points(); mas01cr@498: private: mas01cr@498: unsigned int pointNN; mas01cr@498: unsigned int trackNN; mas01cr@672: std::map, T > *, adb_result_ikey_lt> *queues; mas01cr@498: }; mas01cr@498: mas01cr@498: template PerTrackAccumulator::PerTrackAccumulator(unsigned int pointNN, unsigned int trackNN) mas01cr@610: : pointNN(pointNN), trackNN(trackNN), queues(0) { mas01cr@672: queues = new std::map, T > *, adb_result_ikey_lt>; mas01cr@498: } mas01cr@498: mas01cr@498: template PerTrackAccumulator::~PerTrackAccumulator() { mas01cr@498: if(queues) { mas01cr@672: typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_ikey_lt>::iterator it; mas01cr@498: for(it = queues->begin(); it != queues->end(); it++) { mas01cr@498: delete (*it).second; mas01cr@498: } mas01cr@498: delete queues; mas01cr@498: } mas01cr@498: } mas01cr@498: mas01cr@498: template void PerTrackAccumulator::add_point(adb_result_t *r) { mas01cr@498: if(!isnan(r->dist)) { mas01cr@672: typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_ikey_lt>::iterator it; mas01cr@610: std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *queue; mas01cr@610: it = queues->find(*r); mas01cr@610: if(it == queues->end()) { mas01cr@610: queue = new std::priority_queue< adb_result_t, std::vector< adb_result_t >, T >; mas01cr@610: (*queues)[*r] = queue; mas01cr@610: } else { mas01cr@610: queue = (*it).second; mas01cr@610: } mas01cr@610: mas01cr@610: queue->push(*r); mas01cr@610: if(queue->size() > pointNN) { mas01cr@610: queue->pop(); mas01cr@498: } mas01cr@498: } mas01cr@498: } mas01cr@498: mas01cr@498: template adb_query_results_t *PerTrackAccumulator::get_points() { mas01cr@672: typename std::map< adb_result_t, std::vector< adb_result_t >, adb_result_ikey_lt> points; mas01cr@498: typename std::priority_queue< adb_result_t, std::vector< adb_result_t >, T> queue; mas01cr@672: typename std::map< adb_result_t, std::priority_queue< adb_result_t, std::vector< adb_result_t >, T > *, adb_result_ikey_lt>::iterator it; mas01cr@498: mas01cr@498: unsigned int size = 0; mas01cr@498: for(it = queues->begin(); it != queues->end(); it++) { mas01cr@498: unsigned int n = ((*it).second)->size(); mas01cr@498: std::vector v; mas01cr@498: adb_result_t r; mas01cr@498: double dist = 0; mas01cr@498: for(unsigned int k = 0; k < n; k++) { mas01cr@498: r = ((*it).second)->top(); mas01cr@498: dist += r.dist; mas01cr@498: v.push_back(r); mas01cr@498: ((*it).second)->pop(); mas01cr@498: } mas01cr@498: points[r] = v; mas01cr@498: dist /= n; mas01cr@498: size += n; mas01cr@498: r.dist = dist; mas01cr@498: /* I will burn in hell */ mas01cr@498: r.ipos = n; mas01cr@498: queue.push(r); mas01cr@498: if(queue.size() > trackNN) { mas01cr@498: size -= queue.top().ipos; mas01cr@498: queue.pop(); mas01cr@498: } mas01cr@498: } mas01cr@498: mas01cr@498: adb_query_results_t *r = (adb_query_results_t *) malloc(sizeof(adb_query_results_t)); mas01cr@498: adb_result_t *rs = (adb_result_t *) calloc(size, sizeof(adb_result_t)); mas01cr@498: r->nresults = size; mas01cr@498: r->results = rs; mas01cr@498: mas01cr@498: unsigned int k = 0; mas01cr@498: while(queue.size() > 0) { mas01cr@498: std::vector v = points[queue.top()]; mas01cr@498: queue.pop(); mas01cr@498: while(v.size() > 0) { mas01cr@498: rs[k++] = v.back(); mas01cr@498: v.pop_back(); mas01cr@498: } mas01cr@498: } mas01cr@498: return r; mas01cr@498: } mas01cr@498: