Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_trees.c
Go to the documentation of this file.
1
8#include <stdlib.h>
9#include <string.h>
10#include <pthread.h>
11
12#include "nilorea/n_common.h"
13#include "nilorea/n_log.h"
14#include "nilorea/n_str.h"
15#include "nilorea/n_trees.h"
16
22 TREE *tree = NULL ;
23 Malloc( tree , TREE , 1 );
24 __n_assert( tree , n_log(LOG_ERR, "Failed to allocate memory for tree.\n"); return NULL; );
25
26 tree->root = NULL;
27 tree->nb_nodes = 0;
28 tree->height = 0;
29 pthread_rwlock_init(&(tree->rwlock), NULL);
30
31 return tree;
32}
33
40TREE_NODE *tree_create_node( NODE_DATA value, void (*destroy_func)( void *ptr )) {
41 TREE_NODE *node = (TREE_NODE *)malloc(sizeof(TREE_NODE));
42 if (node == NULL) {
43 n_log(LOG_ERR, "Failed to allocate memory for tree node.\n");
44 return NULL;
45 }
46
47 node->data = value;
48 node->destroy_func = destroy_func;
49 node->parent_list_node = NULL;
50 node->parent = NULL;
51 node->children = new_generic_list(0);
52
53 return node;
54}
55
63 if (parent == NULL || child == NULL) {
64 return FALSE;
65 }
66
67 LIST_NODE *node = new_list_node( child , child -> destroy_func );
68 __n_assert( node , n_log(LOG_ERR, "Failed to create child node"); return FALSE );
69
70 if (parent->children == NULL) {
71 parent->children = new_generic_list(0);
72 if( !parent->children )
73 {
74 if( node -> destroy_func != NULL )
75 {
76 node -> destroy_func( node -> ptr );
77 }
78 Free( node );
79 n_log(LOG_ERR, "Failed to create parent->children list");
80 return FALSE;
81 }
82 }
83 list_push(parent->children, child, child -> destroy_func );
84 child->parent_list_node = node ;
85 child->parent = parent;
86 return TRUE;
87}
88
95int tree_delete_node(TREE *tree, TREE_NODE *node) {
96 if (tree == NULL || node == NULL) {
97 return FALSE;
98 }
99
100 // Recursively delete child nodes
101 LIST_NODE *child_node = node->children->start;
102 while (child_node) {
103 TREE_NODE *child = (TREE_NODE *)child_node->ptr;
104 tree_delete_node(tree, child);
105 child_node = child_node->next;
106 }
107
108 // Remove the node from its parent's child list, if applicable
109 if (node->parent && node->parent->children) {
111 }
112
113 // Free node data if necessary
114 if (node->destroy_func) {
115 node->destroy_func(node->data.value.ptr);
116 } else {
117 free(node->data.value.ptr);
118 }
119
120 // Free the node itself
121 free(node);
122 tree->nb_nodes--;
123
124 return TRUE;
125}
126
131void tree_destroy(TREE **tree) {
132 if (tree == NULL || *tree == NULL) {
133 return;
134 }
135
136 TREE_NODE *root = (*tree)->root;
137 if (root != NULL) {
138 tree_delete_node(*tree, root);
139 }
140
141 pthread_rwlock_destroy(&((*tree)->rwlock));
142 free(*tree);
143 *tree = NULL;
144}
145
146
154 return a.i - b.i;
155}
156
164 return (a.f > b.f) - (a.f < b.f);
165}
166
174 return (a.d > b.d) - (a.d < b.d);
175}
176
182 printf("%d", val.i);
183}
184
191 printf("%f", val.f);
192}
193
199 printf("%lf", val.d);
200}
201
207QUADTREE* create_quadtree(int coord_type) {
208 QUADTREE* qt = (QUADTREE*)malloc(sizeof(QUADTREE));
209 qt->coord_type = coord_type;
210 qt->root = NULL;
211
212 switch (coord_type) {
213 case COORD_INT:
214 qt->compare = compare_int;
215 qt->print = print_int;
216 break;
217 case COORD_FLOAT:
219 qt->print = print_float;
220 break;
221 case COORD_DOUBLE:
223 qt->print = print_double;
224 break;
225 }
226
227 return qt;
228}
229
238 QUADTREE_NODE* node = (QUADTREE_NODE*)malloc(sizeof(QUADTREE_NODE));
239 node->x = x;
240 node->y = y;
241 node->data_ptr = data_ptr;
242 node->nw = NULL;
243 node->ne = NULL;
244 node->sw = NULL;
245 node->se = NULL;
246 return node;
247}
248
257void insert(QUADTREE *qt, QUADTREE_NODE **root, COORD_VALUE x, COORD_VALUE y, void *data_ptr) {
258 if (*root == NULL) {
259 *root = create_node(x, y, data_ptr);
260 return;
261 }
262
263 if (qt->compare(x, (*root)->x) < 0 && qt->compare(y, (*root)->y) < 0) {
264 insert(qt, &((*root)->sw), x, y, data_ptr);
265 } else if (qt->compare(x, (*root)->x) < 0 && qt->compare(y, (*root)->y) >= 0) {
266 insert(qt, &((*root)->nw), x, y, data_ptr);
267 } else if (qt->compare(x, (*root)->x) >= 0 && qt->compare(y, (*root)->y) < 0) {
268 insert(qt, &((*root)->se), x, y, data_ptr);
269 } else if (qt->compare(x, (*root)->x) >= 0 && qt->compare(y, (*root)->y) >= 0) {
270 insert(qt, &((*root)->ne), x, y, data_ptr);
271 }
272}
273
283 if (root == NULL || (qt->compare(root->x, x) == 0 && qt->compare(root->y, y) == 0)) {
284 return root;
285 }
286
287 if (qt->compare(x, root->x) < 0 && qt->compare(y, root->y) < 0) {
288 return search(qt, root->sw, x, y);
289 } else if (qt->compare(x, root->x) < 0 && qt->compare(y, root->y) >= 0) {
290 return search(qt, root->nw, x, y);
291 } else if (qt->compare(x, root->x) >= 0 && qt->compare(y, root->y) < 0) {
292 return search(qt, root->se, x, y);
293 } else if (qt->compare(x, root->x) >= 0 && qt->compare(y, root->y) >= 0) {
294 return search(qt, root->ne, x, y);
295 }
296
297 return NULL; // Should not reach here
298}
299
305 if (root == NULL) return;
306
307 free_quadtree(root->nw);
308 free_quadtree(root->ne);
309 free_quadtree(root->sw);
310 free_quadtree(root->se);
311
312 free(root);
313}
314
321OCTREE_NODE* create_octree_node(POINT3D point, void *data_ptr) {
322 OCTREE_NODE *node = (OCTREE_NODE*)malloc(sizeof(OCTREE_NODE));
323 if (node) {
324 node->point = point;
325 node->data_ptr = data_ptr;
326 for (int i = 0; i < 8; i++) {
327 node->children[i] = NULL;
328 }
329 }
330 return node;
331}
332
339 OCTREE *octree = (OCTREE*)malloc(sizeof(OCTREE));
340 if (octree) {
341 octree->root = NULL;
342 octree->coord_type = type;
343 }
344 return octree;
345}
346
354int determine_octant(POINT3D point, POINT3D center, int type) {
355 int octant = 0;
356 if (type == COORD_INT) {
357 if (point.x.i >= center.x.i) octant |= 4;
358 if (point.y.i >= center.y.i) octant |= 2;
359 if (point.z.i >= center.z.i) octant |= 1;
360 } else if (type == COORD_FLOAT) {
361 if (point.x.f >= center.x.f) octant |= 4;
362 if (point.y.f >= center.y.f) octant |= 2;
363 if (point.z.f >= center.z.f) octant |= 1;
364 } else if (type == COORD_DOUBLE) {
365 if (point.x.d >= center.x.d) octant |= 4;
366 if (point.y.d >= center.y.d) octant |= 2;
367 if (point.z.d >= center.z.d) octant |= 1;
368 }
369 return octant;
370}
371
379void insert_octree_node(OCTREE_NODE *node, POINT3D point, void *data_ptr, int type) {
380 int octant = determine_octant(point, node->point, type);
381 if (!node->children[octant]) {
382 node->children[octant] = create_octree_node(point, data_ptr);
383 } else {
384 insert_octree_node(node->children[octant], point, data_ptr, type);
385 }
386}
387
394void insert_octree(OCTREE *octree, POINT3D point, void *data_ptr) {
395 if (!octree->root) {
396 octree->root = create_octree_node(point, data_ptr);
397 } else {
398 insert_octree_node(octree->root, point, data_ptr, octree->coord_type);
399 }
400}
401
407 if (node) {
408 for (int i = 0; i < 8; i++) {
409 free_octree_node(node->children[i]);
410 }
411 free(node);
412 }
413}
414
419void free_octree(OCTREE *octree) {
420 if (octree) {
421 free_octree_node(octree->root);
422 free(octree);
423 }
424}
425
426
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:191
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:284
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:264
void * ptr
void pointer to store
Definition n_list.h:29
LIST_NODE * start
pointer to the start of the list
Definition n_list.h:52
struct LIST_NODE * next
pointer to the next node
Definition n_list.h:35
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition n_list.c:244
LIST_NODE * new_list_node(void *ptr, void(*destructor)(void *ptr))
Allocate a new node to link in a list.
Definition n_list.c:46
void * remove_list_node_f(LIST *list, LIST_NODE *node)
Internal function called each time we need to get a node out of a list.
Definition n_list.c:68
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
Definition n_list.c:20
Structure of a generic list node.
Definition n_list.h:27
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:74
#define LOG_ERR
error conditions
Definition n_log.h:58
print_func print
pointer to print function
Definition n_trees.h:157
compare_func compare
pointer to comparison function
Definition n_trees.h:155
TREE_NODE * root
pointer to first node
Definition n_trees.h:71
pthread_rwlock_t rwlock
mutex for thread safety (optional)
Definition n_trees.h:73
struct QUADTREE_NODE * nw
North-West child.
Definition n_trees.h:141
int coord_type
type of coordinate used in the quad tree
Definition n_trees.h:153
size_t nb_nodes
number of nodes in the tree
Definition n_trees.h:75
COORD_VALUE z
z coordinate
Definition n_trees.h:122
void * data_ptr
Pointer to additional data, can be NULL.
Definition n_trees.h:178
OCTREE_NODE * root
tree list first node
Definition n_trees.h:186
COORD_VALUE y
Y coordinate.
Definition n_trees.h:135
QUADTREE_NODE * root
tree list first node
Definition n_trees.h:159
union NODE_DATA_TYPES value
node value
Definition n_trees.h:47
NODE_DATA data
structure holding values for node
Definition n_trees.h:56
struct QUADTREE_NODE * sw
South-West child.
Definition n_trees.h:145
COORD_VALUE x
x coordinate
Definition n_trees.h:118
void * ptr
pointer type
Definition n_trees.h:36
void * data_ptr
Pointer to data, can be NULL.
Definition n_trees.h:139
struct QUADTREE_NODE * se
South-East child.
Definition n_trees.h:147
POINT3D point
Point represented by this node.
Definition n_trees.h:176
struct QUADTREE_NODE * ne
North-East child.
Definition n_trees.h:143
void(* destroy_func)(void *ptr)
value destructor if of type ptr and specified, else a simple free will be used
Definition n_trees.h:58
COORD_VALUE y
y coordinate
Definition n_trees.h:120
COORD_VALUE x
X coordinate.
Definition n_trees.h:133
struct OCTREE_NODE * children[8]
Child nodes.
Definition n_trees.h:180
LIST_NODE * parent_list_node
pointer to parent container of the TREE_NODE, LIST_NODE
Definition n_trees.h:62
struct TREE_NODE * parent
pointer to parent
Definition n_trees.h:60
size_t height
height of the tree
Definition n_trees.h:77
LIST * children
ordered list of children
Definition n_trees.h:64
int coord_type
Coordinate type for the entire tree.
Definition n_trees.h:188
void free_octree_node(OCTREE_NODE *node)
recursive function to free an OCTREE node and its children
Definition n_trees.c:406
void insert_octree(OCTREE *octree, POINT3D point, void *data_ptr)
Insert a point into the OCTREE.
Definition n_trees.c:394
int tree_insert_child(TREE_NODE *parent, TREE_NODE *child)
insert a child node into the parent node
Definition n_trees.c:62
void free_quadtree(QUADTREE_NODE *root)
Function to free the quad tree.
Definition n_trees.c:304
TREE * new_tree()
create a new TREE
Definition n_trees.c:21
TREE_NODE * tree_create_node(NODE_DATA value, void(*destroy_func)(void *ptr))
create a TREE node
Definition n_trees.c:40
QUADTREE_NODE * search(QUADTREE *qt, QUADTREE_NODE *root, COORD_VALUE x, COORD_VALUE y)
Function to search for a point in the quad tree.
Definition n_trees.c:282
void free_octree(OCTREE *octree)
free the OCTREE
Definition n_trees.c:419
void tree_destroy(TREE **tree)
destroy a TREE
Definition n_trees.c:131
OCTREE_NODE * create_octree_node(POINT3D point, void *data_ptr)
create and OCTREE node
Definition n_trees.c:321
OCTREE * create_octree(int type)
Create a new OCTREE with a specified coordinate type.
Definition n_trees.c:338
int tree_delete_node(TREE *tree, TREE_NODE *node)
delete a TREE node
Definition n_trees.c:95
void insert(QUADTREE *qt, QUADTREE_NODE **root, COORD_VALUE x, COORD_VALUE y, void *data_ptr)
Function to insert a point into the quad tree.
Definition n_trees.c:257
QUADTREE * create_quadtree(int coord_type)
Function to create a new quad tree.
Definition n_trees.c:207
QUADTREE_NODE * create_node(COORD_VALUE x, COORD_VALUE y, void *data_ptr)
function to create a new quad tree node
Definition n_trees.c:237
structure of a TREE node data
Definition n_trees.h:45
structure of an OCTREE
Definition n_trees.h:184
structure of an OCTREE node
Definition n_trees.h:174
Structure for a POINT3D in the 3D space.
Definition n_trees.h:115
structure of a quad tree
Definition n_trees.h:151
structure of a quad tree node
Definition n_trees.h:131
structure of a TREE
Definition n_trees.h:69
structure of a n-ary TREE node
Definition n_trees.h:54
Union to store the coordinate values.
Definition n_trees.h:99
Common headers and low-level hugly functions & define.
Generic log system.
N_STR and string function declaration.
int determine_octant(POINT3D point, POINT3D center, int type)
function to determine the octant for the given point relative to the node
Definition n_trees.c:354
void insert_octree_node(OCTREE_NODE *node, POINT3D point, void *data_ptr, int type)
recursive function to insert a point into the OCTREE
Definition n_trees.c:379
void print_int(COORD_VALUE val)
 
Definition n_trees.c:181
int compare_float(COORD_VALUE a, COORD_VALUE b)
float comparison function
Definition n_trees.c:163
int compare_double(COORD_VALUE a, COORD_VALUE b)
double comparison functions
Definition n_trees.c:173
void print_double(COORD_VALUE val)
 
Definition n_trees.c:198
int compare_int(COORD_VALUE a, COORD_VALUE b)
int comparison function
Definition n_trees.c:153
void print_float(COORD_VALUE val)
 
Definition n_trees.c:190
trees module headers