Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / tests / Hash_Map_Manager_Test.cpp
blobef9ffe69760961c015632520efaf44cc34865b38
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"
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 *,
39 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 *,
45 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 *,
51 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 *,
57 const ACE_TCHAR *,
58 ACE_Hash<const ACE_TCHAR *>,
59 ACE_Equal_To<const ACE_TCHAR *>,
60 ACE_Null_Mutex> HASH_STRING_REVERSE_ITER;
62 struct String_Table
64 const ACE_TCHAR *key_;
65 const ACE_TCHAR *value_;
68 static String_Table string_table[] =
71 ACE_TEXT ("hello"),
72 ACE_TEXT ("guten Tag")
75 ACE_TEXT ("goodbye"),
76 ACE_TEXT ("auf wiedersehen")
79 ACE_TEXT ("funny"),
80 ACE_TEXT ("lustig")
88 static
89 int test_two_allocators ()
91 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing both allocators\n")));
92 int status = 0;
94 // Number of entries in string_table above:
95 size_t chunks = 3;
96 size_t chunk_size = sizeof (HASH_STRING_MAP::ENTRY);
98 // Allocators:
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);
112 if (status < 0)
113 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed: %d (%s)\n"),
114 status, ACE_OS::strerror (ACE_OS::last_error ())));
115 else
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 ()));
125 ACE_DEBUG
126 ((LM_DEBUG,
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);
130 if (status < 0)
131 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
132 status, ACE_OS::strerror (ACE_OS::last_error ())), -1);
133 else
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_);
147 if (status < 0)
148 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("*** Something is wrong: %d (%s)\n"),
149 status, ACE_OS::strerror (ACE_OS::last_error ())), -1);
150 else
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"),
159 key, val));
160 ACE_OS::last_error (0);
161 status = hash.bind (key, val);
162 if (status < 0)
163 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("OK, failed (%s).\n"),
164 ACE_OS::strerror (ACE_OS::last_error ())));
165 else
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 ()));
177 return 0;
180 static int
181 run_test (void)
183 ace_test_allocator.dump ();
185 HASH_STRING_MAP hash (MAX_HASH, &ace_test_allocator);
187 size_t i;
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"),
195 ACE_TEXT ("bind"),
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_,
203 entry) == 0)
204 ACE_DEBUG ((LM_DEBUG,
205 ACE_TEXT ("`%s' found `%s'\n"),
206 string_table[i].key_,
207 entry));
208 else
209 ACE_ERROR_RETURN ((LM_ERROR,
210 ACE_TEXT ("`%s' not found\n"),
211 string_table[i].key_),
212 -1);
214 // Check the <trybind> operation.
216 const ACE_TCHAR *pc = string_table[1].value_;
217 if (hash.trybind (string_table[0].key_,
218 pc) != 1)
219 ACE_ERROR_RETURN ((LM_ERROR,
220 ACE_TEXT ("::trybind missed existing entry.")),
221 -1);
222 else if (pc != string_table[0].value_)
223 ACE_ERROR_RETURN ((LM_ERROR,
224 ACE_TEXT ("::trybind doesn't return existing value.")),
225 -1);
228 // Let's test the iterator while we are at it.
230 HASH_STRING_ENTRY *entry = 0;
231 size_t i = 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"),
240 entry->ext_id_,
241 entry->int_id_));
242 i++;
246 // And now test the const iterator
248 HASH_STRING_ENTRY *entry = 0;
249 size_t i = 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"),
258 entry->ext_id_,
259 entry->int_id_));
260 i++;
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_,
269 entry) == 0)
270 ACE_DEBUG ((LM_DEBUG,
271 ACE_TEXT ("`%s' found `%s'\n"),
272 string_table[i].key_,
273 entry));
274 else if (i != 2)
275 ACE_ERROR_RETURN ((LM_ERROR,
276 ACE_TEXT ("`%s' not found\n"),
277 string_table[i].key_),
278 -1);
280 // Let's test the iterator backwards.
282 HASH_STRING_ENTRY *entry = 0;
283 size_t i = 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"),
292 entry->ext_id_,
293 entry->int_id_));
294 i++;
298 // Remove all the entries.
299 if (hash.unbind_all () != 0)
300 ACE_ERROR_RETURN ((LM_ERROR,
301 ACE_TEXT ("unbind_all failed\n")),
302 -1);
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"),
310 ACE_TEXT ("bind"),
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);
323 return 0;
327 run_main (int, ACE_TCHAR *[])
329 ACE_START_TEST (ACE_TEXT ("Hash_Map_Manager_Test"));
331 run_test ();
333 ACE_END_TEST;
335 return 0;