MultiIndex
ordered_lists_merger.h
Go to the documentation of this file.
00001 
00002 // Copyright 2012 Yandex Artem Babenko
00003 #pragma once
00004 
00005 #include "data_util.h"
00006 #include "multitable.hpp"
00007 
00012 typedef vector<int> MergedItemIndices;
00013 
00022 template<class OrderType, class MetaInfo>
00023 class OrderedListsMerger {
00024  public:
00028   OrderedListsMerger();
00033   void setLists(const vector<vector<pair<OrderType, MetaInfo> > >& lists);
00039   inline bool GetNextMergedItemIndices(MergedItemIndices* merged_item_indices);
00043   const vector<vector<pair<OrderType, MetaInfo> > >* lists_ptr;
00047   Multitable<char>& GetYieldedItems() {
00048     return yielded_items_indices_;
00049   }
00050  private:
00055   void InsertMergedItemIndicesInHeap(const MergedItemIndices& merged_item_indices);
00060   void UpdatePrioirityQueue(MergedItemIndices& merged_item_indices);
00064   multimap<OrderType, MergedItemIndices> heap_;
00068   Multitable<char> yielded_items_indices_;
00069 };
00070 
00072 
00073 template<class OrderType, class MetaInfo>
00074 OrderedListsMerger<OrderType, MetaInfo>::OrderedListsMerger() {
00075 }
00076 
00077 template<class OrderType, class MetaInfo>
00078 void OrderedListsMerger<OrderType, MetaInfo>::InsertMergedItemIndicesInHeap(const MergedItemIndices& merged_item_indices) {
00079   OrderType sum = 0;
00080   for(int list_index = 0; list_index < lists_ptr->size(); ++list_index) {
00081     sum += lists_ptr->at(list_index)[merged_item_indices[list_index]].first;
00082   }
00083   heap_.insert(std::make_pair(sum, merged_item_indices));
00084 }
00085 
00086 template<class OrderType, class MetaInfo>
00087 void OrderedListsMerger<OrderType, MetaInfo>::setLists(const vector<vector<pair<OrderType, MetaInfo> > >& lists) {
00088   lists_ptr = &lists;
00089   heap_.clear();
00090   MergedItemIndices first_item_indices(lists.size());
00091   for(int list_index = 0; list_index < lists.size(); ++list_index) {
00092     first_item_indices[list_index] = 0;
00093   }
00094   memset(&(yielded_items_indices_.table[0]), 0, yielded_items_indices_.table.size());
00095   InsertMergedItemIndicesInHeap(first_item_indices);
00096 }
00097 
00098 template<class OrderType, class MetaInfo>
00099 void OrderedListsMerger<OrderType, MetaInfo>::UpdatePrioirityQueue(MergedItemIndices& merged_item_indices) {
00100   for(int list_index = 0; list_index < lists_ptr->size(); ++list_index) {
00101     if(merged_item_indices[list_index] >= lists_ptr->at(list_index).size()) {
00102       return;
00103     }
00104     int current_index = merged_item_indices[list_index];
00105     merged_item_indices[list_index] -= 1;
00106     if(current_index > 0 && !yielded_items_indices_.GetValue(merged_item_indices)) {
00107       merged_item_indices[list_index] += 1;
00108       return;
00109     } else {
00110       merged_item_indices[list_index] += 1;
00111     }
00112   }
00113   InsertMergedItemIndicesInHeap(merged_item_indices);
00114 }
00115 
00116 template<class OrderType, class MetaInfo>
00117 inline bool OrderedListsMerger<OrderType, MetaInfo>::GetNextMergedItemIndices(MergedItemIndices* next_merged_item_indices) {
00118   if(heap_.empty()) {
00119     return false;
00120   }
00121   *next_merged_item_indices = heap_.begin()->second;
00122   yielded_items_indices_.SetValue(1, *next_merged_item_indices);
00123   for(int list_index = 0; list_index < lists_ptr->size(); ++list_index) {
00124     next_merged_item_indices->at(list_index) += 1;
00125     UpdatePrioirityQueue(*next_merged_item_indices);
00126     next_merged_item_indices->at(list_index) -= 1;
00127   }
00128   heap_.erase(heap_.begin());
00129   return true;
00130 }
00131 
00132 template class OrderedListsMerger<Distance, PointId>;
00133 template class OrderedListsMerger<Distance, pair<ClusterId, ClusterId> >;
 All Classes Files Functions Variables Typedefs Enumerations Enumerator