libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 #ifndef MULTI_MAP_CONTAINER_H__ 00029 #define MULTI_MAP_CONTAINER_H__ 00030 00031 #include <string> 00032 #include <vector> 00033 #include <algorithm> 00034 #include <map> 00035 00036 #include "../which.hpp" 00037 #include "policies/dense_hash_map.hpp" 00038 00039 #include "dense_hash_map.hpp" 00040 00041 namespace moost { namespace container { 00042 00043 typedef std::pair<int, int> multimap_value_type; 00044 00045 // ----------------------------------------------------------------------------- 00046 // ----------------------------------------------------------------------------- 00047 00090 template < typename TKey, 00091 typename TVal, 00092 typename TLocMap = moost::container::dense_hash_map<TKey, multimap_value_type > 00093 > 00094 class multi_map 00095 { 00096 private: 00097 00098 typedef multi_map<TKey, TVal, TLocMap> self_type; 00099 00100 public: 00101 00102 typedef TKey first_type; 00103 typedef TVal second_type; 00104 00105 typedef typename 00106 policies::map_policy_selector 00107 < TKey, multimap_value_type, TLocMap>::policy_type loc_map_policy_type; 00108 00109 typedef typename std::vector<TVal>::iterator range_iterator; 00110 typedef typename std::vector<TVal>::const_iterator const_range_iterator; 00111 00112 class range 00113 { 00114 public: 00115 range() {} 00116 range( range_iterator f, range_iterator l ) : first(f), last(l) {} 00117 00118 range_iterator begin() const { return first; } 00119 range_iterator end() const { return last; } 00120 size_t size() const { return last - first; } 00121 bool empty() const { return (last - first) == 0; } 00122 00123 private: 00124 range_iterator first; 00125 range_iterator last; 00126 }; 00127 00128 class const_range 00129 { 00130 public: 00131 00132 const_range() {} 00133 const_range( const_range_iterator f, const_range_iterator l ) : first(f), last(l) {} 00134 const_range( const range& r ) : first(r.begin()), last(r.end()) {} 00135 00136 void operator=( const range& r ) 00137 { first = r.begin(); last = r.end(); } 00138 00139 const_range_iterator begin() const { return first; } 00140 const_range_iterator end() const { return last; } 00141 00142 size_t size() const { return last - first; } 00143 bool empty() const { return (last - first) == 0; } 00144 00145 private: 00146 const_range_iterator first; 00147 const_range_iterator last; 00148 }; 00149 00150 00151 public: 00152 00153 class const_iterator; 00154 00155 class iterator /*: public const_iterator*/ 00156 { 00157 friend class const_iterator; 00158 00159 public: 00160 00161 iterator() : m_pSelf(NULL) {} 00162 iterator( typename TLocMap::iterator it, 00163 typename TLocMap::iterator lastIt, 00164 self_type* pSelf ) 00165 : m_loc_map_it(it), m_pSelf(pSelf) 00166 { 00167 if ( it == lastIt ) 00168 std::make_pair( -1, range(m_pSelf->m_data.end(), m_pSelf->m_data.end()) ); 00169 else 00170 update_iterator(); 00171 } 00172 00173 std::pair<int, range>& operator*() 00174 { 00175 update_iterator(); 00176 return m_it; 00177 } 00178 std::pair<int, range>* operator->() 00179 { 00180 update_iterator(); 00181 return &m_it; 00182 } 00183 00184 iterator& operator++() 00185 { // preincrement 00186 ++m_loc_map_it; 00187 return (*this); 00188 } 00189 00190 iterator& operator--() 00191 { // predecrement 00192 --m_loc_map_it; 00193 return (*this); 00194 } 00195 00196 bool operator!=(const iterator& other) const 00197 { // test for iterator inequality 00198 return other.m_loc_map_it != m_loc_map_it; 00199 } 00200 00201 private: 00202 00203 void update_iterator() 00204 { 00205 m_it.first = m_pSelf->m_locHandlerPolicy.template get_key<int>(m_pSelf->m_locations, m_loc_map_it); 00206 //m_it.first = TLocHandler::get_index(m_pSelf->m_locations, m_loc_map_it); // m_loc_map_it->first 00207 m_it.second = create_range(); 00208 } 00209 00210 range create_range() 00211 { 00212 multimap_value_type loc = m_pSelf->m_locHandlerPolicy.template get_value<multimap_value_type>(m_pSelf->m_locations, m_loc_map_it); 00213 00214 //multimap_value_t loc = TLocHandler::get_location(m_loc_map_it); 00215 return range( m_pSelf->m_data.begin() + loc.first, // start 00216 m_pSelf->m_data.begin() + loc.first + loc.second ); //end 00217 } 00218 00219 std::pair< int, range > m_it; 00220 typename TLocMap::iterator m_loc_map_it; 00221 self_type* m_pSelf; 00222 }; 00223 00224 class const_iterator 00225 { 00226 public: 00227 00228 const_iterator() : m_pSelf(NULL) {} 00229 const_iterator(const iterator& i) 00230 : m_it(i.m_it), 00231 m_loc_map_it(i.m_loc_map_it), 00232 m_pSelf(i.m_pSelf) {} 00233 00234 const_iterator( typename TLocMap::const_iterator it, 00235 typename TLocMap::const_iterator lastIt, 00236 const self_type* pSelf ) 00237 : m_loc_map_it(it), m_pSelf(pSelf) 00238 { 00239 if ( it == lastIt ) 00240 std::make_pair( -1, const_range(m_pSelf->m_data.end(), m_pSelf->m_data.end()) ); 00241 else 00242 update_iterator(); 00243 } 00244 00245 void operator=(const iterator& i) 00246 { m_pSelf = i.m_pSelf; m_it = i.m_it; m_loc_map_it = i.m_loc_map_it; } 00247 00248 std::pair<int, const_range>& operator*() 00249 { 00250 update_iterator(); 00251 return m_it; 00252 } 00253 std::pair<int, const_range>* operator->() 00254 { 00255 update_iterator(); 00256 return &m_it; 00257 } 00258 00259 const_iterator& operator++() 00260 { // preincrement 00261 ++m_loc_map_it; 00262 return (*this); 00263 } 00264 00265 const_iterator& operator--() 00266 { // predecrement 00267 --m_loc_map_it; 00268 return (*this); 00269 } 00270 00271 bool operator!=(const const_iterator& other) const 00272 { // test for iterator inequality 00273 return other.m_loc_map_it != m_loc_map_it; 00274 } 00275 00276 protected: 00277 00278 void update_iterator() 00279 { 00280 m_it.first = m_pSelf->m_locHandlerPolicy.template get_key<int>(m_pSelf->m_locations, m_loc_map_it); // m_loc_map_it->first 00281 //m_it.first = TLocHandler::get_index(m_pSelf->m_locations, m_loc_map_it); // m_loc_map_it->first 00282 m_it.second = create_range(); 00283 } 00284 00285 const_range create_range() 00286 { 00287 multimap_value_type loc = m_pSelf->m_locHandlerPolicy.template get_value<multimap_value_type>(m_pSelf->m_locations, m_loc_map_it); 00288 //multimap_value_t loc = TLocHandler::get_location(m_loc_map_it); 00289 return const_range( m_pSelf->m_data.begin() + loc.first, // start 00290 m_pSelf->m_data.begin() + loc.first + loc.second ); //end 00291 } 00292 00293 std::pair< int, const_range > m_it; 00294 typename TLocMap::const_iterator m_loc_map_it; 00295 const self_type* m_pSelf; 00296 //std::vector<TVal>* m_pData; 00297 }; 00298 00299 00301 00302 iterator begin() { return iterator(m_locations.begin(), m_locations.end(), this); } 00303 const_iterator begin() const { return const_iterator(m_locations.begin(), m_locations.end(), this); } 00304 00305 iterator end() { return iterator(m_locations.end(), m_locations.end(), this); } 00306 const_iterator end() const { return const_iterator(m_locations.end(), m_locations.end(), this); } 00307 00308 public: 00309 00310 multi_map(const loc_map_policy_type& locHandlerPolicy = loc_map_policy_type() ) 00311 : m_locHandlerPolicy(locHandlerPolicy) 00312 { m_locHandlerPolicy.init(m_locations); } 00313 00321 template <int WhichKey, typename Iterator> 00322 void create_map(Iterator first, Iterator last, size_t suggestedSize = 128); 00323 00328 template < typename Iterator, 00329 typename GetKeyPolicy, // int operator()( typename const Entry& e ) 00330 typename GetValuesPolicy > // void operator()( typename const Entry& e, vector<TVal>& vals) 00331 void create_map( Iterator first, Iterator last, 00332 const GetKeyPolicy& getKey, 00333 const GetValuesPolicy& getValues, 00334 size_t suggestedSize = 128 ); 00335 00343 template <int WhichKey, typename TFirst, typename TSecond> 00344 void create_map( std::vector<TFirst, TSecond>& i2i, bool doSort = true); 00345 00346 template <int WhichKey, typename TFirst, typename TSecond> 00347 void create_map_compressed(std::vector<TFirst, TSecond>& i2i, bool doSort = true); 00348 00356 template <int WhichKey, typename Iterator> 00357 void create_map_compressed(Iterator first, Iterator last, size_t suggestedSize = 128); 00358 00359 00360 range operator[](const TKey& key); 00361 const_range operator[](const TKey& key) const; 00362 00364 void clear(); 00365 00367 size_t size() const 00368 { return m_locations.size(); } 00369 00370 bool empty() const 00371 { return m_locations.empty(); } 00372 00373 protected: 00374 00375 TLocMap m_locations; 00376 loc_map_policy_type m_locHandlerPolicy; 00377 //TLocHandler m_locHandler; 00378 std::vector<TVal> m_data; 00379 00380 }; 00381 00382 // ----------------------------------------------------------------------------- 00383 // ----------------------------------------------------------------------------- 00384 00385 template <typename TKey, typename TVal, typename TLocMap> 00386 template <int WhichKey, typename TFirst, typename TSecond> 00387 void multi_map<TKey, TVal, TLocMap>::create_map( std::vector<TFirst, TSecond>& i2i, 00388 bool doSort ) 00389 { 00390 if ( i2i.empty() ) 00391 return; 00392 if ( doSort ) 00393 { 00394 using namespace moost; 00395 typename which<WhichKey>::template comparer<std::less> comparer; 00396 std::stable_sort(i2i.begin(), i2i.end(), comparer ); 00397 } 00398 00399 create_map<WhichKey>( i2i.begin(), i2i.end(), i2i.size() ); 00400 } 00401 00402 // ----------------------------------------------------------------------------- 00403 00404 template <typename TKey, typename TVal, typename TLocMap> 00405 template <int WhichKey, typename Iterator> 00406 void multi_map<TKey, TVal, TLocMap>::create_map( Iterator first, Iterator last, 00407 size_t suggestedSize ) 00408 { 00409 if ( first == last ) 00410 return; 00411 00412 int currPos = 0; 00413 int currSize = 0; 00414 00415 typename moost::which<WhichKey> getKey; 00416 typename moost::which<WhichKey>::other_type getValue; 00417 00418 TKey currKey = getKey(*first); 00419 00420 if ( suggestedSize > 0 ) 00421 m_data.reserve(suggestedSize); 00422 00423 Iterator it; 00424 for ( it = first; it != last; ++it ) 00425 { 00426 if ( currKey != getKey(*it) ) 00427 { 00428 m_locHandlerPolicy.put(m_locations, currKey, std::make_pair(currPos, currSize)); 00429 currKey = getKey(*it); 00430 currPos = static_cast<int>(m_data.size()); 00431 currSize = 0; 00432 } 00433 00434 m_data.push_back( getValue(*it) ); 00435 ++currSize; 00436 } 00437 00438 // last one 00439 m_locHandlerPolicy.put(m_locations, currKey, std::make_pair(currPos, currSize)); 00440 } 00441 00442 // ----------------------------------------------------------------------------- 00443 00444 template <typename TKey, typename TVal, typename TLocMap> 00445 template < typename Iterator, typename GetKeyPolicy, typename GetValuesPolicy > 00446 void multi_map<TKey, TVal, TLocMap>::create_map( Iterator first, 00447 Iterator last, 00448 const GetKeyPolicy& getKey, 00449 const GetValuesPolicy& getValues, 00450 size_t suggestedSize /*= 128 */) 00451 { 00452 if ( suggestedSize > 0 ) 00453 m_data.reserve(suggestedSize); 00454 00455 int currKey; 00456 std::vector<TVal> values; 00457 00458 int entryPos = 0; 00459 int valuesSize; 00460 00461 for ( Iterator it = first; it != last; ++it ) 00462 { 00463 currKey = getKey(*it); 00464 getValues(*it, values); 00465 if ( values.empty() ) 00466 continue; 00467 00468 valuesSize = static_cast<int>(values.size()); 00469 00470 std::copy( values.begin(), values.end(), back_inserter(m_data) ); 00471 m_locHandlerPolicy.put(m_locations, currKey, std::make_pair(entryPos, valuesSize)); 00472 entryPos += valuesSize; 00473 } 00474 } 00475 00476 // ----------------------------------------------------------------------------- 00477 00478 template <typename TKey, typename TVal, typename TLocMap> 00479 template <int WhichKey, typename TFirst, typename TSecond> 00480 void multi_map<TKey, TVal, TLocMap>::create_map_compressed( std::vector<TFirst, TSecond>& i2i, 00481 bool doSort ) 00482 { 00483 if ( i2i.empty() ) 00484 return; 00485 if ( doSort ) 00486 { 00487 using namespace moost; 00488 typename which<WhichKey>::template comparer<std::less> comparer; 00489 std::stable_sort(i2i.begin(), i2i.end(), comparer ); 00490 } 00491 00492 create_map_compressed<WhichKey>( i2i.begin(), i2i.end(), i2i.size() ); 00493 } 00494 00495 // ----------------------------------------------------------------------------- 00496 00497 template <typename TKey, typename TVal, typename TLocMap> 00498 template <int WhichKey, typename Iterator> 00499 void multi_map<TKey, TVal, TLocMap>::create_map_compressed( Iterator first, Iterator last, 00500 size_t suggestedSize ) 00501 { 00502 if ( first == last ) 00503 return; 00504 00505 int currPos = 0; 00506 int currSize = 0; 00507 00508 typename moost::which<WhichKey> getKey; 00509 typename moost::which<WhichKey>::other_type getValue; 00510 00511 TKey currKey = getKey(*first); 00512 00513 if ( suggestedSize > 0 ) 00514 m_data.reserve(suggestedSize); 00515 00516 std::map<TVal, int> compressedLocsMap; 00517 typename std::map<TVal, int>::iterator clIt; 00518 00519 Iterator it; 00520 for ( it = first; it != last; ++it ) 00521 { 00522 if ( currKey != getKey(*it) ) 00523 { 00524 if ( currSize == 1 ) 00525 { 00526 // does it have the given value? 00527 clIt = compressedLocsMap.find( m_data.back() ); 00528 if ( clIt == compressedLocsMap.end() ) 00529 { 00530 // not found! Add it! 00531 compressedLocsMap[m_data.back()] = currPos; 00532 } 00533 else 00534 { 00535 m_data.pop_back(); 00536 currPos = clIt->second; 00537 } 00538 } 00539 00540 m_locHandlerPolicy.put(m_locations, currKey, std::make_pair(currPos, currSize)); 00541 currKey = getKey(*it); 00542 currPos = static_cast<int>(m_data.size()); 00543 currSize = 0; 00544 } 00545 00546 m_data.push_back( getValue(*it) ); 00547 ++currSize; 00548 } 00549 00550 // last one 00551 m_locHandlerPolicy.put(m_locations, currKey, std::make_pair(currPos, currSize)); 00552 } 00553 00554 // ----------------------------------------------------------------------------- 00555 00556 template <typename TKey, typename TVal, typename TLocMap> 00557 typename multi_map<TKey, TVal, TLocMap>::range 00558 multi_map<TKey, TVal, TLocMap>::operator[]( const TKey& key ) 00559 { 00560 multimap_value_type loc; 00561 if ( m_locHandlerPolicy(m_locations, key, loc) ) 00562 { 00563 return range( m_data.begin() + loc.first, // start 00564 m_data.begin() + loc.first + loc.second // end 00565 ); 00566 } 00567 else 00568 { 00569 return range(m_data.end(), m_data.end()); 00570 } 00571 } 00572 00573 // ----------------------------------------------------------------------------- 00574 00575 template <typename TKey, typename TVal, typename TLocMap> 00576 typename multi_map<TKey, TVal, TLocMap>::const_range 00577 multi_map<TKey, TVal, TLocMap>::operator[]( const TKey& key ) const 00578 { 00579 multimap_value_type loc; 00580 if ( m_locHandlerPolicy(m_locations, key, loc) ) 00581 { 00582 return const_range( m_data.begin() + loc.first, // start 00583 m_data.begin() + loc.first + loc.second // end 00584 ); 00585 } 00586 else 00587 { 00588 return const_range(m_data.end(), m_data.end()); 00589 } 00590 } 00591 00592 // ----------------------------------------------------------------------------- 00593 00594 template <typename TKey, typename TVal, typename TLocMap> 00595 void multi_map<TKey, TVal, TLocMap>::clear() 00596 { 00597 m_data.clear(); 00598 m_locations.clear(); 00599 } 00600 00601 // ----------------------------------------------------------------------------- 00602 00603 }} 00604 00605 #endif // MULTI_MAP_CONTAINER_H__ 00606 00607 // -----------------------------------------------------------------------------