コード例 #1
0
ファイル: hamt.c プロジェクト: 4n3w/dump
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;
}
コード例 #2
0
ファイル: hamt.c プロジェクト: 4n3w/dump
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;
}
コード例 #3
0
ファイル: ohamt.c プロジェクト: pombredanne/ydb
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;
}
コード例 #4
0
ファイル: hamt.c プロジェクト: 4n3w/dump
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);
        }
}
コード例 #5
0
ファイル: ohamt.c プロジェクト: pombredanne/ydb
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);
        }
}
コード例 #6
0
ファイル: cmd_addlibrary.c プロジェクト: pipul/cpkg
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;
}
コード例 #7
0
ファイル: hamt.c プロジェクト: 4n3w/dump
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;
}