12 static void _trap(int line)
15 printf("Trapped from line %d, use debugger to get backtrace\n",
22 #define trap() _trap(__LINE__)
24 static int quadtree_compare_coord(const struct vector *a,
25 const struct vector *b)
41 static int quadtree_compare(const struct quadtree *a, const struct quadtree *b)
43 return quadtree_compare_coord(&a->pos, &b->pos);
46 static void validate_subtree(const struct quadtree *node)
53 printf("Attempted to validate a null pointer\n");
58 for (i = 0; i < 4; i++) {
62 if (node->child[i]->parent != node) {
63 printf("%s:%d Fatal! Tree inconsistency detected at "
64 "child %d %p in node %p, incorrent parent %p\n",
65 __func__, __LINE__, i, node->child[i], node,
66 node->child[i]->parent);
72 if (node->child[i] == node->parent) {
73 printf("%s:%d Fatal! Tree loop detected "
74 "at child %d in node %p\n",
75 __func__, __LINE__, i, node);
81 dir = quadtree_compare(node, node->child[i]);
84 printf("%s:%d Fatal! Spatial inconsistency detected "
85 "at child %d in node %p\n"
86 "parent: (%f %f), child (%f %f), "
88 __func__, __LINE__, i, node,
89 node->pos.x, node->pos.y,
90 node->child[i]->pos.x, node->child[i]->pos.y,
96 children += node->child[i]->children + 1;
98 validate_subtree(node->child[i]);
101 if (node->depth < 0) {
102 printf("%s:%d Tree statistics inconsistency detected! "
103 "Negative depth: %ld\n",
104 __func__, __LINE__, node->depth);
107 if (node->children != children) {
108 printf("%s:%d Tree statistics inconsistency detected! "
109 "child count mismatch. Expected %ld, got %ld\n",
110 __func__, __LINE__, children, node->children);
115 for (i = 0; i < 4 && node->children; i++) {
119 if (node->depth == node->child[i]->depth + 1)
122 if (node->child[i]->depth > node->depth) {
123 printf("%s:%d Tree statistics inconsistency detected! "
124 "child depth mismatch %ld > %ld\n",
125 __func__, __LINE__, node->child[i]->depth,
131 printf("%s:%d Tree statistics inconsistency detected! "
132 "child depth mismatch.",
139 static void validate_tree(const struct quadtree *node)
147 return validate_subtree(node);
149 for (i = 0; i < 4; i++)
150 if (node->parent->child[i] == node)
154 printf("%s:%d Tree inconsistency detected! "
155 "Wrong parent %p for node %p\n",
156 __func__, __LINE__, node->parent, node);
161 validate_tree(node->parent);
164 void _quadtree_validate_tree(const struct quadtree *node)
172 * quadtree_add - add a node to a quadtree
173 * @parent: parent node
174 * @new: the new node to be added
176 * Add a node to a quadtree. The tree is kept in order, the new node
177 * is placed in the end of appropriate branch.
179 * The case of nodes sharing identical coordinates is not taken into
183 struct quadtree *quadtree_add(struct quadtree *parent, struct quadtree *new,
184 struct quadtree_ops *ops)
190 validate_tree(parent);
192 ret = quadtree_compare(parent, new);
194 if (ret < 0 || ret >= 4) {
195 printf("Invalid comparison result of %d\n", ret);
199 if (parent->child[ret])
200 return quadtree_add(parent->child[ret], new, ops);
202 parent->child[ret] = new;
203 new->parent = parent;
204 for (i = 0; i < 4; i++)
208 printf("adding node %p to parent %p\n", new, parent);
212 quadtree_recalculate_parent_stats(new, ops);
220 * _qt_optimal_del - Delete nodes from a detached subtree in optimal order
222 * All nodes are moved under the new parent node
224 static void _qt_optimal_del(struct quadtree *parent, struct quadtree *node,
225 struct quadtree_ops *ops, int parents)
227 struct quadtree *child[4] = {0};
228 int i, children = 0, max_c, max_i;
230 for (i = 0; i < 4; i++) {
231 if (!node->child[i]) {
236 child[children] = node->child[i];
237 node->child[i] = NULL;
242 * Try to remove the nodes in such order that the node which
243 * has child number one quarter of the parent's child numer
244 * gets deleted first.
247 if (node->children <= parents / 4) {
249 printf("%d: Moving node %p away from parent %p\n",
250 __LINE__, node, parent);
253 validate_tree(parent);
254 quadtree_add(parent, node, ops);
262 for (i = 0; i < 4; i++) {
266 if (max_c < child[i]->children) {
267 max_c = child[i]->children;
272 _qt_optimal_del(parent, child[max_i], ops, parents / 4);
278 validate_tree(parent);
280 printf("%d: Moving node %p away from parent %p\n",
281 __LINE__, node, parent);
284 quadtree_add(parent, node, ops);
289 * quadtree_del - Detach a node from the tree
291 * Return value: The new root node of the tree. If we are detaching
292 * anything but the root node of the entire tree, the returned root
293 * value will be the original root of the tree.
295 struct quadtree *quadtree_del(struct quadtree *node,
296 struct quadtree_ops *ops)
298 struct quadtree *parent = 0;
302 printf("Deleting node %p under parent %p\n",
307 * We are deleting the root node. This means we have to select
308 * a new root node and reconstruct the entire tree under it
312 for (i = 0; i < 4; i++) {
317 parent = node->child[i];
321 _qt_optimal_del(parent, node->child[i], ops,
330 * We are not deleting the parent. Detach the node from the
331 * parent abd relocate the children. The node will be then
332 * detached from the tree.
335 for (i = 0; i < 4; i++) {
336 if (node->parent->child[i] == node) {
337 node->parent->child[i] = 0;
344 parent = node->parent;
347 * The sub branch is now detached from the main tree. Fix the
350 quadtree_recalculate_parent_stats(node->parent, ops);
352 parent = quadtree_find_parent(parent);
354 if (node->children) {
355 for (i = 0; i < 4; i++) {
359 _qt_optimal_del(parent, node->child[i], ops,
364 validate_tree(parent);
369 static int _walk_tree(struct quadtree *head, const struct quadtree_iterator *it)
371 int direction, count = 0;
373 direction = it->direction(head, (struct quadtree_iterator *)it);
375 if ((direction & QUADTREE_UPLEFT) && head->child[0])
376 count += _walk_tree(head->child[0], it);
378 if ((direction & QUADTREE_UPRIGHT) && head->child[1])
379 count += _walk_tree(head->child[1], it);
381 if ((direction & QUADTREE_DOWNLEFT) && head->child[2])
382 count += _walk_tree(head->child[2], it);
384 if ((direction & QUADTREE_DOWNRIGHT) && head->child[3])
385 count += _walk_tree(head->child[3], it);
387 if ((direction & QUADTREE_SELF) && it->callback) {
388 it->callback(head, (struct quadtree_iterator *)it);
395 int walk_quadtree(const struct quadtree_iterator *it)
397 return _walk_tree(it->head, it);