Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Map_Manager.cpp
blob9b5e9052e44dffba4b27938823f97c28a90eb8ba
1 #ifndef ACE_MAP_MANAGER_CPP
2 #define ACE_MAP_MANAGER_CPP
4 #include "ace/Map_Manager.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 # pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #include "ace/Malloc_Base.h"
12 #if !defined (__ACE_INLINE__)
13 #include "ace/Map_Manager.inl"
14 #endif /* __ACE_INLINE__ */
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Map_Entry)
19 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Manager)
20 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Const_Iterator_Base)
21 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Iterator_Base)
22 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Const_Iterator)
23 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Iterator)
24 ACE_ALLOC_HOOK_DEFINE_Tccc(ACE_Map_Reverse_Iterator)
26 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
27 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::open (size_t size,
28 ACE_Allocator *alloc)
30 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
32 // Close old map (if any).
33 this->close_i ();
35 // Use the user specified allocator or the default singleton one.
36 if (alloc == 0)
37 alloc = ACE_Allocator::instance ();
39 this->allocator_ = alloc;
41 // This assertion is here to help track a situation that shouldn't
42 // happen.
43 ACE_ASSERT (size != 0);
45 // Active_Map_Manager depends on the <slot_index_> being of fixed
46 // size. It cannot be size_t because size_t is 64-bits on 64-bit
47 // platform and 32-bits on 32-bit platforms. Size of the <slot_index_>
48 // has to be consistent across platforms. ACE_UIN32 is chosen as
49 // ACE_UIN32_MAX is big enough. The assert is to ensure that the user
50 // doesn't open the ACE_Map_Manager with a bigger size than we can
51 // handle.
52 ACE_ASSERT (size <= ACE_UINT32_MAX);
54 // Resize from 0 to <size>. Note that this will also set up the
55 // circular free list.
56 return this->resize_i ((ACE_UINT32) size);
59 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
60 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::close_i ()
62 // Free entries.
63 this->free_search_structure ();
65 // Reset sizes.
66 this->total_size_ = 0;
67 this->cur_size_ = 0;
69 // Reset circular free list.
70 this->free_list_.next (this->free_list_id ());
71 this->free_list_.prev (this->free_list_id ());
73 // Reset circular occupied list.
74 this->occupied_list_.next (this->occupied_list_id ());
75 this->occupied_list_.prev (this->occupied_list_id ());
77 return 0;
80 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
81 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
82 const INT_ID &int_id)
84 // Try to find the key.
85 ACE_UINT32 slot = 0;
86 int result = this->find_and_return_index (ext_id,
87 slot);
89 if (result == 0)
90 // We found the key. Nothing to change.
91 return 1;
92 else
93 // We didn't find the key.
94 return this->shared_bind (ext_id,
95 int_id);
98 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
99 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::next_free (ACE_UINT32 &free_slot)
101 // Look in the free list for an empty slot.
102 free_slot = this->free_list_.next ();
104 // If we do find a free slot, return successfully.
105 if (free_slot != this->free_list_id ())
106 return 0;
108 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
110 // Move any free slots from occupied list to free list.
111 this->move_all_free_slots_from_occupied_list ();
113 // Try again in case we found any free slots in the occupied list.
114 free_slot = this->free_list_.next ();
116 // If we do find a free slot, return successfully.
117 if (free_slot != this->free_list_id ())
118 return 0;
120 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
122 // Resize the map.
123 int result = this->resize_i (this->new_size ());
125 // Check for errors.
126 if (result == 0)
127 // New free slot.
128 free_slot = this->free_list_.next ();
130 return result;
133 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
135 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
136 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::move_all_free_slots_from_occupied_list ()
139 // In the case of lazy map managers, the movement of free slots from
140 // the occupied list to the free list is delayed until we run out of
141 // free slots in the free list.
144 // Go through the entire occupied list, moving free slots to the
145 // free list. Note that all free slots in the occupied list are
146 // moved in this loop.
147 for (ACE_UINT32 i = this->occupied_list_.next ();
148 i != this->occupied_list_id ();
152 // Note the trick used here: Information about the current slot
153 // is first noted; <i> then moves to the next occupied slot;
154 // only after this is the slot (potentially) moved from the
155 // occupied list to the free list. This order of things, i.e.,
156 // moving <i> before moving the free slot is necessary,
157 // otherwise we'll forget which our next occupied slot is.
160 // Note information about current slot.
161 ACE_Map_Entry<EXT_ID, INT_ID> &current_slot = this->search_structure_[i];
162 ACE_UINT32 position_of_current_slot = i;
164 // Move <i> to next occupied slot.
165 i = this->search_structure_[i].next ();
167 // If current slot is free
168 if (current_slot.free_)
170 // Reset free flag to zero before moving to free list.
171 current_slot.free_ = false;
173 // Move from occupied list to free list.
174 this->move_from_occupied_list_to_free_list (position_of_current_slot);
179 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
181 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
182 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_move (ACE_UINT32 slot,
183 ACE_Map_Entry<EXT_ID, INT_ID> &current_list,
184 ACE_UINT32 current_list_id,
185 ACE_Map_Entry<EXT_ID, INT_ID> &new_list,
186 ACE_UINT32 new_list_id)
188 // Grab the entry.
189 ENTRY &entry = this->search_structure_[slot];
191 // Remove from current list.
193 // Fix the entry before us.
194 ACE_UINT32 current_list_prev = entry.prev ();
196 if (current_list_prev == current_list_id)
197 current_list.next (entry.next ());
198 else
199 this->search_structure_[current_list_prev].next (entry.next ());
201 // Fix the entry after us.
202 ACE_UINT32 current_list_next = entry.next ();
204 if (current_list_next == current_list_id)
205 current_list.prev (entry.prev ());
206 else
207 this->search_structure_[current_list_next].prev (entry.prev ());
209 // Add to new list.
211 // Fix us.
212 ACE_UINT32 new_list_next = new_list.next ();
213 entry.next (new_list_next);
214 entry.prev (new_list_id);
216 // Fix entry before us.
217 new_list.next (slot);
219 // Fix entry after us.
220 if (new_list_next == new_list_id)
221 new_list.prev (slot);
222 else
223 this->search_structure_[new_list_next].prev (slot);
226 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
227 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_bind (const EXT_ID &ext_id,
228 const INT_ID &int_id)
230 // This function assumes that the find() has already been done, and
231 // therefore, simply adds to the map.
233 // Find an empty slot.
234 ACE_UINT32 slot = 0;
235 int result = this->next_free (slot);
237 if (result == 0)
239 // Copy key and value.
240 this->search_structure_[slot].int_id_ = int_id;
241 this->search_structure_[slot].ext_id_ = ext_id;
243 // Move from free list to occupied list
244 this->move_from_free_list_to_occupied_list (slot);
246 // Update the current size.
247 ++this->cur_size_;
250 return result;
253 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
254 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
255 const INT_ID &int_id,
256 EXT_ID &old_ext_id,
257 INT_ID &old_int_id)
259 // First try to find the key.
260 ACE_UINT32 slot = 0;
261 int result = this->find_and_return_index (ext_id,
262 slot);
263 if (result == 0)
265 // We found it, so make copies of the old entries and rebind
266 // current entries.
267 ENTRY &ss = this->search_structure_[slot];
268 old_ext_id = ss.ext_id_;
269 old_int_id = ss.int_id_;
270 ss.ext_id_ = ext_id;
271 ss.int_id_ = int_id;
273 // Sync changed entry.
274 this->allocator_->sync (&ss, sizeof ss);
276 return 1;
278 else
279 // We didn't find it, so let's add it.
280 return this->shared_bind (ext_id,
281 int_id);
284 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
285 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
286 const INT_ID &int_id,
287 INT_ID &old_int_id)
289 // First try to find the key.
290 ACE_UINT32 slot = 0;
291 int result = this->find_and_return_index (ext_id,
292 slot);
293 if (result == 0)
295 // We found it, so make copies of the old entries and rebind
296 // current entries.
297 ENTRY &ss = this->search_structure_[slot];
298 old_int_id = ss.int_id_;
299 ss.ext_id_ = ext_id;
300 ss.int_id_ = int_id;
302 // Sync changed entry.
303 this->allocator_->sync (&ss, sizeof ss);
305 return 1;
307 else
308 // We didn't find it, so let's add it.
309 return this->shared_bind (ext_id,
310 int_id);
313 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
314 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
315 const INT_ID &int_id)
317 // First try to find the key.
318 ACE_UINT32 slot = 0;
319 int result = this->find_and_return_index (ext_id,
320 slot);
321 if (result == 0)
323 // We found it, so rebind current entries.
324 ENTRY &ss = this->search_structure_[slot];
325 ss.ext_id_ = ext_id;
326 ss.int_id_ = int_id;
328 // Sync changed entry.
329 this->allocator_->sync (&ss, sizeof ss);
331 return 1;
333 else
334 // We didn't find it, so let's add it.
335 return this->shared_bind (ext_id,
336 int_id);
339 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
340 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
341 INT_ID &int_id)
343 // Try to find the key.
344 ACE_UINT32 slot = 0;
345 int result = this->find_and_return_index (ext_id,
346 slot);
347 if (result == 0)
349 // Key was found. Make a copy of value, but *don't* update
350 // anything in the map!
351 int_id = this->search_structure_[slot].int_id_;
352 return 1;
354 else
355 // We didn't find it, so let's bind it!
356 return this->bind_i (ext_id,
357 int_id);
360 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
361 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_and_return_index (const EXT_ID &ext_id,
362 ACE_UINT32 &slot)
364 // Go through the entire occupied list looking for the key.
365 for (ACE_UINT32 i = this->occupied_list_.next ();
366 i != this->occupied_list_id ();
367 i = this->search_structure_[i].next ())
369 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
370 if (this->search_structure_[i].free_)
371 continue;
372 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
374 if (this->equal (this->search_structure_[i].ext_id_,
375 ext_id))
377 // If found, return slot.
378 slot = i;
379 return 0;
383 // Key was not found.
384 return -1;
387 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
388 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_all ()
390 // Go through the entire occupied list.
391 for (ACE_UINT32 i = this->occupied_list_.next ();
392 i != this->occupied_list_id ();
396 // Note the trick used here: Information about the current slot
397 // is first noted; <i> then moves to the next occupied slot;
398 // only after this is the slot (potentially) moved from the
399 // occupied list to the free list. This order of things, i.e.,
400 // moving <i> before moving the free slot is necessary,
401 // otherwise we'll forget which our next occupied slot is.
404 // Note information about current slot.
405 ACE_Map_Entry<EXT_ID, INT_ID> &current_slot =
406 this->search_structure_[i];
407 ACE_UINT32 position_of_current_slot = i;
409 // Move <i> to next occupied slot.
410 i = current_slot.next ();
412 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
413 if (current_slot.free_)
414 continue;
415 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
417 this->unbind_slot (position_of_current_slot);
421 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
422 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i (const EXT_ID &ext_id,
423 INT_ID &int_id)
425 // Try to find the key.
426 ACE_UINT32 slot = 0;
427 int result = this->find_and_return_index (ext_id,
428 slot);
429 if (result == 0)
430 // Key was found. Make a copy of value.
431 int_id = this->search_structure_[slot].int_id_;
433 return result;
436 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
437 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_and_return_index (const EXT_ID &ext_id,
438 ACE_UINT32 &slot)
440 // Try to find the key.
441 int result = this->find_and_return_index (ext_id,
442 slot);
444 if (result == 0)
445 this->unbind_slot (slot);
447 return result;
450 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
451 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_slot (ACE_UINT32 slot)
453 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
456 // In the case of lazy map managers, the movement of free slots
457 // from the occupied list to the free list is delayed until we
458 // run out of free slots in the free list.
461 this->search_structure_[slot].free_ = true;
463 #else
465 // Move from occupied list to free list.
466 this->move_from_occupied_list_to_free_list (slot);
468 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
470 // Update the current size.
471 --this->cur_size_;
474 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
475 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
476 INT_ID &int_id)
478 // Unbind the entry.
479 ACE_UINT32 slot = 0;
480 int result = this->unbind_and_return_index (ext_id,
481 slot);
482 if (result == 0)
483 // If found, copy the value.
484 int_id = this->search_structure_[slot].int_id_;
486 return result;
489 template <class EXT_ID, class INT_ID, class ACE_LOCK> int
490 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::resize_i (ACE_UINT32 new_size)
492 ACE_UINT32 i;
493 ENTRY *temp = 0;
495 // Allocate new memory.
496 ACE_ALLOCATOR_RETURN (temp,
497 (ENTRY *) this->allocator_->malloc (new_size * sizeof (ENTRY)),
498 -1);
500 // Copy over the occupied entires.
501 for (i = this->occupied_list_.next ();
502 i != this->occupied_list_id ();
503 i = this->search_structure_[i].next ())
504 // Call the copy constructor using operator placement new.
505 new (&(temp[i])) ENTRY (this->search_structure_[i]);
507 // Copy over the free entires.
508 for (i = this->free_list_.next ();
509 i != this->free_list_id ();
510 i = this->search_structure_[i].next ())
511 // Call the copy constructor using operator placement new.
512 new (&(temp[i])) ENTRY (this->search_structure_[i]);
514 // Construct the new elements.
515 for (i = this->total_size_; i < new_size; i++)
517 // Call the constructor for each element in the array using
518 // operator placement new. Note that this requires a default
519 // constructor for <EXT_ID> and <INT_ID>.
520 new (&(temp[i])) ENTRY;
521 temp[i].next (i + 1);
522 temp[i].prev (i - 1);
524 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
526 // Even though this slot is initially free, we need the <free_>
527 // flag to be zero so that we don't have to set it when the slot
528 // is moved to the occupied list. In addition, this flag has no
529 // meaning while this slot is in the free list.
530 temp[i].free_ = false;
532 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
536 // Add new entries to the free list.
537 this->free_list_.next (this->total_size_);
538 this->free_list_.prev (new_size - 1);
539 temp[new_size - 1].next (this->free_list_id ());
540 temp[this->total_size_].prev (this->free_list_id ());
542 // Remove/free old elements, update the new totoal size.
543 this->free_search_structure ();
544 this->total_size_ = new_size;
546 // Start using new elements.
547 this->search_structure_ = temp;
549 return 0;
552 template <class EXT_ID, class INT_ID, class ACE_LOCK> ACE_UINT32
553 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::new_size ()
555 // Calculate the new size.
556 ACE_UINT32 current_size = this->total_size_;
558 if (current_size < MAX_EXPONENTIAL)
559 // Exponentially increase if we haven't reached MAX_EXPONENTIAL.
560 current_size *= 2;
561 else
562 // Linear increase if we have reached MAX_EXPONENTIAL.
563 current_size += LINEAR_INCREASE;
565 // This should be the new size.
566 return current_size;
569 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
570 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::free_search_structure ()
572 // Free up the structure.
573 if (this->search_structure_ != 0)
575 for (ACE_UINT32 i = 0; i < this->total_size_; i++)
576 // Explicitly call the destructor.
578 ENTRY *ss = &this->search_structure_[i];
579 // The "if" second argument results in a no-op instead of
580 // deallocation.
581 ACE_DES_FREE_TEMPLATE2 (ss, ACE_NOOP,
582 ACE_Map_Entry, EXT_ID, INT_ID);
585 // Actually free the memory.
586 this->allocator_->free (this->search_structure_);
587 this->search_structure_ = 0;
591 template <class EXT_ID, class INT_ID> void
592 ACE_Map_Entry<EXT_ID, INT_ID>::dump () const
594 #if defined (ACE_HAS_DUMP)
595 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
596 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
597 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("prev_ = %d"), this->prev_));
599 #if defined (ACE_HAS_LAZY_MAP_MANAGER)
600 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("free_ = %d"), this->free_));
601 #endif /* ACE_HAS_LAZY_MAP_MANAGER */
603 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
604 #endif /* ACE_HAS_DUMP */
607 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
608 ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump () const
610 #if defined (ACE_HAS_DUMP)
611 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
612 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("total_size_ = %d"), this->total_size_));
613 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d"), this->cur_size_));
614 this->allocator_->dump ();
615 this->lock_.dump ();
616 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
617 #endif /* ACE_HAS_DUMP */
620 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
621 ACE_Map_Iterator_Base<EXT_ID, INT_ID, ACE_LOCK>::dump_i () const
623 #if defined (ACE_HAS_DUMP)
624 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
625 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
626 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
627 #endif /* ACE_HAS_DUMP */
630 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
631 ACE_Map_Const_Iterator_Base<EXT_ID, INT_ID, ACE_LOCK>::dump_i () const
633 #if defined (ACE_HAS_DUMP)
634 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
635 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
636 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
637 #endif /* ACE_HAS_DUMP */
640 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
641 ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump () const
643 #if defined (ACE_HAS_DUMP)
644 this->dump_i ();
645 #endif /* ACE_HAS_DUMP */
648 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
649 ACE_Map_Const_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump () const
651 #if defined (ACE_HAS_DUMP)
652 this->dump_i ();
653 #endif /* ACE_HAS_DUMP */
656 template <class EXT_ID, class INT_ID, class ACE_LOCK> void
657 ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump () const
659 #if defined (ACE_HAS_DUMP)
660 this->dump_i ();
661 #endif /* ACE_HAS_DUMP */
664 ACE_END_VERSIONED_NAMESPACE_DECL
666 #endif /* ACE_MAP_MANAGER_CPP */