feat: add PollFd, PrioQNode and PrioQueue
This commit is contained in:
1 parent
25f50f156a
commit
8af9a09f89
4 files changed
+198
No files matched your search
@@ -0,0 +1,63 @@
|
||||
#ifndef FROSTBYTE_RBT_H
|
||||
#define FROSTBYTE_RBT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* Rbt: an intrusive red-black tree, Linux-kernel style. Embed an RbtNode in
|
||||
* your own struct (next to a key field) and use rbtEntry() (mirrors
|
||||
* listEntry from list.h) to recover the containing struct. No allocation,
|
||||
* no element copying -- the tree only ever relinks the nodes you give it.
|
||||
*
|
||||
* Ordering is supplied by the caller as plain function pointers rather than
|
||||
* baked into the node, so the same node type can be indexed by different
|
||||
* keys in different trees (compare two full nodes for rbtInsert; compare a
|
||||
* raw key against a node for rbtFind, same convention as bsearch).
|
||||
*/
|
||||
|
||||
typedef struct RbtNode {
|
||||
struct RbtNode* left;
|
||||
struct RbtNode* right;
|
||||
struct RbtNode* parent;
|
||||
bool red;
|
||||
} RbtNode;
|
||||
|
||||
#define rbtEntry(ptr, type, member) \
|
||||
((type*)((uint8*)(ptr) - __builtin_offsetof(type, member)))
|
||||
|
||||
/* Returns <0, 0, >0 as a compares below/equal/above b. Equal means "already
|
||||
present" -- rbtInsert rejects the new node in that case (no duplicates;
|
||||
encode a tiebreaker into the comparison if you need a multiset). */
|
||||
typedef int (*RbtCompareFn)(const RbtNode* a, const RbtNode* b);
|
||||
|
||||
/* Same convention as bsearch: <0 if key sorts before node, >0 if after. */
|
||||
typedef int (*RbtLookupFn)(const void* key, const RbtNode* node);
|
||||
|
||||
typedef struct RbTree {
|
||||
RbtNode* root;
|
||||
usize count;
|
||||
} RbTree;
|
||||
|
||||
void rbtInit(RbTree* t);
|
||||
|
||||
/* Links node into the tree according to compare. Returns false (node left
|
||||
untouched) if a node comparing equal is already present. */
|
||||
bool rbtInsert(RbTree* t, RbtNode* node, RbtCompareFn compare);
|
||||
|
||||
/* Unlinks node from the tree. node must currently be a member of t. */
|
||||
void rbtRemove(RbTree* t, RbtNode* node);
|
||||
|
||||
RbtNode* rbtFind(const RbTree* t, const void* key, RbtLookupFn lookup);
|
||||
|
||||
RbtNode* rbtFirst(const RbTree* t); /* leftmost (minimum) */
|
||||
RbtNode* rbtLast(const RbTree* t); /* rightmost (maximum) */
|
||||
|
||||
/* In-order successor/predecessor of node. nullptr past either end. Walking
|
||||
rbtFirst()..rbtNext()..nullptr visits every node in ascending order. */
|
||||
RbtNode* rbtNext(const RbtNode* node);
|
||||
RbtNode* rbtPrev(const RbtNode* node);
|
||||
|
||||
usize rbtCount(const RbTree* t);
|
||||
bool rbtIsEmpty(const RbTree* t);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user