void slice_vector(unsigned* map, unsigned sd, unsigned dd) { adv_slice slice; unsigned i, j; slice_set(&slice, sd, dd); if (sd < dd) { /* expansion */ unsigned count = slice.count; int error = slice.error; i = 0; j = 0; while (count) { unsigned run = slice.whole; if ((error += slice.up) > 0) { ++run; error -= slice.down; } while (run) { map[i] = j; ++i; --run; } ++j; --count; } } else { /* reduction */ unsigned count = slice.count; int error = slice.error; i = 0; j = 0; while (count) { unsigned run = slice.whole; if ((error += slice.up) > 0) { ++run; error -= slice.down; } map[i] = j; ++i; j += run; --count; } } }
static void *__hamt_down(struct hamt_state *s) { if (!is_leaf(s->ptr[s->level])) { struct hamt_node *node = ston(*s->ptr[s->level]); int slice = set_first(node->mask); s->hash = slice_set(s->hash, slice, s->level); int slot = set_slot_number(node->mask, slice); s->ptr[s->level + 1] = &node->slots[slot]; s->level += 1; return __hamt_down(s); } else { return to_leaf(s->ptr[s->level]); } }
static inline struct hamt_slot item_to_slot(void *item) { return (struct hamt_slot){(uint64_t)item | LEAF_MASK}; } static inline struct hamt_node *ston(struct hamt_slot slot) { return (struct hamt_node *)(uint64_t)slot.off; } static inline struct hamt_slot ntos(struct hamt_node *node) { return (struct hamt_slot){(uint64_t)node}; } /**************************************************************************/ static inline void *__hamt_search(struct hamt_root *root, uint128_t *hash, struct hamt_state *s) { if (!is_leaf(s->ptr[s->level])) { struct hamt_node *node = ston(*s->ptr[s->level]); int slice = slice_get(*hash, s->level); if (set_contains(node->mask, slice)) { s->hash = slice_set(s->hash, slice, s->level); int slot = set_slot_number(node->mask, slice); s->ptr[s->level + 1] = &node->slots[slot]; s->level += 1; return __hamt_search(root, hash, s); } return NULL; } else { void *item = to_leaf(s->ptr[s->level]); if (*root->hash(root->hash_ud, item) == *hash) { return item; } else { return NULL; } } } void *hamt_search(struct hamt_root *root, uint128_t *hash) { if (unlikely(ston(root->slot) == NULL)) { return NULL; } struct hamt_state s; s.level = 0; s.ptr[0] = &root->slot; return __hamt_search(root, hash, &s); } /**************************************************************************/ static struct hamt_node *__hamt_new_node(struct hamt_root *root, uint64_t mask, int len) { int size = sizeof(struct hamt_node) + len * sizeof(struct hamt_slot); struct hamt_node *node = \ (struct hamt_node *)root->mem_alloc(size); assert(((unsigned long)node & ITEM_MASK) == 0); node->mask = mask; return node; }