1 // $Id: Unbounded_Queue.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #ifndef ACE_UNBOUNDED_QUEUE_CPP
4 #define ACE_UNBOUNDED_QUEUE_CPP
6 #include "ace/Unbounded_Queue.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 #if !defined (__ACE_INLINE__)
13 #include "ace/Unbounded_Queue.inl"
14 #endif /* __ACE_INLINE__ */
16 #include "ace/Malloc_Base.h"
17 #include "ace/Log_Msg.h"
18 #include "ace/os_include/os_errno.h"
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Queue
)
25 ACE_Unbounded_Queue
<T
>::ACE_Unbounded_Queue (ACE_Allocator
*alloc
)
30 // ACE_TRACE ("ACE_Unbounded_Queue<T>::ACE_Unbounded_Queue (void)");
32 if (this->allocator_
== 0)
33 this->allocator_
= ACE_Allocator::instance ();
35 ACE_NEW_MALLOC (this->head_
,
36 (ACE_Node
<T
> *) this->allocator_
->malloc (sizeof (ACE_Node
<T
>)),
38 // Make the list circular by pointing it back to itself.
39 this->head_
->next_
= this->head_
;
43 ACE_Unbounded_Queue
<T
>::ACE_Unbounded_Queue (const ACE_Unbounded_Queue
<T
> &us
)
46 allocator_ (us
.allocator_
)
48 // ACE_TRACE ("ACE_Unbounded_Queue<T>::ACE_Unbounded_Queue");
50 if (this->allocator_
== 0)
51 this->allocator_
= ACE_Allocator::instance ();
53 ACE_NEW_MALLOC (this->head_
,
54 (ACE_Node
<T
> *) this->allocator_
->malloc (sizeof (ACE_Node
<T
>)),
56 this->head_
->next_
= this->head_
;
57 this->copy_nodes (us
);
60 template <class T
> void
61 ACE_Unbounded_Queue
<T
>::operator= (const ACE_Unbounded_Queue
<T
> &us
)
63 // ACE_TRACE ("ACE_Unbounded_Queue<T>::operator=");
67 this->delete_nodes ();
68 this->copy_nodes (us
);
72 template <class T
> ACE_Unbounded_Queue_Iterator
<T
>
73 ACE_Unbounded_Queue
<T
>::begin (void)
75 // ACE_TRACE ("ACE_Unbounded_Queue<T>::begin");
76 return ACE_Unbounded_Queue_Iterator
<T
> (*this);
79 template <class T
> ACE_Unbounded_Queue_Iterator
<T
>
80 ACE_Unbounded_Queue
<T
>::end (void)
82 // ACE_TRACE ("ACE_Unbounded_Queue<T>::end");
83 return ACE_Unbounded_Queue_Iterator
<T
> (*this, 1);
86 template <class T
> void
87 ACE_Unbounded_Queue
<T
>::dump (void) const
89 #if defined (ACE_HAS_DUMP)
90 // ACE_TRACE ("ACE_Unbounded_Queue<T>::dump");
92 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
93 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhead_ = %u"), this->head_
));
94 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhead_->next_ = %u"), this->head_
->next_
));
95 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ncur_size_ = %d\n"), this->cur_size_
));
98 #if !defined (ACE_NLOGGING)
100 #endif /* ! ACE_NLOGGING */
102 for (ACE_Unbounded_Queue_Iterator
<T
> iter (*(ACE_Unbounded_Queue
<T
> *) this);
103 iter
.next (item
) != 0;
105 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("count = %d\n"), count
++));
107 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
108 #endif /* ACE_HAS_DUMP */
111 template <class T
> void
112 ACE_Unbounded_Queue
<T
>::copy_nodes (const ACE_Unbounded_Queue
<T
> &us
)
114 for (ACE_Node
<T
> *curr
= us
.head_
->next_
;
117 if (this->enqueue_tail (curr
->item_
) == -1)
118 // @@ What's the right thing to do here?
119 this->delete_nodes ();
122 template <class T
> void
123 ACE_Unbounded_Queue
<T
>::delete_nodes (void)
125 for (ACE_Node
<T
> *curr
= this->head_
->next_
;
126 // Keep looking until we've hit the dummy node.
130 ACE_Node
<T
> *temp
= curr
;
133 ACE_DES_FREE_TEMPLATE (temp
,
134 this->allocator_
->free
,
138 // @@ Doesnt make sense to have this check since
139 // this will always be true.
140 // ACE_ASSERT (this->cur_size_ >= 0);
143 // Reset the list to be a circular list with just a dummy node.
144 this->head_
->next_
= this->head_
;
148 ACE_Unbounded_Queue
<T
>::~ACE_Unbounded_Queue (void)
150 // ACE_TRACE ("ACE_Unbounded_Queue<T>::~ACE_Unbounded_Queue (void)");
152 this->delete_nodes ();
153 ACE_DES_FREE_TEMPLATE (head_
,
154 this->allocator_
->free
,
160 template <class T
> int
161 ACE_Unbounded_Queue
<T
>::enqueue_head (const T
&new_item
)
163 // ACE_TRACE ("ACE_Unbounded_Queue<T>::enqueue_head");
165 ACE_Node
<T
> *temp
= 0;
167 // Create a new node that points to the original head.
168 ACE_NEW_MALLOC_RETURN (temp
,
169 static_cast<ACE_Node
<T
> *> (this->allocator_
->malloc (sizeof (ACE_Node
<T
>))),
170 ACE_Node
<T
> (new_item
, this->head_
->next_
),
172 // Link this pointer into the front of the list. Note that the
173 // "real" head of the queue is <head_->next_>, whereas <head_> is
174 // just a pointer to the dummy node.
175 this->head_
->next_
= temp
;
181 template <class T
> int
182 ACE_Unbounded_Queue
<T
>::enqueue_tail (const T
&new_item
)
184 // ACE_TRACE ("ACE_Unbounded_Queue<T>::enqueue_tail");
186 // Insert <item> into the old dummy node location. Note that this
187 // isn't actually the "head" item in the queue, it's a dummy node at
188 // the "tail" of the queue...
189 this->head_
->item_
= new_item
;
191 ACE_Node
<T
> *temp
= 0;
193 // Create a new dummy node.
194 ACE_NEW_MALLOC_RETURN (temp
,
195 static_cast<ACE_Node
<T
> *> (this->allocator_
->malloc (sizeof (ACE_Node
<T
>))),
196 ACE_Node
<T
> (this->head_
->next_
),
198 // Link this dummy pointer into the list.
199 this->head_
->next_
= temp
;
201 // Point the head to the new dummy node.
208 template <class T
> int
209 ACE_Unbounded_Queue
<T
>::dequeue_head (T
&item
)
211 // ACE_TRACE ("ACE_Unbounded_Queue<T>::dequeue_head");
213 // Check for empty queue.
214 if (this->is_empty ())
217 ACE_Node
<T
> *temp
= this->head_
->next_
;
220 this->head_
->next_
= temp
->next_
;
221 ACE_DES_FREE_TEMPLATE (temp
,
222 this->allocator_
->free
,
229 template <class T
> void
230 ACE_Unbounded_Queue
<T
>::reset (void)
234 this->delete_nodes ();
237 template <class T
> int
238 ACE_Unbounded_Queue
<T
>::get (T
*&item
, size_t slot
) const
240 // ACE_TRACE ("ACE_Unbounded_Queue<T>::get");
242 ACE_Node
<T
> *curr
= this->head_
->next_
;
246 for (i
= 0; i
< this->cur_size_
; i
++)
254 if (i
< this->cur_size_
)
263 template <class T
> int
264 ACE_Unbounded_Queue
<T
>::set (const T
&item
,
267 // ACE_TRACE ("ACE_Unbounded_Queue<T>::set");
269 ACE_Node
<T
> *curr
= this->head_
->next_
;
274 i
< slot
&& i
< this->cur_size_
;
278 if (i
< this->cur_size_
)
280 // We're in range, so everything's cool.
286 // We need to expand the list.
288 // A common case will be increasing the set size by 1.
289 // Therefore, we'll optimize for this case.
292 // Try to expand the size of the set by 1.
293 if (this->enqueue_tail (item
) == -1)
300 T
const dummy
= T ();
302 // We need to expand the list by multiple (dummy) items.
303 for (; i
< slot
; ++i
)
305 // This head points to the existing dummy node, which is
306 // about to be overwritten when we add the new dummy
310 // Try to expand the size of the set by 1, but don't
311 // store anything in the dummy node (yet).
312 if (this->enqueue_tail (dummy
) == -1)
322 // ****************************************************************
324 template <class T
> void
325 ACE_Unbounded_Queue_Const_Iterator
<T
>::dump (void) const
327 #if defined (ACE_HAS_DUMP)
328 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::dump");
329 #endif /* ACE_HAS_DUMP */
333 ACE_Unbounded_Queue_Const_Iterator
<T
>::ACE_Unbounded_Queue_Const_Iterator (const ACE_Unbounded_Queue
<T
> &q
, int end
)
334 : current_ (end
== 0 ? q
.head_
->next_
: q
.head_
),
337 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::ACE_Unbounded_Queue_Const_Iterator");
340 template <class T
> int
341 ACE_Unbounded_Queue_Const_Iterator
<T
>::advance (void)
343 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::advance");
344 this->current_
= this->current_
->next_
;
345 return this->current_
!= this->queue_
.head_
;
348 template <class T
> int
349 ACE_Unbounded_Queue_Const_Iterator
<T
>::first (void)
351 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::first");
352 this->current_
= this->queue_
.head_
->next_
;
353 return this->current_
!= this->queue_
.head_
;
356 template <class T
> int
357 ACE_Unbounded_Queue_Const_Iterator
<T
>::done (void) const
359 ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::done");
361 return this->current_
== this->queue_
.head_
;
364 template <class T
> int
365 ACE_Unbounded_Queue_Const_Iterator
<T
>::next (T
*&item
)
367 // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator<T>::next");
368 if (this->current_
== this->queue_
.head_
)
372 item
= &this->current_
->item_
;
377 // ****************************************************************
379 template <class T
> void
380 ACE_Unbounded_Queue_Iterator
<T
>::dump (void) const
382 #if defined (ACE_HAS_DUMP)
383 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::dump");
384 #endif /* ACE_HAS_DUMP */
388 ACE_Unbounded_Queue_Iterator
<T
>::ACE_Unbounded_Queue_Iterator (ACE_Unbounded_Queue
<T
> &q
, int end
)
389 : current_ (end
== 0 ? q
.head_
->next_
: q
.head_
),
392 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::ACE_Unbounded_Queue_Iterator");
395 template <class T
> int
396 ACE_Unbounded_Queue_Iterator
<T
>::advance (void)
398 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::advance");
399 this->current_
= this->current_
->next_
;
400 return this->current_
!= this->queue_
.head_
;
403 template <class T
> int
404 ACE_Unbounded_Queue_Iterator
<T
>::first (void)
406 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::first");
407 this->current_
= this->queue_
.head_
->next_
;
408 return this->current_
!= this->queue_
.head_
;
411 template <class T
> int
412 ACE_Unbounded_Queue_Iterator
<T
>::done (void) const
414 ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::done");
416 return this->current_
== this->queue_
.head_
;
419 template <class T
> int
420 ACE_Unbounded_Queue_Iterator
<T
>::next (T
*&item
)
422 // ACE_TRACE ("ACE_Unbounded_Queue_Iterator<T>::next");
423 if (this->current_
== this->queue_
.head_
)
427 item
= &this->current_
->item_
;
432 ACE_END_VERSIONED_NAMESPACE_DECL
434 #endif /* ACE_UNBOUNDED_QUEUE_CPP */