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
|
#ifndef KARLOS_TIME_H
|
||||||
#define 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
|
#endif
|
||||||
|
|
|
||||||
96
src/time.c
96
src/time.c
|
|
@ -1,3 +1,99 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <time.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