Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / tests / Cache_Map_Manager_Test.cpp
blob51e9e765767c9c04c330cee547e40a9e95ce104e
2 //=============================================================================
3 /**
4 * @file Cache_Map_Manager_Test.cpp
6 * This is a test of the <ACE_Cache_Map_Manager> and
7 * <ACE_Hash_Cache_Map_Manager> that illustrates how to use the
8 * forward and reverse iterators, as well as the purging and
9 * caching features.
11 * @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
13 //=============================================================================
16 #include "ace/OS_NS_string.h"
18 #include "ace/OS_Memory.h"
19 #include "ace/OS_NS_stdlib.h"
20 #include "ace/OS_NS_time.h"
21 #include "test_config.h"
22 #include "ace/Hash_Cache_Map_Manager_T.h"
23 #include "ace/Map_Manager.h"
24 #include "ace/Caching_Strategies_T.h"
25 #include "ace/Functor.h"
26 #include "ace/Get_Opt.h"
27 #include "Cache_Map_Manager_Test.h" // Hash_Key class defined in here
29 using KEY = size_t;
30 using VALUE = size_t;
31 using ATTR = int;
32 using CACHE_VALUE = std::pair<VALUE, ATTR>;
33 using COMPARE_KEYS = ACE_Equal_To<KEY>;
35 using HASH_MAP_MANAGER = ACE_Hash_Map_Manager_Ex<KEY, CACHE_VALUE, Hash_Key, ACE_Equal_To<KEY>, ACE_Null_Mutex>;
36 using HASH_MAP_ITERATOR = ACE_Hash_Map_Iterator_Ex<KEY, CACHE_VALUE, Hash_Key, ACE_Equal_To<KEY>, ACE_Null_Mutex>;
37 using HASH_MAP_REVERSE_ITERATOR = ACE_Hash_Map_Reverse_Iterator_Ex<KEY, CACHE_VALUE, Hash_Key, ACE_Equal_To<KEY>, ACE_Null_Mutex>;
39 using MAP_MANAGER = ACE_Map_Manager<KEY, CACHE_VALUE, ACE_Null_Mutex>;
40 using MAP_ITERATOR = ACE_Map_Iterator<KEY, CACHE_VALUE, ACE_Null_Mutex>;
41 using MAP_REVERSE_ITERATOR = ACE_Map_Reverse_Iterator<KEY, CACHE_VALUE, ACE_Null_Mutex>;
43 using HASH_MAP_CLEANUP = ACLE<KEY, CACHE_VALUE, HASH_MAP_MANAGER>;
45 using MAP_CLEANUP = ACLE<KEY, CACHE_VALUE, MAP_MANAGER>;
47 using HASH_MAP_CACHING_UTILITY = ACE_Pair_Caching_Utility<KEY, CACHE_VALUE, HASH_MAP_MANAGER, HASH_MAP_ITERATOR, ATTR>;
49 using MAP_CACHING_UTILITY = ACE_Pair_Caching_Utility<KEY, CACHE_VALUE, MAP_MANAGER, MAP_ITERATOR, ATTR>;
51 // = Hash_Map_Manager related
52 using HASH_MAP_CACHING_STRATEGY = ACS<ATTR, HASH_MAP_CACHING_UTILITY>;
53 using HASH_MAP_LRU = ALRU<ATTR, HASH_MAP_CACHING_UTILITY>;
54 using HASH_MAP_LFU = ALFU<ATTR, HASH_MAP_CACHING_UTILITY>;
55 using HASH_MAP_FIFO = AFIFO<ATTR, HASH_MAP_CACHING_UTILITY>;
56 using HASH_MAP_NULL = ANULL<ATTR, HASH_MAP_CACHING_UTILITY>;
57 using HASH_MAP_LRU_ADAPTER = ACSA<ATTR, HASH_MAP_CACHING_UTILITY, HASH_MAP_LRU>;
58 using HASH_MAP_LFU_ADAPTER = ACSA<ATTR, HASH_MAP_CACHING_UTILITY, HASH_MAP_LFU>;
59 using HASH_MAP_FIFO_ADAPTER = ACSA<ATTR, HASH_MAP_CACHING_UTILITY, HASH_MAP_FIFO>;
60 using HASH_MAP_NULL_ADAPTER = ACSA<ATTR, HASH_MAP_CACHING_UTILITY, HASH_MAP_NULL>;
62 // = Map_Manager related
63 using MAP_CACHING_STRATEGY = ACS<ATTR, MAP_CACHING_UTILITY>;
64 using MAP_LRU = ALRU<ATTR, MAP_CACHING_UTILITY>;
65 using MAP_LFU = ALFU<ATTR, MAP_CACHING_UTILITY>;
66 using MAP_FIFO = AFIFO<ATTR, MAP_CACHING_UTILITY>;
67 using MAP_NULL = ANULL<ATTR, MAP_CACHING_UTILITY>;
68 using MAP_LRU_ADAPTER = ACSA<ATTR, MAP_CACHING_UTILITY, MAP_LRU>;
69 using MAP_LFU_ADAPTER = ACSA<ATTR, MAP_CACHING_UTILITY, MAP_LFU>;
70 using MAP_FIFO_ADAPTER = ACSA<ATTR, MAP_CACHING_UTILITY, MAP_FIFO>;
71 using MAP_NULL_ADAPTER = ACSA<ATTR, MAP_CACHING_UTILITY, MAP_NULL>;
73 using HASH_MAP_CACHE = ACE_Hash_Cache_Map_Manager<KEY, VALUE, Hash_Key, ACE_Equal_To<KEY>, HASH_MAP_CACHING_STRATEGY, ATTR>;
74 using MAP_CACHE = ACMM<KEY, VALUE, MAP_MANAGER, MAP_ITERATOR, MAP_REVERSE_ITERATOR, MAP_CACHING_STRATEGY, ATTR>;
76 enum Caching_Strategy_Type
78 ACE_LFU,
79 ACE_FIFO,
80 ACE_LRU,
81 ACE_NULL,
82 ACE_ALL
85 static size_t iterations = ACE_MAX_ITERATIONS;
86 static size_t no_of_lookups = iterations / 2;
87 static int randomize_lookups = 1;
88 static int purge_percent = 10;
89 static int debug = 0;
90 static Caching_Strategy_Type caching_strategy_type = ACE_ALL;
91 static KEY *lookup_array = 0;
93 static void
94 run_iterator_cache (MAP_CACHE &cache)
96 size_t iterations = cache.current_size ();
97 size_t counter = 0;
98 MAP_CACHE::iterator end = cache.end ();
100 for (MAP_CACHE::iterator iter = cache.begin ();
101 iter != end;
102 ++iter)
104 // Debugging info.
105 ACE_DEBUG ((LM_DEBUG,
106 ACE_TEXT ("(%d|%d)"),
107 (*iter).first (),
108 (*iter).second ()));
110 ACE_TEST_ASSERT ((*iter).first () == (*iter).second ());
111 ++counter;
114 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
116 ACE_UNUSED_ARG (iterations);
117 ACE_TEST_ASSERT (counter == iterations);
120 static void
121 run_iterator_hash_cache (HASH_MAP_CACHE &cache)
123 size_t iterations = cache.current_size ();
124 size_t counter = 0;
125 HASH_MAP_CACHE::iterator end = cache.end ();
127 for (HASH_MAP_CACHE::iterator iter = cache.begin ();
128 iter != end;
129 ++iter)
131 // Debugging info.
132 ACE_DEBUG ((LM_DEBUG,
133 ACE_TEXT ("(%d|%d)"),
134 (*iter).first (),
135 (*iter).second ()));
137 ACE_TEST_ASSERT ((*iter).first () == (*iter).second ());
138 ++counter;
141 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
143 ACE_UNUSED_ARG (iterations);
144 ACE_TEST_ASSERT (counter == iterations);
147 static void
148 run_reverse_iterator_cache (MAP_CACHE &cache)
150 size_t counter = cache.current_size ();
151 MAP_CACHE::reverse_iterator rend = cache.rend ();
153 for (MAP_CACHE::reverse_iterator iter = cache.rbegin ();
154 iter != rend;
155 ++iter)
157 ACE_TEST_ASSERT ((*iter).first () == (*iter).second ());
159 // Debugging info.
160 if (debug)
161 ACE_DEBUG ((LM_DEBUG,
162 ACE_TEXT ("(%d|%d)"),
163 (*iter).first (),
164 (*iter).second ()));
165 --counter;
168 if (debug)
169 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
171 ACE_TEST_ASSERT (counter == 0);
174 static void
175 run_reverse_iterator_hash_cache (HASH_MAP_CACHE &cache)
177 size_t counter = cache.current_size ();
178 HASH_MAP_CACHE::reverse_iterator rend = cache.rend ();
180 for (HASH_MAP_CACHE::reverse_iterator iter = cache.rbegin ();
181 iter != rend;
182 ++iter)
184 ACE_TEST_ASSERT ((*iter).first () == (*iter).second ());
186 // Debugging info.
187 if (debug)
188 ACE_DEBUG ((LM_DEBUG,
189 ACE_TEXT ("(%d|%d)"),
190 (*iter).first (),
191 (*iter).second ()));
192 --counter;
195 if (debug)
196 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
198 ACE_TEST_ASSERT (counter == 0);
201 static void
202 find_test_cache (MAP_CACHE &cache)
204 for (size_t i = 0; i < no_of_lookups; ++i)
206 VALUE j = 0;
207 int result = cache.find (lookup_array[i], j);
208 result = cache.find (lookup_array[i]);
209 ACE_TEST_ASSERT (result != -1);
210 ACE_TEST_ASSERT (j == lookup_array[i]);
212 if (debug)
213 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d "), j));
215 // Once more, with only the key. Test Bugzilla #4029.
216 result = cache.find (lookup_array[i]);
217 ACE_TEST_ASSERT (result != -1);
219 ACE_UNUSED_ARG (result);
222 if (debug)
223 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
226 static void
227 find_test_hash_cache (HASH_MAP_CACHE &cache)
229 for (size_t i = 0; i < no_of_lookups; ++i)
231 VALUE j = 0;
232 int result = cache.find (lookup_array[i], j);
234 ACE_TEST_ASSERT (result != -1);
235 ACE_TEST_ASSERT (j == lookup_array[i]);
237 if (debug)
238 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d "), j));
240 ACE_UNUSED_ARG (result);
243 if (debug)
244 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
247 static void
248 purge_test_cache (MAP_CACHE &cache)
250 // Get the number of entries in the container.
251 size_t current_map_size = cache.current_size ();
253 // Find the number of entries which will get purged.
254 size_t entries_to_remove = size_t ((double (purge_percent) / 100 * current_map_size) + 0.5);
256 // Tell the caching strategy how much to purge.
257 cache.caching_strategy ().purge_percent (purge_percent);
259 // Purge from cache.
260 int result = cache.purge ();
261 ACE_TEST_ASSERT (result != -1);
262 ACE_UNUSED_ARG (result);
264 size_t resultant_size = 0;
265 if (caching_strategy_type == ACE_NULL)
266 resultant_size = current_map_size;
267 else
268 resultant_size = current_map_size - entries_to_remove;
270 // Make sure the purge took out the appropriate number of entries.
271 ACE_TEST_ASSERT (cache.current_size () == resultant_size);
272 ACE_UNUSED_ARG (resultant_size);
275 static void
276 purge_test_hash_cache (HASH_MAP_CACHE &cache)
278 // Get the number of entries in the container.
279 size_t current_map_size = cache.current_size ();
281 // Find the number of entries which will get purged.
282 size_t entries_to_remove = size_t ((double (purge_percent) / 100 * current_map_size) + 0.5);
284 // Tell the caching strategy how much to purge.
285 cache.caching_strategy ().purge_percent (purge_percent);
287 // Purge from cache.
288 int result = cache.purge ();
289 ACE_TEST_ASSERT (result != -1);
290 ACE_UNUSED_ARG (result);
292 size_t resultant_size = 0;
293 if (caching_strategy_type == ACE_NULL)
294 resultant_size = current_map_size;
295 else
296 resultant_size = current_map_size - entries_to_remove;
298 // Make sure the purge took out the appropriate number of entries.
299 ACE_TEST_ASSERT (cache.current_size () == resultant_size);
300 ACE_UNUSED_ARG (resultant_size);
303 static void
304 functionality_test_cache (MAP_CACHING_STRATEGY &caching_strategy)
306 MAP_CACHE cache (caching_strategy);
307 KEY i = 0;
308 VALUE j = 0;
310 // Add it to the map now.
311 for (size_t counter = 0;
312 i < iterations;
313 ++i, ++j)
315 int result = cache.bind (i, j);
316 ACE_TEST_ASSERT (result == 0);
317 ACE_UNUSED_ARG (result);
319 if (debug)
320 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"),
321 i, i, j, j));
322 ++counter;
323 ACE_TEST_ASSERT (cache.current_size () == counter);
326 ACE_DEBUG ((LM_DEBUG,
327 ACE_TEXT ("Number of entries in cache before purging: %d\n"),
328 cache.current_size ()));
330 run_iterator_cache (cache);
331 run_reverse_iterator_cache (cache);
333 find_test_cache (cache);
335 purge_test_cache (cache);
337 run_iterator_cache (cache);
338 run_reverse_iterator_cache (cache);
340 ACE_DEBUG ((LM_DEBUG,
341 ACE_TEXT ("Number of entries in cache after purging: %d\n"),
342 cache.current_size ()));
345 static void
346 functionality_test_hash_cache (HASH_MAP_CACHING_STRATEGY &caching_strategy)
348 HASH_MAP_CACHE cache (caching_strategy);
349 KEY i = 0;
350 VALUE j = 0;
352 // Add it to the map now.
353 for (size_t counter = 0;
354 i < iterations;
355 ++i, ++j)
357 int result = cache.bind (i, j);
358 ACE_TEST_ASSERT (result == 0);
359 ACE_UNUSED_ARG (result);
361 if (debug)
362 ACE_DEBUG ((LM_DEBUG,
363 ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"),
364 i, i, j, j));
365 ++counter;
366 ACE_TEST_ASSERT (cache.current_size () == counter);
369 ACE_DEBUG ((LM_DEBUG,
370 ACE_TEXT ("Number of entries in cache before purging: %d\n"),
371 cache.current_size ()));
373 run_iterator_hash_cache (cache);
374 run_reverse_iterator_hash_cache (cache);
376 find_test_hash_cache (cache);
378 purge_test_hash_cache (cache);
380 run_iterator_hash_cache (cache);
381 run_reverse_iterator_hash_cache (cache);
383 ACE_DEBUG ((LM_DEBUG,
384 ACE_TEXT ("Number of entries in cache after purging: %d\n"),
385 cache.current_size ()));
388 void
389 test_caching_strategy_type ()
391 HASH_MAP_CACHING_STRATEGY *hash_map_caching_strategy = 0;
392 MAP_CACHING_STRATEGY *map_caching_strategy = 0;
394 switch (caching_strategy_type)
396 case ACE_NULL:
397 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nNull_Caching_Strategy\n\n")));
398 ACE_NEW (map_caching_strategy,
399 MAP_NULL_ADAPTER);
400 ACE_NEW (hash_map_caching_strategy,
401 HASH_MAP_NULL_ADAPTER);
402 break;
404 case ACE_LRU:
405 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nLRU_Caching_Strategy\n\n")));
406 ACE_NEW (map_caching_strategy,
407 MAP_LRU_ADAPTER);
408 ACE_NEW (hash_map_caching_strategy,
409 HASH_MAP_LRU_ADAPTER);
410 break;
412 case ACE_LFU:
413 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nLFU_Caching_Strategy\n\n")));
414 ACE_NEW (map_caching_strategy,
415 MAP_LFU_ADAPTER);
416 ACE_NEW (hash_map_caching_strategy,
417 HASH_MAP_LFU_ADAPTER);
418 break;
420 case ACE_FIFO:
421 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nFIFO_Caching_Strategy\n\n")));
422 ACE_NEW (map_caching_strategy,
423 MAP_FIFO_ADAPTER);
424 ACE_NEW (hash_map_caching_strategy,
425 HASH_MAP_FIFO_ADAPTER);
426 break;
428 case ACE_ALL: // Just to remove warnings!
429 break;
432 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("map cache\n")));
433 functionality_test_cache (*map_caching_strategy);
435 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhash map cache\n")));
436 functionality_test_hash_cache (*hash_map_caching_strategy);
438 delete map_caching_strategy;
439 delete hash_map_caching_strategy;
442 static int
443 parse_args (int argc, ACE_TCHAR *argv[])
445 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("c:i:r:f:p:d"));
447 int cc;
448 while ((cc = get_opt ()) != -1)
450 switch (cc)
452 case 'c':
453 if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("null")) == 0)
454 caching_strategy_type = ACE_NULL;
455 if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("lru")) == 0)
456 caching_strategy_type = ACE_LRU;
457 if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("lfu")) == 0)
458 caching_strategy_type = ACE_LFU;
459 if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("fifo")) == 0)
460 caching_strategy_type = ACE_FIFO;
461 break;
462 case 'i':
463 iterations = ACE_OS::atoi (get_opt.opt_arg ());
464 break;
465 case 'f':
466 no_of_lookups = ACE_OS::atoi (get_opt.opt_arg ());
467 break;
468 case 'r':
469 randomize_lookups = ACE_OS::atoi (get_opt.opt_arg ());
470 break;
471 case 'p':
472 purge_percent = ACE_OS::atoi (get_opt.opt_arg ());
473 break;
474 case 'd':
475 debug = 1;
476 break;
477 case '?':
478 case 'h':
479 default:
480 ACE_ERROR ((LM_ERROR,
481 ACE_TEXT ("usage: %s ")
482 ACE_TEXT ("[-c (caching strategy: lru / lfu / fifo / null [default = all])] ")
483 ACE_TEXT ("[-r (randomize lookups)] ")
484 ACE_TEXT ("[-i (iterations)] ")
485 ACE_TEXT ("[-d (debug, i.e., addition printouts)] ")
486 ACE_TEXT ("[-p (purge percent)] ")
487 ACE_TEXT ("[-f (number of lookups)]\n"),
488 ACE_TEXT ("Cache_Map_Manager_Test")));
489 return -1;
492 return 0;
496 run_main (int argc, ACE_TCHAR *argv[])
498 // Validate options.
499 int result = parse_args (argc, argv);
500 if (result != 0)
501 return result;
503 // Start the test only if options are valid.
504 ACE_START_TEST (ACE_TEXT ("Cache_Map_Manager_Test"));
506 // Remove the extra debugging attributes from Log_Msg output.
507 ACE_LOG_MSG->clr_flags (ACE_Log_Msg::VERBOSE_LITE);
509 // Providing random a unique seed.
510 ACE_OS::srand (static_cast<u_int> (ACE_OS::time (0)));
512 // Create the lookup array.
513 ACE_NEW_RETURN (lookup_array,
514 KEY[no_of_lookups],
515 -1);
517 ACE_DEBUG ((LM_DEBUG,
518 ACE_TEXT ("\nLookup sequence: ")));
520 // Initialize the lookup array.
521 for (size_t k = 0;
522 k < no_of_lookups;
523 ++k)
525 if (randomize_lookups != 0)
526 lookup_array[k] = ACE_OS::rand () % iterations;
527 else
528 lookup_array[k] = k % iterations;
530 ACE_DEBUG ((LM_DEBUG,
531 ACE_TEXT ("%d "),
532 lookup_array[k]));
535 ACE_DEBUG ((LM_DEBUG,
536 ACE_TEXT ("\n\n")));
538 // Do we need to test all the strategies.
539 if (caching_strategy_type == ACE_ALL)
541 caching_strategy_type = ACE_NULL;
542 test_caching_strategy_type ();
544 caching_strategy_type = ACE_LRU;
545 test_caching_strategy_type ();
547 caching_strategy_type = ACE_LFU;
548 test_caching_strategy_type ();
550 caching_strategy_type = ACE_FIFO;
551 test_caching_strategy_type ();
553 else
555 test_caching_strategy_type ();
558 delete[] lookup_array;
560 ACE_LOG_MSG->set_flags (ACE_Log_Msg::VERBOSE_LITE);
561 ACE_END_TEST;
563 return 0;