diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-13 06:53:56 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-13 06:53:56 +0000 |
commit | 9a4015e3745ffdcabce4aefb7306f1e685005b0f (patch) | |
tree | ef38939ea1d530093d0ddde463a80f052577941a /ace/Timer_Heap.cpp | |
parent | e3a0ffa03433e389ca436b5b749fcb70950c4409 (diff) | |
download | ATCD-9a4015e3745ffdcabce4aefb7306f1e685005b0f.tar.gz |
foo
Diffstat (limited to 'ace/Timer_Heap.cpp')
-rw-r--r-- | ace/Timer_Heap.cpp | 143 |
1 files changed, 109 insertions, 34 deletions
diff --git a/ace/Timer_Heap.cpp b/ace/Timer_Heap.cpp index b69872928eb..f32ab68bf88 100644 --- a/ace/Timer_Heap.cpp +++ b/ace/Timer_Heap.cpp @@ -14,15 +14,9 @@ ACE_Timer_Heap_Iterator::next (ACE_Timer_Node *&node, return 0; else { - node = this->timer_heap_.heap_[0]; + // Remove the first item and restore the heap property. - // Transfer the last element in the heap to the front and - // restore the heap property. - - this->timer_heap_.heap_[0] = - this->timer_heap_.heap_[--this->timer_heap_.cur_size_]; - - this->timer_heap_.reheap_down (); + node = this->timer_heap_.remove (0); return 1; } } @@ -72,49 +66,93 @@ ACE_Timer_Heap::dump (void) const this->heap_[index]->dump (); } -void -ACE_Timer_Heap::reheap_down (void) +ACE_Timer_Node * +ACE_Timer_Heap::remove (int index) +{ + ACE_Timer_Node *result = this->heap_[index]; + + this->cur_size_--; + + // Only try to reheapify if we're not deleting the last entry. + + if (index < this->cur_size_) + { + // Move the end node to the location being removed. + this->heap_[index] = this->heap_[this->cur_size_]; + + ACE_Timer_Node *moved_node = this->heap_[index]; + + // If we're at the top there's no place to go but down! + if (index == 0) + this->reheap_down (moved_node, 1); + + // If the moved_node->time_value_ is smaller than its parent it + // needs be moved up the heap. + else if (moved_node->timer_value_ < this->heap_[(index - 1) / 2]->timer_value_) + this->reheap_up (moved_node); + + // Call <reheap_down>, which will reheapify if the + // moved_node->time_value_ is larger than either of its children + // (who start at location <index + index>). + else + this->reheap_down (moved_node, index + index); + } + + return result; +} + +void +ACE_Timer_Heap::reheap_down (ACE_Timer_Node *moved_node, + int child_index) { int parent = 0; - int child = 1; - ACE_Timer_Node *temp = this->heap_[parent]; - // Restore the heap property. + // Restore the heap property after a deletion. - while (child < this->cur_size_) + for (int child = child_index; + child < this->cur_size_; + child += child + 1) // Multiple child by 2 and add 1. { + // Choose the smaller of the two children. if (child + 1 < this->cur_size_ - && this->heap_[child + 1]->timer_value_ > this->heap_[child]->timer_value_) + && this->heap_[child + 1]->timer_value_ < this->heap_[child]->timer_value_) child++; - if (this->heap_[child]->timer_value_ > temp->timer_value_) + // Perform a swap if the child has a larger timeout value than + // the front node. + if (this->heap_[child]->timer_value_ < moved_node->timer_value_) { this->heap_[parent] = this->heap_[child]; parent = child; - // Multiple child by 2 and add 1. - child += child + 1; } else break; } - this->heap_[parent] = temp; + // Insert moved_node into its final resting place. + this->heap_[parent] = moved_node; +} + +void +ACE_Timer_Heap::insert (ACE_Timer_Node *new_node) +{ + this->reheap_up (new_node); + this->cur_size_++; } void -ACE_Timer_Heap::reheap_up (void) +ACE_Timer_Heap::reheap_up (ACE_Timer_Node *new_node) { int parent; - int child = this->cur_size_ - 1; - ACE_Timer_Node *temp = this->heap_[child]; - - // Restore the heap property. + int child = this->cur_size_; + + // Restore the heap property after an insertion. while (child > 0) { parent = (child - 1) / 2; - if (temp->timer_value_ < this->heap_[parent]->timer_value_) + if (new_node->timer_value_ < this->heap_[parent]->timer_value_) { this->heap_[child] = this->heap_[parent]; child = parent; @@ -123,7 +161,7 @@ ACE_Timer_Heap::reheap_up (void) break; } - this->heap_[child] = temp; + this->heap_[child] = new_node; } // Reschedule a periodic timer. This function must be called with the @@ -134,10 +172,8 @@ ACE_Timer_Heap::reschedule (ACE_Timer_Node *expired) { ACE_TRACE ("ACE_Timer_Heap::reschedule"); - // Insert the <expired> node into the end of the heap and restore - // the heap property. - this->heap_[this->cur_size_++] = expired; - this->reheap_up (); + // Restore the heap property. + this->insert (expired); } // Insert a new handler that expires at time future_time; if interval @@ -174,7 +210,7 @@ ACE_Timer_Heap::schedule (ACE_Event_Handler *handler, timer_id), -1); - this->reheap_up (temp); + this->insert (temp); } return timer_id; @@ -184,12 +220,33 @@ ACE_Timer_Heap::schedule (ACE_Event_Handler *handler, // <timer_id> from the timer queue. int -ACE_Timer_Heap::cancel (int timer_id, const void **arg) +ACE_Timer_Heap::cancel (int timer_id, + const void **arg) { ACE_TRACE ("ACE_Timer_Heap::cancel"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); - return 0; + int i; + + // Try to locate the ACE_Timer_Node that matches the timer_id. + + for (i = 0; + i < this->cur_size_ && this->heap_[i]->timer_id_ != timer_id; + i++) + continue; + + if (i == this->cur_size_) + return 0; + else + { + ACE_Timer_Node *temp = this->remove (i); + + if (arg != 0) + *arg = temp->arg_; + + delete temp; + return 1; + } } // Locate and remove all values of <handler> from the timer queue. @@ -200,5 +257,23 @@ ACE_Timer_Heap::cancel (ACE_Event_Handler *handler) ACE_TRACE ("ACE_Timer_Heap::cancel"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); - return 0; + int number_of_cancellations = 0; + + // Try to locate the ACE_Timer_Node that matches the timer_id. + + for (int i = 0; + i < this->cur_size_; + ) + { + if (this->heap_[i]->handler_ == handler) + { + ACE_Timer_Node *temp = this->remove (i); + delete temp; + number_of_cancellations++; + } + else + i++; + } + + return number_of_cancellations; } |