forked from GitHub/gf-core
libpgf: simple optimization in the implementation for heaps
This commit is contained in:
@@ -164,33 +164,29 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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) {
|
while (pos > startpos) {
|
||||||
int parentpos = (pos - 1) >> 1;
|
int parentpos = (pos - 1) >> 1;
|
||||||
void *parent = &buf->data[buf->elem_size * parentpos];
|
void *parent = &buf->data[buf->elem_size * parentpos];
|
||||||
|
|
||||||
if (order->compare(order, newitem, parent) < 0) {
|
if (order->compare(order, value, parent) >= 0)
|
||||||
memcpy(&buf->data[buf->elem_size * pos], parent, buf->elem_size);
|
break;
|
||||||
pos = parentpos;
|
|
||||||
continue;
|
memcpy(&buf->data[buf->elem_size * pos], parent, buf->elem_size);
|
||||||
}
|
pos = parentpos;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&buf->data[buf->elem_size * pos], newitem, buf->elem_size);
|
memcpy(&buf->data[buf->elem_size * pos], value, buf->elem_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 startpos = pos;
|
||||||
int endpos = gu_buf_length(buf);
|
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;
|
int childpos = 2*pos + 1;
|
||||||
while (childpos < endpos) {
|
while (childpos < endpos) {
|
||||||
@@ -208,15 +204,14 @@ gu_heap_siftup(GuBuf *buf, GuOrder *order, int pos)
|
|||||||
childpos = 2*pos + 1;
|
childpos = 2*pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&buf->data[buf->elem_size * pos], newitem, buf->elem_size);
|
gu_heap_siftdown(buf, order, value, startpos, pos);
|
||||||
gu_heap_siftdown(buf, order, startpos, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gu_buf_heap_push(GuBuf *buf, GuOrder *order, void *value)
|
gu_buf_heap_push(GuBuf *buf, GuOrder *order, void *value)
|
||||||
{
|
{
|
||||||
memcpy(gu_buf_extend(buf), value, buf->elem_size);
|
gu_buf_extend(buf);
|
||||||
gu_heap_siftdown(buf, order, 0, gu_buf_length(buf)-1);
|
gu_heap_siftdown(buf, order, value, 0, gu_buf_length(buf)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -226,8 +221,7 @@ gu_buf_heap_pop(GuBuf *buf, GuOrder *order, void* data_out)
|
|||||||
|
|
||||||
if (gu_buf_length(buf) > 0) {
|
if (gu_buf_length(buf) > 0) {
|
||||||
memcpy(data_out, buf->data, buf->elem_size);
|
memcpy(data_out, buf->data, buf->elem_size);
|
||||||
memcpy(buf->data, last, buf->elem_size);
|
gu_heap_siftup(buf, order, last, 0);
|
||||||
gu_heap_siftup(buf, order, 0);
|
|
||||||
} else {
|
} else {
|
||||||
memcpy(data_out, last, buf->elem_size);
|
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);
|
gu_require(gu_buf_length(buf) > 0);
|
||||||
|
|
||||||
memcpy(data_out, buf->data, buf->elem_size);
|
memcpy(data_out, buf->data, buf->elem_size);
|
||||||
memcpy(buf->data, value, buf->elem_size);
|
gu_heap_siftup(buf, order, value, 0);
|
||||||
gu_heap_siftup(buf, order, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gu_buf_heapify(GuBuf *buf, GuOrder *order)
|
gu_buf_heapify(GuBuf *buf, GuOrder *order)
|
||||||
{
|
{
|
||||||
size_t middle = gu_buf_length(buf) / 2;
|
size_t middle = gu_buf_length(buf) / 2;
|
||||||
|
void *value = alloca(buf->elem_size);
|
||||||
|
|
||||||
for (size_t i = 0; i < middle; i++) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user