void *hamt_delete(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; void *found_item = __hamt_search(root, hash, &s); if (unlikely(found_item == NULL)) { return NULL; } if (unlikely(s.level == 0)) { root->slot = (struct hamt_slot){0}; goto done; } struct hamt_slot *found_slot = s.ptr[s.level]; s.level--; struct hamt_node *node = ston(*s.ptr[s.level]); int slice = slice_get(*hash, s.level); if (set_count(node->mask) != 2) { *s.ptr[s.level] = ntos(__hamt_del_node(root, node, slice)); goto done; } else { // set_count == 2 struct hamt_slot other_slot = \ __hamt_get_other_slot(node, found_slot); if(!is_leaf(&other_slot)) { uint64_t other_slice = set_first(set_del(node->mask, slice)); __hamt_free_node(root, node); *s.ptr[s.level] = ntos(__hamt_new_node1(root, other_slice, other_slot)); goto done; } else { while (1) { __hamt_free_node(root, node); if (unlikely(s.level == 0)) { root->slot = other_slot; goto done; } s.level--; node = ston(*s.ptr[s.level]); if (set_count(node->mask) != 1) { break; } } slice = slice_get(*hash, s.level); int slot = set_slot_number(node->mask, slice); node->slots[slot] = other_slot; goto done; } } done: return found_item; }
static struct hamt_node *__hamt_add_slot(struct hamt_root *root, struct hamt_slot *slot_ptr, void *item, uint128_t *item_hash, int level) { uint64_t slice = slice_get(*item_hash, level); struct hamt_node *old_node = ston(*slot_ptr); int old_size = set_count(old_node->mask); int new_size = old_size + 1; struct hamt_node *node = __hamt_new_node(root, set_add(old_node->mask, slice), new_size); *slot_ptr = ntos(node); int slot = set_slot_number(node->mask, slice); memcpy(&node->slots[0], &old_node->slots[0], sizeof(struct hamt_slot)*slot); memcpy(&node->slots[slot+1], &old_node->slots[slot], sizeof(struct hamt_slot)*(old_size-slot)); node->slots[slot] = item_to_slot(item); __hamt_free_node(root, old_node); return node; }
static void __ohamt_delete(struct ohamt_root *root, uint128_t hash, struct ohamt_state *s) { if (unlikely(s->level == 0)) { root->slot = (struct ohamt_slot){0}; goto done; } struct ohamt_slot *found_slot = s->ptr[s->level]; s->level--; struct ohamt_node *node = ston(*s->ptr[s->level]); int slice = slice_get(hash, s->level); if (set_count(node->mask) != 2) { *s->ptr[s->level] = ntos(__ohamt_del_node(root, node, slice)); goto done; } else { // set_count == 2 struct ohamt_slot other_slot = \ __ohamt_get_other_slot(node, found_slot); if(!is_leaf(&other_slot)) { uint64_t other_slice = set_first(set_del(node->mask, slice)); __ohamt_free_node(root, node); *s->ptr[s->level] = ntos(__ohamt_new_node1(root, other_slice, other_slot)); goto done; } else { while (1) { __ohamt_free_node(root, node); if (unlikely(s->level == 0)) { root->slot = other_slot; goto done; } s->level--; node = ston(*s->ptr[s->level]); if (set_count(node->mask) != 1) { break; } } slice = slice_get(hash, s->level); int slot = set_slot_number(node->mask, slice); node->slots[slot] = other_slot; goto done; } } done: return; }
static inline void __hamt_insert_leaf(struct hamt_root *root, struct hamt_state *s, uint128_t *item_hash, void *item, uint128_t *leaf_hash, void *leaf) { int leaf_slice = slice_get(*leaf_hash, s->level); int item_slice = slice_get(*item_hash, s->level); if (leaf_slice != item_slice) { *s->ptr[s->level] = ntos(__hamt_new_node2(root, item, item_slice, leaf, leaf_slice)); } else { struct hamt_node *node = __hamt_new_node1(root, item_slice, item_to_slot(NULL)); *s->ptr[s->level] = ntos(node); s->ptr[s->level + 1] = &node->slots[0]; s->level += 1; __hamt_insert_leaf(root, s, item_hash, item, leaf_hash, leaf); } }
static void __ohamt_insert_leaf(struct ohamt_root *root, struct ohamt_state *s, uint128_t item_hash, uint64_t item, uint128_t leaf_hash, uint64_t leaf) { int leaf_slice = slice_get(leaf_hash, s->level); int item_slice = slice_get(item_hash, s->level); if (leaf_slice != item_slice) { *s->ptr[s->level] = ntos(__ohamt_new_node2(root, item, item_slice, leaf, leaf_slice)); } else { struct ohamt_node *node = __ohamt_new_node1(root, item_slice, item_to_slot(OHAMT_NOT_FOUND)); *s->ptr[s->level] = ntos(node); s->ptr[s->level + 1] = &node->slots[0]; s->level += 1; __ohamt_insert_leaf(root, s, item_hash, item, leaf_hash, leaf); } }
static void addlibrary_process(struct package *pkg, int argc, char **argv) { char *pkg_name; int i, j; char *cmd_name; struct slice *cmd_args; struct package *impkg; if (argc < 1) { fprintf(stderr, "too few arguments for to cmd: add_library\n"); exit(-1); } // maybe a ring //if (pkg->status & PKG_PENDING) { // fprintf(stderr, "the dependence link is a loop: %s\n", pkg->name); // exit(-1); //} for (i = 0; i < argc; i++) { if (!(impkg = pkg_find(argv[i]))) { fprintf(stderr, "unknown package: %s\n", argv[i]); exit(-1); } if (!(impkg->status & PKG_DEPENDENCE_DONE)) { for (j = 0; j < slice_size(&impkg->cmdops); j++) { cmd_args = slice_get(&impkg->cmdops, j); if ((cmd_name = slice_get(cmd_args, 0)) && (strcmp(cmd_name, "add_library"))) { addlibrary_process(impkg, slice_size(&impkg->cmdops) - 1, (char **)slice_data(&impkg->cmdops) + 1); } } } slice_merge_from(&pkg->aux_source, &impkg->aux_source); } return; }
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; }