Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Hash_Map_Manager_T.cpp
blob579b7784b56ec73e3172d58bb05aad7f78fe047f
2 //=============================================================================
3 /**
4 * @file Hash_Map_Manager_T.cpp
6 * @author Douglas C. Schmidt <schmidt@cse.wustl.edu>
7 */
8 //=============================================================================
11 #ifndef ACE_HASH_MAP_MANAGER_T_CPP
12 #define ACE_HASH_MAP_MANAGER_T_CPP
14 #include "ace/Hash_Map_Manager_T.h"
16 #if !defined (ACE_LACKS_PRAGMA_ONCE)
17 # pragma once
18 #endif /* ACE_LACKS_PRAGMA_ONCE */
20 #if !defined (__ACE_INLINE__)
21 # include "ace/Hash_Map_Manager_T.inl"
22 #endif /* __ACE_INLINE__ */
24 #include "ace/Malloc_Base.h"
26 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
28 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Manager_Ex)
29 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Iterator_Base_Ex)
30 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Iterator_Ex)
31 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Const_Iterator_Base_Ex)
32 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Const_Iterator_Ex)
33 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Reverse_Iterator_Ex)
34 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Map_Const_Reverse_Iterator_Ex)
36 template <class EXT_ID, class INT_ID>
37 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_Entry (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next,
38 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev)
39 : next_ (next),
40 prev_ (prev)
44 template <class EXT_ID, class INT_ID>
45 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_Entry (const EXT_ID &ext_id,
46 const INT_ID &int_id,
47 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next,
48 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev)
49 : ext_id_ (ext_id),
50 int_id_ (int_id),
51 next_ (next),
52 prev_ (prev)
56 template <class EXT_ID, class INT_ID>
57 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry ()
61 template <class EXT_ID, class INT_ID> EXT_ID &
62 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::key ()
64 return ext_id_;
67 template <class EXT_ID, class INT_ID> const EXT_ID &
68 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::key () const
70 return ext_id_;
73 template <class EXT_ID, class INT_ID> INT_ID &
74 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::item ()
76 return int_id_;
79 template <class EXT_ID, class INT_ID> const INT_ID &
80 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::item () const
82 return int_id_;
85 template <class EXT_ID, class INT_ID> void
86 ACE_Hash_Map_Entry<EXT_ID, INT_ID>::dump () const
88 #if defined (ACE_HAS_DUMP)
89 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
90 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
91 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("prev_ = %d"), this->prev_));
92 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
93 #endif /* ACE_HAS_DUMP */
96 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
97 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump () const
99 #if defined (ACE_HAS_DUMP)
100 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
101 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("total_size_ = %d\n"), this->total_size_));
102 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("cur_size_ = %d\n"), this->cur_size_));
103 this->table_allocator_->dump ();
104 this->entry_allocator_->dump ();
105 this->lock_.dump ();
106 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
107 #endif /* ACE_HAS_DUMP */
110 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
111 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::create_buckets (size_t size)
113 size_t bytes = size * sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>);
114 void *ptr = 0;
116 ACE_ALLOCATOR_RETURN (ptr,
117 this->table_allocator_->malloc (bytes),
118 -1);
120 this->table_ = (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *) ptr;
122 this->total_size_ = size;
124 // Initialize each entry in the hash table to be a circular linked
125 // list with the dummy node in the front serving as the anchor of
126 // the list.
127 for (size_t i = 0; i < size; i++)
128 new (&this->table_[i]) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (&this->table_[i],
129 &this->table_[i]);
130 return 0;
133 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
134 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open (size_t size,
135 ACE_Allocator *table_alloc,
136 ACE_Allocator *entry_alloc)
138 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
140 // Calling this->close_i () to ensure we release previous allocated
141 // memory before allocating new one.
142 this->close_i ();
144 if (table_alloc == 0)
145 table_alloc = ACE_Allocator::instance ();
147 this->table_allocator_ = table_alloc;
149 if (entry_alloc == 0)
150 entry_alloc = table_alloc;
152 this->entry_allocator_ = entry_alloc;
154 // This assertion is here to help track a situation that shouldn't
155 // happen, but did with Sun C++ 4.1 (before a change to this class
156 // was made: it used to have an enum that was supposed to be defined
157 // to be ACE_DEFAULT_MAP_SIZE, but instead was defined to be 0).
158 if (size == 0)
159 return -1;
161 return this->create_buckets (size);
164 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
165 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::close_i ()
167 // Protect against "double-deletion" in case the destructor also
168 // gets called.
169 if (this->table_ != 0)
171 // Remove all the entries.
172 this->unbind_all_i ();
174 // Iterate through the buckets cleaning up the sentinels.
175 for (size_t i = 0; i < this->total_size_; i++)
177 // Destroy the dummy entry.
178 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry = &this->table_[i];
180 // The second argument results in a no-op instead of
181 // deallocation.
182 ACE_DES_FREE_TEMPLATE2 (entry, ACE_NOOP,
183 ACE_Hash_Map_Entry, EXT_ID, INT_ID);
186 // Reset size.
187 this->total_size_ = 0;
189 // Free table memory.
190 this->table_allocator_->free (this->table_);
192 // Should be done last...
193 this->table_ = 0;
196 return 0;
199 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
200 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_all_i ()
202 // Iterate through the entire map calling the destuctor of each
203 // <ACE_Hash_Map_Entry>.
204 for (size_t i = 0; i < this->total_size_; i++)
206 for (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp_ptr = this->table_[i].next_;
207 temp_ptr != &this->table_[i];
210 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *hold_ptr = temp_ptr;
211 temp_ptr = temp_ptr->next_;
213 // Explicitly call the destructor.
214 ACE_DES_FREE_TEMPLATE2 (hold_ptr, this->entry_allocator_->free,
215 ACE_Hash_Map_Entry, EXT_ID, INT_ID);
218 // Restore the sentinel.
219 this->table_[i].next_ = &this->table_[i];
220 this->table_[i].prev_ = &this->table_[i];
223 this->cur_size_ = 0;
225 return 0;
228 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
229 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
230 const INT_ID &int_id,
231 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
233 size_t loc = 0;
234 if (this->shared_find (ext_id, entry, loc) == -1)
236 void *ptr = 0;
237 // Not found.
238 ACE_ALLOCATOR_RETURN (ptr,
239 this->entry_allocator_->malloc (sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>)),
240 -1);
242 entry = new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id,
243 int_id,
244 this->table_[loc].next_,
245 &this->table_[loc]);
246 this->table_[loc].next_ = entry;
247 entry->next_->prev_ = entry;
248 ++this->cur_size_;
249 return 0;
251 else
252 return 1;
255 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
256 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
257 INT_ID &int_id,
258 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
260 size_t loc = 0;
261 if (this->shared_find (ext_id, entry, loc) == -1)
263 // Not found.
264 void *ptr = 0;
265 ACE_ALLOCATOR_RETURN (ptr,
266 this->entry_allocator_->malloc (sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>)),
267 -1);
269 entry = new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id,
270 int_id,
271 this->table_[loc].next_,
272 &this->table_[loc]);
273 this->table_[loc].next_ = entry;
274 entry->next_->prev_ = entry;
275 ++this->cur_size_;
276 return 0;
278 else
279 return 1;
282 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
283 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
284 INT_ID &int_id)
286 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = 0;
288 size_t loc = 0;
289 if (this->shared_find (ext_id, temp, loc) == -1)
291 errno = ENOENT;
292 return -1;
295 int_id = temp->int_id_;
297 return this->unbind_i (temp);
300 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
301 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry)
303 entry->next_->prev_ = entry->prev_;
304 entry->prev_->next_ = entry->next_;
306 // Explicitly call the destructor.
307 ACE_DES_FREE_TEMPLATE2 (entry, this->entry_allocator_->free,
308 ACE_Hash_Map_Entry, EXT_ID, INT_ID);
310 --this->cur_size_;
311 return 0;
314 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
315 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
316 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry,
317 size_t &loc)
319 if (this->total_size_ == 0)
321 errno = ENOENT;
322 return -1;
325 loc = this->hash (ext_id) % this->total_size_;
327 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc].next_;
329 while (temp != &this->table_[loc] && this->equal (temp->ext_id_, ext_id) == 0)
330 temp = temp->next_;
332 if (temp == &this->table_[loc])
334 errno = ENOENT;
335 return -1;
337 else
339 entry = temp;
340 return 0;
344 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
345 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
346 const INT_ID &int_id,
347 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
349 size_t dummy = 0;
350 if (this->shared_find (ext_id, entry, dummy) == -1)
351 return this->bind_i (ext_id, int_id);
352 else
354 entry->ext_id_ = ext_id;
355 entry->int_id_ = int_id;
356 return 1;
360 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
361 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
362 const INT_ID &int_id,
363 INT_ID &old_int_id,
364 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
366 size_t dummy = 0;
367 if (this->shared_find (ext_id, entry, dummy) == -1)
368 return this->bind_i (ext_id, int_id);
369 else
371 old_int_id = entry->int_id_;
372 entry->ext_id_ = ext_id;
373 entry->int_id_ = int_id;
374 return 1;
378 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
379 ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
380 const INT_ID &int_id,
381 EXT_ID &old_ext_id,
382 INT_ID &old_int_id,
383 ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
385 size_t dummy = 0;
386 if (this->shared_find (ext_id, entry, dummy) == -1)
387 return this->bind_i (ext_id, int_id);
388 else
390 old_ext_id = entry->ext_id_;
391 old_int_id = entry->int_id_;
392 entry->ext_id_ = ext_id;
393 entry->int_id_ = int_id;
394 return 1;
398 // ------------------------------------------------------------
400 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
401 ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i () const
403 ACE_TRACE ("ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
405 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
406 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
407 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
408 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
411 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
412 ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i ()
414 ACE_TRACE ("ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
416 if (this->map_man_->table_ == 0)
417 return -1;
418 // Handle initial case specially.
419 else if (this->index_ == -1)
421 this->index_++;
422 return this->forward_i ();
424 else if (this->index_ >= static_cast<ssize_t> (this->map_man_->total_size_))
425 return 0;
427 this->next_ = this->next_->next_;
428 if (this->next_ == &this->map_man_->table_[this->index_])
430 while (++this->index_ < static_cast<ssize_t> (this->map_man_->total_size_))
432 this->next_ = this->map_man_->table_[this->index_].next_;
433 if (this->next_ != &this->map_man_->table_[this->index_])
434 break;
438 return this->index_ < static_cast<ssize_t> (this->map_man_->total_size_);
441 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
442 ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i ()
444 ACE_TRACE ("ACE_Hash_Map_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
446 if (this->map_man_->table_ == 0)
447 return -1;
448 else if (this->index_ == static_cast<ssize_t> (this->map_man_->total_size_))
450 --this->index_;
451 return this->reverse_i ();
453 else if (this->index_ < 0)
454 return 0;
456 this->next_ = this->next_->prev_;
457 if (this->next_ == &this->map_man_->table_[this->index_])
459 while (--this->index_ >= 0)
461 this->next_ = this->map_man_->table_[this->index_].prev_;
462 if (this->next_ != &this->map_man_->table_[this->index_])
463 break;
467 return this->index_ >= 0;
470 // ------------------------------------------------------------
472 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
473 ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i () const
475 ACE_TRACE ("ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
477 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
478 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
479 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
480 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
483 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
484 ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i ()
486 ACE_TRACE ("ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
488 if (this->map_man_->table_ == 0)
489 return -1;
490 // Handle initial case specially.
491 else if (this->index_ == -1)
493 ++this->index_;
494 return this->forward_i ();
496 else if (this->index_ >= (ssize_t) this->map_man_->total_size_)
497 return 0;
499 this->next_ = this->next_->next_;
500 if (this->next_ == &this->map_man_->table_[this->index_])
502 while (++this->index_ < (ssize_t) this->map_man_->total_size_)
504 this->next_ = this->map_man_->table_[this->index_].next_;
505 if (this->next_ != &this->map_man_->table_[this->index_])
506 break;
510 return this->index_ < (ssize_t) this->map_man_->total_size_;
513 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
514 ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i ()
516 ACE_TRACE ("ACE_Hash_Map_Const_Iterator_Base_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
518 if (this->map_man_->table_ == 0)
519 return -1;
520 else if (this->index_ == (ssize_t) this->map_man_->total_size_)
522 --this->index_;
523 return this->reverse_i ();
525 else if (this->index_ < 0)
526 return 0;
528 this->next_ = this->next_->prev_;
529 if (this->next_ == &this->map_man_->table_[this->index_])
531 while (--this->index_ >= 0)
533 this->next_ = this->map_man_->table_[this->index_].prev_;
534 if (this->next_ != &this->map_man_->table_[this->index_])
535 break;
539 return this->index_ >= 0;
542 ACE_END_VERSIONED_NAMESPACE_DECL
544 #endif /* ACE_HASH_MAP_MANAGER_T_CPP */