diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
commit | 99aa8c60282c7b8072eb35eb9ac815702f5bf586 (patch) | |
tree | bda96bf8c3a4c2875a083d7b16720533c8ffeaf4 /ACE/tests/Hash_Map_Manager_Test.cpp | |
parent | c4078c377d74290ebe4e66da0b4975da91732376 (diff) | |
download | ATCD-99aa8c60282c7b8072eb35eb9ac815702f5bf586.tar.gz |
undoing accidental deletion
Diffstat (limited to 'ACE/tests/Hash_Map_Manager_Test.cpp')
-rw-r--r-- | ACE/tests/Hash_Map_Manager_Test.cpp | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/ACE/tests/Hash_Map_Manager_Test.cpp b/ACE/tests/Hash_Map_Manager_Test.cpp new file mode 100644 index 00000000000..e960e127f8c --- /dev/null +++ b/ACE/tests/Hash_Map_Manager_Test.cpp @@ -0,0 +1,343 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Hash_Map_Manager_Test.cpp +// +// = DESCRIPTION +// This test illustrates the use of <ACE_Hash_Map_Manager> to +// maintain a hash table using strings. In addition, it also +// illustrates how the <ACE_Static_Allocator> works in +// conjunction with the <ACE_Hash_Map_Manager>. +// +// = AUTHOR +// James Hu <jxh@cs.wustl.edu> and +// Douglas C. Schmidt <schmidt@cs.wustl.edu> +// +// ============================================================================ + +#include "test_config.h" +#include "STL_algorithm_Test_T.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Malloc_T.h" +#include "ace/Null_Mutex.h" + +ACE_RCSID(tests, Hash_Map_Manager_Test, "$Id$") + +static const size_t STRING_TABLE_ENTRIES = 3 * 2; +static const size_t MAX_HASH = 6; + +typedef ACE_Hash_Map_Entry<const ACE_TCHAR *, + const ACE_TCHAR *> HASH_STRING_ENTRY; + +// @@ The following requires too much internal implementation +// information about the <ACE_Hash_Map_Manager>. We need to figure +// out how to simplify this. +static const size_t STRING_TABLE_SIZE = + sizeof (HASH_STRING_ENTRY) * (STRING_TABLE_ENTRIES + MAX_HASH); + +static ACE_Static_Allocator<STRING_TABLE_SIZE> ace_test_allocator; + +typedef ACE_Hash_Map_Manager_Ex<const ACE_TCHAR *, + const ACE_TCHAR *, + ACE_Hash<const ACE_TCHAR *>, + ACE_Equal_To<const ACE_TCHAR *>, + ACE_Null_Mutex> HASH_STRING_MAP; + +typedef ACE_Hash_Map_Iterator_Ex<const ACE_TCHAR *, + const ACE_TCHAR *, + ACE_Hash<const ACE_TCHAR *>, + ACE_Equal_To<const ACE_TCHAR *>, + ACE_Null_Mutex> HASH_STRING_ITER; + +typedef ACE_Hash_Map_Const_Iterator_Ex<const ACE_TCHAR *, + const ACE_TCHAR *, + ACE_Hash<const ACE_TCHAR *>, + ACE_Equal_To<const ACE_TCHAR *>, + ACE_Null_Mutex> HASH_STRING_CONST_ITER; + +typedef ACE_Hash_Map_Reverse_Iterator_Ex<const ACE_TCHAR *, + const ACE_TCHAR *, + ACE_Hash<const ACE_TCHAR *>, + ACE_Equal_To<const ACE_TCHAR *>, + ACE_Null_Mutex> HASH_STRING_REVERSE_ITER; + +struct String_Table +{ + const ACE_TCHAR *key_; + const ACE_TCHAR *value_; +}; + +static String_Table string_table[] = +{ + { + ACE_TEXT ("hello"), + ACE_TEXT ("guten Tag") + }, + { + ACE_TEXT ("goodbye"), + ACE_TEXT ("auf wiedersehen") + }, + { + ACE_TEXT ("funny"), + ACE_TEXT ("lustig") + }, + { + 0, + 0 + } +}; + +static +int test_two_allocators () +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing both allocators\n"))); + int status = 0; + + // Number of entries in string_table above: + size_t chunks = 3; + size_t chunk_size = sizeof (HASH_STRING_MAP::ENTRY); + + // Allocators: + ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> table_alloc (1 , chunk_size * chunks); + ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> table_alloc_small (1, chunk_size * chunks - 1); + ACE_Cached_Allocator<HASH_STRING_MAP::ENTRY, ACE_Null_Mutex> entry_alloc (chunks); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing hash map manager with %d elements...\n"), chunks)); + + HASH_STRING_MAP hash; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Opening hash map manager with ") + ACE_TEXT ("insufficient table allocator, should fail...\n"))); + ACE_OS::last_error (0); + status = hash.open (chunks, &table_alloc_small, &entry_alloc); + if (status < 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed: %d (%s)\n"), + status, ACE_OS::strerror (ACE_OS::last_error ()))); + else + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong...\n")), -1); + + status = hash.close (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d.\n"), + table_alloc.pool_depth ())); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"), + entry_alloc.pool_depth ())); + + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Opening hash map manager again, should succeed...\n"))); + ACE_OS::last_error (0); + status = hash.open (chunks, &table_alloc, &entry_alloc); + if (status < 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"), + status, ACE_OS::strerror (ACE_OS::last_error ())), -1); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK.\n"))); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d\n"), + table_alloc.pool_depth ())); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"), + entry_alloc.pool_depth ())); + + for (size_t i = 0; i < chunks; i++) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("- Binding ('%s', '%s'), should succeed...\n"), + string_table[i].key_ , string_table[i].value_)); + ACE_OS::last_error (0); + status = hash.bind (string_table[i].key_, string_table[i].value_); + if (status < 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"), + status, ACE_OS::strerror (ACE_OS::last_error ())), -1); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, entry allocator depth: %d\n"), + entry_alloc.pool_depth ())); + } + + const ACE_TCHAR *key = ACE_TEXT ("key"); + const ACE_TCHAR *val = ACE_TEXT ("value"); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("- Binding ('%s', '%s'), should fail...\n"), + key, val)); + ACE_OS::last_error (0); + status = hash.bind (key, val); + if (status < 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed (%s).\n"), + ACE_OS::strerror (ACE_OS::last_error ()))); + else + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"), + status, ACE_OS::strerror (ACE_OS::last_error ())), -1); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Closing hash map.\n"))); + status = hash.close (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d.\n"), + table_alloc.pool_depth ())); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"), + entry_alloc.pool_depth ())); + + return 0; +} + +static int +run_test (void) +{ + ace_test_allocator.dump (); + + HASH_STRING_MAP hash (MAX_HASH, &ace_test_allocator); + + size_t i; + + // Check the <bind> operation. + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.bind (string_table[i].key_, + string_table[i].value_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p failed for %s \n"), + ACE_TEXT ("bind"), + string_table[i].key_), -1); + + const ACE_TCHAR *entry; + + // Check the <find> operation. + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.find (string_table[i].key_, + entry) == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("`%s' found `%s'\n"), + string_table[i].key_, + entry)); + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("`%s' not found\n"), + string_table[i].key_), + -1); + + // Check the <trybind> operation. + { + const ACE_TCHAR *pc = string_table[1].value_; + if (hash.trybind (string_table[0].key_, + pc) != 1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("::trybind missed existing entry.")), + -1); + else if (pc != string_table[0].value_) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("::trybind doesn't return existing value.")), + -1); + } + + // Let's test the iterator while we are at it. + { + HASH_STRING_ENTRY *entry = 0; + size_t i = 0; + + for (HASH_STRING_ITER hash_iter (hash); + hash_iter.next (entry) != 0; + hash_iter.advance ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("iterating (%d): [%s, %s]\n"), + i, + entry->ext_id_, + entry->int_id_)); + i++; + } + } + + // And now test the const iterator + { + HASH_STRING_ENTRY *entry = 0; + size_t i = 0; + + for (HASH_STRING_CONST_ITER hash_iter (hash); + hash_iter.next (entry) != 0; + hash_iter.advance ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("const iterating (%d): [%s, %s]\n"), + i, + entry->ext_id_, + entry->int_id_)); + i++; + } + } + + hash.unbind (string_table[2].key_, entry); + + // Check the <find> operation again. + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.find (string_table[i].key_, + entry) == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("`%s' found `%s'\n"), + string_table[i].key_, + entry)); + else if (i != 2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("`%s' not found\n"), + string_table[i].key_), + -1); + + // Let's test the iterator backwards. + { + HASH_STRING_ENTRY *entry = 0; + size_t i = 0; + + for (HASH_STRING_REVERSE_ITER hash_iter (hash); + hash_iter.next (entry) != 0; + hash_iter.advance ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("iterating (%d): [%s, %s]\n"), + i, + entry->ext_id_, + entry->int_id_)); + i++; + } + } + + // Remove all the entries. + if (hash.unbind_all () != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("unbind_all failed\n")), + -1); + + // Redo the <bind> operations. + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.bind (string_table[i].key_, + string_table[i].value_) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p failed for %s \n"), + ACE_TEXT ("bind"), + string_table[i].key_), -1); + + ace_test_allocator.dump (); + + test_two_allocators(); + + // Run the STL algorithm test on the hash map. + const HASH_STRING_MAP & chash = hash; + + test_STL_algorithm (hash); + test_STL_algorithm (chash); + + return 0; +} + +int +run_main (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Hash_Map_Manager_Test")); + + run_test (); + + ACE_END_TEST; + + return 0; +} |