Imported my own pairing-heap timer queue implementation

This commit is contained in:
Thomas Oltmann 2025-09-24 20:24:26 +02:00
parent 9161b58c7b
commit 24755d7907
2 changed files with 113 additions and 0 deletions

View file

@ -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

View file

@ -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;
}