2 //=============================================================================
4 * @file Hash_Multi_Map_Manager_T.cpp
6 * @author Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
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)
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
)
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
)
48 int_id_set_ (int_id_set
),
54 template <class EXT_ID
, class INT_ID
> EXT_ID
&
55 ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
>::key ()
60 template <class EXT_ID
, class INT_ID
> ACE_Unbounded_Set
<INT_ID
> &
61 ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
>::item ()
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 ();
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
>);
97 ACE_ALLOCATOR_RETURN (ptr
,
98 this->table_allocator_
->malloc (bytes
),
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
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
],
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.
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).
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
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
163 ACE_DES_FREE_TEMPLATE2 (entry
, ACE_NOOP
,
164 ACE_Hash_Multi_Map_Entry
, EXT_ID
, INT_ID
);
168 this->total_size_
= 0;
170 // Free table memory.
171 this->table_allocator_
->free (this->table_
);
173 // Should be done last...
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
];
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
)
215 int result
= this->shared_find (ext_id
, entry
, loc
);
217 ACE_Unbounded_Set
<INT_ID
> int_id_set
;
222 ACE_ALLOCATOR_RETURN (ptr
,
223 this->entry_allocator_
->malloc (sizeof (ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
>)),
226 int_id_set
.insert (int_id
);
228 entry
= new (ptr
) ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
> (ext_id
,
230 this->table_
[loc
].next_
,
232 this->table_
[loc
].next_
= entry
;
233 entry
->next_
->prev_
= entry
;
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
);
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
)
257 int result
= this->shared_find (ext_id
, entry
, loc
);
263 ACE_ALLOCATOR_RETURN (ptr
,
264 this->entry_allocator_
->malloc (sizeof (ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
>)),
267 entry
= new (ptr
) ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
> (ext_id
,
269 this->table_
[loc
].next_
,
271 this->table_
[loc
].next_
= entry
;
272 entry
->next_
->prev_
= entry
;
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
)
286 int result
= this->shared_find (ext_id
, entry
, loc
);
292 ACE_ALLOCATOR_RETURN (ptr
,
293 this->entry_allocator_
->malloc (sizeof (ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
>)),
296 entry
= new (ptr
) ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
> (ext_id
,
298 this->table_
[loc
].next_
,
300 this->table_
[loc
].next_
= entry
;
301 entry
->next_
->prev_
= entry
;
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
;
316 int result
= this->shared_find (ext_id
, temp
, loc
);
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
);
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
;
350 int result
= this->shared_find (ext_id
, temp
, loc
);
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
);
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
,
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)
385 if (temp
== &this->table_
[loc
])
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
)
403 if (this->shared_find (ext_id
, entry
, dummy
) == -1)
404 return this->bind_i (ext_id
, int_id_set
);
407 entry
->ext_id_
= ext_id
;
408 entry
->int_id_set_
= int_id_set
;
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
)
420 if (this->shared_find (ext_id
, entry
, dummy
) == -1)
421 return this->bind_i (ext_id
, int_id_set
);
424 old_int_id_set
= entry
->int_id_set_
;
425 entry
->ext_id_
= ext_id
;
426 entry
->int_id_set_
= int_id_set
;
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
,
435 ACE_Unbounded_Set
<INT_ID
> &old_int_id_set
,
436 ACE_Hash_Multi_Map_Entry
<EXT_ID
, INT_ID
> *&entry
)
439 if (this->shared_find (ext_id
, entry
, dummy
) == -1)
440 return this->bind_i (ext_id
, int_id_set
);
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
;
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)
471 // Handle initial case specially.
472 else if (this->index_
== -1)
475 return this->forward_i ();
477 else if (this->index_
>= static_cast<ssize_t
> (this->map_man_
->total_size_
))
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_
])
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)
501 else if (this->index_
== static_cast<ssize_t
> (this->map_man_
->total_size_
))
504 return this->reverse_i ();
506 else if (this->index_
< 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_
])
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)
543 // Handle initial case specially.
544 else if (this->index_
== -1)
547 return this->forward_i ();
549 else if (this->index_
>= (ssize_t
) this->map_man_
->total_size_
)
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_
])
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)
573 else if (this->index_
== (ssize_t
) this->map_man_
->total_size_
)
576 return this->reverse_i ();
578 else if (this->index_
< 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_
])
592 return this->index_
>= 0;
595 ACE_END_VERSIONED_NAMESPACE_DECL
597 #endif /* ACE_Hash_Multi_Map_Manager_T_CPP */