Beispiel #1
0
 void insert_leaf(t_node **root, m_tile tile) {
	/* check if the tree is empty */
	if (!(*root)) {
		/* if true insert node as root */
		t_node *node_to_insert = (t_node*)malloc(sizeof(t_node));

		assert(node_to_insert != NULL);

		/* initialize data */
		node_to_insert->left = node_to_insert->right = NULL;
		node_to_insert->tile = tile;

		/* set the root node to the new node */
		*root = node_to_insert;

		return;
	}
	
	/* Check if the new tile value is less than the root tile */
	if (tile->cost < (*root)->tile->cost) {
		/* Call recursively while there is non-NULL left leaf */
		insert_leaf(&(*root)->left, tile);
	}
	/* Check if the new tile value is greater than the root tile */
	else if (tile->cost > (*root)->tile->cost) {
		/* Call recursively while there is non-NULL right leaf */
		insert_leaf(&(*root)->right, tile);
	}
 }
Beispiel #2
0
// color: 1 for leaf, 0 for inner
static int insert_internal(rxt_node *newleaf, rxt_node *n)
{
    // FIRST: check for common bits
    rxt_node *left = n->left, *right = n->right;
    int bits   = count_common_bits(newleaf->key, left->key,
                                   rdx_min(newleaf->pos, left->pos));
    int bits2  = count_common_bits(newleaf->key, right->key,
                                   rdx_min(newleaf->pos, right->pos));

    if (rdx_min(bits, bits2) < n->pos) {
        if (bits >= bits2)
            return insert_leaf(newleaf, n->left, n);
        return insert_leaf(newleaf, n->right, n);
    }

    if (bits >= bits2) {
         if (left->color)
            return insert_leaf(newleaf, n->left, n);
        return insert_internal(newleaf, left);
    } else {
        if (right->color)
            return insert_leaf(newleaf, n->right, n);
        return insert_internal(newleaf, right);
    }

    return -1; // this should never happen
}
Beispiel #3
0
CSG_Node *divide(CSG *csg, CSG_Node *state, int lprefix, CSG_Node *target)
{
	CSG_Node *waiting   = target;
	int waiting_lprefix = LEN_L(state) - lprefix;
	int is_leaf         = IS_LEAF(state);
	//int j;

	/* delete */
	LEN_L(state) = lprefix;
	if (is_leaf) {
		/* the leaf is converted to a node and is created a new leaf */
		DEC_NLEAFS;
		INC_NNODES;
		if (target == NINDEF || LABEL(target)!=(LABEL(state) + lprefix))
		{
			INC_NLEAFS;
			waiting = insert_leaf(csg, LABEL(state) + lprefix, LINDEF);
		}
	} else {
		INC_NNODES;
 		if (target == NINDEF) {
 			waiting = insert_leaf(csg, LABEL(state) + lprefix, waiting_lprefix);
		}
		LG(waiting) = (IS_INITIAL(state) ? 0 
		: LG(state) + LEN_L(state));
		waiting->arc = state->arc;
		OUT(waiting) = OUT(state);
		OUT(state)   = 0;
	}
	INS_EDGE(csg, state, waiting);
	return waiting;
}
Beispiel #4
0
void build_CSG(CSG *csg, const char *s, long int size, int debug)
{
	CSG_Node *state = INITIAL;
	int lprefix     = 1;
	const char *pendent   = s;
	CSG_Node *nextState;
	int offset;
	int cloned = FALSE;
	CSG_Node *node_cloned = NINDEF;

	int go;
	CSG_Node *waiting;

	while (*pendent != LAST_SYMBOL) {
		lprefix = state == INITIAL ? 1 
		: prefix_comu(csg,  state, pendent);
		offset  = state == INITIAL ? 0 : lprefix;
		if (lprefix == LEN_L(state)) {
			go        = *(pendent + offset);
			nextState = NEXT(csg, state, go);
			pendent  += offset;
			cloned = FALSE;
			if (nextState == NINDEF) {
				/* INSERT SUFIXES */
				INC_NLEAFS;
				waiting = insert_leaf(csg, pendent, LINDEF);
				INS_EDGE(csg, state, waiting);
				nextState =  add_suffixes(csg,  state, waiting, &pendent);
			} else if (!GET_SOLID(csg, state, nextState) 
			|| cloned) {
				node_cloned = nextState;
				nextState   = to_clone(csg,  state, nextState);
				cloned      = TRUE;
			}
		} else {
			if (!cloned)
				waiting = divide(csg,  state, lprefix, NINDEF);
			else {
				waiting = divide_and_compress(csg,  state
    				, node_cloned, lprefix);
        			cloned = FALSE;	
     			}
			state = arrange_link(csg,  state, waiting, TRUE);
			offset  = state == INITIAL ? 0 : lprefix;
			pendent += offset;
			INC_NLEAFS;
			waiting = insert_leaf(csg, pendent, LINDEF);
   			INS_EDGE(csg, state, waiting);
			nextState = add_suffixes(csg,  state, waiting, &pendent);
		}
		state = nextState;

	}
	// eliminate the last leaf "$"
	DEC_NLEAFS;

}
Beispiel #5
0
/*
 * Split leaf, then insert to parent.
 * key:  key to add after split (cursor will point leaf which is including key)
 * hint: hint for split
 *
 * return value:
 *   0 - success
 * < 0 - error
 */
static int btree_leaf_split(struct cursor *cursor, tuxkey_t key, tuxkey_t hint)
{
	if(DEBUG_MODE_K==1)
	{
		printf("\t\t\t\t%25s[K]  %25s  %4d  #in\n",__FILE__,__func__,__LINE__);
	}
	trace("split leaf");
	struct btree *btree = cursor->btree;
	struct buffer_head *newbuf;

	newbuf = new_leaf(btree);
	if (IS_ERR(newbuf))
		return PTR_ERR(newbuf);
	log_balloc(btree->sb, bufindex(newbuf), 1);

	struct buffer_head *leafbuf = cursor_leafbuf(cursor);
	tuxkey_t newkey = btree->ops->leaf_split(btree, hint, bufdata(leafbuf),
						 bufdata(newbuf));
	assert(cursor_this_key(cursor) < newkey);
	assert(newkey < cursor_next_key(cursor));
	if (key < newkey)
		mark_buffer_dirty_non(newbuf);
	else
		mark_buffer_dirty_non(leafbuf);
	return insert_leaf(cursor, newkey, newbuf, key < newkey);
}
Beispiel #6
0
/* Insert new leaf to next cursor position, then set cursor to new leaf */
int btree_insert_leaf(struct cursor *cursor, tuxkey_t key, struct buffer_head *leafbuf)
{
	if(DEBUG_MODE_K==1)
	{
		printf("\t\t\t\t%25s[K]  %25s  %4d  #in\n",__FILE__,__func__,__LINE__);
	}
	return insert_leaf(cursor, key, leafbuf, 0);
}
Beispiel #7
0
static int insert_node (tree_s *tree, void *node, u64 key, void *rec, unint size)
{
FN;
	switch (magic(node)) {
	case LEAF:	return insert_leaf(tree, node, key, rec, size);
	case BRANCH:	return insert_branch(tree, node, key, rec, size);
	default:	return qERR_BAD_BLOCK;
	}
}
Beispiel #8
0
void insert_bucket (bucket_s *bucket, u32 x, u32 shift)
{
	switch (bucket->b_type) {
	case EMPTY:	insert_empty(bucket, x, shift);	return;
	case NODE:	insert_node(bucket, x, shift);	return;
	case LEAF:	insert_leaf(bucket, x, shift);	return;
	default:	printf("bad type %ld", bucket->b_type);	return;
	}
}
Beispiel #9
0
static int insert_head (
	tree_s	*tree,
	void	*child,
	u64	key,
	void	*rec,
	unint	len)
{
FN;
	switch (type(child)) {
	case LEAF:	return insert_leaf(tree, child, key, rec, len);
	case BRANCH:	return insert_branch(tree, child, key, rec, len);
	default:	return qERR_BAD_BLOCK;
	}
}
Beispiel #10
0
Datei: btree.c Projekt: Zkin/tux3
/*
 * Split leaf, then insert to parent.
 * key:  key to add after split (cursor will point leaf which is including key)
 * hint: hint for split
 *
 * return value:
 *   0 - success
 * < 0 - error
 */
static int btree_leaf_split(struct cursor *cursor, tuxkey_t key, tuxkey_t hint)
{
	trace("split leaf");
	struct btree *btree = cursor->btree;
	struct buffer_head *newbuf;

	newbuf = new_leaf(btree);
	if (IS_ERR(newbuf))
		return PTR_ERR(newbuf);
	log_balloc(btree->sb, bufindex(newbuf), 1);

	struct buffer_head *leafbuf = cursor_leafbuf(cursor);
	tuxkey_t newkey = btree->ops->leaf_split(btree, hint, bufdata(leafbuf),
						 bufdata(newbuf));
	assert(cursor_this_key(cursor) < newkey);
	assert(newkey < cursor_next_key(cursor));
	if (key < newkey)
		mark_buffer_dirty_non(newbuf);
	else
		mark_buffer_dirty_non(leafbuf);
	return insert_leaf(cursor, newkey, newbuf, key < newkey);
}
Beispiel #11
0
	/**
	 * Insert or update the given value under the given key.
	 *
	 * The map takes ownership of the value.
	 *
	 * @param key The key to insert under.
	 * @param value The value to be inserted.
	 *
	 * @return 0 on success, negative values on error.
	 */
	int
	insert(key_type key, value_type value)
	{
		auto dest_entry = root;
		while (dest_entry->inode != nullptr) {
			auto n = dest_entry->inode;
			dest_entry = n->entries[BIT_IS_SET(key, n->diff)];
		}

		entry e(key, value);
		auto pop = nvobj::pool_by_vptr(this);
		nvobj::transaction::exec_tx(pop, [&] {
			if (dest_entry->key == 0 || dest_entry->key == key) {
				nvobj::delete_persistent<T>(dest_entry->value);
				*dest_entry = e;
			} else {
				insert_leaf(&e, find_crit_bit(dest_entry->key,
							      key));
			}
		});

		return 0;
	}
Beispiel #12
0
static int insert_leaf(rxt_node *newleaf, rxt_node *sibling, rxt_node *parent)
{
    int idx, bit, max_len;
    rxt_node *inner;


    max_len = rdx_min(newleaf->pos, sibling->pos);
    idx  = count_common_bits(newleaf->key, sibling->key, max_len);
    bit = get_bit_at(newleaf->key, idx);

    if (!parent) {
        // insert at the root, so rotate things like so:
/*
           /\    to     /\
          1  2         /\ 3
                      1  2                   */

        parent = sibling;
        inner = (rxt_node *)malloc(sizeof(rxt_node));
        if (!inner) return -1;
        inner->color = 0;
        inner->value = NULL;
        inner->parent = parent;
        inner->left = parent->left;
        inner->right = parent->right;
        inner->key = parent->key;
        inner->pos = parent->pos;
        parent->pos = idx;
        parent->left->parent = inner;
        parent->right->parent = inner;
        newleaf->parent = parent;
        if (bit) {
            parent->right = newleaf;
            parent->left = inner;
        } else {
            parent->right = inner;
            parent->left = newleaf;
        }
        return 0;
    }

    if (idx < parent->pos) {
        // use the parent as a sibling
        return insert_leaf(newleaf, parent, parent->parent);
    } else {
        // otherwise, add newleaf as a child of inner

        // Check for duplicates.
        // FIXME feels hackish; do this properly.
        if (newleaf->pos == sibling->pos &&
            !strncmp(newleaf->key, sibling->key, newleaf->pos)) {
            free(newleaf);
            return -1;
        }

        inner = (rxt_node *)malloc(sizeof(rxt_node));
        if (!inner) free(inner);
        inner->color = 0;
        inner->value = NULL;
        inner->parent = parent;
        inner->pos = idx;
        inner->key = sibling->key;
        newleaf->parent = inner;
        sibling->parent = inner;

        if (bit) {
            inner->right = newleaf;
            inner->left = sibling;
        } else {
            inner->right = sibling;
            inner->left = newleaf;
        }

        // now find out which branch of parent to assign inner
        if (parent->left == sibling)
            parent->left = inner;
        else if (parent->right == sibling)
            parent->right = inner;
        else {
            fprintf(stderr, "inappropriate child %s/%s found in parent when inserting leaf %s (expected %s)\n", parent->left->key, parent->right->key, newleaf->key, sibling->key);
            return -1;
        }
    }
    return 0;
}
Beispiel #13
0
Datei: btree.c Projekt: Zkin/tux3
/* Insert new leaf to next cursor position, then set cursor to new leaf */
int btree_insert_leaf(struct cursor *cursor, tuxkey_t key, struct buffer_head *leafbuf)
{
	return insert_leaf(cursor, key, leafbuf, 0);
}