Added user_data capability to data callbacks and some sequential processing

routines for hashes.


SVN revision: 12747
This commit is contained in:
werkt 2005-01-04 22:45:06 +00:00 committed by werkt
parent 68d6c5facf
commit 958efc06f5
5 changed files with 148 additions and 30 deletions

View File

@ -16,7 +16,7 @@ extern "C" {
extern const unsigned int ecore_prime_table[];
typedef void (*Ecore_For_Each) (void *value);
typedef void (*Ecore_For_Each) (void *value, void *user_data);
# define ECORE_FOR_EACH(function) ((Ecore_For_Each)function)
typedef void (*Ecore_Free_Cb) (void *data);
@ -163,7 +163,8 @@ extern "C" {
int ecore_list_nodes(Ecore_List * list);
/* Traversing the list */
int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function);
int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
void *user_data);
inline void *ecore_list_goto_first(Ecore_List * list);
inline void *ecore_list_goto_last(Ecore_List * list);
inline void *ecore_list_goto_index(Ecore_List * list, int index);
@ -221,8 +222,8 @@ extern "C" {
void *ecore_dlist_remove_last(Ecore_DList * _e_dlist);
/* Traversing the list */
# define ecore_dlist_for_each(list, function) \
ecore_list_for_each(ECORE_LIST(list), function)
# define ecore_dlist_for_each(list, function, user_data) \
ecore_list_for_each(ECORE_LIST(list), function, user_data)
inline void *ecore_dlist_goto_first(Ecore_DList * _e_dlist);
inline void *ecore_dlist_goto_last(Ecore_DList * _e_dlist);
inline void *ecore_dlist_goto_index(Ecore_DList * _e_dlist, int index);
@ -274,6 +275,9 @@ extern "C" {
int size; /* An index into the table of primes to
determine size */
int nodes; /* The number of nodes currently in the hash */
int index; /* The current index into the bucket table */
Ecore_Hash_Node *current; /* the current node in the current bucket */
Ecore_Compare_Cb compare; /* The function used to compare node values */
Ecore_Hash_Cb hash_func; /* The function used to compare node values */
@ -292,7 +296,12 @@ extern "C" {
int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function);
int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function);
void ecore_hash_destroy(Ecore_Hash *hash);
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func);
Ecore_Hash_Node *ecore_hash_goto_first(Ecore_Hash *hash);
Ecore_Hash_Node *ecore_hash_next(Ecore_Hash *hash);
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func,
void *user_data);
Ecore_List *ecore_hash_keys(Ecore_Hash *hash);
/* Retrieve and store data into the hash */
void *ecore_hash_get(Ecore_Hash *hash, void *key);
@ -528,10 +537,12 @@ extern "C" {
/* For each node in the tree perform the for_each_func function */
/* For this one pass in the node */
int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func);
int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func,
void *user_data);
/* And here pass in the node's value */
int ecore_tree_for_each_node_value(Ecore_Tree * tree,
Ecore_For_Each for_each_func);
Ecore_For_Each for_each_func,
void *user_data);
/* Some basic node functions */
/* Initialize a node */

View File

@ -198,14 +198,79 @@ void ecore_hash_destroy(Ecore_Hash *hash)
* Functions that iterate through hash tables.
*/
/**
* Move the current index to the beginning of the given hash for sequential
* processing
* @param hash The given hash
* @return the topmost node on success, NULL otherwise
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
*/
Ecore_Hash_Node *ecore_hash_goto_first(Ecore_Hash *hash)
{
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
hash->index = 0;
ECORE_READ_LOCK(hash);
if( hash->buckets[hash->index] )
hash->current = ecore_list_goto_first( hash->buckets[hash->index] )
ECORE_READ_UNLOCK(hash);
return hash->current;
}
/**
* Return the current node and move to the next node of the given hash
* @param hash The given hash
* @return the current node on success, NULL if end reached
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
*/
Ecore_Hash_Node *ecore_hash_next(Ecore_Hash *hash)
{
Ecore_Hash_Node *node;
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
ECORE_READ_LOCK(hash);
node = hash->current;
if( hash->index < ecore_prime_table[hash->size] &&
hash->buckets[hash->index] ) {
if( hash->current )
ecore_list_goto( hash->buckets[hash->index], hash->current );
else
ecore_list_goto_first( hash->buckets[hash->index] );
ecore_list_next( hash->buckets[hash->index] );
hash->current = ecore_list_current( hash->buckets[hash->index] );
if( !hash->current ) {
hash->index++;
ECORE_READ_UNLOCK(hash);
ecore_hash_next(hash);
ECORE_READ_LOCK(hash);
}
} else {
hash->current = NULL;
}
ECORE_READ_UNLOCK(hash);
return node;
}
/**
* Runs the @p for_each_func function on each entry in the given hash.
* @param hash The given hash.
* @param for_each_func The function that each entry is passed to.
* @param user_data a pointer passed to calls of for_each_func
* @return TRUE on success, FALSE otherwise.
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
*/
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func)
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func,
void *user_data)
{
int i = 0;
@ -220,7 +285,7 @@ int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func)
ecore_list_goto_first(hash->buckets[i]);
while ((node = ecore_list_next(hash->buckets[i]))) {
for_each_func(node);
for_each_func(node, user_data);
}
}
i++;
@ -231,6 +296,40 @@ int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func)
return TRUE;
}
/**
* Retrieves an ecore_list of all keys in the given hash.
* @param hash The given hash.
* @return new ecore_list on success, NULL otherwise
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
*/
Ecore_List *ecore_hash_keys(Ecore_Hash *hash)
{
int i = 0;
Ecore_List *keys;
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
ECORE_READ_LOCK(hash);
keys = ecore_list_new();
while (i < ecore_prime_table[hash->size]) {
if (hash->buckets[i]) {
Ecore_Hash_Node *node;
ecore_list_goto_first(hash->buckets[i]);
while ((node = ecore_list_next(hash->buckets[i]))) {
ecore_list_append(keys, node->key);
}
}
i++;
}
ECORE_READ_UNLOCK(hash);
return keys;
}
/**
* Prints the distribution of the given hash table for graphing.
* @param hash The given hash table.

View File

@ -22,7 +22,8 @@ static void *_ecore_list_goto(Ecore_List * list, void *data);
static void *_ecore_list_goto_index(Ecore_List *list, int index);
/* Iterative function */
static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function);
static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
void *user_data);
/* Private double linked list functions */
static void *_ecore_dlist_previous(Ecore_DList * list);
@ -916,19 +917,21 @@ int ecore_list_clear(Ecore_List * list)
* @return Returns @c TRUE on success, @c FALSE on failure.
* @ingroup Ecore_Data_List_Traverse_Group
*/
int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function)
int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
void *user_data)
{
int ret;
CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
ret = _ecore_list_for_each(list, function);
ret = _ecore_list_for_each(list, function, user_data);
return ret;
}
/* The real meat of executing the function for each data node */
static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function)
static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
void *user_data)
{
void *value;
@ -937,7 +940,7 @@ static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function)
_ecore_list_goto_first(list);
while ((value = _ecore_list_next(list)) != NULL)
function(value);
function(value, user_data);
return TRUE;
}

View File

@ -65,7 +65,7 @@ ecore_path_group_del(int group_id)
if (group->paths) {
ecore_list_for_each(group->paths,
ECORE_FOR_EACH(free));
ECORE_FOR_EACH(free), NULL);
ecore_list_destroy(group->paths);
}

View File

@ -15,9 +15,10 @@ int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
/* Fucntions for executing a specified function on each node of a tree */
int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func);
int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func,
void *user_data);
int tree_for_each_node_value(Ecore_Tree_Node * node,
Ecore_For_Each for_each_func);
Ecore_For_Each for_each_func, void *user_data);
/**
* @brief Allocate a new tree structure.
@ -572,10 +573,11 @@ int ecore_tree_is_empty(Ecore_Tree * tree)
* @brief Execute function for each value in the tree
* @param tree: the tree to traverse
* @param for_each_func: the function to execute for each value in the tree
* @param user_data: data passed to each for_each_func call
* @return Returns TRUE on success, FALSE on failure.
*/
int ecore_tree_for_each_node_value(Ecore_Tree * tree,
Ecore_For_Each for_each_func)
Ecore_For_Each for_each_func, void *user_data)
{
CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
@ -583,17 +585,18 @@ int ecore_tree_for_each_node_value(Ecore_Tree * tree,
if (!tree->tree)
return FALSE;
return tree_for_each_node_value(tree->tree, for_each_func);
return tree_for_each_node_value(tree->tree, for_each_func, user_data);
}
/**
* @brief Execute the function for each node in the tree
* @param tree: the tree to traverse
* @param for_each_func: the function to execute for each node
*
* @param user_data: data passed to each for_each_func call
* @return Returns TRUE on success, FALSE on failure.
*/
int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func)
int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func,
void *user_data)
{
CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
@ -601,7 +604,7 @@ int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func)
if (!tree->tree)
return FALSE;
return tree_for_each_node(tree->tree, for_each_func);
return tree_for_each_node(tree->tree, for_each_func, user_data);
}
/* Find the parent for the key */
@ -770,19 +773,21 @@ int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node)
* @brief Execute a function for each node below this point in the tree.
* @param node: the highest node in the tree the function will be executed for
* @param for_each_func: the function to pass the nodes as data into
* @param user_data: data passed to each for_each_func call
* @return Returns FALSE if an error condition occurs, otherwise TRUE
*/
int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func)
int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func,
void *user_data)
{
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
if (node->right_child)
tree_for_each_node(node->right_child, for_each_func);
tree_for_each_node(node->right_child, for_each_func, user_data);
if (node->left_child)
tree_for_each_node(node->left_child, for_each_func);
tree_for_each_node(node->left_child, for_each_func, user_data);
for_each_func(node);
for_each_func(node, user_data);
return TRUE;
}
@ -795,17 +800,17 @@ int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func)
* @return Returns FALSE if an error condition occurs, otherwise TRUE
*/
int tree_for_each_node_value(Ecore_Tree_Node * node,
Ecore_For_Each for_each_func)
Ecore_For_Each for_each_func, void *user_data)
{
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
if (node->right_child)
tree_for_each_node_value(node->right_child, for_each_func);
tree_for_each_node_value(node->right_child, for_each_func, user_data);
if (node->left_child)
tree_for_each_node_value(node->left_child, for_each_func);
tree_for_each_node_value(node->left_child, for_each_func, user_data);
for_each_func(node->value);
for_each_func(node->value, user_data);
return TRUE;
}