treetrie-2015/treetrie.h

103 lines
2.8 KiB
C
Raw Normal View History

2015-06-30 00:39:49 +00:00
#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 {
2015-06-30 16:07:48 +00:00
TT_NO_IDX = 0, /* invalid node index, means "no node at all", not even empty */
TT_EMPTY_IDX, /* empty treetrie */
TT_OK_IDX, /* terminal marker */
2015-06-30 00:39:49 +00:00
TT_FIRST_VALID_NODE_IDX
} tt_reserved_node_idx_t;
2015-06-30 16:07:48 +00:00
#define TT_NO_PTR (tt_mkptr(TT_NO_IDX, 0))
#define TT_EMPTY (tt_mkptr(TT_EMPTY_IDX, 0))
#define TT_OK (tt_mkptr(TT_OK_IDX, 0))
#define TT_FIRST_VALID_NODE_PTR (tt_mkptr(TT_FIRST_VALID_NODE_IDX, 0))
2015-06-30 00:39:49 +00:00
typedef uint32_t tt_node_idx_t; /* N.B. tt_reserved_node_idx_t */
2015-06-30 16:07:48 +00:00
typedef uint32_t tt_node_ptr_t; /* An index shifted left 2 with tag or'd in low bits */
2015-06-30 00:39:49 +00:00
2015-06-30 03:19:44 +00:00
typedef uint32_t tt_atom_t; /* Atom number 0 is the wildcard atom. */
2015-06-30 00:39:49 +00:00
typedef union tt_header_t {
2015-06-30 16:07:48 +00:00
tt_node_idx_t next_free;
2015-06-30 00:39:49 +00:00
struct {
uint32_t refcount : 24;
2015-06-30 16:07:48 +00:00
uint32_t index : 8; /* this really doesn't need to be more than 5 or 6 bits wide */
2015-06-30 00:39:49 +00:00
} inuse;
} tt_header_t;
#define TT_REFCOUNT_LIMIT ((1 << 24) - 1)
typedef struct tt_node_t {
2015-06-30 16:07:48 +00:00
tt_node_ptr_t a; /* always a real node ptr */
tt_node_ptr_t b; /* a real node ptr unless corresponding tag is TT_TAG_LEAF */
2015-06-30 00:39:49 +00:00
} tt_node_t;
2015-06-30 03:19:44 +00:00
typedef struct tt_free_chain_t {
tt_node_idx_t head; /* remove links from here */
tt_node_idx_t tail; /* append links here */
} tt_free_chain_t;
2015-06-30 00:39:49 +00:00
typedef struct tt_arena_t {
/* Fields for the Robin Hood hashset used for hashconsing of tt_nodes */
unsigned int max_probe;
unsigned int table_length;
2015-06-30 16:07:48 +00:00
tt_node_ptr_t *table;
2015-06-30 00:39:49 +00:00
tt_header_t *headers;
tt_node_t *nodes;
2015-06-30 03:19:44 +00:00
unsigned int free_count;
tt_free_chain_t free_chain;
2015-06-30 00:39:49 +00:00
} tt_arena_t;
2015-06-30 16:07:48 +00:00
static inline tt_node_ptr_t tt_mkptr(tt_node_idx_t i, tt_tag_t tag) {
return (i << 2) | tag;
}
static inline tt_node_idx_t tt_ptr_idx(tt_node_ptr_t p) {
return p >> 2;
}
static inline tt_tag_t tt_ptr_tag(tt_node_ptr_t p) {
return p & 3;
}
2015-06-30 00:39:49 +00:00
extern int tt_arena_init(tt_arena_t *a);
extern void tt_arena_done(tt_arena_t *a);
2015-06-30 03:19:44 +00:00
extern void tt_dump_arena_summary(tt_arena_t *a);
extern void tt_dump_arena(tt_arena_t *a);
extern void tt_arena_flush(tt_arena_t *a);
2015-06-30 16:09:28 +00:00
/* Returns TT_NO_PTR if consing failed (because of out-of-memory).
2015-06-30 00:39:49 +00:00
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. */
2015-06-30 16:07:48 +00:00
extern tt_node_ptr_t tt_arena_cons(tt_arena_t *a,
2015-06-30 00:39:49 +00:00
uint32_t tag,
uint32_t index,
2015-06-30 16:07:48 +00:00
tt_node_ptr_t na,
tt_node_ptr_t nb);
2015-06-30 00:39:49 +00:00
2015-06-30 16:07:48 +00:00
extern tt_node_ptr_t tt_grab(tt_arena_t *a, tt_node_ptr_t i);
extern void tt_drop(tt_arena_t *a, tt_node_ptr_t i);
2015-06-30 00:39:49 +00:00
#ifdef __cplusplus
}
#endif
#endif