Commit daaa2133b298e6fe27c3a20dd0b297463b2e84af

Authored by Georg Hopp
1 parent 21cf5258

use threadsave libc. Prepare code for locks. Separate tree and tree elements. Use c99 standard.

... ... @@ -53,6 +53,9 @@ AM_CFLAGS="${AM_CFLAGS} ${MEM_OPT_FLAGS}"
53 53 AM_CFLAGS="${AM_CFLAGS} ${CFLAGS}"
54 54 AC_SUBST(AM_CFLAGS)
55 55
  56 +AM_LDFLAGS=""
  57 +AC_SUBST(AM_LDFLAGS)
  58 +
56 59 AC_CONFIG_FILES([Makefile
57 60 docs/Makefile
58 61 tests/Makefile
... ...
... ... @@ -28,25 +28,25 @@
28 28 #include "trbase.h"
29 29 #include "tr/tree.h"
30 30
31   -#define TR_HASH_IS_EMPTY(h) ((h)->root)
  31 +#define TR_HASH_IS_EMPTY(h) ((h)->tree->root)
32 32
33 33 TR_CLASS(TR_Hash) {
34   - TR_Tree root;
  34 + TR_Tree tree;
35 35 int cleanup_no_free;
36 36 };
37 37 TR_INSTANCE_INIT(TR_Hash);
38 38 TR_CLASSVARS_DECL(TR_Hash) {};
39 39
40   -#define TR_hashEmpty(hash) (NULL == (hash)->root)
  40 +//#define TR_hashEmpty(hash) (NULL == (hash)->tree->root)
41 41
42   -void * TR_hashAdd(TR_Hash, void *);
43   -void * TR_hashDelete(TR_Hash, const char *, size_t);
44   -void * TR_hashGet(TR_Hash, const char *, size_t);
45   -void * TR_hashGetFirst(TR_Hash);
46   -void * TR_hashDeleteByVal(TR_Hash, unsigned long);
47   -void * TR_hashGetByVal(TR_Hash, unsigned long);
48   -void TR_hashEach(TR_Hash, const void *, void (*)(const void *, const void *));
49   -void TR_hashCleanup(TR_Hash);
  42 +void * TR_hashAdd(TR_Hash, void *);
  43 +void * TR_hashDelete(TR_Hash, const char *, size_t);
  44 +void * TR_hashGet(TR_Hash, const char *, size_t);
  45 +void * TR_hashGetFirst(TR_Hash);
  46 +void * TR_hashDeleteByVal(TR_Hash, unsigned long);
  47 +void * TR_hashGetByVal(TR_Hash, unsigned long);
  48 +unsigned long TR_hashEach(TR_Hash, const void *, void (*)(const void *, const void *));
  49 +void TR_hashCleanup(TR_Hash);
50 50
51 51 #endif // __TR_HASH_H__
52 52
... ...
... ... @@ -26,14 +26,20 @@
26 26 #include "tr/tree_macros.h"
27 27 #include "trbase.h"
28 28
29   -TR_CLASS(TR_Tree) {
  29 +TR_CLASS(TR_TreeNode) {
30 30 void * data;
31 31
32 32 TR_rbColor color;
33 33
34   - TR_Tree parent;
35   - TR_Tree left;
36   - TR_Tree right;
  34 + TR_TreeNode parent;
  35 + TR_TreeNode left;
  36 + TR_TreeNode right;
  37 +};
  38 +TR_INSTANCE_INIT(TR_TreeNode);
  39 +TR_CLASSVARS_DECL(TR_TreeNode) {};
  40 +
  41 +TR_CLASS(TR_Tree) {
  42 + TR_TreeNode root;
37 43 };
38 44 TR_INSTANCE_INIT(TR_Tree);
39 45 TR_CLASSVARS_DECL(TR_Tree) {};
... ... @@ -41,11 +47,11 @@ TR_CLASSVARS_DECL(TR_Tree) {};
41 47 typedef int (*TR_TreeComp)(const void *, const void *);
42 48 typedef void (*TR_TreeAction)(const void *, const void *, const int);
43 49
44   -void * TR_treeFind(TR_Tree, const void *, TR_TreeComp);
45   -void * TR_treeInsert(TR_Tree *, const void *, TR_TreeComp);
46   -void * TR_treeDelete(TR_Tree *, const void *, TR_TreeComp);
47   -void TR_treeWalk(TR_Tree, const void *, TR_TreeAction);
48   -void TR_treeDestroy(TR_Tree *, TR_TreeAction);
  50 +void * TR_treeFind(TR_Tree, const void *, TR_TreeComp);
  51 +void * TR_treeInsert(TR_Tree, const void *, TR_TreeComp);
  52 +void * TR_treeDelete(TR_Tree, const void *, TR_TreeComp);
  53 +unsigned long TR_treeWalk(TR_Tree, const void *, TR_TreeAction);
  54 +void TR_treeDestroy(TR_Tree, TR_TreeAction);
49 55
50 56 #endif // __TR_TREE_H__
51 57
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4   -AM_CFLAGS += -I../include/
  4 +AM_CFLAGS += -I../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
5 6
6 7 TRDATALIBS = cbuf/libcbuf.la \
7 8 hash/libhash.la \
... ... @@ -13,5 +14,6 @@ lib_LTLIBRARIES = libtrdata.la
13 14 libtrdata_la_SOURCES =
14 15 libtrdata_la_CFLAGS = $(AM_CFLAGS)
15 16 libtrdata_la_LIBADD = $(TRDATALIBS)
  17 +libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS)
16 18
17 19 SUBDIRS = cbuf hash queue tree
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4   -AM_CFLAGS += -I../../include/
  4 +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
5 6
6 7 CB = cbuf.c read.c \
7 8 get_line.c set_data.c get_data.c \
... ... @@ -14,3 +15,4 @@ noinst_LTLIBRARIES = libcbuf.la
14 15
15 16 libcbuf_la_SOURCES = $(CB)
16 17 libcbuf_la_CFLAGS = $(AM_CFLAGS)
  18 +libcbuf_la_LIBADD = $(AM_LDFLAGS)
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4   -AM_CFLAGS += -I../../include/
  4 +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
5 6
6 7 HASH = hash.c add.c get.c get_first.c delete.c each.c value.c \
7 8 cleanup.c interface/hashable.c
... ... @@ -10,3 +11,4 @@ noinst_LTLIBRARIES = libhash.la
10 11
11 12 libhash_la_SOURCES = $(HASH)
12 13 libhash_la_CFLAGS = $(AM_CFLAGS)
  14 +libhash_la_LIBADD = $(AM_LDFLAGS)
... ...
... ... @@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b)
48 48 void *
49 49 TR_hashAdd(TR_Hash this, void * operand)
50 50 {
51   - void * found = TR_treeInsert(&this->root, operand, hashAddComp);
  51 + void * found = TR_treeInsert(this->tree, operand, hashAddComp);
52 52
53 53 if (NULL == found) {
54 54 return NULL;
... ...
... ... @@ -36,10 +36,12 @@ void
36 36 TR_hashCleanup(TR_Hash this)
37 37 {
38 38 if (this->cleanup_no_free) {
39   - TR_treeDestroy(&(this->root), NULL);
  39 + TR_treeDestroy(this->tree, NULL);
40 40 } else {
41   - TR_treeDestroy(&(this->root), tDelete);
  41 + TR_treeDestroy(this->tree, tDelete);
42 42 }
  43 +
  44 + TR_delete(this->tree);
43 45 }
44 46
45 47 // vim: set ts=4 sw=4:
... ...
... ... @@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
51 51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
52 52 void * found = NULL;
53 53
54   - found = TR_treeDelete(&(this->root), &hash, hashDeleteComp);
  54 + found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
55 55
56 56 return found;
57 57 }
... ... @@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
59 59 void *
60 60 TR_hashDeleteByVal(TR_Hash this, unsigned long hash)
61 61 {
62   - void * found = TR_treeDelete(&(this->root), &hash, hashDeleteComp);
  62 + void * found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
63 63
64 64 return found;
65 65 }
... ...
... ... @@ -34,7 +34,7 @@ walk(const void * node, const void * data, const int depth)
34 34 cb(node, data);
35 35 }
36 36
37   -void
  37 +unsigned long
38 38 TR_hashEach(
39 39 TR_Hash this,
40 40 const void * data,
... ... @@ -42,7 +42,7 @@ TR_hashEach(
42 42 {
43 43 cb = callback;
44 44
45   - TR_treeWalk(this->root, data, walk);
  45 + return TR_treeWalk(this->tree, data, walk);
46 46 }
47 47
48 48 // vim: set ts=4 sw=4:
... ...
... ... @@ -52,7 +52,7 @@ void *
52 52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
53 53 {
54 54 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
55   - void * found = TR_treeFind(this->root, &hash, hashGetComp);
  55 + void * found = TR_treeFind(this->tree, &hash, hashGetComp);
56 56
57 57 return found;
58 58 }
... ... @@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
60 60 void *
61 61 TR_hashGetByVal(TR_Hash this, unsigned long hash)
62 62 {
63   - void * found = TR_treeFind(this->root, &hash, hashGetComp);
  63 + void * found = TR_treeFind(this->tree, &hash, hashGetComp);
64 64
65 65 return found;
66 66 }
... ...
... ... @@ -27,7 +27,7 @@
27 27 void *
28 28 TR_hashGetFirst(TR_Hash this)
29 29 {
30   - return this->root;
  30 + return this->tree->root;
31 31 }
32 32
33 33 // vim: set ts=4 sw=4:
... ...
... ... @@ -31,6 +31,10 @@ static
31 31 int
32 32 hashCtor(void * _this, va_list * params)
33 33 {
  34 + TR_Hash this = _this;
  35 +
  36 + this->tree = TR_new(TR_Tree);
  37 +
34 38 return 0;
35 39 }
36 40
... ... @@ -41,6 +45,8 @@ hashDtor(void * _this)
41 45 TR_Hash this = _this;
42 46
43 47 TR_hashCleanup(this);
  48 +
  49 + TR_delete(this->tree);
44 50 }
45 51
46 52 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL);
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4   -AM_CFLAGS += -I../../include/
  4 +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
5 6
6   -noinst_LTLIBRARIES = libqueue.la
  7 +QUEUE = queue.c get.c put.c put_first.c find.c find_parent.c delete.c destroy.c
7 8
8   -libqueue_la_SOURCES = queue.c \
9   - get.c \
10   - put.c \
11   - put_first.c \
12   - find.c \
13   - find_parent.c \
14   - delete.c \
15   - destroy.c
  9 +noinst_LTLIBRARIES = libqueue.la
16 10
  11 +libqueue_la_SOURCES = $(QUEUE)
17 12 libqueue_la_CFLAGS = $(AM_CFLAGS)
  13 +libqueue_la_LIBADD = $(AM_LDFLAGS)
... ...
... ... @@ -26,9 +26,13 @@
26 26 void
27 27 TR_queueDelete(TR_Queue this, void * msg)
28 28 {
29   - TR_Queue node, parent = TR_queueFindParent(this, msg);
  29 + TR_Queue node, parent;
  30 +
  31 + parent = TR_queueFindParent(this, msg);
30 32
31   - if (! parent) return;
  33 + if (! parent) {
  34 + return;
  35 + }
32 36
33 37 node = parent->next;
34 38 parent->next = node->next;
... ...
... ... @@ -28,8 +28,10 @@
28 28 void
29 29 TR_queueDestroy(TR_Queue this)
30 30 {
31   - TR_Queue node = this->first;
  31 + TR_Queue node;
32 32
  33 + node = this->first;
  34 +
33 35 while (NULL != node) {
34 36 TR_Queue next = node->next;
35 37 if (this->free_msgs) {
... ...
... ... @@ -26,7 +26,9 @@
26 26 void
27 27 TR_queuePut(TR_Queue this, void * msg)
28 28 {
29   - TR_Queue node = (this->last)? this->last : this;
  29 + TR_Queue node;
  30 +
  31 + node = (this->last)? this->last : this;
30 32
31 33 node->next = TR_new(TR_Queue);
32 34 this->last = node->next;
... ...
... ... @@ -26,7 +26,9 @@
26 26 void
27 27 TR_queuePutFirst(TR_Queue this, void * msg)
28 28 {
29   - TR_Queue current_first = this->first;
  29 + TR_Queue current_first;
  30 +
  31 + current_first = this->first;
30 32
31 33 this->first = this->next = TR_new(TR_Queue);
32 34 this->first->next = current_first;
... ...
... ... @@ -40,7 +40,9 @@ static
40 40 void
41 41 queueDtor(void * _this)
42 42 {
43   - TR_queueDestroy((TR_Queue)_this);
  43 + TR_Queue this = _this;
  44 +
  45 + TR_queueDestroy(this);
44 46 }
45 47
46 48 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
  4 +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
  6 +
4 7 TREE = tree.c \
  8 + tree_node.c \
5 9 find.c \
6 10 insert.c \
7 11 delete.c \
8 12 walk.c \
9 13 destroy.c
10 14
11   -AM_CFLAGS += -I../../include/
12   -
13 15 noinst_LTLIBRARIES = libtree.la
14 16
15 17 libtree_la_SOURCES = $(TREE)
16 18 libtree_la_CFLAGS = $(AM_CFLAGS)
  19 +libtree_la_LIBADD = $(AM_LDFLAGS)
... ...
... ... @@ -24,14 +24,15 @@
24 24 #include "tr/tree.h"
25 25
26 26 void *
27   -TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
  27 +TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
28 28 {
29   - TR_Tree node = *this;
30   - TR_Tree del_node;
31   - TR_Tree sibling;
32   - int found;
  29 + TR_TreeNode node;
  30 + TR_TreeNode del_node;
  31 + TR_TreeNode sibling;
  32 + int found;
  33 + void * data;
33 34
34   - void * data;
  35 + node = this->root;
35 36
36 37 TR_TREE_FIND(node, search, found, comp);
37 38
... ... @@ -57,7 +58,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
57 58 * out inOrderSuccessor and remove the inOrderSuccessor.
58 59 */
59 60 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) {
60   - TR_Tree successor;
  61 + TR_TreeNode successor;
61 62
62 63 TR_TREE_INORDER_SUCC(node, successor);
63 64
... ... @@ -66,12 +67,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
66 67 }
67 68
68 69 {
69   - TR_Tree child = TR_TREE_CHILD(node);
  70 + TR_TreeNode child = TR_TREE_CHILD(node);
70 71
71 72 /*
72 73 * if we still have one child replace ourself with it.
73 74 */
74   - TR_TREE_REPLACE_NODE(this, node, child);
  75 + TR_TREE_REPLACE_NODE(&(this->root), node, child);
75 76
76 77 /*
77 78 * and finally delete the node...and prepare ourselfs
... ... @@ -105,9 +106,10 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
105 106 * rebalancing process...(this does not make much sense, but
106 107 * to be honest I don't know now.)
107 108 */
108   - TR_TREE_BALANCE_DELETE(this, node, sibling);
  109 + TR_TREE_BALANCE_DELETE(&(this->root), node, sibling);
109 110
110 111 TR_delete(del_node);
  112 +
111 113 return data;
112 114 }
113 115
... ...
... ... @@ -24,12 +24,15 @@
24 24 #include "tr/tree.h"
25 25
26 26 void
27   -TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
  27 +TR_treeDestroy(TR_Tree this, TR_TreeAction action)
28 28 {
29   - TR_Tree previous = * this;
30   - TR_Tree node = * this;
31   - int depth = 1;
  29 + TR_TreeNode previous;
  30 + TR_TreeNode node;
  31 + int depth = 1;
32 32
  33 + previous = this->root;
  34 + node = this->root;
  35 +
33 36 /*
34 37 * I think this has something like O(n+log(n)) on a ballanced
35 38 * tree because I have to traverse back the rightmost leaf to
... ... @@ -44,7 +47,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
44 47 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node))
45 48 || previous == TR_TREE_RIGHT(node)) {
46 49
47   - TR_Tree parent = TR_TREE_PARENT(node);
  50 + TR_TreeNode parent = TR_TREE_PARENT(node);
48 51
49 52 if (action) {
50 53 action(node->data, NULL, depth);
... ... @@ -82,7 +85,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
82 85 }
83 86 }
84 87
85   - *this = NULL;
  88 + this->root = NULL;
86 89 }
87 90
88 91 // vim: set ts=4 sw=4:
... ...
... ... @@ -25,11 +25,15 @@
25 25 void *
26 26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
27 27 {
28   - int found;
  28 + int found;
  29 + TR_TreeNode node;
  30 + void * retval;
29 31
30   - TR_TREE_FIND(this, search, found, comp);
  32 + node = this->root;
  33 + TR_TREE_FIND(node, search, found, comp);
  34 + retval = found == 0 ? node->data : NULL;
31 35
32   - return found == 0 ? this->data : NULL;
  36 + return retval;
33 37 }
34 38
35 39 // vim: set ts=4 sw=4:
... ...
... ... @@ -24,11 +24,14 @@
24 24 #include "tr/tree.h"
25 25
26 26 void *
27   -TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
  27 +TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
28 28 {
29   - TR_Tree node = *this;
30   - TR_Tree new_node = NULL;
31   - int found;
  29 + TR_TreeNode new_node = NULL;
  30 + TR_TreeNode node;
  31 + int found;
  32 + void * retval;
  33 +
  34 + node = this->root;
32 35
33 36 /*
34 37 * insert the node or return the one in tree if comparison
... ... @@ -39,7 +42,7 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
39 42 * if the root is NULL we simple add the element and set
40 43 * node to it.
41 44 */
42   - *this = node = new_node = TR_new(TR_Tree, search);
  45 + this->root = node = new_node = TR_new(TR_TreeNode, search);
43 46 } else {
44 47 TR_TREE_FIND(node, search, found, comp);
45 48
... ... @@ -55,11 +58,11 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
55 58 } else {
56 59 // not found
57 60 if (0 < found) {
58   - node->left = TR_new(TR_Tree, search);
  61 + node->left = TR_new(TR_TreeNode, search);
59 62 node->left->parent = node;
60 63 node = new_node = node->left;
61 64 } else {
62   - node->right = TR_new(TR_Tree, search);
  65 + node->right = TR_new(TR_TreeNode, search);
63 66 node->right->parent = node;
64 67 node = new_node = node->right;
65 68 }
... ... @@ -70,9 +73,10 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
70 73 * we expect node not to be NULL and pointing to our
71 74 * new node at this point...now rabalance the tree
72 75 */
73   - TR_TREE_BALANCE_INSERT(this, node);
  76 + TR_TREE_BALANCE_INSERT(&(this->root), node);
  77 + retval = new_node->data;
74 78
75   - return new_node->data;
  79 + return retval;
76 80 }
77 81
78 82 // vim: set ts=4 sw=4:
... ...
... ... @@ -33,11 +33,7 @@ treeCtor(void * _this, va_list * params)
33 33 {
34 34 TR_Tree this = _this;
35 35
36   - this->data = va_arg(*params, void *);
37   - this->color = rbRed;
38   - this->parent = NULL;
39   - this->left = NULL;
40   - this->right = NULL;
  36 + this->root = NULL;
41 37
42 38 return 0;
43 39 }
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2014 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#define _GNU_SOURCE
  24 +
  25 +#include <stdarg.h>
  26 +
  27 +#include "trbase.h"
  28 +#include "tr/tree.h"
  29 +
  30 +static
  31 +int
  32 +treeNodeCtor(void * _this, va_list * params)
  33 +{
  34 + TR_TreeNode this = _this;
  35 +
  36 + this->data = va_arg(*params, void *);
  37 + this->color = rbRed;
  38 + this->parent = NULL;
  39 + this->left = NULL;
  40 + this->right = NULL;
  41 +
  42 + return 0;
  43 +}
  44 +
  45 +static void treeNodeDtor(void * _this) {}
  46 +
  47 +TR_INIT_IFACE(TR_Class, treeNodeCtor, treeNodeDtor, NULL);
  48 +TR_CREATE_CLASS(TR_TreeNode, NULL, NULL, TR_IF(TR_Class));
  49 +
  50 +// vim: set ts=4 sw=4:
... ...
... ... @@ -22,12 +22,16 @@
22 22
23 23 #include "tr/tree.h"
24 24
25   -void
  25 +unsigned long
26 26 TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
27 27 {
28   - TR_Tree previous = this;
29   - TR_Tree node = this;
30   - int depth = 1;
  28 + TR_TreeNode previous;
  29 + TR_TreeNode node;
  30 + int depth = 1;
  31 + unsigned long processed = 0;
  32 +
  33 + previous = this->root;
  34 + node = this->root;
31 35
32 36 while (NULL != node) {
33 37 if (previous == TR_TREE_RIGHT(node)) {
... ... @@ -40,6 +44,7 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
40 44 if (NULL == TR_TREE_LEFT(node) || previous == TR_TREE_LEFT(node)) {
41 45 if (action) {
42 46 action(node->data, data, depth);
  47 + processed++;
43 48 }
44 49 previous = node;
45 50
... ... @@ -56,6 +61,8 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
56 61 depth++;
57 62 }
58 63 }
  64 +
  65 + return processed;
59 66 }
60 67
61 68 // vim: set ts=4 sw=4:
... ...
Please register or login to post a comment