Commit 31e0b1b6 authored by Vitezslav Kriz's avatar Vitezslav Kriz

heap position tracking for better find operation

parent 58c53bde
......@@ -42,6 +42,9 @@ static inline void heap_swap(heap_val_t *e1, heap_val_t *e2)
heap_val_t tmp = *e1; /* Even faster than 2-XOR nowadays. */
*e1 = *e2;
*e2 = tmp;
int pos = (*e1)->pos;
(*e1)->pos = (*e2)->pos;
(*e2)->pos = pos;
}
int heap_init(struct heap *h, int (*cmp)(void *, void *), int init_size)
......@@ -83,19 +86,21 @@ static inline void _heap_bubble_up(struct heap *h, int e)
}
static void heap_increase(struct heap *h, int pos, void *e)
static void heap_increase(struct heap *h, int pos, heap_val_t e)
{
*HELEMENT(h, pos) = e;
e->pos = pos;
_heap_bubble_down(h, pos);
}
static void heap_decrease(struct heap *h, int pos, void *e)
static void heap_decrease(struct heap *h, int pos, heap_val_t e)
{
*HELEMENT(h, pos) = e;
e->pos = pos;
_heap_bubble_up(h, pos);
}
void heap_replace(struct heap *h, int pos, void *e)
void heap_replace(struct heap *h, int pos, heap_val_t e)
{
if (h->cmp(*HELEMENT(h, pos),e) < 0) {
heap_increase(h, pos, e);
......@@ -111,11 +116,12 @@ void heap_delmin(struct heap *h)
{
heap_swap(HHEAD(h),HELEMENT(h,h->num));
}
(*HELEMENT(h, h->num))->pos = 0;
--h->num;
_heap_bubble_down(h, 1);
}
int heap_insert(struct heap *h, void *e)
int heap_insert(struct heap *h, heap_val_t e)
{
if(h->num == h->max_size)
{
......@@ -128,25 +134,20 @@ int heap_insert(struct heap *h, void *e)
h->num++;
*HELEMENT(h,h->num) = e;
e->pos = h->num;
_heap_bubble_up(h,h->num);
return 1;
}
int heap_find(struct heap *h, void *elm) /* FIXME - very slow */
int heap_find(struct heap *h, heap_val_t elm)
{
int i = 1; /* Skip tmp element. */
int np = h->num + 1; /* Start from min-heap top. */
while(i != np)
{
if(*HELEMENT(h, i) == elm) return i;
++i;
}
return 0;
return ((struct heap_val *) elm)->pos;
}
void heap_delete(struct heap *h, int e)
{
heap_swap(HELEMENT(h, e), HELEMENT(h, h->num));
(*HELEMENT(h, h->num))->pos = 0;
h->num--;
if(h->cmp(*HELEMENT(h, e), *HELEMENT(h, h->num + 1)) < 0) _heap_bubble_up(h, e);
else _heap_bubble_down(h, e);
......
......@@ -16,7 +16,11 @@
#pragma once
typedef void* heap_val_t;
struct heap_val {
int pos;
};
typedef struct heap_val* heap_val_t;
struct heap {
int num; /* Number of elements */
......@@ -34,7 +38,7 @@ struct heap {
int heap_init(struct heap *, int (*cmp)(), int);
void heap_delmin(struct heap *);
int heap_insert(struct heap *, void *);
int heap_find(struct heap *, void *);
int heap_insert(struct heap *, heap_val_t);
int heap_find(struct heap *, heap_val_t);
void heap_delete(struct heap *, int);
void heap_replace(struct heap *h, int pos, void *e);
void heap_replace(struct heap *h, int pos, heap_val_t e);
......@@ -130,7 +130,7 @@ void evsched_deinit(evsched_t *sched)
pthread_cond_destroy(&sched->notify);
while (!EMPTY_HEAP(&sched->heap)) {
event_t *e = *HHEAD(&sched->heap);
event_t *e = (event_t *)*HHEAD(&sched->heap);
heap_delmin(&sched->heap);
evsched_event_free(e);
}
......@@ -163,6 +163,7 @@ event_t *evsched_event_create(evsched_t *sched, event_cb_t cb, void *data)
e->sched = sched;
e->cb = cb;
e->data = data;
e->hpos.pos=0;
return e;
}
......@@ -192,11 +193,11 @@ int evsched_schedule(event_t *ev, uint32_t dt)
ev->tv = new_time;
/* Make sure it's not already enqueued. */
int found = heap_find(&sched->heap, ev);
int found = heap_find(&sched->heap, (heap_val_t)ev);
if (found > 0) {
heap_replace(&sched->heap, found, ev);
heap_replace(&sched->heap, found, (heap_val_t)ev);
} else {
heap_insert(&sched->heap, ev);
heap_insert(&sched->heap, (heap_val_t)ev);
}
/* Unlock calendar. */
......@@ -217,7 +218,7 @@ int evsched_cancel(event_t *ev)
/* Lock calendar. */
pthread_mutex_lock(&sched->heap_lock);
int found = heap_find(&sched->heap, ev);
int found = heap_find(&sched->heap, (heap_val_t)ev);
if (found > 0) {
heap_delete(&sched->heap, found);
}
......
......@@ -57,6 +57,7 @@ typedef void (*event_cb_t)(struct event *);
* \brief Event structure.
*/
typedef struct event {
struct heap_val hpos;
struct timeval tv; /*!< Event scheduled time. */
void *data; /*!< Usable data ptr. */
event_cb_t cb; /*!< Event callback. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment