libmoost
/home/mhx/git/github/libmoost/test/container/neigh_multi_map.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #include <boost/test/unit_test.hpp>
00029 #include <boost/test/test_tools.hpp>
00030 #include <boost/cstdint.hpp>
00031 
00032 #include <vector>
00033 #include <fstream>
00034 #include <cstdio>
00035 #include <cmath> // for fabs
00036 
00037 #include "../../include/moost/container/neigh_multi_map.hpp"
00038 
00039 #include "../../include/moost/container/policies/dense_hash_map.hpp"
00040 #include "../../include/moost/container/policies/sparse_hash_map.hpp"
00041 #include "../../include/moost/container/policies/vector_map.hpp"
00042 
00043 using namespace moost::container;
00044 using namespace std;
00045 
00046 BOOST_AUTO_TEST_SUITE( neigh_multi_map_test )
00047 
00048 template <typename TMultiMap>
00049 struct Fixture_generic
00050 {
00051    typedef TMultiMap multi_map_type;
00052 
00053    int m_num_keys;
00054    int m_num_vals;
00055    const std::string m_fileName;
00056 
00057    Fixture_generic()
00058       : m_num_keys(10), m_num_vals(5), m_fileName("neigh_multi_map_test_data.bin")
00059    {
00060       // create the file
00061       const std::string fileName = "neigh_multi_map_test_data.bin";
00062 
00063       std::ofstream outFile(m_fileName.c_str(), ios::binary);
00064       outFile.write( reinterpret_cast<const char*>(&m_num_keys), sizeof(int) );
00065       float score;
00066 
00067       for ( int k = 0; k < m_num_keys; ++k )
00068       {
00069          outFile.write( reinterpret_cast<const char*>(&k), sizeof(int) );
00070          outFile.write( reinterpret_cast<const char*>(&m_num_vals), sizeof(int) );
00071 
00072          for ( int v = 0; v < m_num_vals; ++v )
00073          {
00074             outFile.write( reinterpret_cast<const char*>(&v), sizeof(int) );
00075             score = static_cast<float>(v);
00076 
00077             outFile.write( reinterpret_cast<const char*>(&score), sizeof(float) );
00078          }
00079       }
00080    }
00081 
00082    ~Fixture_generic()
00083    {
00084       remove( m_fileName.c_str() );
00085    }
00086 
00087 
00088    void load_data(multi_map_type& map)
00089    {
00090       map.create_map(m_fileName);
00091    }
00092 
00093    void check_map( multi_map_type& map )
00094    {
00095       BOOST_CHECK_EQUAL( map.size(), m_num_keys );
00096       std::pair<int, float> val;
00097       float eps = 0.00001f;
00098 
00099       // const
00100       {
00101          const multi_map_type& cmap = map;
00102          typename multi_map_type::const_range rt = cmap[m_num_keys+1];
00103          BOOST_CHECK( rt.empty() ); // not found!
00104 
00105          typename multi_map_type::const_range_iterator cmapIt;
00106 
00107          for ( typename multi_map_type::first_type k = 0; k < m_num_keys; ++k )
00108          {
00109             rt = cmap[k];
00110             BOOST_CHECK( !rt.empty() );
00111             BOOST_CHECK_EQUAL( rt.size(), m_num_vals );
00112 
00113             int i = 0;
00114             for ( cmapIt = rt.begin(); cmapIt != rt.end(); ++cmapIt, ++i )
00115             {
00116                val.first = i;
00117                val.second = static_cast<float>(i);
00118 
00119                BOOST_CHECK_EQUAL( cmapIt->first, val.first );
00120                BOOST_CHECK( fabs(cmapIt->second - val.second) < eps );
00121             }
00122          }
00123 
00124       }
00125 
00126       // non const
00127       {
00128          typename multi_map_type::range rt = map[m_num_keys+1];
00129          BOOST_CHECK( rt.empty() ); // not found!
00130 
00131          typename multi_map_type::range_iterator mapIt;
00132 
00133          for ( typename multi_map_type::first_type k = 0; k < m_num_keys; ++k )
00134          {
00135             rt = map[k];
00136             BOOST_CHECK( !rt.empty() );
00137             BOOST_CHECK_EQUAL( rt.size(), m_num_vals );
00138 
00139             int i = 0;
00140             for ( mapIt = rt.begin(); mapIt != rt.end(); ++mapIt, ++i )
00141             {
00142                val.first = i;
00143                val.second = static_cast<float>(i);
00144 
00145                BOOST_CHECK_EQUAL( mapIt->first, val.first );
00146                BOOST_CHECK( abs(mapIt->second - val.second) < eps );
00147             }
00148          }
00149       }
00150 
00151    }
00152 
00153 };
00154 
00155 struct Fixture_default : public Fixture_generic< neigh_multi_map<> >
00156 {
00157    // using dense hash map
00158    // initialized with bucket size of 1024
00159    Fixture_default()
00160       : m_map( multi_map_type::loc_map_policy_type(-1) )  // policy is necessary because I saved key = 0
00161    {}
00162 
00163    multi_map_type m_map;
00164 };
00165 
00166 BOOST_FIXTURE_TEST_CASE( test_default, Fixture_default )
00167 {
00168    // key on first
00169    load_data(m_map);
00170    check_map(m_map);
00171 
00172    m_map.clear();
00173    BOOST_CHECK( m_map.empty() );
00174 }
00175 
00176 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00177 
00178 struct Fixture_dense : public Fixture_generic<
00179                                        neigh_multi_map< moost::container::dense_hash_map< int, multimap_value_type > > >
00180 {
00181    // using dense hash map
00182    // empty key is -1
00183    // no initialization of the bucket as neigh_multi_map will figure it out
00184    Fixture_dense()
00185       : m_map( multi_map_type::loc_map_policy_type(-1) )
00186    {}
00187 
00188    multi_map_type m_map;
00189 };
00190 
00191 // just check if it compiles
00192 BOOST_FIXTURE_TEST_CASE( test_dense, Fixture_dense )
00193 {
00194    // key on first
00195    load_data(m_map);
00196    check_map(m_map);
00197 
00198    m_map.clear();
00199    BOOST_CHECK( m_map.empty() );
00200 }
00201 
00202 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00203 
00204 struct Fixture_sparse : public Fixture_generic<
00205                               neigh_multi_map< moost::container::sparse_hash_map< int, multimap_value_type > > >
00206 {
00207    // using sparse hash map
00208    // no initialization of the bucket as neigh_multi_map will figure it out
00209    Fixture_sparse()
00210       : m_map( multi_map_type::loc_map_policy_type() )
00211    {}
00212 
00213    multi_map_type m_map;
00214 };
00215 
00216 // just check if it compiles
00217 BOOST_FIXTURE_TEST_CASE( test_sparse, Fixture_sparse )
00218 {
00219    // key on first
00220    load_data(m_map);
00221    check_map(m_map);
00222 
00223    m_map.clear();
00224    BOOST_CHECK( m_map.empty() );
00225 }
00226 
00227 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00228 
00229 struct Fixture_stl_map : public Fixture_generic<
00230                      neigh_multi_map< std::map< int, multimap_value_type > > >
00231 {
00232    // using sparse hash map
00233    // no initialization of the bucket as neigh_multi_map will figure it out
00234    Fixture_stl_map()
00235    {}
00236 
00237    multi_map_type m_map;
00238 };
00239 
00240 // just check if it compiles
00241 BOOST_FIXTURE_TEST_CASE( test_stl_map, Fixture_stl_map )
00242 {
00243    // key on first
00244    load_data(m_map);
00245    check_map(m_map);
00246 
00247    m_map.clear();
00248    BOOST_CHECK( m_map.empty() );
00249 }
00250 
00251 
00252 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00253 
00254 struct Fixture_vector : public Fixture_generic<
00255                               neigh_multi_map< vector<multimap_value_type> > >
00256 {
00257    // using a vector
00258    // initialized with vector size of m_num_keys
00259    Fixture_vector()
00260    {}
00261 
00262    multi_map_type m_map;
00263 };
00264 
00265 // just check if it compiles
00266 BOOST_FIXTURE_TEST_CASE( test_vector, Fixture_vector )
00267 {
00268    // key on first
00269    load_data(m_map);
00270    check_map(m_map);
00271 
00272    m_map.clear();
00273    BOOST_CHECK( m_map.empty() );
00274 }
00275 
00276 
00277 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00278 
00279 BOOST_AUTO_TEST_SUITE_END()