#define WRAP_NODE_FUNCTIONS(Type, prefix) \
- void *prefix ## add(Type *self, void *dat, Comparator cmp, Transformer func) \
+ void *prefix ## add(Type *self, void *dat, Comparator cmp, Transformer trans) \
{ \
Type ## Node **node = prefix ## nfd(self, dat, cmp); \
\
if (! *node) \
- prefix ## nmk(self, node, func ? func(dat) : dat); \
+ prefix ## nmk(self, node, trans ? trans(dat) : dat); \
\
return (*node)->dat; \
} \
\
- void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer func) \
+ void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer trans) \
{ \
Type ## Node **node = prefix ## nfd(self, key, cmp); \
\
if (! *node) \
return NULL; \
\
- return func ? func((*node)->dat) : (*node)->dat; \
+ return trans ? trans((*node)->dat) : (*node)->dat; \
} \
\
- void *prefix ## del(Type *self, void *key, Comparator cmp, Transformer func) \
+ void *prefix ## del(Type *self, void *key, Comparator cmp, Transformer trans) \
{ \
Type ## Node **node = prefix ## nfd(self, key, cmp); \
\
if (! *node) \
return NULL; \
\
- void *dat = func ? func((*node)->dat) : (*node)->dat; \
+ void *dat = trans ? trans((*node)->dat) : (*node)->dat; \
prefix ## nrm(self, node); \
return dat; \
}
free(old);
}
-void list_itr(List *list, Iterator func, void *arg)
+void list_itr(List *list, Iterator iter, void *arg, Transformer trans)
{
LIST_ITERATE(list, node)
- func(node->dat, arg);
+ iter(trans ? trans(node->dat) : node->dat, arg);
}
-void list_clr(List *list, Iterator func, void *arg)
+void list_clr(List *list, Iterator iter, void *arg, Transformer trans)
{
for (ListNode *node = list->fst; node != NULL;) {
ListNode *next = node->nxt;
- if (func)
- func(node->dat, arg);
+ if (iter)
+ iter(trans ? trans(node->dat) : node->dat, arg);
free(node);
node = next;
This function should be called before any other function is called on the list.
*/
-void *list_add(List *list, void *dat, Comparator cmp, Transformer func);
+void *list_add(List *list, void *dat, Comparator cmp, Transformer trans);
/*
Add an element to the list.
Otherwise, return added element.
*/
-void *list_get(List *list, void *key, Comparator cmp, Transformer func);
+void *list_get(List *list, void *key, Comparator cmp, Transformer trans);
/*
Get an element from the list.
The first matching element is returned, or NULL if none found.
*/
-void *list_del(List *list, void *key, Comparator cmp, Transformer func);
+void *list_del(List *list, void *key, Comparator cmp, Transformer trans);
/*
Delete an element from the list.
Remove the node at the given location.
*/
-void list_itr(List *list, Iterator func, void *arg);
+void list_itr(List *list, Iterator iter, void *arg, Transformer trans);
/*
Iterate over the list.
- Calls func on every element, with the extra argument arg.
+ Calls iter on every element, with the extra argument arg.
Note: the LIST_ITERATE macro can be used to do this without function calls.
*/
-void list_clr(List *list, Iterator func, void *arg);
+void list_clr(List *list, Iterator iter, void *arg, Transformer trans);
/*
Iterates over the list and deletes all elements.
- Calls func on every element, with the extra argument arg.
+ Calls iter on every element, with the extra argument arg.
The list is empty afterwards.
*/
pthread_rwlock_destroy(&map->clk);
}
-void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order)
+void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
pthread_rwlock_wrlock(&map->clk);
map->cnl = true;
pthread_rwlock_wrlock(&map->tlk);
pthread_rwlock_unlock(&map->clk);
- tree_clr(&map->tre, func, arg, order);
+ tree_clr(&map->tre, iter, arg, trans, order);
pthread_rwlock_unlock(&map->tlk);
}
#define WRAP_TREE_FUNC(name, write) \
- void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer func) \
+ void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer trans) \
{ \
if (! get_lock(map, write)) \
return NULL; \
\
- dat = tree_ ## name(&map->tre, dat, cmp, func); \
+ dat = tree_ ## name(&map->tre, dat, cmp, trans); \
pthread_rwlock_unlock(&map->tlk); \
return dat; \
}
WRAP_TREE_FUNC(add, true)
WRAP_TREE_FUNC(get, false)
WRAP_TREE_FUNC(del, true)
+
+void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+{
+ if (! get_lock(map, false))
+ return;
+
+ tree_trv(&map->tre, iter, arg, trans, order);
+}
Make sure to cancel the map before destroying it, to avoid memory leaks.
*/
-void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order);
+void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
[Thread Safe]
Cancels and clears the map.
If no callback is given, the traversion order is irrelevant.
*/
-void *map_add(Map *map, void *dat, Comparator cmp, Transformer func);
+void *map_add(Map *map, void *dat, Comparator cmp, Transformer trans);
/*
[Thread Safe]
Add an element to the map.
Otherwise, return added element.
*/
-void *map_get(Map *map, void *key, Comparator cmp, Transformer func);
+void *map_get(Map *map, void *key, Comparator cmp, Transformer trans);
/*
[Thread Safe]
Get an element from the map, or return NULL if none found.
*/
-void *map_del(Map *map, void *key, Comparator cmp, Transformer func);
+void *map_del(Map *map, void *key, Comparator cmp, Transformer trans);
/*
[Thread Safe]
Delete an element from the map and return it, or NULL if none found.
*/
+void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
+/*
+ [Thread Safe]
+ Traverse the map.
+ Calls iter on every element, with the extra argument arg.
+*/
+
+
#endif
pthread_mutex_destroy(&queue->mtx);
}
-void queue_clr(Queue *queue, Iterator func, void *arg)
+void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans)
{
- list_clr(&queue->lst, func, arg);
+ list_clr(&queue->lst, iter, arg, trans);
}
bool queue_enq(Queue *queue, void *dat)
return success;
}
-void *queue_deq(Queue *queue, Transformer func)
+void *queue_deq(Queue *queue, Transformer trans)
{
void *dat = NULL;
dat = (*node)->dat;
list_nrm(&queue->lst, node);
- if (func)
- dat = func(dat);
+ if (trans)
+ dat = trans(dat);
} else {
pthread_cond_wait(&queue->cnd, &queue->mtx);
}
list is cleared before calling this function.
*/
-void queue_clr(Queue *queue, Iterator func, void *arg);
+void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans);
/*
Clears the queue.
Notifies waiting consumer threads.
*/
-void *queue_deq(Queue *queue, Transformer func);
+void *queue_deq(Queue *queue, Transformer trans);
/*
[Thread Safe]
Dequeue an element.
assert(list_get(&list, &a, &cmp_int, NULL) == NULL);
printf("testing clr\n");
- list_clr(&list, NULL, NULL);
+ list_clr(&list, NULL, NULL, NULL);
assert(list_get(&list, &b, &cmp_int, NULL) == NULL);
}
results[i][0] += results[i][j];
}
- map_cnl(&map, (void *) &refcount_drp, NULL, 0);
+ map_cnl(&map, (void *) &refcount_drp, NULL, NULL, 0);
map_dst(&map);
printf("Time: 10 seconds\n");
return *(const int *) ia - *(const int *) ib;
}
-void clear_callback(void *ia, void *ib)
+void clear_callback(int *ia, int *ib)
{
- assert(*(int *) ia > *(int *) ib);
+ assert(*ia >= *ib);
+ *ib = *ia;
free(ia);
}
assert(tree_get(&tree, &a, &cmp_int, NULL) == NULL);
printf("testing clr\n");
- tree_clr(&tree, NULL, NULL, 0);
+ tree_clr(&tree, NULL, NULL, NULL, 0);
assert(tree_get(&tree, &b, &cmp_int, NULL) == NULL);
printf("testing order and speed with %d elements\n", (int) NUM_ELEMENTS);
}
int last = -1;
- tree_clr(&tree, &clear_callback, &last, TRAVERSION_INORDER);
+ tree_clr(&tree, (void *) &clear_callback, &last, NULL, TRAVERSION_INORDER);
}
return search(&(*node)->rgt, key, cmp);
}
-static inline void traverse(TreeNode *node, Iterator func, void *arg, TreeTraversionOrder order, int delete)
+static inline void traverse(TreeNode *node, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete)
{
if (! node)
return;
- if (func && order == TRAVERSION_PREORDER ) func(node->dat, arg);
- traverse(node->lft, func, arg, order, delete);
- if (func && order == TRAVERSION_INORDER ) func(node->dat, arg);
- traverse(node->rgt, func, arg, order, delete);
- if (func && order == TRAVERSION_POSTORDER) func(node->dat, arg);
+ if (iter && order == TRAVERSION_PREORDER ) iter(trans ? trans(node->dat) : node->dat, arg);
+ traverse(node->lft, iter, arg, trans, order, delete);
+ if (iter && order == TRAVERSION_INORDER ) iter(trans ? trans(node->dat) : node->dat, arg);
+ traverse(node->rgt, iter, arg, trans, order, delete);
+ if (iter && order == TRAVERSION_POSTORDER) iter(trans ? trans(node->dat) : node->dat, arg);
if (delete)
free(node);
free(old);
}
-void tree_trv(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order)
+void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
- traverse(tree->rot, func, arg, order, 0);
+ traverse(tree->rot, iter, arg, trans, order, 0);
}
-void tree_clr(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order)
+void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
- traverse(tree->rot, func, arg, order, 1);
+ traverse(tree->rot, iter, arg, trans, order, 1);
tree_ini(tree);
}
This function should be called before any other function is called on the tree.
*/
-void *tree_add(Tree *tree, void *dat, Comparator cmp, Transformer func);
+void *tree_add(Tree *tree, void *dat, Comparator cmp, Transformer trans);
/*
Add an element to the tree.
Otherwise, return added element.
*/
-void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer func);
+void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer trans);
/*
Get an element from the tree, or return NULL if none found.
*/
-void *tree_del(Tree *tree, void *key, Comparator cmp, Transformer func);
+void *tree_del(Tree *tree, void *key, Comparator cmp, Transformer trans);
/*
Delete an element from the tree and return it, or NULL if none found.
*/
Remove the node at the given location.
*/
-void tree_trv(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order);
+void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
Traverse the tree.
- Calls func on every element, with the extra argument arg.
+ Calls iter on every element, with the extra argument arg.
*/
-void tree_clr(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order);
+void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
Traverses the tree and deletes all elements.
- Calls func on every element, with the extra argument arg.
+ Calls iter on every element, with the extra argument arg.
The tree is empty afterwards.
If no callback is given, the traversion order is irrelevant.