#ifndef TREETRIE_H_f55a3f6d_ef43_45d3_bec3_496a196b5db1 #define TREETRIE_H_f55a3f6d_ef43_45d3_bec3_496a196b5db1 #ifdef __cplusplus extern "C" { #endif typedef enum tt_tag_t { TT_TAG_TAIL = 0, TT_TAG_BRANCH, TT_TAG_LEAF, /* only case where one of node a or b points to non-node */ TT_TAG_NODE } tt_tag_t; typedef enum tt_reserved_node_idx_t { TT_ERROR = 0, /* invalid node index, means "no node at all", not even empty */ TT_EMPTY, /* empty treetrie */ TT_OK, /* terminal marker */ TT_FIRST_VALID_NODE_IDX } tt_reserved_node_idx_t; typedef uint32_t tt_node_idx_t; /* N.B. tt_reserved_node_idx_t */ typedef uint32_t tt_atom_t; typedef union tt_header_t { uint32_t next_free; struct { uint32_t refcount : 24; uint32_t index : 6; tt_tag_t tag : 2; } inuse; } tt_header_t; #define TT_REFCOUNT_LIMIT ((1 << 24) - 1) typedef struct tt_node_t { tt_node_idx_t a; /* always a real node idx */ tt_node_idx_t b; /* a real node idx unless corresponding tag is TT_TAG_LEAF */ } tt_node_t; typedef struct tt_arena_t { /* Fields for the Robin Hood hashset used for hashconsing of tt_nodes */ unsigned int max_probe; unsigned int live_count; unsigned int table_length; tt_node_idx_t *table; tt_header_t *headers; tt_node_t *nodes; tt_node_idx_t free_chain; } tt_arena_t; extern int tt_arena_init(tt_arena_t *a); extern void tt_arena_done(tt_arena_t *a); /* Returns 0 if consing failed (because of out-of-memory). Otherwise, returns a nonzero index. Grabs na and nb (according to tag) IF it needs to allocate a new node, otherwise does not. DOES NOT increase the reference count of the returned node. */ extern tt_node_idx_t tt_arena_cons(tt_arena_t *a, uint32_t tag, uint32_t index, tt_node_idx_t na, tt_node_idx_t nb); extern tt_node_idx_t tt_grab(tt_arena_t *a, tt_node_idx_t i); extern void tt_drop(tt_arena_t *a, tt_node_idx_t i); /* WARNING: private, unsafe */ typedef uint32_t tt_hash_t; extern tt_hash_t tt_hash_node(tt_arena_t *a, tt_node_idx_t i); #ifdef __cplusplus } #endif #endif