Skip to content
Snippets Groups Projects
Commit 616dd783 authored by Francois Chevallier's avatar Francois Chevallier Committed by Morris Jette
Browse files

[PATCH 2/5] Enhance xtree logic for layouts management

Apply freefunc on the node and no longer its internal data in xtree_free
Add XTREE_GROWING xtree_walk target to ease building a tree adding childs
while walking it

(Adapted for slurm-14.11 by Matthieu Hautreux <matthieu.hautreux@cea.fr>)
parent b3d2b932
No related branches found
No related tags found
No related merge requests found
...@@ -64,7 +64,7 @@ static void xtree_free_childs(xtree_t* tree, xtree_node_t* node) ...@@ -64,7 +64,7 @@ static void xtree_free_childs(xtree_t* tree, xtree_node_t* node)
} }
current_node = current_node->parent; current_node = current_node->parent;
if (tree->free) if (tree->free)
tree->free(free_later->data); tree->free(free_later);
xfree(free_later); xfree(free_later);
--tree->count; --tree->count;
} }
...@@ -80,7 +80,7 @@ void xtree_free(xtree_t* tree) ...@@ -80,7 +80,7 @@ void xtree_free(xtree_t* tree)
xtree_free_childs(tree, tree->root); xtree_free_childs(tree, tree->root);
if (tree->free) if (tree->free)
tree->free(tree->root->data); tree->free(tree->root);
xfree(tree->root); xfree(tree->root);
xtree_init(tree, tree->free); xtree_init(tree, tree->free);
...@@ -315,6 +315,14 @@ xtree_node_t* xtree_walk(xtree_t* tree, ...@@ -315,6 +315,14 @@ xtree_node_t* xtree_walk(xtree_t* tree,
current_node = node; current_node = node;
while (current_node) { while (current_node) {
if (level >= min_level && !action(current_node,
XTREE_GROWING,
level,
arg)) {
return current_node;
}
/* go down and continue counting */ /* go down and continue counting */
if (current_node->start) { if (current_node->start) {
if (level >= min_level && !action(current_node, if (level >= min_level && !action(current_node,
...@@ -426,7 +434,7 @@ xtree_node_t* xtree_delete(xtree_t* tree, xtree_node_t* node) ...@@ -426,7 +434,7 @@ xtree_node_t* xtree_delete(xtree_t* tree, xtree_node_t* node)
xtree_free_childs(tree, node); xtree_free_childs(tree, node);
if (tree->free) if (tree->free)
tree->free(node->data); tree->free(node);
xfree(node); xfree(node);
--tree->count; --tree->count;
......
...@@ -38,9 +38,6 @@ ...@@ -38,9 +38,6 @@
#include <stdint.h> #include <stdint.h>
/* function prototype to deallocate data stored in tree nodes */
typedef void (*xtree_free_data_function_t)(void* data);
/** /**
* The root node's parent must always be NULL (or browsing algorithm which * The root node's parent must always be NULL (or browsing algorithm which
* stops at root when going up, will either crash or go to an infinite loop). * stops at root when going up, will either crash or go to an infinite loop).
...@@ -54,6 +51,9 @@ typedef struct xtree_node_st { ...@@ -54,6 +51,9 @@ typedef struct xtree_node_st {
struct xtree_node_st* previous; /* previous node, same level */ struct xtree_node_st* previous; /* previous node, same level */
} xtree_node_t; } xtree_node_t;
/* function prototype to deallocate data stored in tree nodes */
typedef void (*xtree_free_data_function_t)(xtree_node_t* node);
typedef struct xtree_st { typedef struct xtree_st {
xtree_node_t* root; /* root node of the tree */ xtree_node_t* root; /* root node of the tree */
xtree_free_data_function_t free; /* frees nodes data or null */ xtree_free_data_function_t free; /* frees nodes data or null */
...@@ -65,7 +65,7 @@ typedef struct xtree_st { ...@@ -65,7 +65,7 @@ typedef struct xtree_st {
/* free a complete tree whatever the `tree` entry point, it can be a leaf for /* free a complete tree whatever the `tree` entry point, it can be a leaf for
* example. * example.
* *
* The tree itself is freed but the `xtree_t` structure is not free (since it * The tree itself is freed but the `xtree_t` structure is not freed (since it
* can be stored on the stack). * can be stored on the stack).
* *
* During freeing operation the tree is in a invalid state. * During freeing operation the tree is in a invalid state.
...@@ -78,7 +78,10 @@ void xtree_free(xtree_t* tree); ...@@ -78,7 +78,10 @@ void xtree_free(xtree_t* tree);
* initialize a xtree_t structure with an empty tree * initialize a xtree_t structure with an empty tree
* *
* @param freefunc is the function which will be used to free data associated * @param freefunc is the function which will be used to free data associated
* with tree's nodes or NULL * with tree's nodes or NULL, freefunc must only desallocate
* node->data not the node itself, node is passed as a
* parameter if the user wants to do some processing according
* to the being-to-be-freed address of the node.
* @param tree is the structure to initialize * @param tree is the structure to initialize
* *
*/ */
...@@ -101,6 +104,10 @@ void xtree_set_freefunc(xtree_t* tree, xtree_free_data_function_t freefunc); ...@@ -101,6 +104,10 @@ void xtree_set_freefunc(xtree_t* tree, xtree_free_data_function_t freefunc);
/** convenient function to get the parent of a node */ /** convenient function to get the parent of a node */
xtree_node_t* xtree_get_parent(xtree_t* tree, xtree_node_t* node); xtree_node_t* xtree_get_parent(xtree_t* tree, xtree_node_t* node);
#define xtree_node_get_data(node) ((node) ? (node)->data : NULL)
#define xtree_get_root(tree) ((tree) ? (tree)->root : NULL)
/** convenient function to get node count /** convenient function to get node count
* @returns the count of node inside the tree, constant time, or UINT32_MAX * @returns the count of node inside the tree, constant time, or UINT32_MAX
* if tree is NULL. * if tree is NULL.
...@@ -179,6 +186,7 @@ uint32_t xtree_node_depth(const xtree_node_t* node); ...@@ -179,6 +186,7 @@ uint32_t xtree_node_depth(const xtree_node_t* node);
#define XTREE_INORDER 2 #define XTREE_INORDER 2
#define XTREE_ENDORDER 4 #define XTREE_ENDORDER 4
#define XTREE_LEAF 8 #define XTREE_LEAF 8
#define XTREE_GROWING 16
#define XTREE_LEVEL_MAX UINT32_MAX #define XTREE_LEVEL_MAX UINT32_MAX
...@@ -191,6 +199,10 @@ uint32_t xtree_node_depth(const xtree_node_t* node); ...@@ -191,6 +199,10 @@ uint32_t xtree_node_depth(const xtree_node_t* node);
* each children (if more than one), and after visiting the children. * each children (if more than one), and after visiting the children.
* XTREE_LEAF indicates the node being visited is a leaf and receive * XTREE_LEAF indicates the node being visited is a leaf and receive
* consequently only one visit. * consequently only one visit.
*
* XTREE_GROWING is called before any other calls, allowing a node to
* add childs.
*
* @param level is the current level, 0 being the root node. * @param level is the current level, 0 being the root node.
* @param arg is the data assigned to xtree_walk then calling it. * @param arg is the data assigned to xtree_walk then calling it.
* @returns 0 to indicate that xtree_walk do not need to continue to go * @returns 0 to indicate that xtree_walk do not need to continue to go
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment