Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Hash_Map_Manager_Test.cpp
blobf03a5b3f7d518b1d4b3a43969a641efcbf33e2bf
2 //=============================================================================
3 /**
4 * @file Hash_Map_Manager_Test.cpp
6 * This test illustrates the use of <ACE_Hash_Map_Manager> to
7 * maintain a hash table using strings. In addition, it also
8 * illustrates how the <ACE_Static_Allocator> works in
9 * conjunction with the <ACE_Hash_Map_Manager>.
11 * @author James Hu <jxh@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
13 //=============================================================================
16 #include "test_config.h"
17 #include "STL_algorithm_Test_T.h"
18 #include "ace/Hash_Map_Manager.h"
19 #include "ace/Malloc_T.h"
20 #include "ace/Null_Mutex.h"
23 static const size_t STRING_TABLE_ENTRIES = 3 * 2;
24 static const size_t MAX_HASH = 6;
26 using HASH_STRING_ENTRY = ACE_Hash_Map_Entry<const ACE_TCHAR *, const ACE_TCHAR *>;
28 // @@ The following requires too much internal implementation
29 // information about the <ACE_Hash_Map_Manager>. We need to figure
30 // out how to simplify this.
31 static const size_t STRING_TABLE_SIZE =
32 sizeof (HASH_STRING_ENTRY) * (STRING_TABLE_ENTRIES + MAX_HASH);
34 static ACE_Static_Allocator<STRING_TABLE_SIZE> ace_test_allocator;
36 using HASH_STRING_MAP = 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>;
38 using HASH_STRING_ITER = 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>;
40 using HASH_STRING_CONST_ITER = 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>;
42 using HASH_STRING_REVERSE_ITER = 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>;
44 struct String_Table
46 const ACE_TCHAR *key_;
47 const ACE_TCHAR *value_;
50 static String_Table string_table[] =
53 ACE_TEXT ("hello"),
54 ACE_TEXT ("guten Tag")
57 ACE_TEXT ("goodbye"),
58 ACE_TEXT ("auf wiedersehen")
61 ACE_TEXT ("funny"),
62 ACE_TEXT ("lustig")
70 static
71 int test_two_allocators ()
73 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing both allocators\n")));
74 int status = 0;
76 // Number of entries in string_table above:
77 size_t chunks = 3;
78 size_t chunk_size = sizeof (HASH_STRING_MAP::ENTRY);
80 // Allocators:
81 ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> table_alloc (1 , chunk_size * chunks);
82 ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> table_alloc_small (1, chunk_size * chunks - 1);
83 ACE_Cached_Allocator<HASH_STRING_MAP::ENTRY, ACE_Null_Mutex> entry_alloc (chunks);
85 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing hash map manager with %d elements...\n"), chunks));
87 HASH_STRING_MAP hash;
89 ACE_DEBUG ((LM_DEBUG,
90 ACE_TEXT ("Opening hash map manager with ")
91 ACE_TEXT ("insufficient table allocator, should fail...\n")));
92 ACE_OS::last_error (0);
93 status = hash.open (chunks, &table_alloc_small, &entry_alloc);
94 if (status < 0)
95 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed: %d (%s)\n"),
96 status, ACE_OS::strerror (ACE_OS::last_error ())));
97 else
98 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong...\n")), -1);
100 status = hash.close ();
102 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d.\n"),
103 table_alloc.pool_depth ()));
104 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"),
105 entry_alloc.pool_depth ()));
107 ACE_DEBUG
108 ((LM_DEBUG,
109 ACE_TEXT ("Opening hash map manager again, should succeed...\n")));
110 ACE_OS::last_error (0);
111 status = hash.open (chunks, &table_alloc, &entry_alloc);
112 if (status < 0)
113 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
114 status, ACE_OS::strerror (ACE_OS::last_error ())), -1);
115 else
116 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK.\n")));
118 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d\n"),
119 table_alloc.pool_depth ()));
120 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"),
121 entry_alloc.pool_depth ()));
123 for (size_t i = 0; i < chunks; i++)
125 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("- Binding ('%s', '%s'), should succeed...\n"),
126 string_table[i].key_ , string_table[i].value_));
127 ACE_OS::last_error (0);
128 status = hash.bind (string_table[i].key_, string_table[i].value_);
129 if (status < 0)
130 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
131 status, ACE_OS::strerror (ACE_OS::last_error ())), -1);
132 else
133 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, entry allocator depth: %d\n"),
134 entry_alloc.pool_depth ()));
137 const ACE_TCHAR *key = ACE_TEXT ("key");
138 const ACE_TCHAR *val = ACE_TEXT ("value");
140 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("- Binding ('%s', '%s'), should fail...\n"),
141 key, val));
142 ACE_OS::last_error (0);
143 status = hash.bind (key, val);
144 if (status < 0)
145 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed (%s).\n"),
146 ACE_OS::strerror (ACE_OS::last_error ())));
147 else
148 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
149 status, ACE_OS::strerror (ACE_OS::last_error ())), -1);
151 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Closing hash map.\n")));
152 status = hash.close ();
154 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Table allocator depth: %d.\n"),
155 table_alloc.pool_depth ()));
156 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Entry allocator depth: %d.\n"),
157 entry_alloc.pool_depth ()));
159 return 0;
162 static int
163 run_test ()
165 ace_test_allocator.dump ();
167 HASH_STRING_MAP hash (MAX_HASH, &ace_test_allocator);
169 size_t i;
171 // Check the <bind> operation.
172 for (i = 0; string_table[i].key_ != 0; i++)
173 if (hash.bind (string_table[i].key_,
174 string_table[i].value_) == -1)
175 ACE_ERROR_RETURN ((LM_ERROR,
176 ACE_TEXT ("%p failed for %s\n"),
177 ACE_TEXT ("bind"),
178 string_table[i].key_), -1);
180 const ACE_TCHAR *entry = 0;
182 // Check the <find> operation.
183 for (i = 0; string_table[i].key_ != 0; i++)
184 if (hash.find (string_table[i].key_,
185 entry) == 0)
186 ACE_DEBUG ((LM_DEBUG,
187 ACE_TEXT ("`%s' found `%s'\n"),
188 string_table[i].key_,
189 entry));
190 else
191 ACE_ERROR_RETURN ((LM_ERROR,
192 ACE_TEXT ("`%s' not found\n"),
193 string_table[i].key_),
194 -1);
196 // Check the <trybind> operation.
198 const ACE_TCHAR *pc = string_table[1].value_;
199 if (hash.trybind (string_table[0].key_,
200 pc) != 1)
201 ACE_ERROR_RETURN ((LM_ERROR,
202 ACE_TEXT ("::trybind missed existing entry.")),
203 -1);
204 else if (pc != string_table[0].value_)
205 ACE_ERROR_RETURN ((LM_ERROR,
206 ACE_TEXT ("::trybind doesn't return existing value.")),
207 -1);
210 // Let's test the iterator while we are at it.
212 HASH_STRING_ENTRY *entry = 0;
213 size_t i = 0;
215 for (HASH_STRING_ITER hash_iter (hash);
216 hash_iter.next (entry) != 0;
217 hash_iter.advance ())
219 ACE_DEBUG ((LM_DEBUG,
220 ACE_TEXT ("iterating (%d): [%s, %s]\n"),
222 entry->ext_id_,
223 entry->int_id_));
224 i++;
228 // And now test the const iterator
230 HASH_STRING_ENTRY *entry = 0;
231 size_t i = 0;
233 for (HASH_STRING_CONST_ITER hash_iter (hash);
234 hash_iter.next (entry) != 0;
235 hash_iter.advance ())
237 ACE_DEBUG ((LM_DEBUG,
238 ACE_TEXT ("const iterating (%d): [%s, %s]\n"),
240 entry->ext_id_,
241 entry->int_id_));
242 i++;
246 hash.unbind (string_table[2].key_, entry);
248 // Check the <find> operation again.
249 for (i = 0; string_table[i].key_ != 0; i++)
250 if (hash.find (string_table[i].key_,
251 entry) == 0)
252 ACE_DEBUG ((LM_DEBUG,
253 ACE_TEXT ("`%s' found `%s'\n"),
254 string_table[i].key_,
255 entry));
256 else if (i != 2)
257 ACE_ERROR_RETURN ((LM_ERROR,
258 ACE_TEXT ("`%s' not found\n"),
259 string_table[i].key_),
260 -1);
262 // Let's test the iterator backwards.
264 HASH_STRING_ENTRY *entry = 0;
265 size_t i = 0;
267 for (HASH_STRING_REVERSE_ITER hash_iter (hash);
268 hash_iter.next (entry) != 0;
269 hash_iter.advance ())
271 ACE_DEBUG ((LM_DEBUG,
272 ACE_TEXT ("iterating (%d): [%s, %s]\n"),
274 entry->ext_id_,
275 entry->int_id_));
276 i++;
280 // Remove all the entries.
281 if (hash.unbind_all () != 0)
282 ACE_ERROR_RETURN ((LM_ERROR,
283 ACE_TEXT ("unbind_all failed\n")),
284 -1);
286 // Redo the <bind> operations.
287 for (i = 0; string_table[i].key_ != 0; i++)
288 if (hash.bind (string_table[i].key_,
289 string_table[i].value_) != 0)
290 ACE_ERROR_RETURN ((LM_ERROR,
291 ACE_TEXT ("%p failed for %s\n"),
292 ACE_TEXT ("bind"),
293 string_table[i].key_), -1);
295 ace_test_allocator.dump ();
297 test_two_allocators();
299 // Run the STL algorithm test on the hash map.
300 const HASH_STRING_MAP & chash = hash;
302 test_STL_algorithm (hash);
303 test_STL_algorithm (chash);
305 return 0;
309 run_main (int, ACE_TCHAR *[])
311 ACE_START_TEST (ACE_TEXT ("Hash_Map_Manager_Test"));
313 run_test ();
315 ACE_END_TEST;
317 return 0;