}
}
+static int add_to_relocation_list(struct quadtree *node,
+ struct list_head *head)
+{
+ int nodes = 0;
+
+ if (node->child[0])
+ nodes += add_to_relocation_list(node->child[0], head);
+ if (node->child[1])
+ nodes += add_to_relocation_list(node->child[1], head);
+
+ list_add(&node->list, head);
+ nodes++;
+
+ if (node->child[2])
+ nodes += add_to_relocation_list(node->child[2], head);
+ if (node->child[3])
+ nodes += add_to_relocation_list(node->child[3], head);
+
+ return nodes;
+}
+
+static void relocate_from_list(struct quadtree *start, struct quadtree *end,
+ int nodes, struct quadtree *parent,
+ struct quadtree_ops *ops)
+{
+ struct quadtree *tmp = start, *node;
+ int i;
+
+ for (i = 0; i < nodes / 2; i++)
+ tmp = list_to_tree(tmp->list.next);
+
+ node = tmp;
+
+ tmp = list_to_tree(node->list.prev);
+
+ if (debug) {
+ printf("Moving node %p\n", node);
+ fflush(stdout);
+ }
+ list_del(&node->list);
+ quadtree_add(parent, node, ops);
+ node = list_to_tree(tmp->list.next);
+
+ if (nodes / 2 - 1 > 0)
+ relocate_from_list(start, tmp, nodes / 2 - 1, parent, ops);
+
+ if (nodes > 2)
+ relocate_from_list(node, end, nodes - nodes / 2 - 1, parent,
+ ops);
+}
+
/*
* quadtree_del - Detach a node from the tree
*
struct quadtree *quadtree_del(struct quadtree *node,
struct quadtree_ops *ops)
{
- struct quadtree *parent = 0;
- int i;
+ struct quadtree *parent = 0, *start, *end;
+ struct list_head *head = NULL;
+ int i, nodes = 0;
if (debug) {
printf("Deleting node %p under parent %p\n",
parent->parent = 0;
continue;
}
- _qt_optimal_del(parent, node->child[i], ops,
- node->children);
- node->child[i] = 0;
+ if (!head) {
+ head = &node->child[i]->list;
+ INIT_LIST_HEAD(head);
+ }
+
+ nodes += add_to_relocation_list(node->child[i], head);
}
+ start = list_to_tree(head);
+ end = list_to_tree(head->prev);
+
+ relocate_from_list(start, end, nodes, parent, ops);
+
return parent;
}
if (!node->child[i])
continue;
- _qt_optimal_del(parent, node->child[i], ops,
- node->children);
+ if (!head) {
+ head = &node->child[i]->list;
+ INIT_LIST_HEAD(head);
+ }
+
+ nodes += add_to_relocation_list(node->child[i], head);
}
+
+ start = list_to_tree(head);
+ end = list_to_tree(head->prev);
+
+ relocate_from_list(start, end, nodes, parent, ops);
}
validate_tree(parent);