// $Id$ // ============================================================================ // // = LIBRARY // tests // // = FILENAME // Cache_Map_Manager_Test.cpp // // = DESCRIPTION // This is a test of the and // that illustrates how to use the // forward and reverse iterators, as well as the purging and // caching features. // // = AUTHOR // Kirthika Parameswaran // // ============================================================================ #include "ace/OS.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "test_config.h" #include "ace/Hash_Cache_Map_Manager_T.h" #include "ace/Map_Manager.h" #include "ace/Caching_Strategies_T.h" #include "ace/Functor.h" #include "ace/Pair_T.h" #include "ace/Synch.h" #include "ace/Get_Opt.h" #include "Cache_Map_Manager_Test.h" // Hash_Key class defined in here typedef size_t KEY; typedef size_t VALUE; typedef int ATTR; typedef ACE_Pair CACHE_VALUE; typedef ACE_Equal_To COMPARE_KEYS; typedef ACE_Hash_Map_Manager_Ex, ACE_Null_Mutex> HASH_MAP_MANAGER; typedef ACE_Hash_Map_Iterator_Ex, ACE_Null_Mutex> HASH_MAP_ITERATOR; typedef ACE_Hash_Map_Reverse_Iterator_Ex, ACE_Null_Mutex> HASH_MAP_REVERSE_ITERATOR; typedef ACE_Map_Manager MAP_MANAGER; typedef ACE_Map_Iterator MAP_ITERATOR; typedef ACE_Map_Reverse_Iterator MAP_REVERSE_ITERATOR; typedef ACE_Cleanup_Strategy HASH_MAP_CLEANUP; typedef ACE_Cleanup_Strategy MAP_CLEANUP; typedef ACE_Pair_Caching_Utility HASH_MAP_CACHING_UTILITY; typedef ACE_Pair_Caching_Utility MAP_CACHING_UTILITY; // = Hash_Map_Manager related typedef ACE_Caching_Strategy HASH_MAP_CACHING_STRATEGY; typedef ACE_LRU_Caching_Strategy HASH_MAP_LRU; typedef ACE_LFU_Caching_Strategy HASH_MAP_LFU; typedef ACE_FIFO_Caching_Strategy HASH_MAP_FIFO; typedef ACE_Null_Caching_Strategy HASH_MAP_NULL; typedef ACE_Caching_Strategy_Adapter HASH_MAP_LRU_ADAPTER; typedef ACE_Caching_Strategy_Adapter HASH_MAP_LFU_ADAPTER; typedef ACE_Caching_Strategy_Adapter HASH_MAP_FIFO_ADAPTER; typedef ACE_Caching_Strategy_Adapter HASH_MAP_NULL_ADAPTER; // = Map_Manager related typedef ACE_Caching_Strategy MAP_CACHING_STRATEGY; typedef ACE_LRU_Caching_Strategy MAP_LRU; typedef ACE_LFU_Caching_Strategy MAP_LFU; typedef ACE_FIFO_Caching_Strategy MAP_FIFO; typedef ACE_Null_Caching_Strategy MAP_NULL; typedef ACE_Caching_Strategy_Adapter MAP_LRU_ADAPTER; typedef ACE_Caching_Strategy_Adapter MAP_LFU_ADAPTER; typedef ACE_Caching_Strategy_Adapter MAP_FIFO_ADAPTER; typedef ACE_Caching_Strategy_Adapter MAP_NULL_ADAPTER; typedef ACE_Hash_Cache_Map_Manager, HASH_MAP_CACHING_STRATEGY, ATTR> HASH_MAP_CACHE; typedef ACE_Cache_Map_Manager MAP_CACHE; enum Caching_Strategy_Type { ACE_LFU, ACE_FIFO, ACE_LRU, ACE_NULL, ACE_ALL }; static size_t iterations = ACE_MAX_ITERATIONS; static size_t no_of_lookups = iterations / 2; static int randomize_lookups = 1; static int purge_percent = 10; static int debug = 0; static Caching_Strategy_Type caching_strategy_type = ACE_ALL; static KEY *lookup_array = 0; static void run_iterator_cache (MAP_CACHE &cache) { size_t iterations = cache.current_size (); size_t counter = 0; MAP_CACHE::iterator end = cache.end (); for (MAP_CACHE::iterator iter = cache.begin (); iter != end; ++iter) { // Debugging info. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%d|%d)"), (*iter).first (), (*iter).second ())); ACE_ASSERT ((*iter).first () == (*iter).second ()); ++counter; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); ACE_UNUSED_ARG (iterations); ACE_ASSERT (counter == iterations); } static void run_iterator_hash_cache (HASH_MAP_CACHE &cache) { size_t iterations = cache.current_size (); size_t counter = 0; HASH_MAP_CACHE::iterator end = cache.end (); for (HASH_MAP_CACHE::iterator iter = cache.begin (); iter != end; ++iter) { // Debugging info. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%d|%d)"), (*iter).first (), (*iter).second ())); ACE_ASSERT ((*iter).first () == (*iter).second ()); ++counter; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); ACE_UNUSED_ARG (iterations); ACE_ASSERT (counter == iterations); } static void run_reverse_iterator_cache (MAP_CACHE &cache) { size_t counter = cache.current_size (); MAP_CACHE::reverse_iterator rend = cache.rend (); for (MAP_CACHE::reverse_iterator iter = cache.rbegin (); iter != rend; ++iter) { ACE_ASSERT ((*iter).first () == (*iter).second ()); // Debugging info. if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%d|%d)"), (*iter).first (), (*iter).second ())); --counter; } if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); ACE_ASSERT (counter == 0); } static void run_reverse_iterator_hash_cache (HASH_MAP_CACHE &cache) { size_t counter = cache.current_size (); HASH_MAP_CACHE::reverse_iterator rend = cache.rend (); for (HASH_MAP_CACHE::reverse_iterator iter = cache.rbegin (); iter != rend; ++iter) { ACE_ASSERT ((*iter).first () == (*iter).second ()); // Debugging info. if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%d|%d)"), (*iter).first (), (*iter).second ())); --counter; } if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); ACE_ASSERT (counter == 0); } static void find_test_cache (MAP_CACHE &cache) { for (size_t i = 0; i < no_of_lookups; ++i) { VALUE j; int result = cache.find (lookup_array[i], j); ACE_ASSERT (result != -1); ACE_ASSERT (j == lookup_array[i]); if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d "), j)); ACE_UNUSED_ARG (result); } if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } static void find_test_hash_cache (HASH_MAP_CACHE &cache) { for (size_t i = 0; i < no_of_lookups; ++i) { VALUE j; int result = cache.find (lookup_array[i], j); ACE_ASSERT (result != -1); ACE_ASSERT (j == lookup_array[i]); if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d "), j)); ACE_UNUSED_ARG (result); } if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } static void purge_test_cache (MAP_CACHE &cache) { // Get the number of entries in the container. size_t current_map_size = cache.current_size (); // Find the number of entries which will get purged. size_t entries_to_remove = size_t ((double (purge_percent) / 100 * current_map_size) + 0.5); // Tell the caching strategy how much to purge. cache.caching_strategy ().purge_percent (purge_percent); // Purge from cache. int result = cache.purge (); ACE_ASSERT (result != -1); ACE_UNUSED_ARG (result); size_t resultant_size = 0; if (caching_strategy_type == ACE_NULL) resultant_size = current_map_size; else resultant_size = current_map_size - entries_to_remove; // Make sure the purge took out the appropriate number of entries. ACE_ASSERT (cache.current_size () == resultant_size); ACE_UNUSED_ARG (resultant_size); } static void purge_test_hash_cache (HASH_MAP_CACHE &cache) { // Get the number of entries in the container. size_t current_map_size = cache.current_size (); // Find the number of entries which will get purged. size_t entries_to_remove = size_t ((double (purge_percent) / 100 * current_map_size) + 0.5); // Tell the caching strategy how much to purge. cache.caching_strategy ().purge_percent (purge_percent); // Purge from cache. int result = cache.purge (); ACE_ASSERT (result != -1); ACE_UNUSED_ARG (result); size_t resultant_size = 0; if (caching_strategy_type == ACE_NULL) resultant_size = current_map_size; else resultant_size = current_map_size - entries_to_remove; // Make sure the purge took out the appropriate number of entries. ACE_ASSERT (cache.current_size () == resultant_size); ACE_UNUSED_ARG (resultant_size); } static void functionality_test_cache (MAP_CACHING_STRATEGY &caching_strategy) { MAP_CACHE cache (caching_strategy); KEY i = 0; VALUE j = 0; // Add it to the map now. for (size_t counter = 0; i < iterations; ++i, ++j) { int result = cache.bind (i, j); ACE_ASSERT (result == 0); ACE_UNUSED_ARG (result); if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"), i, i, j, j)); ++counter; ACE_ASSERT (cache.current_size () == counter); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Number of entries in cache before purging: %d\n"), cache.current_size ())); run_iterator_cache (cache); run_reverse_iterator_cache (cache); find_test_cache (cache); purge_test_cache (cache); run_iterator_cache (cache); run_reverse_iterator_cache (cache); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Number of entries in cache after purging: %d\n"), cache.current_size ())); } static void functionality_test_hash_cache (HASH_MAP_CACHING_STRATEGY &caching_strategy) { HASH_MAP_CACHE cache (caching_strategy); KEY i = 0; VALUE j = 0; // Add it to the map now. for (size_t counter = 0; i < iterations; ++i, ++j) { int result = cache.bind (i, j); ACE_ASSERT (result == 0); ACE_UNUSED_ARG (result); if (debug) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("keys[%d]=%d value=[%d]=%d\n"), i, i, j, j)); ++counter; ACE_ASSERT (cache.current_size () == counter); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Number of entries in cache before purging: %d\n"), cache.current_size ())); run_iterator_hash_cache (cache); run_reverse_iterator_hash_cache (cache); find_test_hash_cache (cache); purge_test_hash_cache (cache); run_iterator_hash_cache (cache); run_reverse_iterator_hash_cache (cache); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Number of entries in cache after purging: %d\n"), cache.current_size ())); } void test_caching_strategy_type (void) { HASH_MAP_CACHING_STRATEGY *hash_map_caching_strategy = 0; MAP_CACHING_STRATEGY *map_caching_strategy = 0; switch (caching_strategy_type) { case ACE_NULL: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nNull_Caching_Strategy\n\n"))); ACE_NEW (map_caching_strategy, MAP_NULL_ADAPTER); ACE_NEW (hash_map_caching_strategy, HASH_MAP_NULL_ADAPTER); break; case ACE_LRU: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nLRU_Caching_Strategy\n\n"))); ACE_NEW (map_caching_strategy, MAP_LRU_ADAPTER); ACE_NEW (hash_map_caching_strategy, HASH_MAP_LRU_ADAPTER); break; case ACE_LFU: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nLFU_Caching_Strategy\n\n"))); ACE_NEW (map_caching_strategy, MAP_LFU_ADAPTER); ACE_NEW (hash_map_caching_strategy, HASH_MAP_LFU_ADAPTER); break; case ACE_FIFO: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nFIFO_Caching_Strategy\n\n"))); ACE_NEW (map_caching_strategy, MAP_FIFO_ADAPTER); ACE_NEW (hash_map_caching_strategy, HASH_MAP_FIFO_ADAPTER); break; case ACE_ALL: // Just to remove warnings! break; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("map cache\n"))); functionality_test_cache (*map_caching_strategy); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhash map cache\n"))); functionality_test_hash_cache (*hash_map_caching_strategy); delete map_caching_strategy; delete hash_map_caching_strategy; } static int parse_args (int argc, ACE_TCHAR *argv[]) { ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("c:i:r:f:p:d")); int cc; while ((cc = get_opt ()) != -1) { switch (cc) { case 'c': if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("null")) == 0) caching_strategy_type = ACE_NULL; if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("lru")) == 0) caching_strategy_type = ACE_LRU; if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("lfu")) == 0) caching_strategy_type = ACE_LFU; if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("fifo")) == 0) caching_strategy_type = ACE_FIFO; break; case 'i': iterations = ACE_OS::atoi (get_opt.opt_arg ()); break; case 'f': no_of_lookups = ACE_OS::atoi (get_opt.opt_arg ()); break; case 'r': randomize_lookups = ACE_OS::atoi (get_opt.opt_arg ()); break; case 'p': purge_percent = ACE_OS::atoi (get_opt.opt_arg ()); break; case 'd': debug = 1; break; case '?': case 'h': default: ACE_ERROR ((LM_ERROR, ACE_TEXT ("usage: %s ") ACE_TEXT ("[-c (caching strategy: lru / lfu / fifo / null [default = all])] ") ACE_TEXT ("[-r (randomize lookups)] ") ACE_TEXT ("[-i (iterations)] ") ACE_TEXT ("[-d (debug, i.e., addition printouts)] ") ACE_TEXT ("[-p (purge percent)] ") ACE_TEXT ("[-f (number of lookups)] \n"), argv[0])); return -1; } } return 0; } int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { // Validate options. int result = parse_args (argc, argv); if (result != 0) return result; // Start the test only if options are valid. ACE_START_TEST (ACE_TEXT ("Cache_Map_Manager_Test")); // Remove the extra debugging attributes from Log_Msg output. ACE_LOG_MSG->clr_flags (ACE_Log_Msg::VERBOSE_LITE); // Providing random a unique seed. ACE_OS::srand (ACE_static_cast (u_int, ACE_OS::time (0))); // Create the lookup array. ACE_NEW_RETURN (lookup_array, KEY[no_of_lookups], -1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nLookup sequence: "))); // Initialize the lookup array. for (size_t k = 0; k < no_of_lookups; ++k) { if (randomize_lookups != 0) lookup_array[k] = ACE_OS::rand () % iterations; else lookup_array[k] = k % iterations; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d "), lookup_array[k])); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\n"))); // Do we need to test all the strategies. if (caching_strategy_type == ACE_ALL) { caching_strategy_type = ACE_NULL; test_caching_strategy_type (); caching_strategy_type = ACE_LRU; test_caching_strategy_type (); caching_strategy_type = ACE_LFU; test_caching_strategy_type (); caching_strategy_type = ACE_FIFO; test_caching_strategy_type (); } else { test_caching_strategy_type (); } delete[] lookup_array; ACE_LOG_MSG->set_flags (ACE_Log_Msg::VERBOSE_LITE); ACE_END_TEST; return 0; } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Pair; template class ACE_Reference_Pair; template class ACE_Hash_Map_Manager_Ex, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex, ACE_Null_Mutex>; template class ACE_Hash_Map_Reverse_Iterator_Ex, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex, ACE_Null_Mutex>; template class ACE_Hash_Map_Entry; template class ACE_Map_Manager; template class ACE_Map_Iterator_Base; template class ACE_Map_Iterator; template class ACE_Map_Reverse_Iterator; template class ACE_Map_Entry; template class ACE_Pair_Caching_Utility; template class ACE_Pair_Caching_Utility; template class ACE_Caching_Strategy; template class ACE_Caching_Strategy; template class ACE_LRU_Caching_Strategy; template class ACE_LRU_Caching_Strategy; template class ACE_LFU_Caching_Strategy; template class ACE_LFU_Caching_Strategy; template class ACE_FIFO_Caching_Strategy; template class ACE_FIFO_Caching_Strategy; template class ACE_Null_Caching_Strategy; template class ACE_Null_Caching_Strategy; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Caching_Strategy_Adapter; template class ACE_Cleanup_Strategy; template class ACE_Cleanup_Strategy; template class ACE_Cache_Map_Manager; template class ACE_Cache_Map_Iterator; template class ACE_Cache_Map_Reverse_Iterator; template class ACE_Cache_Map_Manager; template class ACE_Cache_Map_Iterator; template class ACE_Cache_Map_Reverse_Iterator; template class ACE_Hash_Cache_Map_Manager, HASH_MAP_CACHING_STRATEGY, ATTR>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Pair #pragma instantiate ACE_Reference_Pair #pragma instantiate ACE_Hash_Map_Manager_Ex, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Entry #pragma instantiate ACE_Map_Manager #pragma instantiate ACE_Map_Iterator_Base #pragma instantiate ACE_Map_Iterator #pragma instantiate ACE_Map_Reverse_Iterator #pragma instantiate ACE_Map_Entry #pragma instantiate ACE_Pair_Caching_Utility #pragma instantiate ACE_Pair_Caching_Utility #pragma instantiate ACE_Caching_Strategy #pragma instantiate ACE_Caching_Strategy #pragma instantiate ACE_LRU_Caching_Strategy #pragma instantiate ACE_LRU_Caching_Strategy #pragma instantiate ACE_LFU_Caching_Strategy #pragma instantiate ACE_LFU_Caching_Strategy #pragma instantiate ACE_FIFO_Caching_Strategy #pragma instantiate ACE_FIFO_Caching_Strategy #pragma instantiate ACE_Null_Caching_Strategy #pragma instantiate ACE_Null_Caching_Strategy #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Caching_Strategy_Adapter #pragma instantiate ACE_Cleanup_Strategy #pragma instantiate ACE_Cleanup_Strategy #pragma instantiate ACE_Cache_Map_Manager #pragma instantiate ACE_Cache_Map_Iterator #pragma instantiate ACE_Cache_Map_Reverse_Iterator #pragma instantiate ACE_Cache_Map_Manager #pragma instantiate ACE_Cache_Map_Iterator #pragma instantiate ACE_Cache_Map_Reverse_Iterator #pragma instantiate ACE_Hash_Cache_Map_Manager, HASH_MAP_CACHING_STRATEGY, ATTR> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */