Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / examples / APG / Shared_Memory / Hash_Map.cpp
blobd4f7de29e54d1617f80abbe0ab14fe0946425bbe
1 #include "ace/OS_NS_stdio.h"
3 // Listing 1 code/ch17
4 #include "ace/MMAP_Memory_Pool.h"
5 #include "ace/Hash_Map_With_Allocator_T.h"
6 #include "ace/Malloc_T.h"
7 #include "ace/PI_Malloc.h"
8 #include "ace/Process_Mutex.h"
9 #include "ace/Process.h"
11 #define BACKING_STORE "map.store"
12 #define MAP_NAME "records.db"
14 #include "Record.h"
16 typedef ACE_Allocator_Adapter<ACE_Malloc_T <ACE_MMAP_MEMORY_POOL,
17 ACE_Process_Mutex,
18 ACE_Control_Block>
19 > ALLOCATOR;
20 typedef ACE_Hash_Map_With_Allocator<int, Record> HASH_MAP;
22 ACE_Process_Mutex coordMutex("Coord-Mutex");
23 // Listing 1
25 // Listing 2 code/ch17
26 HASH_MAP* smap (ALLOCATOR *shmem_allocator)
28 void *db = 0;
29 if (shmem_allocator->find (MAP_NAME, db) == 0)
30 return (HASH_MAP *) db;
31 size_t hash_table_size = sizeof (HASH_MAP);
32 void *hash_map = shmem_allocator->malloc (hash_table_size);
33 if (hash_map == 0)
34 return 0;
35 new (hash_map) HASH_MAP (hash_table_size, shmem_allocator);
36 if (shmem_allocator->bind (MAP_NAME, hash_map) == -1)
38 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
39 ACE_TEXT ("allocate_map")));
40 shmem_allocator->remove ();
41 return 0;
43 return (HASH_MAP*)hash_map;
45 // Listing 2
46 // Listing 6 code/ch17
47 int processRecords (HASH_MAP *map, ALLOCATOR *shmem_allocator)
49 ACE_TRACE ("processRecords");
51 size_t mapLength = map->current_size ();
52 ACE_DEBUG ((LM_DEBUG,
53 ACE_TEXT ("(%P|%t) Found %d records\n\n"),
54 mapLength));
56 int *todelete = new int[mapLength];
57 int i = 0;
59 for (HASH_MAP::iterator iter = map->begin ();
60 iter != map->end ();
61 iter++)
63 int key = (*iter).ext_id_;
64 ACE_DEBUG ((LM_DEBUG,
65 ACE_TEXT ("(%P|%t) [%d] Preprocessing %d:%@\n"),
66 i+1, key, &(*iter).ext_id_));
68 todelete[i++] = key; // Mark message for deletion.
70 // Illustrate the find feature of the map.
71 Record record;
72 int result = map->find (key, record, shmem_allocator);
73 if (result == -1)
74 ACE_DEBUG ((LM_ERROR,
75 ACE_TEXT ("Could not find record for %d\n"),
76 key));
77 else
78 ACE_DEBUG ((LM_DEBUG,
79 ACE_TEXT ("Record name: %C|id1:%d|id2:%d\n"),
80 record.name (), record.id1(), record.id2()));
83 // Delete everything we processed.
84 for (int j = 0; j < i ; j++)
86 int result = map->unbind (todelete[j],
87 shmem_allocator);
88 if (result == -1)
89 ACE_ERROR_RETURN ((LM_ERROR,
90 ACE_TEXT ("Failed on key %d: %p\n"),
91 ACE_TEXT ("unbind"),
92 todelete[j]),
93 -1);
94 else
95 ACE_DEBUG ((LM_INFO,
96 ACE_TEXT ("Fully processed and removed %d\n"),
97 j));
100 delete [] todelete;
102 return 0;
104 // Listing 6
105 // Listing 4 code/ch17
106 int addRecords(HASH_MAP *map, ALLOCATOR *shmem_allocator)
108 ACE_TRACE ("addRecords");
110 char buf[32];
111 int mapLength = static_cast<int> (map->current_size ());
112 ACE_DEBUG ((LM_DEBUG,
113 ACE_TEXT ("Map has %d entries; adding 20 more\n"),
114 mapLength));
116 for (int i = mapLength ; i < mapLength + 20; i++)
118 ACE_OS::sprintf (buf, "%s:%d", "Record", i);
120 // Allocate new record on stack;
121 Record newRecord (i, i+1, buf);
122 ACE_DEBUG ((LM_DEBUG,
123 ACE_TEXT ("Adding a record for %d\n"), i));
125 int result = map->bind (i, newRecord, shmem_allocator);
126 if (result == -1)
127 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
128 ACE_TEXT ("bind failed")), -1);
131 return 0;
133 // Listing 4
134 // Listing 5 code/ch17
135 int handle_child ()
137 ACE_TRACE ("handle_child");
139 ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, coordMutex, -1);
141 ALLOCATOR * shmem_allocator = 0;
142 ACE_MMAP_Memory_Pool_Options options
143 (ACE_DEFAULT_BASE_ADDR,
144 ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED);
146 ACE_NEW_RETURN (shmem_allocator,
147 ALLOCATOR (BACKING_STORE,
148 BACKING_STORE,
149 &options),
150 -1);
152 HASH_MAP *map = smap (shmem_allocator);
154 ACE_DEBUG ((LM_DEBUG,
155 ACE_TEXT ("(%P|%t) Map has %d entries\n"),
156 map->current_size ()));
157 ACE_DEBUG ((LM_DEBUG,
158 ACE_TEXT ("In child, map is located at %@\n"),
159 map));
161 processRecords (map, shmem_allocator);
162 shmem_allocator->sync ();
163 delete shmem_allocator;
165 return 0;
167 // Listing 5
168 // Listing 3 code/ch17
169 int handle_parent (ACE_TCHAR *cmdLine)
171 ACE_TRACE ("handle_parent");
173 ALLOCATOR * shmem_allocator = 0;
174 ACE_MMAP_Memory_Pool_Options options
175 (ACE_DEFAULT_BASE_ADDR,
176 ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED);
178 ACE_NEW_RETURN
179 (shmem_allocator,
180 ALLOCATOR (BACKING_STORE, BACKING_STORE, &options),
181 -1);
183 HASH_MAP *map = smap (shmem_allocator);
185 ACE_Process processa, processb;
186 ACE_Process_Options poptions;
187 const ACE_TCHAR *args[3];
188 args[0] = cmdLine;
189 args[1] = ACE_TEXT ("a");
190 args[2] = 0;
191 poptions.command_line (args);
193 ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon,
194 coordMutex, -1);
195 ACE_DEBUG ((LM_DEBUG,
196 ACE_TEXT ("(%P|%t) Map has %d entries\n"),
197 map->current_size ()));
198 ACE_DEBUG ((LM_DEBUG,
199 ACE_TEXT ("In parent, map is located at %@\n"),
200 map));
202 // Then have the child show and eat them up.
203 processa.spawn (poptions);
205 // First append a few records.
206 addRecords (map, shmem_allocator);
211 ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon,
212 coordMutex, -1);
214 // Add a few more records..
215 addRecords (map, shmem_allocator);
217 // Let's see what's left.
218 ACE_DEBUG ((LM_DEBUG,
219 ACE_TEXT ("(%P|%t) Parent finished adding, ")
220 ACE_TEXT ("map has %d entries\n"),
221 map->current_size ()));
223 // Have another child try to eat them up.
224 processb.spawn (poptions);
227 processa.wait ();
228 processb.wait ();
230 // No processes are left and we don't want to keep the data
231 // around anymore; it's now safe to remove it.
232 // !!This will remove the backing store.!!
233 shmem_allocator->remove ();
234 delete shmem_allocator;
235 return 0;
238 int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
240 if (argc == 1) // parent
241 ACE_ASSERT (handle_parent (argv[0]) == 0);
242 else
243 ACE_ASSERT (handle_child () == 0);
245 ACE_UNUSED_ARG (argv);
246 return 0;
248 // Listing 3