Use override/default for RTPortableServer
[ACE_TAO.git] / ACE / ace / Hash_Multi_Map_Manager_T.cpp
blob0e128647915f89ae9c64a6373c7f91fb72d60a34
2 //=============================================================================
3 /**
4 * @file Hash_Multi_Map_Manager_T.cpp
6 * @author Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
7 */
8 //=============================================================================
10 #ifndef ACE_Hash_Multi_Map_Manager_T_CPP
11 #define ACE_Hash_Multi_Map_Manager_T_CPP
13 #include "ace/Hash_Multi_Map_Manager_T.h"
15 #if !defined (ACE_LACKS_PRAGMA_ONCE)
16 # pragma once
17 #endif /* ACE_LACKS_PRAGMA_ONCE */
19 #if !defined (__ACE_INLINE__)
20 # include "ace/Hash_Multi_Map_Manager_T.inl"
21 #endif /* __ACE_INLINE__ */
23 #include "ace/Malloc_Base.h"
25 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
27 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Manager)
28 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Iterator_Base)
29 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Const_Iterator_Base)
30 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Iterator)
31 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Const_Iterator)
32 ACE_ALLOC_HOOK_DEFINE_Tc5(ACE_Hash_Multi_Map_Reverse_Iterator)
34 template <class EXT_ID, class INT_ID>
35 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Multi_Map_Entry (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *next,
36 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *prev)
37 : next_ (next),
38 prev_ (prev)
42 template <class EXT_ID, class INT_ID>
43 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Multi_Map_Entry (const EXT_ID &ext_id,
44 const ACE_Unbounded_Set<INT_ID> &int_id_set,
45 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *next,
46 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *prev)
47 : ext_id_ (ext_id),
48 int_id_set_ (int_id_set),
49 next_ (next),
50 prev_ (prev)
54 template <class EXT_ID, class INT_ID> EXT_ID &
55 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::key ()
57 return ext_id_;
60 template <class EXT_ID, class INT_ID> ACE_Unbounded_Set<INT_ID> &
61 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::item ()
63 return int_id_set_;
66 template <class EXT_ID, class INT_ID> void
67 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>::dump () const
69 #if defined (ACE_HAS_DUMP)
70 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
71 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %d"), this->next_));
72 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("prev_ = %d"), this->prev_));
73 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
74 #endif /* ACE_HAS_DUMP */
77 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
78 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump () const
80 #if defined (ACE_HAS_DUMP)
81 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
82 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("total_size_ = %d"), this->total_size_));
83 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d"), this->cur_size_));
84 this->table_allocator_->dump ();
85 this->entry_allocator_->dump ();
86 this->lock_.dump ();
87 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
88 #endif /* ACE_HAS_DUMP */
91 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
92 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::create_buckets (size_t size)
94 size_t bytes = size * sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>);
95 void *ptr;
97 ACE_ALLOCATOR_RETURN (ptr,
98 this->table_allocator_->malloc (bytes),
99 -1);
101 this->table_ = (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *) ptr;
103 this->total_size_ = size;
105 // Initialize each entry in the hash table to be a circular linked
106 // list with the dummy node in the front serving as the anchor of
107 // the list.
108 for (size_t i = 0; i < size; i++)
109 new (&this->table_[i]) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (&this->table_[i],
110 &this->table_[i]);
111 return 0;
114 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
115 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open (size_t size,
116 ACE_Allocator *table_alloc,
117 ACE_Allocator *entry_alloc)
119 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
121 // Calling this->close_i () to ensure we release previous allocated
122 // memory before allocating new one.
123 this->close_i ();
125 if (table_alloc == 0)
126 table_alloc = ACE_Allocator::instance ();
128 this->table_allocator_ = table_alloc;
130 if (entry_alloc == 0)
131 entry_alloc = table_alloc;
133 this->entry_allocator_ = entry_alloc;
135 // This assertion is here to help track a situation that shouldn't
136 // happen, but did with Sun C++ 4.1 (before a change to this class
137 // was made: it used to have an enum that was supposed to be defined
138 // to be ACE_DEFAULT_MAP_SIZE, but instead was defined to be 0).
139 if (size == 0)
140 return -1;
142 return this->create_buckets (size);
145 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
146 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::close_i ()
148 // Protect against "double-deletion" in case the destructor also
149 // gets called.
150 if (this->table_ != 0)
152 // Remove all the entries.
153 this->unbind_all_i ();
155 // Iterate through the buckets cleaning up the sentinels.
156 for (size_t i = 0; i < this->total_size_; i++)
158 // Destroy the dummy entry.
159 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *entry = &this->table_[i];
161 // The second argument results in a no-op instead of
162 // deallocation.
163 ACE_DES_FREE_TEMPLATE2 (entry, ACE_NOOP,
164 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
167 // Reset size.
168 this->total_size_ = 0;
170 // Free table memory.
171 this->table_allocator_->free (this->table_);
173 // Should be done last...
174 this->table_ = 0;
177 return 0;
180 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
181 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_all_i ()
183 // Iterate through the entire map calling the destuctor of each
184 // <ACE_Hash_Multi_Map_Entry>.
185 for (size_t i = 0; i < this->total_size_; i++)
187 for (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp_ptr = this->table_[i].next_;
188 temp_ptr != &this->table_[i];
191 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *hold_ptr = temp_ptr;
192 temp_ptr = temp_ptr->next_;
194 // Explicitly call the destructor.
195 ACE_DES_FREE_TEMPLATE2 (hold_ptr, this->entry_allocator_->free,
196 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
199 // Restore the sentinel.
200 this->table_[i].next_ = &this->table_[i];
201 this->table_[i].prev_ = &this->table_[i];
204 this->cur_size_ = 0;
206 return 0;
209 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
210 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
211 const INT_ID &int_id,
212 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
214 size_t loc;
215 int result = this->shared_find (ext_id, entry, loc);
217 ACE_Unbounded_Set<INT_ID> int_id_set;
218 if (result == -1)
220 void *ptr;
221 // Not found.
222 ACE_ALLOCATOR_RETURN (ptr,
223 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
224 -1);
226 int_id_set.insert (int_id);
228 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
229 int_id_set,
230 this->table_[loc].next_,
231 &this->table_[loc]);
232 this->table_[loc].next_ = entry;
233 entry->next_->prev_ = entry;
234 this->cur_size_++;
235 return 0;
237 else
239 int_id_set = (*entry).int_id_set_;
241 if (0 == int_id_set.insert (int_id))
243 this->unbind_i (entry);
244 return this->bind_i (ext_id, int_id_set);
246 else
247 return 1;
251 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
252 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
253 const ACE_Unbounded_Set<INT_ID> &int_id_set,
254 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
256 size_t loc;
257 int result = this->shared_find (ext_id, entry, loc);
259 if (result == -1)
261 void *ptr;
262 // Not found.
263 ACE_ALLOCATOR_RETURN (ptr,
264 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
265 -1);
267 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
268 int_id_set,
269 this->table_[loc].next_,
270 &this->table_[loc]);
271 this->table_[loc].next_ = entry;
272 entry->next_->prev_ = entry;
273 this->cur_size_++;
274 return 0;
276 else
277 return 1;
280 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
281 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
282 ACE_Unbounded_Set<INT_ID> &int_id_set,
283 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
285 size_t loc;
286 int result = this->shared_find (ext_id, entry, loc);
288 if (result == -1)
290 // Not found.
291 void *ptr;
292 ACE_ALLOCATOR_RETURN (ptr,
293 this->entry_allocator_->malloc (sizeof (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID>)),
294 -1);
296 entry = new (ptr) ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> (ext_id,
297 int_id_set,
298 this->table_[loc].next_,
299 &this->table_[loc]);
300 this->table_[loc].next_ = entry;
301 entry->next_->prev_ = entry;
302 this->cur_size_++;
303 return 0;
305 else
306 return 1;
309 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
310 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
311 ACE_Unbounded_Set<INT_ID> &int_id_set)
313 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp;
315 size_t loc;
316 int result = this->shared_find (ext_id, temp, loc);
318 if (result == -1)
320 errno = ENOENT;
321 return -1;
324 int_id_set = temp->int_id_set_;
326 return this->unbind_i (temp);
329 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
330 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *entry)
332 entry->next_->prev_ = entry->prev_;
333 entry->prev_->next_ = entry->next_;
335 // Explicitly call the destructor.
336 ACE_DES_FREE_TEMPLATE2 (entry, this->entry_allocator_->free,
337 ACE_Hash_Multi_Map_Entry, EXT_ID, INT_ID);
339 this->cur_size_--;
340 return 0;
343 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
344 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
345 const INT_ID &int_id)
347 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp;
349 size_t loc;
350 int result = this->shared_find (ext_id, temp, loc);
352 if (result == -1)
354 errno = ENOENT;
355 return -1;
358 ACE_Unbounded_Set<INT_ID> int_id_set = (*temp).int_id_set_;
359 if (0 == int_id_set.remove (int_id))
361 this->unbind_i (temp);
363 if (0 != int_id_set.size ())
364 return this->bind_i (ext_id, int_id_set);
365 else
366 return 0;
368 else
369 return -1;
373 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
374 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
375 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry,
376 size_t &loc)
378 loc = this->hash (ext_id) % this->total_size_;
380 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc].next_;
382 while (temp != &this->table_[loc] && this->equal (temp->ext_id_, ext_id) == 0)
383 temp = temp->next_;
385 if (temp == &this->table_[loc])
387 errno = ENOENT;
388 return -1;
390 else
392 entry = temp;
393 return 0;
397 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
398 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
399 const ACE_Unbounded_Set<INT_ID> &int_id_set,
400 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
402 size_t dummy;
403 if (this->shared_find (ext_id, entry, dummy) == -1)
404 return this->bind_i (ext_id, int_id_set);
405 else
407 entry->ext_id_ = ext_id;
408 entry->int_id_set_ = int_id_set;
409 return 1;
413 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
414 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
415 const ACE_Unbounded_Set<INT_ID> &int_id_set,
416 ACE_Unbounded_Set<INT_ID> &old_int_id_set,
417 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
419 size_t dummy;
420 if (this->shared_find (ext_id, entry, dummy) == -1)
421 return this->bind_i (ext_id, int_id_set);
422 else
424 old_int_id_set = entry->int_id_set_;
425 entry->ext_id_ = ext_id;
426 entry->int_id_set_ = int_id_set;
427 return 1;
431 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
432 ACE_Hash_Multi_Map_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
433 const ACE_Unbounded_Set<INT_ID> &int_id_set,
434 EXT_ID &old_ext_id,
435 ACE_Unbounded_Set<INT_ID> &old_int_id_set,
436 ACE_Hash_Multi_Map_Entry<EXT_ID, INT_ID> *&entry)
438 size_t dummy;
439 if (this->shared_find (ext_id, entry, dummy) == -1)
440 return this->bind_i (ext_id, int_id_set);
441 else
443 old_ext_id = entry->ext_id_;
444 old_int_id_set = entry->int_id_set_;
445 entry->ext_id_ = ext_id;
446 entry->int_id_set_ = int_id_set;
447 return 1;
451 // ------------------------------------------------------------
453 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
454 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i () const
456 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
458 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
459 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
460 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
461 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
464 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
465 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i ()
467 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
469 if (this->map_man_->table_ == 0)
470 return -1;
471 // Handle initial case specially.
472 else if (this->index_ == -1)
474 this->index_++;
475 return this->forward_i ();
477 else if (this->index_ >= static_cast<ssize_t> (this->map_man_->total_size_))
478 return 0;
480 this->next_ = this->next_->next_;
481 if (this->next_ == &this->map_man_->table_[this->index_])
483 while (++this->index_ < static_cast<ssize_t> (this->map_man_->total_size_))
485 this->next_ = this->map_man_->table_[this->index_].next_;
486 if (this->next_ != &this->map_man_->table_[this->index_])
487 break;
491 return this->index_ < static_cast<ssize_t> (this->map_man_->total_size_);
494 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
495 ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i ()
497 ACE_TRACE ("ACE_Hash_Multi_Map_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
499 if (this->map_man_->table_ == 0)
500 return -1;
501 else if (this->index_ == static_cast<ssize_t> (this->map_man_->total_size_))
503 this->index_--;
504 return this->reverse_i ();
506 else if (this->index_ < 0)
507 return 0;
509 this->next_ = this->next_->prev_;
510 if (this->next_ == &this->map_man_->table_[this->index_])
512 while (--this->index_ >= 0)
514 this->next_ = this->map_man_->table_[this->index_].prev_;
515 if (this->next_ != &this->map_man_->table_[this->index_])
516 break;
520 return this->index_ >= 0;
523 // ------------------------------------------------------------
525 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
526 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i () const
528 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::dump_i");
530 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
531 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("index_ = %d "), this->index_));
532 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next_ = %x"), this->next_));
533 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
536 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
537 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i ()
539 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::forward_i");
541 if (this->map_man_->table_ == 0)
542 return -1;
543 // Handle initial case specially.
544 else if (this->index_ == -1)
546 this->index_++;
547 return this->forward_i ();
549 else if (this->index_ >= (ssize_t) this->map_man_->total_size_)
550 return 0;
552 this->next_ = this->next_->next_;
553 if (this->next_ == &this->map_man_->table_[this->index_])
555 while (++this->index_ < (ssize_t) this->map_man_->total_size_)
557 this->next_ = this->map_man_->table_[this->index_].next_;
558 if (this->next_ != &this->map_man_->table_[this->index_])
559 break;
563 return this->index_ < (ssize_t) this->map_man_->total_size_;
566 template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
567 ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i ()
569 ACE_TRACE ("ACE_Hash_Multi_Map_Const_Iterator_Base<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::reverse_i");
571 if (this->map_man_->table_ == 0)
572 return -1;
573 else if (this->index_ == (ssize_t) this->map_man_->total_size_)
575 this->index_--;
576 return this->reverse_i ();
578 else if (this->index_ < 0)
579 return 0;
581 this->next_ = this->next_->prev_;
582 if (this->next_ == &this->map_man_->table_[this->index_])
584 while (--this->index_ >= 0)
586 this->next_ = this->map_man_->table_[this->index_].prev_;
587 if (this->next_ != &this->map_man_->table_[this->index_])
588 break;
592 return this->index_ >= 0;
595 ACE_END_VERSIONED_NAMESPACE_DECL
597 #endif /* ACE_Hash_Multi_Map_Manager_T_CPP */