libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 // TODO: compression has not been tested yet! 00029 00030 #include <boost/test/unit_test.hpp> 00031 #include <boost/test/test_tools.hpp> 00032 #include <boost/cstdint.hpp> 00033 00034 #include <vector> 00035 #include <map> 00036 #include <set> 00037 00038 #include "../../include/moost/container/multi_map.hpp" 00039 00040 #include "../../include/moost/container/policies/dense_hash_map.hpp" 00041 #include "../../include/moost/container/policies/sparse_hash_map.hpp" 00042 #include "../../include/moost/container/policies/vector_map.hpp" 00043 00044 using namespace moost::container; 00045 using namespace std; 00046 00047 BOOST_AUTO_TEST_SUITE( multi_map_test ) 00048 00049 template <typename TMultiMap> 00050 struct Fixture_generic 00051 { 00052 typedef TMultiMap multi_map_type; 00053 00054 template< int WhichKey, typename TKey, typename TVal > 00055 void create_data(multi_map_type& map, TKey num_keys, TVal num_val) 00056 { 00057 00058 vector< pair<TKey, TVal> > vec; 00059 00060 if ( WhichKey == 1 ) 00061 { 00062 for ( TKey k = 0; k < num_keys; ++k ) 00063 { 00064 for ( TVal v = 0; v < num_val; ++v ) 00065 vec.push_back( make_pair(k, v) ); 00066 } 00067 } 00068 else 00069 { 00070 for ( TVal v = 0; v < num_val; ++v ) 00071 { 00072 for ( TKey k = 0; k < num_keys; ++k ) 00073 vec.push_back( make_pair(k, v) ); 00074 } 00075 } 00076 00077 map.template create_map<WhichKey>(vec); 00078 } 00079 00080 void check_map( multi_map_type& map, 00081 typename multi_map_type::first_type num_keys, 00082 typename multi_map_type::second_type num_val) 00083 { 00084 // how many keys? 00085 BOOST_CHECK_EQUAL( map.size(), num_keys ); 00086 00087 std::set<typename multi_map_type::first_type> retrieved_keys; 00088 typename std::set<typename multi_map_type::first_type>::const_iterator rkIt; 00089 00090 typename multi_map_type::first_type key; 00091 typename multi_map_type::second_type val; 00092 00093 // const 00094 { 00095 const multi_map_type& cmap = map; // take a const to simulate passing by const 00096 00097 // try to get a key that does NOT exist 00098 typename multi_map_type::const_range rt = cmap[num_keys+1]; 00099 BOOST_CHECK( rt.empty() ); // not found! 00100 00101 typename multi_map_type::const_range_iterator cmRangeIt; 00102 typename multi_map_type::second_type val; 00103 00104 // checking getting a range from key 00105 for ( typename multi_map_type::first_type k = 0; k < num_keys; ++k ) 00106 { 00107 // get the range for key 'k' 00108 rt = cmap[k]; 00109 BOOST_CHECK( !rt.empty() ); 00110 BOOST_CHECK_EQUAL( rt.size(), num_val ); 00111 00112 val = 0; 00113 // check each value associated to key 'k' 00114 for ( cmRangeIt = rt.begin(); cmRangeIt != rt.end(); ++cmRangeIt, ++val ) 00115 BOOST_CHECK_EQUAL( *cmRangeIt, val ); 00116 } 00117 00118 // checking the available keys 00119 typename multi_map_type::const_iterator cmIt; 00120 for ( cmIt = cmap.begin(); cmIt != cmap.end(); ++cmIt ) 00121 { 00122 retrieved_keys.insert(cmIt->first); 00123 BOOST_CHECK_EQUAL( cmIt->second.size(), num_val ); 00124 } 00125 00126 BOOST_CHECK_EQUAL(retrieved_keys.size(), num_keys); 00127 key = 0; 00128 for ( rkIt = retrieved_keys.begin(); rkIt != retrieved_keys.end(); ++rkIt, ++key ) 00129 BOOST_CHECK_EQUAL( *rkIt, key ); 00130 } 00131 00132 // non const 00133 { 00134 // try to get a key that does NOT exist 00135 typename multi_map_type::range rt = map[num_keys+1]; 00136 BOOST_CHECK( rt.empty() ); // not found! 00137 00138 typename multi_map_type::range_iterator mRangeIt; 00139 00140 for ( typename multi_map_type::first_type k = 0; k < num_keys; ++k ) 00141 { 00142 // get the range for key 'k' 00143 rt = map[k]; 00144 BOOST_CHECK( !rt.empty() ); 00145 BOOST_CHECK_EQUAL( rt.size(), num_val ); 00146 00147 val = 0; 00148 // check each value associated to key 'k' 00149 for ( mRangeIt = rt.begin(); mRangeIt != rt.end(); ++mRangeIt, ++val ) 00150 BOOST_CHECK_EQUAL( *mRangeIt, val ); 00151 } 00152 00153 // checking the available keys 00154 typename multi_map_type::iterator mIt; 00155 retrieved_keys.clear(); 00156 for ( mIt = map.begin(); mIt != map.end(); ++mIt ) 00157 { 00158 retrieved_keys.insert(mIt->first); 00159 BOOST_CHECK_EQUAL( mIt->second.size(), num_val ); 00160 } 00161 00162 BOOST_CHECK_EQUAL(retrieved_keys.size(), num_keys); 00163 key = 0; 00164 for ( rkIt = retrieved_keys.begin(); rkIt != retrieved_keys.end(); ++rkIt, ++key ) 00165 BOOST_CHECK_EQUAL( *rkIt, key ); 00166 } 00167 } 00168 00169 }; 00170 00171 struct Fixture_default : public Fixture_generic< multi_map<int, boost::int8_t> > 00172 { 00173 // using dense hash map 00174 // empty key is -1 00175 // initialized with bucket size of 1024 00176 Fixture_default() 00177 : m_map( multi_map_type::loc_map_policy_type(-1, 1024) ) 00178 {} 00179 00180 multi_map_type m_map; 00181 }; 00182 00183 BOOST_FIXTURE_TEST_CASE( test_default, Fixture_default ) 00184 { 00185 multi_map_type::first_type num_keys = 5; 00186 multi_map_type::second_type num_vals = 10; 00187 00188 // key on first 00189 create_data<1>( m_map, num_keys, num_vals ); 00190 check_map(m_map, num_keys, num_vals); 00191 00192 m_map.clear(); 00193 BOOST_CHECK( m_map.empty() ); 00194 00195 create_data<2>( m_map, num_keys, num_vals ); 00196 00197 // key on second 00198 check_map( m_map, num_vals, num_keys ); 00199 } 00200 00201 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00202 00203 struct Fixture_dense : public Fixture_generic< 00204 multi_map< int, 00205 boost::int8_t, 00206 moost::container::dense_hash_map< int, multimap_value_type > 00207 > > 00208 { 00209 // using dense hash map 00210 // empty key is -1 00211 // initialized with bucket size of 1024 00212 Fixture_dense() 00213 : m_map( multi_map_type::loc_map_policy_type(-1, 1024) ) 00214 {} 00215 00216 multi_map_type m_map; 00217 }; 00218 00219 // just check if it compiles 00220 BOOST_FIXTURE_TEST_CASE( test_dense, Fixture_dense ) 00221 { 00222 multi_map_type::first_type num_keys = 5; 00223 multi_map_type::second_type num_vals = 10; 00224 00225 // key on first 00226 create_data<1>( m_map, num_keys, num_vals ); 00227 check_map(m_map, num_keys, num_vals); 00228 00229 m_map.clear(); 00230 BOOST_CHECK( m_map.empty() ); 00231 00232 create_data<2>( m_map, num_keys, num_vals ); 00233 00234 // key on second 00235 check_map( m_map, num_vals, num_keys ); 00236 } 00237 00238 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00239 00240 struct Fixture_sparse : public Fixture_generic< 00241 multi_map< int, 00242 boost::int8_t, 00243 moost::container::sparse_hash_map< int, multimap_value_type > 00244 > > 00245 { 00246 // using sparse hash map 00247 // initialized with bucket size of 1024 00248 Fixture_sparse() 00249 : m_map( multi_map_type::loc_map_policy_type(1024) ) 00250 {} 00251 00252 multi_map_type m_map; 00253 }; 00254 00255 // just check if it compiles 00256 BOOST_FIXTURE_TEST_CASE( test_sparse, Fixture_sparse ) 00257 { 00258 multi_map_type::first_type num_keys = 5; 00259 multi_map_type::second_type num_vals = 10; 00260 00261 // key on first 00262 create_data<1>( m_map, num_keys, num_vals ); 00263 check_map(m_map, num_keys, num_vals); 00264 00265 m_map.clear(); 00266 BOOST_CHECK( m_map.empty() ); 00267 00268 create_data<2>( m_map, num_keys, num_vals ); 00269 00270 // key on second 00271 check_map( m_map, num_vals, num_keys ); 00272 } 00273 00274 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00275 00276 struct Fixture_stl_map : public Fixture_generic< 00277 multi_map< int, 00278 boost::int8_t, 00279 std::map< int, multimap_value_type > 00280 > > 00281 { 00282 // using sparse hash map 00283 // initialized with bucket size of 1024 00284 Fixture_stl_map() 00285 {} 00286 00287 multi_map_type m_map; 00288 }; 00289 00290 // just check if it compiles 00291 BOOST_FIXTURE_TEST_CASE( test_stl_map, Fixture_stl_map ) 00292 { 00293 multi_map_type::first_type num_keys = 5; 00294 multi_map_type::second_type num_vals = 10; 00295 00296 // key on first 00297 create_data<1>( m_map, num_keys, num_vals ); 00298 check_map(m_map, num_keys, num_vals); 00299 00300 m_map.clear(); 00301 BOOST_CHECK( m_map.empty() ); 00302 00303 create_data<2>( m_map, num_keys, num_vals ); 00304 00305 // key on second 00306 check_map( m_map, num_vals, num_keys ); 00307 } 00308 00309 00310 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00311 00312 struct Fixture_map : public Fixture_generic< 00313 multi_map< int, 00314 boost::int8_t, 00315 map<int, multimap_value_type> 00316 > > 00317 { 00318 // using a stl::map 00319 Fixture_map() 00320 : m_map( ) 00321 {} 00322 00323 multi_map_type m_map; 00324 }; 00325 00326 // just check if it compiles 00327 BOOST_FIXTURE_TEST_CASE( test_map, Fixture_map ) 00328 { 00329 multi_map_type::first_type num_keys = 5; 00330 multi_map_type::second_type num_vals = 10; 00331 00332 // key on first 00333 create_data<1>( m_map, num_keys, num_vals ); 00334 check_map(m_map, num_keys, num_vals); 00335 00336 m_map.clear(); 00337 BOOST_CHECK( m_map.empty() ); 00338 00339 create_data<2>( m_map, num_keys, num_vals ); 00340 00341 // key on second 00342 check_map( m_map, num_vals, num_keys ); 00343 } 00344 00345 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00346 00347 struct Fixture_vector : public Fixture_generic< 00348 multi_map< int, 00349 boost::int8_t, 00350 vector<multimap_value_type> 00351 > > 00352 { 00353 // using a vector 00354 // initialized with vector size of m_num_keys 00355 Fixture_vector() 00356 : m_num_keys(5), m_map( multi_map_type::loc_map_policy_type(m_num_keys) ) 00357 {} 00358 00359 multi_map_type::first_type m_num_keys; 00360 multi_map_type m_map; 00361 }; 00362 00363 // just check if it compiles 00364 BOOST_FIXTURE_TEST_CASE( test_vector1, Fixture_vector ) 00365 { 00366 multi_map_type::second_type num_vals = 10; 00367 00368 // key on first 00369 create_data<1>( m_map, m_num_keys, num_vals ); 00370 check_map(m_map, m_num_keys, num_vals); 00371 00372 m_map.clear(); 00373 BOOST_CHECK( m_map.empty() ); 00374 } 00375 00376 // just check if it compiles 00377 BOOST_FIXTURE_TEST_CASE( test_vector2, Fixture_vector ) 00378 { 00379 multi_map_type::second_type num_vals = 5; // must be the same size of the initialized one! 00380 00381 create_data<2>( m_map, m_num_keys, num_vals ); 00382 // key on second 00383 check_map( m_map, num_vals, m_num_keys ); 00384 00385 m_map.clear(); 00386 BOOST_CHECK( m_map.empty() ); 00387 } 00388 00389 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 00390 00391 BOOST_AUTO_TEST_SUITE_END()