Beispiel #1
0
void leaf_cut ( Leaf * leaf, int w, int h )
{
    gboolean b = leaf->w - w > leaf->h - h;
    if ( leaf->w - w > smallest.width )
        leaf_new( leaf->x + w, leaf->y, leaf->w - w, b ? leaf->h : h );
    if ( leaf->h - h > smallest.height )
        leaf_new( leaf->x, leaf->y + h, b ? w : leaf->w, leaf->h - h );
    
    g_sequence_remove_sorted( leaves_sorted_by_area, leaf, leaf_compare, AREA );
    free( leaf );
}
Beispiel #2
0
/*
 * EFFECT:
 *	- split leaf&lmb into two leaves:a & b
 *	  a&b are both the half of the lmb
 *
 * PROCESS:
 *	- leaf:
 *		+-----------------------------------+
 *		|  0  |  1  |  2  |  3  |  4  |  5  |
 *		+-----------------------------------+
 *
 *	- split:
 *				   root
 *				 +--------+
 *				 |   2    |
 *				 +--------+
 *              /          \
 *	+-----------------+	 +------------------+
 *	    	|  0  |  1  |  2  |	 |  3  |  4  |  5   |
 *	    	+-----------------+	 +------------------+
 *	    	      nodea			nodeb
 *
 * ENTER:
 *	- leaf is already locked (L_WRITE)
 * EXITS:
 *	- a is locked
 *	- b is locked
 */
void leaf_split(void *tree,
                struct node *node,
                struct node **a,
                struct node **b,
                struct msg **split_key)
{
	struct partition *pa;
	struct partition *pb;
	struct node *leafa;
	struct node *leafb;
	struct lmb *mb;
	struct lmb *mba;
	struct lmb *mbb;
	struct msg *sp_key = NULL;
	struct buftree *t = (struct buftree*)tree;

	leafa = node;
	pa = &leafa->parts[0];

	/* split lmb of leaf to mba & mbb */
	mb = pa->msgbuf;
	lmb_split(mb, &mba, &mbb, &sp_key);
	lmb_free(mb);

	/* reset leafa buffer */
	pa->msgbuf = mba;

	/* new leafb */
	NID nid = hdr_next_nid(t->hdr);
	leaf_new(t->hdr,
	         nid,
	         0,
	         1,
	         &leafb);
	leaf_msgbuf_init(leafb);

	cache_put_and_pin(t->cf, nid, leafb);

	pb = &leafb->parts[0];
	lmb_free(pb->msgbuf);
	pb->msgbuf = mbb;

	/* set dirty */
	node_set_dirty(leafa);
	node_set_dirty(leafb);

	*a = leafa;
	*b = leafb;
	*split_key = sp_key;
}
Beispiel #3
0
static int
bplus_tree_insert(struct bplus_tree *tree, int key, int data)
{
        int i;
        struct bplus_node *node = tree->root;
        struct bplus_non_leaf *nln;
        struct bplus_leaf *ln, *root;

        while (node != NULL) {
                switch (node->type) {
                case BPLUS_TREE_NON_LEAF:
                        nln = (struct bplus_non_leaf *)node;
                        i = key_binary_search(nln->key, nln->children - 1, key);
                        if (i >= 0) {
                                node = nln->sub_ptr[i + 1];
                        } else {
                                i = -i - 1;
                                node = nln->sub_ptr[i];
                        }
                        break;
                case BPLUS_TREE_LEAF:
                        ln = (struct bplus_leaf *)node;
                        return leaf_insert(tree, ln, key, data);
                default:
                        assert(0);
                }
        }

        /* new root */
        root = leaf_new();
        root->key[0] = key;
        root->data[0] = data;
        root->entries = 1;
        tree->head[0] = (struct bplus_node *)root;
        tree->root = (struct bplus_node *)root;
        return 0;
}
Beispiel #4
0
void
bplus_tree_insert(struct tree *tree, int key, int data)
{
int i, j, level;
struct node *node = tree->root;
struct non_leaf *nln, *rank_nln;
struct leaf *ln;
struct rank_recorder recorder[MAX_LEVEL];
if (node == NULL) {
struct leaf *leaf = leaf_new();
leaf->key[0] = key;
leaf->data[0] = data;
leaf->entries = 1;
tree->head[0] = (struct node *)leaf;
tree->root = (struct node *)leaf;
return;
}
memset(recorder, 0, sizeof(recorder));
level = MAX_LEVEL;
while (--level > 0) {
if (tree->head[level] == node) {
break;
}
}
rank_nln = (struct non_leaf *)tree->head[level];
while (node != NULL) {
switch (node->type) {
case BPLUS_TREE_NON_LEAF:
nln = (struct non_leaf *)node;
/* rank inheritance */
recorder[level].rank = level == MAX_LEVEL - 1 ? 0 : recorder[level + 1].rank;
while (rank_nln != nln) {
for (j = 0; j < rank_nln->children - 2; j++) {
recorder[level].rank += rank_nln->span[j];
}
rank_nln = rank_nln->next;
}
/* search key */
i = key_binary_search(nln->key, nln->children - 1, key);
if (i >= 0) {
node = nln->sub_ptr[i + 1];
if (i < nln->children - 2) {
recorder[level].node = nln;
recorder[level].index = i + 1;
for (j = 0; j < i + 1; j++) {
recorder[level].rank += nln->span[j];
}
} else {
recorder[level].node = nln->next;
recorder[level].index = 0;
for (j = 0; j < nln->children - 1; j++) {
recorder[level].rank += nln->span[j];
}
}
} else {
i = -i - 1;
node = nln->sub_ptr[i];
if (i < nln->children - 1) {
recorder[level].node = nln;
recorder[level].index = i;
for (j = 0; j < i; j++) {
recorder[level].rank += nln->span[j];
}
} else {
recorder[level].node = nln->next;
recorder[level].index = 0;
for (j = 0; j < nln->children - 1; j++) {
recorder[level].rank += nln->span[j];
}
}
}
if (node->type != BPLUS_TREE_LEAF) {
rank_nln = (struct non_leaf *)node;
}
level--;
break;
case BPLUS_TREE_LEAF:
ln = (struct leaf *)node;
leaf_insert(tree, ln, key, data, &recorder[0]);
return;
default:
break;
}
}
}
Beispiel #5
0
static void
leaf_insert(struct tree *tree, struct leaf *leaf, int key, int data, struct rank_recorder *recorder)
{
int i, j, split = 0;
struct leaf *sibling;
int insert = key_binary_search(leaf->key, leaf->entries, key);
if (insert >= 0) {
/* Already exists */
return;
}
insert = -insert - 1;
/* node full */
if (leaf->entries == ENTRIES) {
/* split = [m/2] */
split = (ENTRIES + 1) / 2;
/* splited sibling node */
sibling = leaf_new();
sibling->next = leaf->next;
leaf->next = sibling;
leaf->entries = split;
/* sibling leaf replication */
if (insert < split) {
for (i = split - 1, j = 0; i < ENTRIES; i++, j++) {
sibling->key[j] = leaf->key[i];
sibling->data[j] = leaf->data[i];
}
sibling->entries = j;
/* leaf insertion and its entry count stays unchanged(split + 1) */
for (i = leaf->entries; i > insert; i--) {
leaf->key[i] = leaf->key[i - 1];
leaf->data[i] = leaf->data[i - 1];
}
leaf->key[i] = key;
leaf->data[i] = data;
} else {
i = split, j = 0;
while (i < ENTRIES) {
if (j != insert - split) {
sibling->key[j] = leaf->key[i];
sibling->data[j] = leaf->data[i];
i++;
}
j++;
}
/* sibling leaf entries */
if (j > insert - split) {
sibling->entries = j;
} else {
sibling->entries = insert - split + 1;
}
/* insert new key */
j = insert - split;
sibling->key[j] = key;
sibling->data[j] = data;
}
} else {
/* simple insertion */
for (i = leaf->entries; i > insert; i--) {
leaf->key[i] = leaf->key[i - 1];
leaf->data[i] = leaf->data[i - 1];
}
leaf->key[i] = key;
leaf->data[i] = data;
leaf->entries++;
}
if (split) {
struct non_leaf *parent = leaf->parent;
if (parent == NULL) {
parent = non_leaf_new();
parent->key[0] = sibling->key[0];
parent->sub_ptr[0] = (struct node *)leaf;
parent->sub_ptr[1] = (struct node *)sibling;
parent->children = 2;
/* new root */
tree->root = (struct node *)parent;
tree->head[1] = (struct node *)parent;
leaf->parent = parent;
sibling->parent = parent;
} else {
/* trace upwards */
sibling->parent = parent;
non_leaf_insert(tree, parent, (struct node *)sibling, sibling->key[0], 1, recorder);
}
}
}
Beispiel #6
0
void octree_insert(octree_t* tree, point_t* point, int index)
{
  if (tree->root == NULL) // Empty tree
  {
    octree_node_t* node = leaf_new(point, index);
    tree->root = node;
    ++tree->num_points;
  }
  else if (tree->root->type == OCTREE_LEAF_NODE)
  {
    point_t center = {.x = 0.5 * (tree->bbox.x1 + tree->bbox.x2),
                      .y = 0.5 * (tree->bbox.y1 + tree->bbox.y2),
                      .z = 0.5 * (tree->bbox.z1 + tree->bbox.z2)};

    // The tree consists of a single node.
    octree_node_t* root = tree->root;

    // Does the given point already exist here?
    if (point_distance(&root->leaf_node.point, point) == 0.0)
      return;

    // We need to create a branch node here.
    octree_node_t* node = root;
    tree->root = branch_new();
    int slot = find_slot(&center, point);
    tree->root->branch_node.children[slot] = node;
  }
  
  // Now we proceed with the normal logic, given that the root node 
  // is a branch node.
  ASSERT(tree->root->type == OCTREE_BRANCH_NODE);
  octree_node_t* node = tree->root;
  point_t center = {.x = 0.5 * (tree->bbox.x1 + tree->bbox.x2),
                    .y = 0.5 * (tree->bbox.y1 + tree->bbox.y2),
                    .z = 0.5 * (tree->bbox.z1 + tree->bbox.z2)};
  real_t lx = tree->bbox.x2 - tree->bbox.x1;
  real_t ly = tree->bbox.y2 - tree->bbox.y1;
  real_t lz = tree->bbox.z2 - tree->bbox.z1;
  int slot = find_slot(&center, point);
  static real_t xf[] = {-0.25, -0.25, -0.25, -0.25, +0.25, +0.25, +0.25, +0.25};
  static real_t yf[] = {-0.25, -0.25, +0.25, +0.25, -0.25, -0.25, +0.25, +0.25};
  static real_t zf[] = {-0.25, +0.25, -0.25, +0.25, -0.25, +0.25, -0.25, +0.25};
  while ((node->branch_node.children[slot] != NULL) && 
         (node->branch_node.children[slot]->type == OCTREE_BRANCH_NODE))
  {
    node = node->branch_node.children[slot];
    center.x += xf[slot]*lx;
    lx *= 0.5;
    center.y += yf[slot]*ly;
    ly *= 0.5;
    center.z += zf[slot]*lz;
    lz *= 0.5;
    slot = find_slot(&center, point);
  }
  octree_node_t* leaf = node->branch_node.children[slot];
  if (leaf == NULL)
  {
    // No leaf here, so we create a new one!
    leaf = leaf_new(point, index);
    node->branch_node.children[slot] = leaf;
    ++tree->num_points;
  }
  else
  {
    // Is the point already in this node?
    if (point_distance(&leaf->leaf_node.point, point) == 0.0)
        return;
    else
    {
      // We have to make a new branch.
      int old_slot, new_slot; 
      do
      {
        node->branch_node.children[slot] = branch_new();
        node = node->branch_node.children[slot];
        center.x += xf[slot]*lx;
        lx *= 0.5;
        center.y += yf[slot]*ly;
        ly *= 0.5;
        center.z += zf[slot]*lz;
        lz *= 0.5;
        new_slot = find_slot(&center, point);
        old_slot = find_slot(&center, &leaf->leaf_node.point);
      }
      while (new_slot == old_slot);
      node->branch_node.children[old_slot] = leaf;
      octree_node_t* new_leaf = leaf_new(point, index);
      node->branch_node.children[new_slot] = new_leaf;
      ++tree->num_points;
    }
  }
}

void octree_delete(octree_t* tree, point_t* point, int index)
{
  // FIXME
}

int octree_size(octree_t* tree)
{
  return tree->num_points;
}

static void node_clear(octree_node_t* node)
{
  if (node == NULL) 
  {
    return;
  }
  else if (node->type == OCTREE_LEAF_NODE)
  {
    polymec_free(node);
  }
  else 
  {
    ASSERT(node->type == OCTREE_BRANCH_NODE);
    for (int i = 0; i < 8; ++i)
      node_clear(node->branch_node.children[i]);
  }
}

void octree_clear(octree_t* tree)
{
  node_clear(tree->root);
  tree->root = NULL;
  tree->num_points = 0;
}