// Timer_Wheel_T.cpp,v 1.62 2003/12/26 21:59:35 shuston Exp

#ifndef ACE_TIMER_WHEEL_T_C
#define ACE_TIMER_WHEEL_T_C

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/OS_NS_sys_time.h"
#include "ace/Guard_T.h"
#include "ace/Timer_Wheel_T.h"
#include "ace/Log_Msg.h"

ACE_RCSID(ace, Timer_Wheel_T, "Timer_Wheel_T.cpp,v 1.62 2003/12/26 21:59:35 shuston Exp")


// Design/implementation notes for ACE_Timer_Wheel_T.
//
// Each timer queue entry is represented by a ACE_Timer_Node.
// The timing wheel is divided into a number of "spokes"; there are
// spoke_count_ spokes in the wheel. Each timer is hashed into one of the
// spokes. Entries within each spoke are linked in a double-linked list
// in order of increasing expiration. The first ACE_Timer_Node in each
// spoke is a "dummy node" that marks the end of the list of ACE_Timer_Nodes
// in that spoke.
//
// The timer ID for a scheduled timer is formed by its spoke position in
// the wheel, and the number of timers that have been inserted in that spoke
// since the queue was initialized. N bits of the long timer_id are used
// to determine the spoke, and M bits are used as a counter.
// Each time a Node is inserted into a spoke, it's counter
// is incremented. The count is kept in the timer ID field
// of the dummy root Node. In the event of overflow of the counter, the spoke
// must be searched for each new id to make sure it's not already in use. To
// prevent having to do an exhaustive search each time, we keep extra data
// in the dummy root Node.
/**
* Default Constructor that sets defaults for spoke_count_ and resolution_
* and doesn't do any preallocation.
*
* @param upcall_functor A pointer to a functor to use instead of the default
* @param freelist       A pointer to a freelist to use instead of the default
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
(FUNCTOR* upcall_functor
 , FreeList* freelist
 )
: Base (upcall_functor, freelist)
, spokes_(0)
, spoke_count_(0) // calculated in open_i
, spoke_bits_(0)
, res_bits_ (0)
, earliest_spoke_ (0)
, iterator_(0)
, timer_count_(0)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T");
  this->open_i (0,
                ACE_DEFAULT_TIMER_WHEEL_SIZE,
                ACE_DEFAULT_TIMER_WHEEL_RESOLUTION);
}

/**
* Constructor that sets up the timing wheel and also may preallocate
* some nodes on the free list
*
* @param spoke_count    The number of lists in the timer wheel
* @param resolution     The time resolution in milliseconds used by the hashing function
* @param prealloc       The number of entries to prealloc in the free_list
* @param upcall_functor A pointer to a functor to use instead of the default
* @param freelist       A pointer to a freelist to use instead of the default
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
  (u_int spoke_count,
   u_int resolution,
   size_t prealloc,
   FUNCTOR* upcall_functor,
   FreeList* freelist)
: Base (upcall_functor, freelist)
, spokes_ (0)
, spoke_count_ (0) // calculated in open_i
, spoke_bits_ (0)
, res_bits_ (0)
, earliest_spoke_ (0)
, iterator_ (0)
, timer_count_ (0)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T");
  this->open_i (prealloc, spoke_count, resolution);
}

template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::power2bits (int n,
                                                        int min_bits,
                                                        int max_bits)
{
  int max = (1 << max_bits) - 1;
  if (n > max)
    return max_bits;

  // count the bits in n.
  int i = 0;
  int tmp = n;
  do
    {
      tmp >>= 1;
      ++i;
    }
  while (tmp != 0);

  if (i <= min_bits)
    return min_bits;

  // Which is nearest?
  int a = (1 << i) - n;
  int b = (1 << (i - 1)) - n;
  if (b < 0)
    b = -b;
  if (b < a)
    return i - 1;
  return i;
}

/**
* Initialize the queue. Uses the established members for all needed
* information.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::open_i
  (size_t prealloc, u_int spokes, u_int res)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::open_i");

  this->gettimeofday (ACE_OS::gettimeofday);

  // Rather than waste bits in our timer id, we might as well round up
  // the spoke count to the next power of two - 1 . (i.e 1,3,7,15,...127,etc.)
  const int MIN_SPOKE_BITS = 3;  // Allow between 8 and 4096 spokes
  const int MAX_SPOKE_BITS = 12;
  const int MAX_RES_BITS = 20;   // 20 is plenty, even on 64 bit platforms.

  this->spoke_bits_ = power2bits (spokes, MIN_SPOKE_BITS, MAX_SPOKE_BITS);
  this->res_bits_ = power2bits (res, 1, MAX_RES_BITS);

  this->spoke_count_ = 1 << this->spoke_bits_;

  this->free_list_->resize (prealloc + this->spoke_count_);

  this->wheel_time_.msec (1 << (this->res_bits_ + this->spoke_bits_));

  ACE_NEW (this->spokes_, ACE_Timer_Node_T<TYPE>* [this->spoke_count_]);

  // Create the root nodes. These will be treated specially
  for (u_int i = 0; i < this->spoke_count_; ++i)
  {
    ACE_Timer_Node_T<TYPE>* root = this->alloc_node ();
    root->set (0, 0, ACE_Time_Value::zero, ACE_Time_Value::zero, root, root, 0);
    this->spokes_[i] = root;
  }

  ACE_NEW (iterator_, Iterator (*this));
}

/// Destructor just cleans up its memory
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Wheel_T (void)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T");

  delete iterator_;

  for (u_int i = 0; i < this->spoke_count_; ++i)
  {
    // Free all the nodes starting at the root
    ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
    for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root;)
    {
      ACE_Timer_Node_T<TYPE>* next = n->get_next ();
      this->upcall_functor ().deletion (*this,
                                        n->get_type (),
                                        n->get_act ());
      this->free_node (n);
      n = next;
    }
    delete root;
  }
  delete[] this->spokes_;
}

/// Searches for a node by timer_id within one spoke.
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Node_T<TYPE>*
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_spoke_node
  (u_int spoke, long timer_id) const
{
  ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
  for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
       n != root;
       n = n->get_next ())
    {
      if (n->get_timer_id () == timer_id)
        return n;
    }
  return 0;
}

/// Searches all spokes for a node matching the specified timer_id
/// Uses the spoke encoded in the timer_id as a starting place.
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Node_T<TYPE>*
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
{
  if (timer_id == -1)
    return 0;

  // Search the spoke where timer_id was originally scheduled
  u_int spoke_mask = this->spoke_count_ - 1;
  u_int start = timer_id & spoke_mask;
  ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (start, timer_id);
  if (n != 0)
    return n;

  //ACE_ERROR((LM_ERROR, "Node not found in original spoke.\n"));

  // Search the rest of the spokes
  for (u_int i = 0; i < this->spoke_count_; ++i)
    {
      if (i != start)
        { // already searched this one
          n = this->find_spoke_node (i, timer_id);
          if (n != 0)
            return n;
        }
    }

  //ACE_ERROR((LM_ERROR, "Node not found.\n"));
  return 0;
}

/**
* Check to see if the wheel is empty
*
* @return True if empty
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
{
  ACE_TRACE ("ACE_Timer_Wheel_T::is_empty");
  return timer_count_ == 0;
}


/**
* @return First (earliest) node in the wheel_'s earliest_spoke_ list
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
{
  ACE_TRACE ("ACE_Timer_Wheel_T::earliest_time");
  ACE_Timer_Node_T<TYPE>* n = this->get_first_i ();
  if (n != 0)
    return n->get_timer_value ();
  return ACE_Time_Value::zero;
}

/// Uses a simple hash to find which spoke to use based on when the
/// timer is due to expire. Hopefully the 64bit int operations avoid
/// any overflow problems.
template <class TYPE, class FUNCTOR, class ACE_LOCK> u_int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_spoke
  (const ACE_Time_Value& t) const
{
  return ACE_static_cast(u_int, (t.msec () >> this->res_bits_) & (this->spoke_count_ - 1));
}

/// Generates a unique timer_id for the given spoke. It should be pretty
/// fast until the point where the counter overflows.  At that time you
/// have to do exhaustive searches within the spoke to ensure that a particular
/// timer id is not already in use. Some optimizations are in place so
/// that this hopefully doesn't have to happen often.
template <class TYPE, class FUNCTOR, class ACE_LOCK> long
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::generate_timer_id (u_int spoke)
{

  int cnt_bits = sizeof (long) * 8 - this->spoke_bits_;
  long max_cnt = ((long)1 << cnt_bits) - 1;
  if (spoke == this->spoke_count_)
    --max_cnt; // Because -1 is used as a special invalid timer_id.

  ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];

  if (root == root->get_next ())
    root->set_act(0);

  // We use this field to keep track of the next counter value that
  // may be in use. Of course it may have expired, so we just use
  // this field so that we know when we don't have to check for duplicates
#if defined (ACE_WIN64)
  // The cast below is legit... we know that long is shorter than a
  // pointer, but are only using it as a 'long' storage area.
#  pragma warning(push)
#  pragma warning(disable : 4311)
#endif /* ACE_WIN64 */
  long next_cnt = ACE_reinterpret_cast (long, root->get_act ());
#if defined (ACE_WIN64)
#  pragma warning(pop)
#endif /* ACE_WIN64 */

  // This field is used as a counter instead of a timer_id.
  long cnt = root->get_timer_id ();

  if (cnt >= max_cnt && root == root->get_next ())
    {
      // Special case when we overflow on an empty spoke. We can just
      // wrap the count around without searching for duplicates. We only
      // want to do this when the counter overflows, so that we return
      // unique timer_id values as often as possible.
      root->set_timer_id (1);
      return spoke;
    }
  else if (cnt >= max_cnt)
    { // overflow
      cnt = 0; // try again starting at zero
    }
  else if (next_cnt == 0 || cnt < next_cnt)
    {
      root->set_timer_id (cnt + 1);
      return (cnt << this->spoke_bits_) | spoke;
    }

  //ACE_ERROR((LM_ERROR, "Timer id overflow. We have to search now.\n"));

  // We've run out of consecutive id numbers so now we have to search
  // for a unique id.
  // We'll try increasing numbers until we find one that is not in use,
  // and we'll record the next highest number so that we can avoid this
  // search as often as possible.
  for (; cnt < max_cnt - 1; ++cnt)
    {
      long id = (cnt << this->spoke_bits_) | spoke;
      ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (spoke, id);
      if (n == 0)
        {
          root->set_timer_id (cnt + 1);
          // Now we need to find the next highest cnt in use
          next_cnt = 0;
          for (; n != root; n = n->get_next ())
            {
              long tmp = n->get_timer_id () >> this->spoke_bits_;
              if (tmp > cnt && (tmp < next_cnt || next_cnt == 0))
                next_cnt = tmp;
            }
#if defined (ACE_WIN64)
          // The cast below is legit... we know we're storing a long in
          // a pointer, but are only using it as a 'long' storage area.
#  pragma warning(push)
#  pragma warning(disable : 4312)
#endif /* ACE_WIN64 */
          root->set_act (ACE_reinterpret_cast (void*, next_cnt));
#if defined (ACE_WIN64)
#  pragma warning(pop)
#endif /* ACE_WIN64 */
          return id;
        }
    }

  return -1; // We did our best, but the spoke is full.
}

/**
* Creates a ACE_Timer_Node_T based on the input parameters.  Then inserts
* the node into the wheel using reschedule ().  Then returns a timer_id.
*
*  @param type            The data of the timer node
*  @param act             Asynchronous Completion Token (AKA magic cookie)
*  @param future_time     The time the timer is scheduled for (absolute time)
*  @param interval        If not ACE_Time_Value::zero, then this is a periodic
*                         timer and interval is the time period
*
*  @return Unique identifier (can be used to cancel the timer).
*          -1 on failure.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> long
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE& type,
                                                        const void* act,
                                                        const ACE_Time_Value& future_time,
                                                        const ACE_Time_Value& interval)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::schedule_i");

  ACE_Timer_Node_T<TYPE>* n = this->alloc_node ();

  if (n != 0)
    {
      u_int spoke = calculate_spoke (future_time);
      long id = generate_timer_id (spoke);

      //ACE_ERROR((LM_ERROR, "Scheduling %x spoke:%d id:%d\n", (long) n, spoke, id));

      if (id != -1)
        {
          n->set (type, act, future_time, interval, 0, 0, id);
          this->schedule_i (n, spoke, future_time);
        }
      return id;
    }

  // Failure return
  errno = ENOMEM;
  return -1;
}

/**
* Takes an ACE_Timer_Node and inserts it into the correct position in
* the correct list.  Also makes sure to update the earliest time.
*
* @param n The timer node to reschedule
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::reschedule");
  const ACE_Time_Value& expire = n->get_timer_value ();
  u_int spoke = calculate_spoke (expire);
  this->schedule_i (n, spoke, expire);
}

/// The shared scheduling functionality between schedule() and reschedule()
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i
  (ACE_Timer_Node_T<TYPE>* n,
   u_int spoke,
   const ACE_Time_Value& expire)
{
  // See if we need to update the earliest time
  if (this->is_empty() || expire < this->earliest_time ())
    this->earliest_spoke_ = spoke;

  ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
  ACE_Timer_Node_T<TYPE>* last = root->get_prev ();

  ++timer_count_;

  // If the spoke is empty
  if (last == root) {
    n->set_prev (root);
    n->set_next (root);
    root->set_prev (n);
    root->set_next (n);
    return;
  }

  // We always want to search backwards from the tail of the list, because
  // this minimizes the search in the extreme case when lots of timers are
  // scheduled for exactly the same time
  ACE_Timer_Node_T<TYPE>* p = root->get_prev ();
  while (p != root && p->get_timer_value () > expire)
    p = p->get_prev ();

  // insert after
  n->set_prev (p);
  n->set_next (p->get_next ());
  p->get_next ()->set_prev (n);
  p->set_next (n);
}


/**
* Find the timer node by using the id as a pointer.  Then use set_interval()
* on the node to update the interval.
*
* @param timer_id The timer identifier
* @param interval The new interval
*
* @return 0 if successful, -1 if no.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
                                                            const ACE_Time_Value &interval
                                                            )
{
  ACE_TRACE ("ACE_Timer_Wheel_T::reset_interval");
  ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
  ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
  if (n != 0)
    {
      // The interval will take effect the next time this node is expired.
      n->set_interval (interval);
      return 0;
    }
  return -1;
}


/**
* Goes through every list in the wheel and whenever we find one with the
* correct type value, we remove it and continue.  At the end make sure
* we reset the earliest time value in case the earliest timers were
* removed.
*
* @param type       The value to search for.
* @param skip_close If this non-zero, the cancellation method of the
*                   functor will not be called for each cancelled timer.
*
* @return Number of timers cancelled
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE& type, int skip_close)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
  ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));

  int num_canceled = 0; // Note : Technically this can overflow.

  if (!this->is_empty ())
    {
      ACE_Timer_Node_T<TYPE>* first = this->get_first ();
      ACE_Time_Value last = first->get_timer_value ();
      int recalc = 0;

      for (u_int i = 0; i < this->spoke_count_; ++i)
        {
          ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
          for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root; )
            {
              if (n->get_type () == type)
                {
                  ++num_canceled;
                  if (n == first)
                    recalc = 1;

                  ACE_Timer_Node_T<TYPE>* tmp = n;
                  n = n->get_next ();

                  this->cancel_i (tmp);
                }
              else
                {
                  n = n->get_next ();
                }
            }
        }

      if (recalc)
        this->recalc_earliest (last);
    }

  // Call the close hooks.
  int cookie = 0;

  // cancel_type() called once per <type>.
  this->upcall_functor ().cancel_type (*this,
                                       type,
                                       skip_close,
                                       cookie);

  for (int i = 0;
       i < num_canceled;
       ++i)
    {
      // cancel_timer() called once per <timer>.
      this->upcall_functor ().cancel_timer (*this,
                                            type,
                                            skip_close,
                                            cookie);
    }

  return num_canceled;
}


/**
* Cancels the single timer that is specified by the timer_id.  In this
* case the timer_id is actually a pointer to the node, so we cast it
* to the node.  This can be dangerous if the timer_id is made up
* (or deleted twice) so we do a little sanity check.  Finally we update
* the earliest time in case the earliest timer was removed.
*
* @param timer_id   Timer Identifier
* @param act        Asychronous Completion Token (AKA magic cookie):
*                   If this is non-zero, stores the magic cookie of
*                   the cancelled timer here.
* @param skip_close If this non-zero, the cancellation method of the
*                   functor will not be called.
*
* @return 1 for sucess and 0 if the timer_id wasn't found (or was
*         found to be invalid)
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
                                                    const void **act,
                                                    int skip_close)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
  ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
  ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
  if (n != 0)
    {
      ACE_Time_Value last = n->get_timer_value ();

      int recalc = (this->get_first_i () == n);

      // Call the close hooks.
      int cookie = 0;

      // cancel_type() called once per <type>.
      this->upcall_functor ().cancel_type (*this,
                                           n->get_type (),
                                           skip_close,
                                           cookie);

      // cancel_timer() called once per <timer>.
      this->upcall_functor ().cancel_timer (*this,
                                            n->get_type (),
                                            skip_close,
                                            cookie);
      if (act != 0)
        *act = n->get_act ();

      this->cancel_i (n);

      if (recalc)
        this->recalc_earliest (last);

      return 1;
    }
  return 0;
}

/// Shared subset of the two cancel() methods.
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
{
  this->unlink (n);
  this->free_node (n);
}

/// There are a few places where we have to figure out which timer
/// will expire next. This method makes the assumption that spokes
/// are always sorted, and that timers are always in the correct spoke
/// determined from their expiration time.
/// The last time is always passed in, even though you can often calculate
/// it as get_first()->get_timer_value().
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::recalc_earliest
  (const ACE_Time_Value& last)
{
  // This is possible because we use a count for is_empty()
  if (this->is_empty ())
    return;

  ACE_Time_Value et = ACE_Time_Value::zero;

  u_int spoke = this->earliest_spoke_;

  // We will have to go around the wheel at most one time.
  for (u_int i = 0; i < this->spoke_count_; ++i)
    {
      ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
      ACE_Timer_Node_T<TYPE>* n = root->get_next ();
      if (n != root)
        {
          ACE_Time_Value t = n->get_timer_value ();
          if (t < last + this->wheel_time_)
            {
              this->earliest_spoke_ = spoke;
              return;
            }
          else if (et == ACE_Time_Value::zero || t < et)
            {
              et = t;
            }
        }
      if (++spoke >= this->spoke_count_)
        spoke = 0;
    }
  //ACE_ERROR((LM_ERROR, "We had to search the whole wheel.\n"));
}

/**
* Dumps out the size of the wheel, the resolution, and the contents
* of the wheel.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_Timer_Wheel_T::dump");
  ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));

  ACE_DEBUG ((LM_DEBUG,
    ACE_LIB_TEXT ("\nspoke_count_ = %d"), this->spoke_count_));
  ACE_DEBUG ((LM_DEBUG,
    ACE_LIB_TEXT ("\nresolution_ = %d"), 1 << this->res_bits_));
  ACE_DEBUG ((LM_DEBUG,
    ACE_LIB_TEXT ("\nwheel_ = \n")));

  for (u_int i = 0; i < this->spoke_count_; ++i)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("%d\n"), i));
      ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
      for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
           n != root;
           n = n->get_next ())
        {
          n->dump ();
        }
    }

  ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}


/**
* Removes the earliest node and then find the new <earliest_spoke_>
*
* @return The earliest timer node.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::remove_first");
  return remove_first_expired (ACE_Time_Value::max_time);
}

template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::unlink");
  --timer_count_;
  n->get_prev ()->set_next (n->get_next ());
  n->get_next ()->set_prev (n->get_prev ());
  n->set_prev (0);
  n->set_next (0);
}

template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first_expired (const ACE_Time_Value& now)
{
  ACE_Timer_Node_T<TYPE>* n = this->get_first ();
  if (n != 0 && n->get_timer_value() <= now)
    {
      this->unlink (n);
      this->recalc_earliest (n->get_timer_value ());
      return n;
    }
  return 0;
}

/**
* Returns the earliest node without removing it
*
* @return The earliest timer node.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Node_T<TYPE>*
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::get_first");
  return this->get_first_i ();
}

template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Node_T<TYPE>*
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
{
  ACE_Timer_Node_T<TYPE>* root = this->spokes_[this->earliest_spoke_];
  ACE_Timer_Node_T<TYPE>* first = root->get_next ();
  if (first != root)
    return first;
  return 0;
}


/**
* @return The iterator
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
{
  this->iterator_->first ();
  return *this->iterator_;
}

/**
* Dummy version of expire to get rid of warnings in Sun CC 4.2
* Just call the expire of the base class.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire ()
{
  return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire ();
}

/**
* This is a specialized version of expire that is more suited for the
* internal data representation.
*
* @param cur_time The time to expire timers up to.
*
* @return Number of timers expired
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value& cur_time)
{
  ACE_TRACE ("ACE_Timer_Wheel_T::expire");
  ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));

  int expcount = 0;
  ACE_Timer_Node_T<TYPE>* n = this->remove_first_expired (cur_time);

  while (n != 0)
    {
      ++expcount;

      //ACE_ERROR((LM_ERROR, "Expiring %x\n", (long) n));

      ACE_Timer_Node_Dispatch_Info_T<TYPE> info;

      // Get the dispatch info
      n->get_dispatch_info (info);

      const void *upcall_act = 0;

      this->preinvoke (info, cur_time, upcall_act);

      this->upcall (info, cur_time);

      this->postinvoke (info, cur_time, upcall_act);

      if (n->get_interval () > ACE_Time_Value::zero)
        {
          // Make sure that we skip past values that have already
          // "expired".
          do
            n->set_timer_value (n->get_timer_value () +
                                n->get_interval ());
          while (n->get_timer_value () <= cur_time);

          this->reschedule (n);
        }
      else
        {
          this->free_node (n);
        }

      n = this->remove_first_expired (cur_time);
    }

  //ACE_ERROR((LM_ERROR, "Expired %d nodes\n", expcount));

  return expcount;
}

///////////////////////////////////////////////////////////////////////////
// ACE_Timer_Wheel_Iterator_T

/**
* Just initializes the iterator with a ACE_Timer_Wheel_T and then calls
* first() to initialize the rest of itself.
*
* @param wheel A reference for a timer queue to iterate over
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK>::ACE_Timer_Wheel_Iterator_T
(Wheel& wheel)
: timer_wheel_ (wheel)
{
  this->first();
}


/**
* Destructor, at this level does nothing.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
ACE_Timer_Wheel_Iterator_T<TYPE,
FUNCTOR,
ACE_LOCK>::~ACE_Timer_Wheel_Iterator_T (void)
{
}


/**
* Positions the iterator at the first position in the timing wheel
* that contains something. spoke_ will be set to the spoke position of
* this entry and current_node_ will point to the first entry in that spoke.
*
* If the wheel is empty, spoke_ will be equal timer_wheel_.spoke_count_ and
* current_node_ would be 0.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
{
  this->goto_next(0);
}


/**
* Positions the iterator at the next node.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
{
  if (this->isdone())
    return;

  ACE_Timer_Node_T<TYPE>* n = this->current_node_->get_next ();
  ACE_Timer_Node_T<TYPE>* root = this->timer_wheel_.spokes_[this->spoke_];
  if (n == root)
    this->goto_next (this->spoke_ + 1);
  else
    this->current_node_ = n;
}

/// Helper class for common functionality of next() and first()
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::goto_next (u_int start_spoke)
{
  // Find the first non-empty entry.
  u_int sc = this->timer_wheel_.spoke_count_;
  for (u_int i = start_spoke; i < sc; ++i)
  {
    ACE_Timer_Node_T<TYPE>* root = this->timer_wheel_.spokes_[i];
    ACE_Timer_Node_T<TYPE>* n = root->get_next ();
    if (n != root)
      {
        this->spoke_ = i;
        this->current_node_ = n;
        return;
      }
  }
  // empty
  this->spoke_ = sc;
  this->current_node_ = 0;
}


/**
* @return True when we there aren't any more items (when current_node_ == 0)
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
{
  return this->current_node_ == 0;
}


/**
* @return The node at the current spokeition in the sequence or 0 if the wheel
*         is empty
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
{
  return this->current_node_;
}


#endif /* ACE_TIMER_WHEEL_T_C */
