#pragma once // ::DataStructures::RedBlackTree::Header:: #define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT) #define RBQueuePop(f, l) SLLQueuePop(P_RB_DN_NIL, f, l) #define RBQueuePush(f, l, n) SLLQueuePush(P_RB_DN_NIL, f, l, n) #define RBQueuePushFront(f, l, n) SLLQueuePush(P_RB_DN_NIL, f, l, n) typedef enum RBNodeColor_e { RB_RED, RB_BLACK, } RBNodeColor; typedef enum RBNodeDir_e { RB_LEFT, RB_RIGHT, } RBNodeDir; typedef struct RBDataNode { rawptr data; struct RBDataNode *next; } RBDataNode; typedef struct RBBucket { RBDataNode *first; RBDataNode *last; } RBBucket; typedef struct RBNode { union { struct { struct RBNode *left; struct RBNode *right; }; struct RBNode *child[2]; }; struct RBNode *parent; u64 key; RBBucket bucket; RBNodeColor color; } RBNode; typedef struct RBTree { RBNode *root; RBNode *nil; } RBTree; static void RBTreeInit (RBTree *tree); static inline RBNode *RBTreeInitNode(u64 key, rawptr value); static inline void RBTreePushDataNode(RBDataNode *first, RBDataNode *last, rawptr value); static void RBTreeInsert(RBTree *tree, u64 key, rawptr value); static b32 RBTreeSearchNearest(RBTree *tree, u64 key, RBNode **node); static b32 RBTreeSearch (RBTree *tree, u64 key, RBNode **node); static void RBTreeDelete (RBTree *tree, u64 key, rawptr value); static void RBTreeLeftRotate (RBTree *tree, RBNode *node); static void RBTreeRightRotate(RBTree *tree, RBNode *node); static void RBTreeRotate (RBTree *tree, RBNode *node, RBNodeDir dir); static void RBTreeCorrect (RBTree *tree, RBNode *node); static void RBTreeTransplant (RBTree *tree, RBNode *node, RBNode *placed_node); // ::DataStructures::HashTable::Functions::Header:: #define HTQueuePop(f, l) SLLQueuePop(P_HT_NIL, f, l) #define HTQueuePush(f, l, n) SLLQueuePush(P_HT_NIL, f, l, n) #define HTQueuePushFront(f, l, n) SLLQueuePush(P_HT_NIL, f, l, n) typedef struct KeyValuePair { union { u64 key_u64; rawptr key_rawptr; }; union { String8 value_string; rawptr value_rawptr; u32 value_u32; u64 value_u64; U64Split value_u64_split; }; } KeyValuePair; typedef struct HashNode { struct HashNode *next; KeyValuePair v; } HashNode; typedef struct HashList { HashNode *first; HashNode *last; } HashList; typedef struct HashTable { HashList *lists; HashList free_lists; u64 count; u32 cap; } HashTable; static void HashTableInit(HashTable *table, u32 init_size); static void HashTableClear(HashTable *table); static void HashTableConcatInPlace(HashList *list, HashList *to_concat); static u64 HashTableHash(String8 str); static HashNode *HashListPop(HashList *list); static KeyValuePair *HashTableSearchU64(HashTable *table, u64 key); static KeyValuePair *HashTableSearchRawptr(HashTable *table, rawptr key); static HashNode *HashTablePush(HashTable *table, u64 hash, KeyValuePair value); static HashNode *HashTablePushU64U32(HashTable *table, u64 key, u32 value); static HashNode *HashTablePushU64U64(HashTable *table, u64 key, u64 value); static HashNode *HashTablePushU64String8(HashTable *table, u64 key, String8 value); static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value); static HashNode *HashTablePushU64U64Split(HashTable *table, u64 key, u32 upper, u32 lower); static rawptr HashTableDeleteU64Rawptr(HashTable *table, u64 key); static void HashTableDeleteU64(HashTable *table, u64 key);