kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

pool.h (1899B)


      1 #ifndef KIT_POOL_H
      2 #define KIT_POOL_H
      3 
      4 #include "core/arena.h"
      5 #include "core/core.h"
      6 #include "core/heap.h"
      7 #include "core/slice.h"
      8 
      9 typedef struct PoolEntry {
     10   const char* data;
     11   u32 len;
     12   u32 hash;
     13 } PoolEntry;
     14 
     15 /* Direct-mapped accelerator cache for pool_intern_slice. Keyed on a cheap fold
     16  * of (len + the leading bytes), NOT full FNV. A hit byte-verifies via the
     17  * interned bytes, so it is a pure accelerator that can never return a wrong
     18  * Sym and never affects Sym numbering (a first occurrence still goes through
     19  * the normal hash+probe+insert). sym == 0 marks an empty slot. We store only
     20  * {keyhash, sym} — never a borrowed input pointer (those aim into transient
     21  * lexer buffers). Power-of-two size; mask is POOL_ICACHE_SIZE - 1. */
     22 #define POOL_ICACHE_SIZE 1024u
     23 typedef struct PoolICacheSlot {
     24   u32 keyhash;
     25   Sym sym;
     26 } PoolICacheSlot;
     27 
     28 struct Pool {
     29   Heap* heap;
     30   Arena arena; /* string storage */
     31 
     32   /* Hash table: 0 means empty. Otherwise it's a Sym id (1-based). */
     33   Sym* table;
     34   u32 cap; /* always a power of two */
     35   u32 used;
     36   u32 grow_threshold; /* precomputed cap*LOAD_NUM/LOAD_DEN; grow when used>= it */
     37 
     38   /* Sym → string mapping. Index 0 reserved as Sym = 0 ("none"). */
     39   PoolEntry* entries;
     40   u32 nentries;
     41   u32 entries_cap;
     42 
     43   /* Direct-mapped intern accelerator (zero-init = all empty). */
     44   PoolICacheSlot* icache;
     45 };
     46 
     47 void pool_init(Pool*, Heap*);
     48 void pool_fini(Pool*);
     49 
     50 /* Interning. Returns the canonical id; equal byte sequences → equal ids
     51  * (Sym 0 for the empty slice). pool_slice returns the interned bytes as a
     52  * slice (SLICE_NULL for Sym 0); its pointer is NUL-terminated as a boundary
     53  * convenience, with the NUL excluded from len. */
     54 Sym pool_intern_slice(Pool*, Slice);
     55 /* Convenience: intern a NUL-terminated C string (interns Sym 0 for NULL). */
     56 Sym pool_intern_cstr(Pool*, const char*);
     57 Slice pool_slice(Pool*, Sym);
     58 
     59 #endif