00001 #ifndef DFDecoderWithEEManagement_HPP 00002 #define DFDecoderWithEEManagement_HPP 00003 00030 #include "CacheDFDecoder.hpp" 00031 00032 #include "common/debug.hpp" 00033 #include <vector> 00034 #include <iostream> 00035 #include <iterator> 00036 #include "io/output/OutputBase.hpp" 00037 00038 template <class DF = CacheDFDecoder< > > 00039 class DFDecoderWithEEManagement : public DF 00040 { 00041 public: 00042 00043 typedef typename DF::params_t params_t; 00044 00045 DFDecoderWithEEManagement(const params_t* par) : 00046 DF(par) 00047 { 00048 ee_buffer_segment_length.push_back(0); 00049 } 00050 00051 size_t nrOfEEItems() const 00052 { 00053 return ee_buffer.size(); 00054 } 00055 bool EEListEmpty() const 00056 { 00057 return ee_buffer.empty(); 00058 } 00065 void pushItem(item_t item) 00066 { 00067 #if DEBUG_LEVEL >= LEVEL_DBG 00068 std::cout << "pushItem " << item << std::endl; 00069 #endif 00070 DF::pushItem(item); 00071 ee_buffer_segment_length.push_back(0); 00072 } 00073 00077 void popItem() 00078 { 00079 #if DEBUG_LEVEL >= LEVEL_DBG 00080 //assert(ee_buffer_segment_length.size()>0); 00081 std::cout << "popItem " << ee_buffer_segment_length.size() << " and "; 00082 #endif 00083 // popEquisupportItems(ee_buffer_segment_length.back()); 00084 popEquisupportItems(ee_buffer_segment_length.back()); 00085 DF::popItem(); 00086 ee_buffer_segment_length.pop_back(); 00087 } 00088 00092 void pushEquisupportItem(item_t item); 00093 00097 void pushEquisupportItemSet(const std::vector<item_t>& itemset); 00098 00099 00104 void write(counter_t support) { 00105 // as is -- w./o. any ee-extension (= empty ee set): 00106 DF::write(support); 00107 write1(); 00108 } 00109 00110 00117 void pushItemWithPrevSupport(item_t item) { 00118 // as is -- w./o. any ee-extension (= empty ee set): 00119 DF::pushItemWithPrevSupport(item); 00120 ee_buffer_segment_length.push_back(0); 00121 write1(); 00122 } 00123 00128 void pushItemWithWrite(item_t item, counter_t support) 00129 { 00130 pushItem(item); 00131 write(support); 00132 } 00133 00137 class EquisupportItemOutputIterator { 00138 public: 00139 EquisupportItemOutputIterator(DFDecoderWithEEManagement& decoder) : decoder(decoder) {} 00140 EquisupportItemOutputIterator& operator= (const item_t item) { decoder.pushEquisupportItem(item); return *this; } 00141 EquisupportItemOutputIterator& operator* () { return *this; } 00142 EquisupportItemOutputIterator& operator++ () { return *this; } 00143 EquisupportItemOutputIterator& operator++ (int) { return *this; } 00144 private: 00145 DFDecoderWithEEManagement& decoder; 00146 }; 00147 00148 private: 00150 std::vector<item_t> ee_buffer; 00151 00155 std::vector<size_t> ee_buffer_segment_length; 00156 00157 00161 void write1(); 00162 00166 void popEquisupportItem(); 00167 00171 void popEquisupportItems(int numEEItems); 00172 00173 }; 00174 00175 00176 template <class DF> inline void DFDecoderWithEEManagement<DF>:: 00177 pushEquisupportItem(item_t item) 00178 { 00179 #if DEBUG_LEVEL >= LEVEL_DBG 00180 std::cout << "pushEE " << item << std::endl; 00181 #endif 00182 ee_buffer_segment_length.back()++; 00183 ee_buffer.push_back(item); 00184 } 00185 00186 template <class DF> inline void DFDecoderWithEEManagement<DF>:: 00187 pushEquisupportItemSet(const std::vector<item_t>& itemset) 00188 { 00189 #if DEBUG_LEVEL >= LEVEL_DBG 00190 std::cout<< "pushEEItemset "<<std::endl; 00191 std::copy( itemset.begin(), itemset.end(), 00192 std::ostream_iterator<item_t>(std::cout, " ")); 00193 std::cout<<std::endl; 00194 #endif 00195 ee_buffer_segment_length.back()+=itemset.size(); 00196 ee_buffer.insert(ee_buffer.end(), itemset.begin(), itemset.end() ); 00197 } 00198 00199 template <class DF> inline void DFDecoderWithEEManagement<DF>:: 00200 popEquisupportItem() 00201 { 00202 assert(!ee_buffer.empty()); 00203 #if DEBUG_LEVEL >= LEVEL_DBG 00204 std::cout << "popEE " << ee_buffer.back() << std::endl; 00205 #endif 00206 ee_buffer.pop_back(); 00207 ee_buffer_segment_length.back()--; 00208 } 00209 00210 template <class DF> inline void DFDecoderWithEEManagement<DF>:: 00211 popEquisupportItems(int numEEItems) 00212 { 00213 assert(int(ee_buffer.size()) >= numEEItems); 00214 #if DEBUG_LEVEL >= LEVEL_DBG 00215 std::cout << "popEEs "; 00216 if (numEEItems == 0) 00217 std::cout << "[empty]"; 00218 for(int i = 0; i < numEEItems; i++) 00219 std::cout << ee_buffer[ee_buffer.size()-1-i] << " "; 00220 std::cout << " [" << numEEItems << "]" << std::endl; 00221 #endif 00222 ee_buffer.resize(ee_buffer.size() - numEEItems); 00223 ee_buffer_segment_length.back() -= numEEItems; 00224 } 00225 00226 00227 00228 template <class DF> inline void DFDecoderWithEEManagement<DF>:: 00229 write1() 00230 { 00232 std::vector<item_t>::size_type ee_buffer_length = ee_buffer.size(); 00233 00234 if (ee_buffer_length == 0) 00235 return; 00236 00237 std::vector<bool> isMember(ee_buffer_length, false); 00238 00239 00240 00241 // set only containing (numItems-1) 00242 isMember[ee_buffer_length-1] = true; 00243 DF::pushItemWithPrevSupport(ee_buffer[ee_buffer_length-1]); 00244 DF::popItem(); 00245 00246 int pos = ee_buffer_length-2; 00247 00248 while (pos >= 0) { 00249 // a. subset containing ee_buffer[pos] but items with larger ee-index: 00250 isMember[pos] = true; 00251 DF::pushItemWithPrevSupport(ee_buffer[pos]); 00252 00253 // b. add item (numItems-1): 00254 DF::pushItemWithPrevSupport(ee_buffer[ee_buffer_length-1]); 00255 00256 // c. search next non-member (and remove all items on our way): 00257 pos = ee_buffer_length-2; 00258 while (pos >= 0 && isMember[pos]) { 00259 isMember[pos] = false; 00260 pos--; 00261 } 00262 // popEquisupportItems(ee_buffer_length-1 - pos); 00263 for (int i = ee_buffer_length-1 - pos; i > 0; i--) 00264 DF::popItem(); 00265 } 00266 } 00267 00268 #endif