10 static void validate_subtree(const struct quadtree *node)
14 for (i = 0; i < 4; i++) {
18 if (node->child[i]->parent != node) {
19 printf("%s:%d Fatal! Tree inconsistency detected "
20 "at child %d in node %p\n",
21 __FUNCTION__, __LINE__, i, node);
25 if (node->child[i] == node->parent) {
26 printf("%s:%d Fatal! Tree loop detected "
27 "at child %d in node %p\n",
28 __FUNCTION__, __LINE__, i, node);
33 validate_subtree(node->child[i]);
37 static void validate_tree(const struct quadtree *node)
39 const struct quadtree *parent = quadtree_find_parent(node);
41 validate_subtree(parent);
45 * quadtree_add - add a node to a quadtree
46 * @parent: parent node
47 * @new: the new node to be added
48 * @compare: pointer to a comparison function
50 * Add a node to a quadtree. The tree is kept in order, the new node
51 * is placed in the end of appropriate branch. The compare function is
52 * used to compare the new node against a branch in the tree. The
53 * comparison function must have following return value depending on
54 * the position of node a compared to the position of node b:
61 * The case of nodes sharing identical coordinates is not taken into
65 struct quadtree *quadtree_add(struct quadtree *parent,
67 int (*compare)(struct quadtree *a,
74 validate_tree(parent);
76 ret = compare(parent, new);
78 if (ret < 0 || ret >= 4) {
79 printf("Invalid comparison result of %d\n", ret);
83 if (parent->child[ret])
84 return quadtree_add(parent->child[ret], new, compare);
86 parent->child[ret] = new;
95 * _quadtree_reposition_reqursively - Move everything under and
96 * including a given node under the new root node
100 _quadtree_reposition_reqursively(struct quadtree *root,
101 struct quadtree *node,
102 int (*compare)(struct quadtree *a,
109 /* First remove all children, if any */
111 for (i = 0; i < 4; i++) {
115 if (node->child[i] == node ||
116 node->child[i] == node->parent)
119 _quadtree_reposition_reqursively(root, node->child[i], compare);
123 /* Then remove this node under the new root. */
124 quadtree_add(root, node, compare);
128 * quadtree_del - Detach a node from the tree
130 * Return value: The new root node of the tree. If we are detaching
131 * anything but the root node of the entire tree, the returned root
132 * value will be the original root of the tree.
134 struct quadtree *quadtree_del(struct quadtree *node,
135 int (*compare)(struct quadtree *a,
138 struct quadtree *parent = 0;
142 * We are deleting the root node. This means we have to select
143 * a new root node and reconstruct the entire tree under it
147 for (i = 0; i < 4; i++) {
152 parent = node->child[i];
155 _quadtree_reposition_reqursively(parent,
165 * We are not deleting the parent. Just relocate the children
166 * and detach the node from the tree.
168 for (i = 0; i < 4; i++) {
172 _quadtree_reposition_reqursively(node->parent, node->child[i],
176 parent = quadtree_find_parent(node);
179 validate_tree(parent);
184 static int _walk_tree(struct quadtree *head, const struct quadtree_iterator *it)
186 int direction, count = 0;
188 direction = it->direction(head, it->ptr);
190 if ((direction & QUADTREE_UPLEFT) && head->child[0])
191 count += _walk_tree(head->child[0], it);
193 if ((direction & QUADTREE_UPRIGHT) && head->child[1])
194 count += _walk_tree(head->child[1], it);
196 if ((direction & QUADTREE_DOWNLEFT) && head->child[2])
197 count += _walk_tree(head->child[2], it);
199 if ((direction & QUADTREE_DOWNRIGHT) && head->child[3])
200 count += _walk_tree(head->child[3], it);
202 if ((direction & QUADTREE_SELF) && it->callback) {
203 it->callback(head, it->ptr);
211 int walk_tree(const struct quadtree_iterator *it)
213 return _walk_tree(it->head, it);