Stxxl  1.4.0
containers/test_map_random.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  containers/test_map_random.cpp
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2004, 2005 Thomas Nowak <t.nowak@imail.de>
00007  *  Copyright (C) 2005, 2006 Roman Dementiev <dementiev@ira.uka.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 //! \file containers/test_map_random.cpp
00015 //! \brief File for testing functionality of stxxl::map.
00016 
00017 //! \example containers/test_map_random.cpp
00018 //! This is an example of use of \c stxxl::map container.
00019 
00020 #include <stxxl/map>
00021 #include "map_test_handlers.h"
00022 
00023 
00024 typedef int key_type;
00025 typedef int data_type;
00026 
00027 struct cmp2 : public std::less<int>
00028 {
00029     static int max_value()
00030     {
00031         return (std::numeric_limits<int>::max)();
00032     }
00033 };
00034 
00035 #define DATA_NODE_BLOCK_SIZE (4096)
00036 #define DATA_LEAF_BLOCK_SIZE (4096)
00037 
00038 typedef std::map<key_type, data_type, cmp2> std_map_type;
00039 typedef stxxl::map<key_type, data_type, cmp2,
00040                    DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> xxl_map_type;
00041 
00042 #define PERCENT_CLEAR 1
00043 #define PERCENT_ERASE_BULK 9
00044 #define PERCENT_ERASE_KEY 90
00045 #define PERCENT_ERASE_ITERATOR 100
00046 #define PERCENT_INSERT_PAIR 100
00047 #define PERCENT_INSERT_BULK 100
00048 #define PERCENT_SIZING 100
00049 #define PERCENT_LOWER 100
00050 #define PERCENT_UPPER 200
00051 #define PERCENT_FIND 100
00052 #define PERCENT_ITERATOR 100
00053 
00054 
00055 //#define MAX_KEY 1000
00056 #define MAX_KEY 10000
00057 
00058 //#define MAX_STEP 0x0001000
00059 
00060 #define NODE_BLOCK_SIZE xxl_map_type::node_block_type::raw_size
00061 #define LEAF_BLOCK_SIZE xxl_map_type::leaf_block_type::raw_size
00062 #define NODE_MELEMENTS xxl_map_type::node_block_type::size
00063 #define LEAF_MELEMENTS xxl_map_type::leaf_block_type::size
00064 
00065 int main(int argc, char * argv[])
00066 {
00067 #ifdef NDEBUG
00068     STXXL_MSG("Program is compiled with NDEBUG option, which makes the testing wrong.");
00069     return 1;
00070 #endif
00071 
00072     typedef std::vector<std::pair<key_type, data_type> > vector_type;
00073 
00074     STXXL_MSG("Node block size: " << NODE_BLOCK_SIZE << " bytes");
00075     STXXL_MSG("Leaf block size: " << LEAF_BLOCK_SIZE << " bytes");
00076     STXXL_MSG("Node max elements: " << NODE_MELEMENTS);
00077     STXXL_MSG("Leaf max elements: " << LEAF_MELEMENTS);
00078 
00079     stxxl::random_number32 rnd;
00080     //stxxl::ran32State = 1141225706;
00081     STXXL_MSG("Init random seed: " << stxxl::ran32State);
00082 
00083     int a = (PERCENT_CLEAR +
00084              PERCENT_SIZING +
00085              PERCENT_ERASE_BULK +
00086              PERCENT_ERASE_KEY +
00087              PERCENT_ERASE_ITERATOR +
00088              PERCENT_INSERT_PAIR +
00089              PERCENT_INSERT_BULK +
00090              PERCENT_LOWER +
00091              PERCENT_UPPER +
00092              PERCENT_FIND +
00093              PERCENT_ITERATOR);
00094 
00095     assert(a == 1000);
00096 
00097     if (argc < 2)
00098     {
00099         STXXL_MSG("Usage: " << argv[0] << " STEP ");
00100         STXXL_MSG("Note, that STEP must be > 1000");
00101         return -1;
00102     }
00103     stxxl::uint64 MAX_STEP = atoi(argv[1]);
00104     assert(MAX_STEP > 1000);
00105     std_map_type stdmap;
00106     xxl_map_type xxlmap(NODE_BLOCK_SIZE * 4, LEAF_BLOCK_SIZE * 3);
00107 
00108     for (stxxl::uint64 i = 0; i < MAX_STEP; i++)
00109     {
00110         // ***************************************************
00111         // A random number is created to determine which kind
00112         // of operation we will be called.
00113         // ***************************************************
00114 
00115         long step = rnd() % 1000;
00116         int percent = 0;
00117 
00118         if (i % (MAX_STEP / 1000) == 0)
00119         {
00120             STXXL_MSG("*****************************************************");
00121             STXXL_MSG("Step=" << i << " (" << (unsigned)stdmap.size() << ")");
00122         }
00123 
00124         // *********************************************************
00125         // The clear function will be called
00126         // *********************************************************
00127         if (step < (percent += PERCENT_CLEAR))
00128         {
00129             if ((unsigned)rand() % 1000 < stdmap.size())
00130             {
00131                 stdmap.clear();
00132                 xxlmap.clear();
00133 
00134                 assert(stdmap.empty());
00135                 assert(xxlmap.empty());
00136             }
00137         }
00138 
00139         // *********************************************************
00140         // The size function will be called
00141         // *********************************************************
00142         else if (step < (percent += PERCENT_SIZING))
00143         {
00144             std_map_type::size_type size1 = stdmap.size();
00145             xxl_map_type::size_type size2 = xxlmap.size();
00146 
00147             assert(size1 == size2);
00148         }
00149 
00150         // *********************************************************
00151         // The erase range function will be called
00152         // *********************************************************
00153         else if (step < (percent += PERCENT_ERASE_BULK))
00154         {
00155             key_type key1 = rand() % MAX_KEY;
00156             key_type key2 = rand() % MAX_KEY;
00157 
00158             if (key1 > key2)
00159             {
00160                 std::swap(key1, key2);
00161             }
00162 
00163             stdmap.erase(stdmap.lower_bound(key1), stdmap.upper_bound(key2));
00164             xxlmap.erase(xxlmap.lower_bound(key1), xxlmap.upper_bound(key2));
00165 
00166             assert(stdmap.size() == xxlmap.size());
00167 
00168             assert(stdmap.lower_bound(key1) == stdmap.end() ||
00169                    stdmap.lower_bound(key1) == stdmap.upper_bound(key2));
00170             assert(xxlmap.lower_bound(key1) == xxlmap.end() ||
00171                    xxlmap.lower_bound(key1) == xxlmap.upper_bound(key2));
00172         }
00173 
00174         // *********************************************************
00175         // The erase a key function will be called
00176         // *********************************************************
00177         else if (step < (percent += PERCENT_ERASE_KEY))
00178         {
00179             key_type key = rnd() % MAX_KEY;
00180 
00181             stdmap.erase(key);
00182             xxlmap.erase(key);
00183 
00184             assert(stxxl::not_there(stdmap, key));
00185             assert(stxxl::not_there(xxlmap, key));
00186         }
00187 
00188         // *********************************************************
00189         // The erase function will be called
00190         // *********************************************************
00191         else if (step < (percent += PERCENT_ERASE_ITERATOR))
00192         {
00193             key_type key = rnd() % MAX_KEY;
00194 
00195             std_map_type::iterator stditer = stdmap.find(key);
00196             xxl_map_type::iterator xxliter = xxlmap.find(key);
00197 
00198             assert(stxxl::is_end(stdmap, stditer) == is_end(xxlmap, xxliter));
00199 
00200             if (stditer != stdmap.end())
00201                 stdmap.erase(stditer);
00202 
00203             if (xxliter != xxlmap.end())
00204                 xxlmap.erase(xxliter);
00205 
00206 
00207             assert(stxxl::not_there(stdmap, key));
00208             assert(stxxl::not_there(xxlmap, key));
00209         }
00210 
00211         // *********************************************************
00212         // The insert function will be called
00213         // *********************************************************
00214         else if (step < (percent += PERCENT_INSERT_PAIR))
00215         {
00216             key_type key = rnd() % MAX_KEY;
00217             stdmap.insert(std::pair<key_type, data_type>(key, 2 * key));
00218             xxlmap.insert(std::pair<key_type, data_type>(key, 2 * key));
00219 
00220             assert(stxxl::there(stdmap, key, 2 * key));
00221             assert(stxxl::there(xxlmap, key, 2 * key));
00222         }
00223 
00224         // *********************************************************
00225         // The bulk insert function will be called
00226         // *********************************************************
00227         else if (step < (percent += PERCENT_INSERT_BULK))
00228         {
00229             unsigned lower = rnd() % MAX_KEY;
00230             unsigned upper = rnd() % MAX_KEY;
00231             if (lower > upper)
00232                 std::swap(lower, upper);
00233 
00234 
00235             vector_type v2(upper - lower);
00236             for (unsigned j = 0; j < (unsigned)(upper - lower); j++)
00237             {
00238                 v2[j].first = lower + j;
00239                 v2[j].second = 2 * v2[j].first;
00240             }
00241 
00242             stdmap.insert(v2.begin(), v2.end());
00243             xxlmap.insert(v2.begin(), v2.end());
00244 
00245             for (unsigned i = lower; i < upper; i++)
00246                 assert(stxxl::there(stdmap, i, 2 * i));
00247 
00248             for (unsigned i = lower; i < upper; i++)
00249                 assert(stxxl::there(xxlmap, i, 2 * i));
00250         }
00251 
00252         // *********************************************************
00253         // The lower_bound function will be called
00254         // *********************************************************
00255         else if (step < (percent += PERCENT_LOWER))
00256         {
00257             key_type key1 = rand() % MAX_KEY;
00258             key_type key2 = rand() % MAX_KEY;
00259             if (key1 > key2)
00260             {
00261                 std::swap(key1, key2);
00262             }
00263 
00264             while (key1 < key2)
00265             {
00266                 std_map_type::iterator stditer = stdmap.lower_bound(key1);
00267                 xxl_map_type::iterator xxliter = xxlmap.lower_bound(key1);
00268 
00269                 assert(stxxl::is_end(stdmap, stditer) == is_end(xxlmap, xxliter));
00270                 if (!stxxl::is_end(stdmap, stditer)) {
00271                     assert(stxxl::is_same(*(stditer), *(xxliter)));
00272                 }
00273 
00274                 key1++;
00275             }
00276         }
00277 
00278         // *********************************************************
00279         // The upper_bound function will be called
00280         // *********************************************************
00281         else if (step < (percent += PERCENT_UPPER))
00282         {
00283             key_type key1 = rand() % MAX_KEY;
00284             key_type key2 = rand() % MAX_KEY;
00285             if (key1 > key2)
00286             {
00287                 std::swap(key1, key2);
00288             }
00289 
00290             while (key1 < key2)
00291             {
00292                 std_map_type::iterator stditer = stdmap.upper_bound(key1);
00293                 xxl_map_type::iterator xxliter = xxlmap.upper_bound(key1);
00294 
00295                 assert(stxxl::is_end(stdmap, stditer) == is_end(xxlmap, xxliter));
00296                 if (!stxxl::is_end(stdmap, stditer)) {
00297                     assert(stxxl::is_same(*(stditer), *(xxliter)));
00298                 }
00299 
00300                 key1++;
00301             }
00302         }
00303 
00304         // *********************************************************
00305         // The find function will be called
00306         // *********************************************************
00307         else if (step < (percent += PERCENT_FIND))
00308         {
00309             key_type key1 = rand() % MAX_KEY;
00310             key_type key2 = rand() % MAX_KEY;
00311             if (key1 > key2)
00312             {
00313                 std::swap(key1, key2);
00314             }
00315 
00316             while (key1 < key2)
00317             {
00318                 std_map_type::iterator stditer = stdmap.find(key1);
00319                 xxl_map_type::iterator xxliter = xxlmap.find(key1);
00320 
00321                 assert(stxxl::is_end(stdmap, stditer) == stxxl::is_end(xxlmap, xxliter));
00322                 if (!stxxl::is_end(stdmap, stditer)) {
00323                     assert(stxxl::is_same(*(stditer), *(xxliter)));
00324                 }
00325 
00326                 key1++;
00327             }
00328         }
00329 
00330         // *********************************************************
00331         // The iterate functions will be called
00332         // *********************************************************
00333         else if (step < (percent += PERCENT_ITERATOR))
00334         {
00335             std_map_type::const_iterator siter1 = stdmap.begin();
00336             xxl_map_type::const_iterator xiter1 = xxlmap.begin();
00337 
00338             std_map_type::const_iterator siter2 = siter1;
00339             xxl_map_type::const_iterator xiter2 = xiter1;
00340 
00341             while (siter1 != stdmap.end())
00342             {
00343                 assert(xiter1 != xxlmap.end());
00344                 assert(stxxl::is_same(*(siter1++), *(xiter1++)));
00345                 if (siter1 != stdmap.end()) {
00346                     assert(!stxxl::is_same(*siter1, *siter2));
00347                 }
00348                 if (xiter1 != xxlmap.end()) {
00349                     assert(!stxxl::is_same(*xiter1, *xiter2));
00350                 }
00351             }
00352             assert(xiter1 == xxlmap.end());
00353             assert(siter2 == stdmap.begin());
00354             assert(xiter2 == xxlmap.begin());
00355         }
00356     }
00357     return 0;
00358 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines