Stxxl
1.4.0
|
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 }