diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-04-23 00:01:24 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-04-23 00:01:24 +0000 |
commit | 8b7a3b3676375d145e0b89d3f3d9194c7031a760 (patch) | |
tree | d346a0df9b85e435985fbe592526b84272f32bbb /minheap-internal.h | |
parent | 0068c98ad2653c3ed3ac70250893531d072c2fbb (diff) | |
download | libevent-8b7a3b3676375d145e0b89d3f3d9194c7031a760.tar.gz |
Fix min_heap_erase when we remove an element from the middle of the heap.
Previously, we could lose the heap property when we removed an item
whose parent was greater than the last element in the heap. We would
replace the removed item with the last element, and consider shifting
it down, but we wouldn't consider shifting it up.
Patch from Marko Kreen.
svn:r1226
Diffstat (limited to 'minheap-internal.h')
-rw-r--r-- | minheap-internal.h | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/minheap-internal.h b/minheap-internal.h index 6cd9c4aa..3b287043 100644 --- a/minheap-internal.h +++ b/minheap-internal.h @@ -88,7 +88,17 @@ int min_heap_erase(min_heap_t* s, struct event* e) { if(((unsigned int)-1) != e->min_heap_idx) { - min_heap_shift_down_(s, e->min_heap_idx, s->p[--s->n]); + struct event *last = s->p[--s->n]; + unsigned parent = (e->min_heap_idx - 1) / 2; + /* we replace e with the last element in the heap. We might need to + shift it upward if it is less than its parent, or downward if it is + greater than one or both its children. Since the children are known + to be less than the parent, it can't need to shift both up and + down. */ + if (e->min_heap_idx > 0 && min_heap_elem_greater(s->p[parent], last)) + min_heap_shift_up_(s, e->min_heap_idx, last); + else + min_heap_shift_down_(s, e->min_heap_idx, last); e->min_heap_idx = -1; return 0; } |