2 //=============================================================================
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
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
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
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;
90 static Caching_Strategy_Type caching_strategy_type
= ACE_ALL
;
91 static KEY
*lookup_array
= 0;
94 run_iterator_cache (MAP_CACHE
&cache
)
96 size_t iterations
= cache
.current_size ();
98 MAP_CACHE::iterator end
= cache
.end ();
100 for (MAP_CACHE::iterator iter
= cache
.begin ();
105 ACE_DEBUG ((LM_DEBUG
,
106 ACE_TEXT ("(%d|%d)"),
110 ACE_TEST_ASSERT ((*iter
).first () == (*iter
).second ());
114 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
116 ACE_UNUSED_ARG (iterations
);
117 ACE_TEST_ASSERT (counter
== iterations
);
121 run_iterator_hash_cache (HASH_MAP_CACHE
&cache
)
123 size_t iterations
= cache
.current_size ();
125 HASH_MAP_CACHE::iterator end
= cache
.end ();
127 for (HASH_MAP_CACHE::iterator iter
= cache
.begin ();
132 ACE_DEBUG ((LM_DEBUG
,
133 ACE_TEXT ("(%d|%d)"),
137 ACE_TEST_ASSERT ((*iter
).first () == (*iter
).second ());
141 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
143 ACE_UNUSED_ARG (iterations
);
144 ACE_TEST_ASSERT (counter
== iterations
);
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 ();
157 ACE_TEST_ASSERT ((*iter
).first () == (*iter
).second ());
161 ACE_DEBUG ((LM_DEBUG
,
162 ACE_TEXT ("(%d|%d)"),
169 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
171 ACE_TEST_ASSERT (counter
== 0);
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 ();
184 ACE_TEST_ASSERT ((*iter
).first () == (*iter
).second ());
188 ACE_DEBUG ((LM_DEBUG
,
189 ACE_TEXT ("(%d|%d)"),
196 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
198 ACE_TEST_ASSERT (counter
== 0);
202 find_test_cache (MAP_CACHE
&cache
)
204 for (size_t i
= 0; i
< no_of_lookups
; ++i
)
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
]);
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
);
223 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
227 find_test_hash_cache (HASH_MAP_CACHE
&cache
)
229 for (size_t i
= 0; i
< no_of_lookups
; ++i
)
232 int result
= cache
.find (lookup_array
[i
], j
);
234 ACE_TEST_ASSERT (result
!= -1);
235 ACE_TEST_ASSERT (j
== lookup_array
[i
]);
238 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("%d "), j
));
240 ACE_UNUSED_ARG (result
);
244 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
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
);
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
;
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
);
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
);
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
;
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
);
304 functionality_test_cache (MAP_CACHING_STRATEGY
&caching_strategy
)
306 MAP_CACHE
cache (caching_strategy
);
310 // Add it to the map now.
311 for (size_t counter
= 0;
315 int result
= cache
.bind (i
, j
);
316 ACE_TEST_ASSERT (result
== 0);
317 ACE_UNUSED_ARG (result
);
320 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"),
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 ()));
346 functionality_test_hash_cache (HASH_MAP_CACHING_STRATEGY
&caching_strategy
)
348 HASH_MAP_CACHE
cache (caching_strategy
);
352 // Add it to the map now.
353 for (size_t counter
= 0;
357 int result
= cache
.bind (i
, j
);
358 ACE_TEST_ASSERT (result
== 0);
359 ACE_UNUSED_ARG (result
);
362 ACE_DEBUG ((LM_DEBUG
,
363 ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"),
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 ()));
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
)
397 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nNull_Caching_Strategy\n\n")));
398 ACE_NEW (map_caching_strategy
,
400 ACE_NEW (hash_map_caching_strategy
,
401 HASH_MAP_NULL_ADAPTER
);
405 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nLRU_Caching_Strategy\n\n")));
406 ACE_NEW (map_caching_strategy
,
408 ACE_NEW (hash_map_caching_strategy
,
409 HASH_MAP_LRU_ADAPTER
);
413 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nLFU_Caching_Strategy\n\n")));
414 ACE_NEW (map_caching_strategy
,
416 ACE_NEW (hash_map_caching_strategy
,
417 HASH_MAP_LFU_ADAPTER
);
421 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nFIFO_Caching_Strategy\n\n")));
422 ACE_NEW (map_caching_strategy
,
424 ACE_NEW (hash_map_caching_strategy
,
425 HASH_MAP_FIFO_ADAPTER
);
428 case ACE_ALL
: // Just to remove warnings!
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
;
443 parse_args (int argc
, ACE_TCHAR
*argv
[])
445 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("c:i:r:f:p:d"));
448 while ((cc
= get_opt ()) != -1)
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
;
463 iterations
= ACE_OS::atoi (get_opt
.opt_arg ());
466 no_of_lookups
= ACE_OS::atoi (get_opt
.opt_arg ());
469 randomize_lookups
= ACE_OS::atoi (get_opt
.opt_arg ());
472 purge_percent
= ACE_OS::atoi (get_opt
.opt_arg ());
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")));
496 run_main (int argc
, ACE_TCHAR
*argv
[])
499 int result
= parse_args (argc
, argv
);
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
,
517 ACE_DEBUG ((LM_DEBUG
,
518 ACE_TEXT ("\nLookup sequence: ")));
520 // Initialize the lookup array.
525 if (randomize_lookups
!= 0)
526 lookup_array
[k
] = ACE_OS::rand () % iterations
;
528 lookup_array
[k
] = k
% iterations
;
530 ACE_DEBUG ((LM_DEBUG
,
535 ACE_DEBUG ((LM_DEBUG
,
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 ();
555 test_caching_strategy_type ();
558 delete[] lookup_array
;
560 ACE_LOG_MSG
->set_flags (ACE_Log_Msg::VERBOSE_LITE
);