shrub/i/n/h.h

121 lines
3.6 KiB
C
Raw Normal View History

2014-09-04 07:44:53 +04:00
/* include/g/h.h
**
** This file is in the public domain.
*/
/** Data structures.
**/
/** Straightforward implementation of the classic Bagwell
*** HAMT (hash array mapped trie), using a mug hash.
***
*** Because a mug is 31 bits, the root table is 64 wide.
*** Thereupon 5 bits each are warm for each layer. The
*** final leaf is simply a linear search.
***
*** We store an extra "freshly warm" bit for a simple
*** clock-algorithm reclamation policy, not yet implemented.
*** Search "clock algorithm" to figure it out.
**/
2014-11-06 03:20:01 +03:00
/* u3h_slot: map slot.
**
** Either a key-value cell or a loom offset, decoded as a pointer
2014-11-06 03:20:01 +03:00
** to a u3h_node. Matches the u3_noun format - coordinate with
** meme.h. The top two bits are:
**
** 00 - empty (in the root table only)
** 01 - table
** 02 - entry, stale
** 03 - entry, fresh
*/
2014-11-06 03:20:01 +03:00
typedef c3_w u3h_slot;
2014-11-06 03:20:01 +03:00
/* u3h_node: map node.
*/
typedef struct {
c3_w map_w;
2014-11-06 03:20:01 +03:00
u3h_slot sot_w[0];
} u3h_node;
2014-11-06 03:20:01 +03:00
/* u3h_root: hash root table, with future-proof clock.
*/
typedef struct {
c3_w clk_w;
2014-11-06 03:20:01 +03:00
u3h_slot sot_w[64];
} u3h_root;
2014-11-06 03:20:01 +03:00
/* u3h_buck: bottom bucket.
*/
typedef struct {
c3_w len_w;
u3_noun kev[0];
2014-11-06 03:20:01 +03:00
} u3h_buck;
/** HAMT macros.
***
*** Coordinate with u3_noun definition!
**/
2014-11-06 03:20:01 +03:00
/* u3h_slot_is_null(): yes iff slot is empty
** u3h_slot_is_noun(): yes iff slot contains a key/value cell
** u3h_slot_is_node(): yes iff slot contains a subtable/bucket
** u3h_slot_is_warm(): yes iff fresh bit is set
** u3h_slot_to_node(): slot to node pointer
** u3h_node_to_slot(): node pointer to slot
** u3h_slot_to_noun(): slot to cell
** u3h_noun_to_slot(): cell to slot
*/
2014-11-06 03:20:01 +03:00
# define u3h_slot_is_null(sot) ((0 == ((sot) >> 30)) ? c3y : c3n)
# define u3h_slot_is_node(sot) ((1 == ((sot) >> 30)) ? c3y : c3n)
# define u3h_slot_is_noun(sot) ((1 == ((sot) >> 31)) ? c3y : c3n)
# define u3h_slot_is_warm(sot) (((sot) & 0x40000000) ? c3y : c3n)
# define u3h_slot_to_node(sot) (u3a_into((sot) & 0x3fffffff))
# define u3h_node_to_slot(ptr) (u3a_outa(ptr) | 0x40000000)
# define u3h_slot_to_noun(sot) (0x40000000 | (sot))
# define u3h_noun_to_slot(som) (som)
# define u3h_noun_be_warm(sot) ((sot) | 0x40000000)
# define u3h_noun_be_cold(sot) ((sot) & ~0x40000000)
2014-09-04 07:44:53 +04:00
/** Functions.
***
*** Needs: delete and merge functions; clock reclamation function.
**/
2014-11-06 03:20:01 +03:00
/* u3h_new(): create hashtable.
2014-09-04 07:44:53 +04:00
*/
2014-11-06 03:20:01 +03:00
u3p(u3h_root)
u3h_new(void);
2014-09-04 07:44:53 +04:00
2014-11-06 03:20:01 +03:00
/* u3h_put(): insert in hashtable.
2014-09-04 07:44:53 +04:00
**
** `key` is RETAINED; `val` is transferred.
*/
void
2014-11-06 03:20:01 +03:00
u3h_put(u3p(u3h_root) har_p, u3_noun key, u3_noun val);
2014-09-04 07:44:53 +04:00
2014-11-06 03:20:01 +03:00
/* u3h_get(): read from hashtable.
2014-09-04 07:44:53 +04:00
**
** `key` is RETAINED.
*/
2014-09-06 00:13:24 +04:00
u3_weak
2014-11-06 03:20:01 +03:00
u3h_get(u3p(u3h_root) har_p, u3_noun key);
2014-09-04 07:44:53 +04:00
2014-11-06 03:20:01 +03:00
/* u3h_gut(): read from hashtable, unifying key nouns.
2014-10-09 02:16:24 +04:00
**
** `key` is RETAINED.
*/
u3_weak
2014-11-06 03:20:01 +03:00
u3h_gut(u3p(u3h_root) har_p, u3_noun key);
2014-10-09 02:16:24 +04:00
2014-11-06 03:20:01 +03:00
/* u3h_free(): free hashtable.
2014-09-04 07:44:53 +04:00
*/
void
2014-11-06 03:20:01 +03:00
u3h_free(u3p(u3h_root) har_p);
2014-09-04 07:44:53 +04:00
2014-11-06 03:20:01 +03:00
/* u3h_mark(): mark hashtable for gc.
2014-10-09 06:20:57 +04:00
*/
void
2014-11-06 03:20:01 +03:00
u3h_mark(u3p(u3h_root) har_p);
2014-10-31 00:40:05 +03:00
2014-11-06 03:20:01 +03:00
/* u3h_walk(): traverse hashtable with key, value fn; RETAINS.
2014-10-31 00:40:05 +03:00
*/
void
2014-11-06 03:20:01 +03:00
u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun));