2 //=============================================================================
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"
24 static const size_t STRING_TABLE_ENTRIES
= 3 * 2;
25 static const size_t MAX_HASH
= 6;
27 typedef ACE_Hash_Map_Entry
<const ACE_TCHAR
*,
28 const ACE_TCHAR
*> HASH_STRING_ENTRY
;
30 // @@ The following requires too much internal implementation
31 // information about the <ACE_Hash_Map_Manager>. We need to figure
32 // out how to simplify this.
33 static const size_t STRING_TABLE_SIZE
=
34 sizeof (HASH_STRING_ENTRY
) * (STRING_TABLE_ENTRIES
+ MAX_HASH
);
36 static ACE_Static_Allocator
<STRING_TABLE_SIZE
> ace_test_allocator
;
38 typedef ACE_Hash_Map_Manager_Ex
<const ACE_TCHAR
*,
40 ACE_Hash
<const ACE_TCHAR
*>,
41 ACE_Equal_To
<const ACE_TCHAR
*>,
42 ACE_Null_Mutex
> HASH_STRING_MAP
;
44 typedef ACE_Hash_Map_Iterator_Ex
<const ACE_TCHAR
*,
46 ACE_Hash
<const ACE_TCHAR
*>,
47 ACE_Equal_To
<const ACE_TCHAR
*>,
48 ACE_Null_Mutex
> HASH_STRING_ITER
;
50 typedef ACE_Hash_Map_Const_Iterator_Ex
<const ACE_TCHAR
*,
52 ACE_Hash
<const ACE_TCHAR
*>,
53 ACE_Equal_To
<const ACE_TCHAR
*>,
54 ACE_Null_Mutex
> HASH_STRING_CONST_ITER
;
56 typedef ACE_Hash_Map_Reverse_Iterator_Ex
<const ACE_TCHAR
*,
58 ACE_Hash
<const ACE_TCHAR
*>,
59 ACE_Equal_To
<const ACE_TCHAR
*>,
60 ACE_Null_Mutex
> HASH_STRING_REVERSE_ITER
;
64 const ACE_TCHAR
*key_
;
65 const ACE_TCHAR
*value_
;
68 static String_Table string_table
[] =
72 ACE_TEXT ("guten Tag")
76 ACE_TEXT ("auf wiedersehen")
89 int test_two_allocators ()
91 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Testing both allocators\n")));
94 // Number of entries in string_table above:
96 size_t chunk_size
= sizeof (HASH_STRING_MAP::ENTRY
);
99 ACE_Dynamic_Cached_Allocator
<ACE_Null_Mutex
> table_alloc (1 , chunk_size
* chunks
);
100 ACE_Dynamic_Cached_Allocator
<ACE_Null_Mutex
> table_alloc_small (1, chunk_size
* chunks
- 1);
101 ACE_Cached_Allocator
<HASH_STRING_MAP::ENTRY
, ACE_Null_Mutex
> entry_alloc (chunks
);
103 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Testing hash map manager with %d elements...\n"), chunks
));
105 HASH_STRING_MAP hash
;
107 ACE_DEBUG ((LM_DEBUG
,
108 ACE_TEXT ("Opening hash map manager with ")
109 ACE_TEXT ("insufficient table allocator, should fail...\n")));
110 ACE_OS::last_error (0);
111 status
= hash
.open (chunks
, &table_alloc_small
, &entry_alloc
);
113 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("OK, failed: %d (%s)\n"),
114 status
, ACE_OS::strerror (ACE_OS::last_error ())));
116 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("*** Something is wrong...\n")), -1);
118 status
= hash
.close ();
120 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Table allocator depth: %d.\n"),
121 table_alloc
.pool_depth ()));
122 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Entry allocator depth: %d.\n"),
123 entry_alloc
.pool_depth ()));
127 ACE_TEXT ("Opening hash map manager again, should succeed...\n")));
128 ACE_OS::last_error (0);
129 status
= hash
.open (chunks
, &table_alloc
, &entry_alloc
);
131 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
132 status
, ACE_OS::strerror (ACE_OS::last_error ())), -1);
134 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("OK.\n")));
136 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Table allocator depth: %d\n"),
137 table_alloc
.pool_depth ()));
138 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Entry allocator depth: %d.\n"),
139 entry_alloc
.pool_depth ()));
141 for (size_t i
= 0; i
< chunks
; i
++)
143 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("- Binding ('%s', '%s'), should succeed...\n"),
144 string_table
[i
].key_
, string_table
[i
].value_
));
145 ACE_OS::last_error (0);
146 status
= hash
.bind (string_table
[i
].key_
, string_table
[i
].value_
);
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 ("OK, entry allocator depth: %d\n"),
152 entry_alloc
.pool_depth ()));
155 const ACE_TCHAR
*key
= ACE_TEXT ("key");
156 const ACE_TCHAR
*val
= ACE_TEXT ("value");
158 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("- Binding ('%s', '%s'), should fail...\n"),
160 ACE_OS::last_error (0);
161 status
= hash
.bind (key
, val
);
163 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("OK, failed (%s).\n"),
164 ACE_OS::strerror (ACE_OS::last_error ())));
166 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
167 status
, ACE_OS::strerror (ACE_OS::last_error ())), -1);
169 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Closing hash map.\n")));
170 status
= hash
.close ();
172 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Table allocator depth: %d.\n"),
173 table_alloc
.pool_depth ()));
174 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Entry allocator depth: %d.\n"),
175 entry_alloc
.pool_depth ()));
183 ace_test_allocator
.dump ();
185 HASH_STRING_MAP
hash (MAX_HASH
, &ace_test_allocator
);
189 // Check the <bind> operation.
190 for (i
= 0; string_table
[i
].key_
!= 0; i
++)
191 if (hash
.bind (string_table
[i
].key_
,
192 string_table
[i
].value_
) == -1)
193 ACE_ERROR_RETURN ((LM_ERROR
,
194 ACE_TEXT ("%p failed for %s\n"),
196 string_table
[i
].key_
), -1);
198 const ACE_TCHAR
*entry
= 0;
200 // Check the <find> operation.
201 for (i
= 0; string_table
[i
].key_
!= 0; i
++)
202 if (hash
.find (string_table
[i
].key_
,
204 ACE_DEBUG ((LM_DEBUG
,
205 ACE_TEXT ("`%s' found `%s'\n"),
206 string_table
[i
].key_
,
209 ACE_ERROR_RETURN ((LM_ERROR
,
210 ACE_TEXT ("`%s' not found\n"),
211 string_table
[i
].key_
),
214 // Check the <trybind> operation.
216 const ACE_TCHAR
*pc
= string_table
[1].value_
;
217 if (hash
.trybind (string_table
[0].key_
,
219 ACE_ERROR_RETURN ((LM_ERROR
,
220 ACE_TEXT ("::trybind missed existing entry.")),
222 else if (pc
!= string_table
[0].value_
)
223 ACE_ERROR_RETURN ((LM_ERROR
,
224 ACE_TEXT ("::trybind doesn't return existing value.")),
228 // Let's test the iterator while we are at it.
230 HASH_STRING_ENTRY
*entry
= 0;
233 for (HASH_STRING_ITER
hash_iter (hash
);
234 hash_iter
.next (entry
) != 0;
235 hash_iter
.advance ())
237 ACE_DEBUG ((LM_DEBUG
,
238 ACE_TEXT ("iterating (%d): [%s, %s]\n"),
246 // And now test the const iterator
248 HASH_STRING_ENTRY
*entry
= 0;
251 for (HASH_STRING_CONST_ITER
hash_iter (hash
);
252 hash_iter
.next (entry
) != 0;
253 hash_iter
.advance ())
255 ACE_DEBUG ((LM_DEBUG
,
256 ACE_TEXT ("const iterating (%d): [%s, %s]\n"),
264 hash
.unbind (string_table
[2].key_
, entry
);
266 // Check the <find> operation again.
267 for (i
= 0; string_table
[i
].key_
!= 0; i
++)
268 if (hash
.find (string_table
[i
].key_
,
270 ACE_DEBUG ((LM_DEBUG
,
271 ACE_TEXT ("`%s' found `%s'\n"),
272 string_table
[i
].key_
,
275 ACE_ERROR_RETURN ((LM_ERROR
,
276 ACE_TEXT ("`%s' not found\n"),
277 string_table
[i
].key_
),
280 // Let's test the iterator backwards.
282 HASH_STRING_ENTRY
*entry
= 0;
285 for (HASH_STRING_REVERSE_ITER
hash_iter (hash
);
286 hash_iter
.next (entry
) != 0;
287 hash_iter
.advance ())
289 ACE_DEBUG ((LM_DEBUG
,
290 ACE_TEXT ("iterating (%d): [%s, %s]\n"),
298 // Remove all the entries.
299 if (hash
.unbind_all () != 0)
300 ACE_ERROR_RETURN ((LM_ERROR
,
301 ACE_TEXT ("unbind_all failed\n")),
304 // Redo the <bind> operations.
305 for (i
= 0; string_table
[i
].key_
!= 0; i
++)
306 if (hash
.bind (string_table
[i
].key_
,
307 string_table
[i
].value_
) != 0)
308 ACE_ERROR_RETURN ((LM_ERROR
,
309 ACE_TEXT ("%p failed for %s\n"),
311 string_table
[i
].key_
), -1);
313 ace_test_allocator
.dump ();
315 test_two_allocators();
317 // Run the STL algorithm test on the hash map.
318 const HASH_STRING_MAP
& chash
= hash
;
320 test_STL_algorithm (hash
);
321 test_STL_algorithm (chash
);
327 run_main (int, ACE_TCHAR
*[])
329 ACE_START_TEST (ACE_TEXT ("Hash_Map_Manager_Test"));