LCOV - code coverage report
Current view: top level - tests/vtree - vtree_mmap_suite.cpp (source / functions) Hit Total Coverage
Test: v-set-coverage.info Lines: 18 209 8.6 %
Date: 2019-09-12 Functions: 12 32 37.5 %

          Line data    Source code
       1             : //
       2             : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
       3             : //
       4             : // Copyright: See COPYING file that comes with this distribution
       5             : //
       6             : 
       7             : #include <fas/testing.hpp>
       8             : #include <vset/vtree/vtree.hpp>
       9             : #include <vset/vtree/strategy.hpp>
      10             : 
      11             : #include <stdexcept>
      12             : #include <sstream>
      13             : #include <set>
      14             : #include <list>
      15             : #include <stack>
      16             : #include <vector>
      17             : 
      18           1 : std::stack<std::string> test_stack;
      19           1 : std::stringstream output_buffer;
      20             : 
      21             : void raise(const std::string& text, const std::string& file = __FILE__, int pos = __LINE__  );
      22           0 : void raise(const std::string& text, const std::string& file, int pos  )
      23             : {
      24           0 :   std::cout << output_buffer.str();
      25           0 :   while ( !test_stack.empty() )
      26             :   {
      27           0 :     std::cout << test_stack.top() << std::endl;
      28           0 :     test_stack.pop();
      29             :   }
      30           0 :   std::stringstream ss;
      31           0 :   ss << file << ":" << pos << " " << std::endl << text;
      32           0 :   throw std::logic_error(ss.str());
      33             : }
      34             : 
      35           0 : struct init_sequence
      36             : {
      37             :   int count;
      38             :   int first;
      39             :   int last;
      40             : 
      41             :   std::vector<int> vect;
      42             : 
      43           0 :   init_sequence(int c, int f, int l)
      44             :     : count(c)
      45             :     , first(f)
      46           0 :     , last(l)
      47             :   {
      48           0 :     double step = double(last - first)/count;
      49           0 :     double curr = first;
      50             : 
      51           0 :     for (; count != 0; curr += step, --count)
      52             :     {
      53           0 :       vect.push_back( static_cast<int>(curr) );
      54             :     }
      55           0 :   }
      56             : 
      57             :   template<typename Container>
      58           0 :   void operator()(Container& cnt) const
      59             :   {
      60           0 :     std::copy(vect.begin(), vect.end(), std::back_inserter(cnt));
      61           0 :   }
      62             : };
      63             : 
      64           0 : struct init_random
      65             : {
      66             :   int count;
      67             :   int first;
      68             :   int last;
      69             : 
      70             :   std::vector<int> vect;
      71             : 
      72           0 :   init_random(int c, int f, int l)
      73             :     : count(c)
      74             :     , first(f)
      75           0 :     , last(l)
      76             :   {
      77           0 :     int dist = last - first;
      78           0 :     for (; count != 0; --count)
      79             :     {
      80           0 :       vect.push_back( first + std::rand()%dist );
      81             :     }
      82           0 :   }
      83             : 
      84             :   template<typename Container>
      85           0 :   void operator()(Container& cnt)  const
      86             :   {
      87           0 :     std::copy(vect.begin(), vect.end(), std::back_inserter(cnt));
      88           0 :   }
      89             : };
      90             : 
      91             : 
      92             : template<typename Container1, typename Container2>
      93           0 : bool equal( const Container1& cnt1, const Container2& cnt2)
      94             : {
      95           0 :   if (cnt1.size() != cnt2.size() )
      96             :   {
      97           0 :     return false;
      98             :   }
      99             : 
     100           0 :   typename Container1::const_iterator cur1 = cnt1.begin();
     101           0 :   typename Container2::const_iterator  cur2 = cnt2.begin();
     102           0 :   for (size_t i=0; i < cnt1.size(); ++i, ++cur1, ++cur2)
     103             :   {
     104           0 :     if ( *cur1 != *cur2 )
     105             :     {
     106           0 :       return false;
     107             :     }
     108             :   }
     109           0 :   return true;
     110             : }
     111             : 
     112             : template<size_t ArraySize>
     113             : class persist_container
     114             : {
     115             : public:
     116             : 
     117             :   typedef vset::vtree::vtree< vset::vtree::strategy::vtree_fsb_mmap<int, std::less<int>, ArraySize> > set_type;
     118             :   typedef typename set_type::iterator iterator;
     119             :   typedef typename set_type::const_iterator const_iterator;
     120             : 
     121           0 :   persist_container(const std::string& filename, bool clear)
     122             :   {
     123           0 :     output_buffer << "persist_container::persist_container() clear = " << clear << std::endl;
     124             :     
     125           0 :     _vset = new set_type;
     126             :     
     127           0 :     _vset->get_allocator().memory().buffer().open( filename.c_str() );
     128           0 :     _vset->get_allocator().memory().buffer().reserve( 1024*1024);
     129           0 :     output_buffer << "persist_container size after open: " << _vset->size() << std::endl;
     130           0 :     if ( clear )
     131             :     {
     132           0 :       _vset->clear();
     133           0 :       output_buffer << "persist_container size after clear: " << _vset->size() << std::endl;
     134             :     }
     135           0 :   }
     136             : 
     137           0 :   ~persist_container()
     138             :   {
     139           0 :     output_buffer << "~persist_container() " << _vset->size() << std::endl;
     140           0 :     output_buffer << "~persist_container() " << _vset->get_allocator().memory().buffer().size() << std::endl;
     141             : 
     142             :     typedef typename set_type::allocator_type::memory_type::pointer pointer;
     143           0 :     pointer beg = _vset->get_allocator().memory().begin();
     144           0 :     pointer end = _vset->get_allocator().memory().end();
     145           0 :     size_t count = 0;
     146           0 :     for (;beg != end; ++beg)
     147             :     {
     148           0 :       count += beg->size();
     149             :     }
     150           0 :     output_buffer << "~persist_container() " << count << std::endl;
     151             :     
     152           0 :     _vset->get_allocator().memory().buffer().sync();
     153           0 :     _vset->get_allocator().memory().buffer().close();
     154           0 :     delete _vset;
     155           0 :   }
     156             : 
     157           0 :   set_type& operator*() const
     158             :   {
     159           0 :     return *_vset;
     160             :   }
     161             : 
     162           0 :   set_type* operator->() const
     163             :   {
     164           0 :     return _vset;
     165             :   }
     166             : 
     167             :   persist_container(const persist_container& );
     168             : private:
     169             :   
     170             :   set_type* _vset;
     171             : };
     172             : 
     173             : template<size_t ArraySize>
     174             : class non_persist_container
     175             : {
     176             :   non_persist_container(const non_persist_container&);
     177             :   non_persist_container& operator=(const non_persist_container&);
     178             : public:
     179             : 
     180             :   typedef vset::vtree::vtree< vset::vtree::strategy::vtree_fsb_mmap<int, std::less<int>, ArraySize> > set_type;
     181             :   typedef typename set_type::iterator iterator;
     182             :   
     183             : 
     184             :   non_persist_container(const std::string& filename, bool /*clear*/)
     185             :   {
     186             :     _vset = new set_type;
     187             :     _vset->get_allocator().memory().buffer().open(filename.c_str());
     188             :   }
     189             : 
     190             :   ~non_persist_container()
     191             :   {
     192             :     delete _vset;
     193             :   }
     194             : 
     195             :   set_type& operator*() const
     196             :   {
     197             :     return *_vset;
     198             :   }
     199             : 
     200             :   set_type* operator->() const
     201             :   {
     202             :     return _vset;
     203             :   }
     204             : 
     205             : private:
     206             :   set_type* _vset;
     207             : };
     208             : 
     209             : 
     210             : template<typename T, typename Container, typename F>
     211           0 : void test_insert1(T& /*t*/, const Container& cnt, const F& init, bool onlyCheck)
     212             : {
     213           0 :   output_buffer << "test_insert1 onlyCheck=" << onlyCheck << "{"  << std::endl;
     214             :   //std::stringstream ss;
     215           0 :   if ( onlyCheck )
     216             :   {
     217           0 :     test_stack.push("test_insert1 onlyCheck");
     218             :   }
     219             :   else
     220             :   {
     221           0 :     test_stack.push("test_insert1");
     222             :   }
     223           0 :   std::vector<int> values;
     224           0 :   init(values);
     225           0 :   if ( !onlyCheck )
     226             :   {
     227           0 :     cnt->insert( values.begin(), values.end() );
     228             :   }
     229           0 :   output_buffer << "<<<--- 1" << std::endl;
     230           0 :   if ( values.size() != cnt->size() )
     231             :   {
     232           0 :     output_buffer << "----------------------" << std::endl;
     233           0 :     output_buffer << values.size() << std::endl;
     234           0 :     output_buffer << cnt->size() << std::endl;
     235           0 :     output_buffer << "======================" << std::endl;
     236           0 :     raise("values1.size() != cnt->size()", __FILE__, __LINE__);
     237             :   }
     238           0 :   output_buffer << "<<<--- 2" << std::endl;
     239           0 :   std::sort(values.begin(), values.end());
     240           0 :   output_buffer << "<<<--- 3" << std::endl;
     241           0 :   if (!equal(*cnt, values))
     242             :   {
     243           0 :     typename Container::iterator itr = cnt->begin();
     244           0 :     for (size_t i = 0; i < values.size(); ++i, ++itr )
     245             :     {
     246           0 :       output_buffer << "<<<--- X" << std::endl;
     247           0 :       output_buffer << "[" << values[i] << "=" << "=" << *itr<< "],";
     248           0 :       if ( values[i] != *itr )
     249             :       {
     250           0 :         output_buffer << "<<<";
     251             :       }
     252             :     }
     253             : 
     254           0 :     output_buffer << std::endl << "END CHECK" << std::endl;
     255           0 :     raise("test_insert1", __FILE__, __LINE__);
     256             : 
     257             :   }
     258           0 :   test_stack.pop();
     259           0 :   output_buffer << "}test_insert1"<< std::endl;
     260           0 : }
     261             : 
     262             : 
     263             : template<typename Container, typename T>
     264           0 : void test_insert(T& t)
     265             : {
     266           0 :   output_buffer << "test_insert {" << std::endl;
     267             :   
     268           0 :   test_stack.push("test_insert");
     269             : 
     270           0 :   test_insert1(t, Container("test_insert.bin", true), init_sequence(1, 1, 1), false );
     271           0 :   test_insert1(t, Container("test_insert.bin", false), init_sequence(1, 1, 1), true );
     272             : 
     273           0 :   test_insert1(t, Container("test_insert.bin", true), init_sequence(10, 1, 5), false );
     274           0 :   test_insert1(t, Container("test_insert.bin", false), init_sequence(10, 1, 5), true );
     275             : 
     276           0 :   test_insert1(t, Container("test_insert.bin", true), init_sequence(256, 1, 5), false );
     277           0 :   test_insert1(t, Container("test_insert.bin", false), init_sequence(256, 1, 5), true );
     278             : 
     279           0 :   test_insert1(t, Container("test_insert.bin", true), init_sequence(2048, 1, 500), false );
     280           0 :   test_insert1(t, Container("test_insert.bin", false), init_sequence(2048, 1, 500), true );
     281             : 
     282           0 :   init_random rnd(100000, 1, 1000);
     283           0 :   output_buffer << "------------1-----------" << std::endl;
     284           0 :   test_insert1(t, Container("test_insert1.bin", true), rnd, false );
     285           0 :   output_buffer << "------------2-----------" << std::endl;
     286           0 :   test_insert1(t, Container("test_insert1.bin", false), rnd, true );
     287             : 
     288           0 :   test_stack.pop();
     289           0 :   output_buffer << "}test_insert" << std::endl;
     290           0 : }
     291             : 
     292             : template<typename T, typename Container, typename F>
     293           0 : void test_erase1(T& /*t*/, const Container& cnt, const F& init, bool onlyCheck)
     294             : {
     295           0 :   output_buffer << "void test_erase1(const Container& cnt, const F& init, bool onlyCheck) " << init.count << std::endl;
     296           0 :   if ( onlyCheck )
     297             :   {
     298           0 :     test_stack.push("test_insert1 onlyCheck");
     299             :   }
     300             :   else
     301             :   {
     302           0 :     test_stack.push("test_erase1");
     303             :   }
     304           0 :   std::list<int> values1, values2;
     305           0 :   init(values1);
     306             : 
     307           0 :   if ( !onlyCheck )
     308             :   {
     309           0 :     cnt->insert( values1.begin(), values1.end() );
     310             :   }
     311             : 
     312           0 :   std::list<int>::iterator beg = values1.begin();
     313           0 :   std::list<int>::iterator end = values1.end();
     314             : 
     315             :   // Перемещаем каждый второй
     316           0 :   for ( ;beg!=end; ++beg)
     317             :   {
     318           0 :     values2.push_back(*beg);
     319             :     try
     320             :     {
     321           0 :       values1.erase(beg++);
     322             :     }
     323             :     catch(const std::exception& e)
     324             :     {
     325             :       raise( e.what(), __FILE__, __LINE__);
     326             :     }
     327             :   }
     328             : 
     329           0 :   if ( !onlyCheck )
     330             :   {
     331           0 :     for ( std::list<int>::iterator beg2 = values2.begin(); beg2!=values2.end(); ++beg2 )
     332             :     {
     333             :       try
     334             :       {
     335           0 :         if ( cnt->find( *beg2 ) == cnt->end() )
     336             :         {
     337           0 :           output_buffer << "fatal " << *beg2 << std::endl ;
     338           0 :           raise( "Cannot find value while iterating", __FILE__, __LINE__);
     339             :         }
     340             : 
     341           0 :         typename Container::iterator upper = cnt->upper_bound(*beg2);
     342           0 :         if ( upper != cnt->end() )
     343             :         {
     344           0 :           if ( *upper == *beg2 )
     345             :           {
     346           0 :             output_buffer << "fatal2" << *upper << std::endl ;
     347             :           }
     348             :           else
     349             :           {
     350           0 :             output_buffer << "UPPER " << *upper << std::endl ;
     351             :           }
     352             :         }
     353           0 :         cnt->erase( *beg2 );
     354             :       }
     355           0 :       catch(const std::exception& e)
     356             :       {
     357           0 :         raise( e.what(), __FILE__, __LINE__);
     358             :       }
     359             :     }
     360             :   }
     361             : 
     362           0 :   if ( values1.size() != cnt->size() )
     363             :   {
     364           0 :     output_buffer << values1.size() << std::endl;
     365           0 :     output_buffer << values2.size() << std::endl;
     366           0 :     output_buffer << cnt->size() << std::endl;
     367           0 :     raise("values1.size() != cnt->size()", __FILE__, __LINE__);
     368             :   }
     369             : 
     370           0 :   if (!equal(*cnt, values1))
     371             :   {
     372           0 :     typename Container::iterator itr = cnt->begin();
     373           0 :     beg = values1.begin();
     374           0 :     for (size_t i = 0; i < values1.size(); ++i, ++itr, ++beg )
     375             :     {
     376           0 :       output_buffer << "[" << *beg << "=" << "=" << *itr<< "],";
     377           0 :       if ( *beg != *itr )
     378             :       {
     379           0 :         output_buffer << "<<<";
     380             :       }
     381             :     }
     382             : 
     383           0 :     output_buffer << std::endl;
     384             : 
     385           0 :     raise("test_erase1", __FILE__, __LINE__);
     386             :   }
     387           0 :   test_stack.pop();
     388           0 : }
     389             : 
     390             : template<typename Container, typename T>
     391           0 : void test_erase(T& t)
     392             : {
     393           0 :   test_stack.push("test_erase");
     394             : 
     395           0 :   test_erase1( t, Container("test_erase.bin", true), init_sequence(1, 1, 1), false );
     396             :   
     397           0 :   test_erase1(t, Container("test_erase.bin", false), init_sequence(1, 1, 1), true );
     398             : 
     399           0 :   test_erase1( t,  Container("test_erase.bin", true), init_sequence(10, 1, 20), false );
     400           0 :   test_erase1(t, Container("test_erase.bin", false), init_sequence(10, 1, 20), true );
     401             : 
     402           0 :   test_erase1( t, Container("test_erase.bin", true), init_sequence(256, 1, 512), false );
     403           0 :   test_erase1(t, Container("test_erase.bin", false), init_sequence(256, 1, 512), true );
     404             : 
     405           0 :   test_erase1( t, Container("test_erase.bin", true), init_sequence(2048, 0, 2048), false );
     406           0 :   test_erase1(t, Container("test_erase.bin", false), init_sequence(2048, 0, 2048), true );
     407             : 
     408           0 :   init_sequence init(10000, 0, 100000);
     409           0 :   test_erase1( t, Container("test_erase.bin", true), init, false );
     410           0 :   test_erase1(t, Container("test_erase.bin", false), init, true );
     411             :   
     412           0 :   test_stack.pop();
     413           0 : }
     414             : 
     415             : 
     416             : template<typename Container, typename T>
     417           0 : void test_all(T& t)
     418             : {
     419           0 :   test_stack.push("test_all");
     420           0 :   output_buffer << "test_all insert {" << std::endl;
     421           0 :   test_insert<Container>(t);
     422           0 :   output_buffer << "}test_all insert" << std::endl;
     423           0 :   output_buffer << "test_all erase {" << std::endl;
     424           0 :   test_erase<Container>(t);
     425           0 :   output_buffer << "}test_all erase" << std::endl;
     426           0 :   test_stack.pop();
     427           0 : }
     428             : 
     429             : template<size_t BlockSize, typename T>
     430           1 : void test_persist(T& t)
     431             : {
     432           1 :   if ( -1 == ::truncate( "./test_erase.bin", 0) )
     433           1 :     return;
     434           0 :   if ( -1 == ::truncate( "./test_insert.bin", 0) )
     435           0 :     return;
     436           0 :   if ( -1 == ::truncate( "./test_insert1.bin", 0) )
     437           0 :     return;
     438           0 :   output_buffer << "------------------- test_persist ------------------- " << BlockSize << std::endl;
     439           0 :   test_stack.push("test_persist");
     440             :   typedef persist_container<BlockSize> container;
     441           0 :   test_all<container>(t);
     442           0 :   test_stack.pop();
     443             : }
     444             : 
     445             : template<typename T>
     446           1 : void test_all_persist(T& t)
     447             : {
     448           1 :   output_buffer << "------------------- test_all_persist -------------------" << std::endl;
     449           1 :   test_stack.push("test_all_persist");
     450             : 
     451           1 :   test_persist<3>(t);
     452             :   /*
     453             :   test_persist<4>(t);
     454             :   test_persist<5>(t);
     455             :   test_persist<7>(t);
     456             :   test_persist<13>(t);
     457             :   */
     458             :   /*test_persist<64>(t);
     459             :   test_persist<256>(t);
     460             :   test_persist<500>(t);
     461             :   test_persist<1000>(t);
     462             :   test_persist<1024>(t);
     463             :   test_persist<4000>(t);*/
     464             : 
     465           1 :   test_stack.pop();
     466             : 
     467           1 :   t << fas::testing::nothing;
     468           1 : }
     469             : 
     470           3 : UNIT(vtree_mmap_test, "")
     471             : {
     472             :   using namespace fas::testing;
     473             : #if ( ! (__GNUC__==4 && __GNUC_MINOR__==6) )
     474           1 :   test_all_persist(t); // internal compiler error 
     475             : #endif
     476           1 :   t << nothing;
     477           1 : }
     478             : 
     479           1 : BEGIN_SUITE(vtree_mmap_suite, "")
     480             :   ADD_UNIT(vtree_mmap_test)
     481           7 : END_SUITE(vtree_mmap_suite)

Generated by: LCOV version 1.10