Imported my own pairing-heap timer queue implementation
This commit is contained in:
parent
aa39334c34
commit
fd72fe38f3
2 changed files with 113 additions and 0 deletions
|
|
@ -1,4 +1,21 @@
|
|||
#ifndef KARLOS_TIME_H
|
||||
#define KARLOS_TIME_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Timer Timer;
|
||||
typedef void (*TimerFunc)(Timer *timer);
|
||||
|
||||
struct Timer {
|
||||
Timer *parent;
|
||||
Timer *prev;
|
||||
Timer *next;
|
||||
Timer *first;
|
||||
uint64_t time;
|
||||
TimerFunc func;
|
||||
};
|
||||
|
||||
void timer_insert(Timer **queue, Timer *timer, uint64_t time, TimerFunc func);
|
||||
void timer_delete(Timer **queue, Timer *timer);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
96
src/time.c
96
src/time.c
|
|
@ -1,3 +1,99 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static Timer *
|
||||
timer_meld(Timer *heap1, Timer *heap2)
|
||||
{
|
||||
if (!heap1) {
|
||||
return heap2;
|
||||
}
|
||||
if (!heap2) {
|
||||
return heap1;
|
||||
}
|
||||
if (heap1->time <= heap2->time) {
|
||||
heap2->parent = heap1;
|
||||
heap2->prev = NULL;
|
||||
heap2->next = heap1->first;
|
||||
heap1->parent = NULL;
|
||||
heap1->prev = NULL;
|
||||
heap1->next = NULL;
|
||||
heap1->first = heap2;
|
||||
return heap1;
|
||||
} else {
|
||||
heap1->parent = heap2;
|
||||
heap1->prev = NULL;
|
||||
heap1->next = heap2->first;
|
||||
heap2->parent = NULL;
|
||||
heap2->prev = NULL;
|
||||
heap2->next = NULL;
|
||||
heap2->first = heap1;
|
||||
return heap2;
|
||||
}
|
||||
}
|
||||
|
||||
static Timer *
|
||||
timer_pair(Timer *list)
|
||||
{
|
||||
Timer *root = NULL, *black = list, *white, *gray;
|
||||
while (black) {
|
||||
white = black->next;
|
||||
if (white) {
|
||||
gray = timer_meld(black, white);
|
||||
root = timer_meld(root, gray);
|
||||
black = white->next;
|
||||
} else {
|
||||
root = timer_meld(root, black);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
void
|
||||
timer_insert(Timer **queue, Timer *timer, uint64_t time, TimerFunc func)
|
||||
{
|
||||
timer->time = time;
|
||||
timer->func = func;
|
||||
timer->parent = NULL;
|
||||
timer->prev = NULL;
|
||||
timer->next = NULL;
|
||||
timer->first = NULL;
|
||||
*queue = timer_meld(*queue, timer);
|
||||
}
|
||||
|
||||
void
|
||||
timer_delete(Timer **queue, Timer *timer)
|
||||
{
|
||||
Timer *root = *queue;
|
||||
|
||||
if (root == timer) {
|
||||
root = NULL;
|
||||
}
|
||||
if (timer->parent && timer->parent->first == timer) {
|
||||
timer->parent->first = timer->next;
|
||||
}
|
||||
if (timer->prev) {
|
||||
timer->prev->next = timer->next;
|
||||
}
|
||||
if (timer->next) {
|
||||
timer->next->prev = timer->prev;
|
||||
}
|
||||
if (timer->first) {
|
||||
Timer *list = timer->first;
|
||||
if (root) {
|
||||
root->next = list;
|
||||
list->prev = root;
|
||||
list = root;
|
||||
}
|
||||
root = timer_pair(list);
|
||||
}
|
||||
|
||||
timer->parent = NULL;
|
||||
timer->prev = NULL;
|
||||
timer->next = NULL;
|
||||
timer->first = NULL;
|
||||
|
||||
*queue = root;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue