12 static void trap(void)
18 static int quadtree_compare_coord(const struct vector *a,
19 const struct vector *b)
35 static int quadtree_compare(const struct quadtree *a, const struct quadtree *b)
37 return quadtree_compare_coord(&a->pos, &b->pos);
40 static void validate_subtree(const struct quadtree *node)
47 printf("Attempted to validate a null pointer\n");
52 for (i = 0; i < 4; i++) {
56 if (node->child[i]->parent != node) {
57 printf("%s:%d Fatal! Tree inconsistency detected at "
58 "child %d %p in node %p, incorrent parent %p\n",
59 __func__, __LINE__, i, node->child[i], node,
60 node->child[i]->parent);
66 if (node->child[i] == node->parent) {
67 printf("%s:%d Fatal! Tree loop detected "
68 "at child %d in node %p\n",
69 __func__, __LINE__, i, node);
75 children += node->child[i]->children + 1;
77 validate_subtree(node->child[i]);
80 if (node->depth < 0) {
81 printf("%s:%d Tree statistics inconsistency detected! "
82 "Negative depth: %ld\n",
83 __func__, __LINE__, node->depth);
86 if (node->children != children) {
87 printf("%s:%d Tree statistics inconsistency detected! "
88 "child count mismatch. Expected %ld, got %ld\n",
89 __func__, __LINE__, children, node->children);
94 for (i = 0; i < 4 && node->children; i++) {
98 if (node->depth == node->child[i]->depth + 1)
101 if (node->child[i]->depth > node->depth) {
102 printf("%s:%d Tree statistics inconsistency detected! "
103 "child depth mismatch %ld > %ld\n",
104 __func__, __LINE__, node->child[i]->depth,
110 printf("%s:%d Tree statistics inconsistency detected! "
111 "child depth mismatch.",
118 static void validate_tree(const struct quadtree *node)
121 validate_subtree(quadtree_find_parent(node));
125 * quadtree_add - add a node to a quadtree
126 * @parent: parent node
127 * @new: the new node to be added
129 * Add a node to a quadtree. The tree is kept in order, the new node
130 * is placed in the end of appropriate branch.
132 * The case of nodes sharing identical coordinates is not taken into
136 struct quadtree *quadtree_add(struct quadtree *parent, struct quadtree *new,
137 struct quadtree_ops *ops)
143 validate_tree(parent);
145 ret = quadtree_compare(parent, new);
147 if (ret < 0 || ret >= 4) {
148 printf("Invalid comparison result of %d\n", ret);
152 if (parent->child[ret])
153 return quadtree_add(parent->child[ret], new, ops);
155 parent->child[ret] = new;
156 new->parent = parent;
157 for (i = 0; i < 4; i++)
161 printf("adding node %p to parent %p\n", new, parent);
165 quadtree_recalculate_parent_stats(new, ops);
173 * _qt_optimal_del - Delete nodes from a detached subtree in optimal order
175 * All nodes are moved under the new parent node
177 static void _qt_optimal_del(struct quadtree *parent, struct quadtree *node,
178 struct quadtree_ops *ops, int parents)
180 struct quadtree *child[4] = {0};
181 int i, children = 0, max_c, max_i;
183 for (i = 0; i < 4; i++) {
184 if (!node->child[i]) {
189 child[children] = node->child[i];
190 node->child[i] = NULL;
195 * Try to remove the nodes in such order that the node which
196 * has child number one quarter of the parent's child numer
197 * gets deleted first.
200 if (node->children <= parents / 4) {
202 printf("%d: Moving node %p away from parent %p\n",
203 __LINE__, node, parent);
206 validate_tree(parent);
207 quadtree_add(parent, node, ops);
215 for (i = 0; i < 4; i++) {
219 if (max_c < child[i]->children) {
220 max_c = child[i]->children;
225 _qt_optimal_del(parent, child[max_i], ops, parents / 4);
231 validate_tree(parent);
233 printf("%d: Moving node %p away from parent %p\n",
234 __LINE__, node, parent);
237 quadtree_add(parent, node, ops);
242 * quadtree_del - Detach a node from the tree
244 * Return value: The new root node of the tree. If we are detaching
245 * anything but the root node of the entire tree, the returned root
246 * value will be the original root of the tree.
248 struct quadtree *quadtree_del(struct quadtree *node,
249 struct quadtree_ops *ops)
251 struct quadtree *parent = 0;
255 printf("Deleting node %p under parent %p\n",
260 * We are deleting the root node. This means we have to select
261 * a new root node and reconstruct the entire tree under it
265 for (i = 0; i < 4; i++) {
270 parent = node->child[i];
274 _qt_optimal_del(parent, node->child[i], ops,
283 * We are not deleting the parent. Detach the node from the
284 * parent abd relocate the children. The node will be then
285 * detached from the tree.
288 for (i = 0; i < 4; i++) {
289 if (node->parent->child[i] == node) {
290 node->parent->child[i] = 0;
297 parent = node->parent;
300 * The sub branch is now detached from the main tree. Fix the
303 quadtree_recalculate_parent_stats(node->parent, ops);
305 parent = quadtree_find_parent(parent);
307 if (node->children) {
308 for (i = 0; i < 4; i++) {
312 _qt_optimal_del(parent, node->child[i], ops,
317 validate_tree(parent);
322 static int _walk_tree(struct quadtree *head, const struct quadtree_iterator *it)
324 int direction, count = 0;
326 direction = it->direction(head, (struct quadtree_iterator *)it);
328 if ((direction & QUADTREE_UPLEFT) && head->child[0])
329 count += _walk_tree(head->child[0], it);
331 if ((direction & QUADTREE_UPRIGHT) && head->child[1])
332 count += _walk_tree(head->child[1], it);
334 if ((direction & QUADTREE_DOWNLEFT) && head->child[2])
335 count += _walk_tree(head->child[2], it);
337 if ((direction & QUADTREE_DOWNRIGHT) && head->child[3])
338 count += _walk_tree(head->child[3], it);
340 if ((direction & QUADTREE_SELF) && it->callback) {
341 it->callback(head, (struct quadtree_iterator *)it);
348 int walk_quadtree(const struct quadtree_iterator *it)
350 return _walk_tree(it->head, it);