From 58b6bbd2422dfe84379c0764e91e987e8852d022 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Fri, 2 Mar 2012 17:43:46 +0000 Subject: [PATCH] libpgf: simple optimization in the implementation for heaps --- src/runtime/c/gu/seq.c | 43 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index ab1ba7f29..7b9f9c1ab 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -164,34 +164,30 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool) } static void -gu_heap_siftdown(GuBuf *buf, GuOrder *order, int startpos, int pos) +gu_heap_siftdown(GuBuf *buf, GuOrder *order, + const void *value, int startpos, int pos) { - void *newitem = alloca(buf->elem_size); - memcpy(newitem, &buf->data[buf->elem_size * pos], buf->elem_size); - while (pos > startpos) { int parentpos = (pos - 1) >> 1; void *parent = &buf->data[buf->elem_size * parentpos]; - if (order->compare(order, newitem, parent) < 0) { - memcpy(&buf->data[buf->elem_size * pos], parent, buf->elem_size); - pos = parentpos; - continue; - } - break; + if (order->compare(order, value, parent) >= 0) + break; + + memcpy(&buf->data[buf->elem_size * pos], parent, buf->elem_size); + pos = parentpos; } - memcpy(&buf->data[buf->elem_size * pos], newitem, buf->elem_size); + memcpy(&buf->data[buf->elem_size * pos], value, buf->elem_size); } static void -gu_heap_siftup(GuBuf *buf, GuOrder *order, int pos) +gu_heap_siftup(GuBuf *buf, GuOrder *order, + const void *value, int pos) { int startpos = pos; int endpos = gu_buf_length(buf); - void *newitem = alloca(buf->elem_size); - memcpy(newitem, &buf->data[buf->elem_size * pos], buf->elem_size); - + int childpos = 2*pos + 1; while (childpos < endpos) { int rightpos = childpos + 1; @@ -208,15 +204,14 @@ gu_heap_siftup(GuBuf *buf, GuOrder *order, int pos) childpos = 2*pos + 1; } - memcpy(&buf->data[buf->elem_size * pos], newitem, buf->elem_size); - gu_heap_siftdown(buf, order, startpos, pos); + gu_heap_siftdown(buf, order, value, startpos, pos); } void gu_buf_heap_push(GuBuf *buf, GuOrder *order, void *value) { - memcpy(gu_buf_extend(buf), value, buf->elem_size); - gu_heap_siftdown(buf, order, 0, gu_buf_length(buf)-1); + gu_buf_extend(buf); + gu_heap_siftdown(buf, order, value, 0, gu_buf_length(buf)-1); } void @@ -226,8 +221,7 @@ gu_buf_heap_pop(GuBuf *buf, GuOrder *order, void* data_out) if (gu_buf_length(buf) > 0) { memcpy(data_out, buf->data, buf->elem_size); - memcpy(buf->data, last, buf->elem_size); - gu_heap_siftup(buf, order, 0); + gu_heap_siftup(buf, order, last, 0); } else { memcpy(data_out, last, buf->elem_size); } @@ -239,17 +233,18 @@ gu_buf_heap_replace(GuBuf *buf, GuOrder *order, void *value, void *data_out) gu_require(gu_buf_length(buf) > 0); memcpy(data_out, buf->data, buf->elem_size); - memcpy(buf->data, value, buf->elem_size); - gu_heap_siftup(buf, order, 0); + gu_heap_siftup(buf, order, value, 0); } void gu_buf_heapify(GuBuf *buf, GuOrder *order) { size_t middle = gu_buf_length(buf) / 2; + void *value = alloca(buf->elem_size); for (size_t i = 0; i < middle; i++) { - gu_heap_siftup(buf, order, i); + memcpy(value, &buf->data[buf->elem_size * i], buf->elem_size); + gu_heap_siftup(buf, order, value, i); } }