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,6 +53,9 @@ AM_CFLAGS="${AM_CFLAGS} ${MEM_OPT_FLAGS}"
53 AM_CFLAGS="${AM_CFLAGS} ${CFLAGS}" 53 AM_CFLAGS="${AM_CFLAGS} ${CFLAGS}"
54 AC_SUBST(AM_CFLAGS) 54 AC_SUBST(AM_CFLAGS)
55 55
  56 +AM_LDFLAGS=""
  57 +AC_SUBST(AM_LDFLAGS)
  58 +
56 AC_CONFIG_FILES([Makefile 59 AC_CONFIG_FILES([Makefile
57 docs/Makefile 60 docs/Makefile
58 tests/Makefile 61 tests/Makefile
@@ -28,25 +28,25 @@ @@ -28,25 +28,25 @@
28 #include "trbase.h" 28 #include "trbase.h"
29 #include "tr/tree.h" 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 TR_CLASS(TR_Hash) { 33 TR_CLASS(TR_Hash) {
34 - TR_Tree root; 34 + TR_Tree tree;
35 int cleanup_no_free; 35 int cleanup_no_free;
36 }; 36 };
37 TR_INSTANCE_INIT(TR_Hash); 37 TR_INSTANCE_INIT(TR_Hash);
38 TR_CLASSVARS_DECL(TR_Hash) {}; 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 #endif // __TR_HASH_H__ 51 #endif // __TR_HASH_H__
52 52
@@ -26,14 +26,20 @@ @@ -26,14 +26,20 @@
26 #include "tr/tree_macros.h" 26 #include "tr/tree_macros.h"
27 #include "trbase.h" 27 #include "trbase.h"
28 28
29 -TR_CLASS(TR_Tree) { 29 +TR_CLASS(TR_TreeNode) {
30 void * data; 30 void * data;
31 31
32 TR_rbColor color; 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 TR_INSTANCE_INIT(TR_Tree); 44 TR_INSTANCE_INIT(TR_Tree);
39 TR_CLASSVARS_DECL(TR_Tree) {}; 45 TR_CLASSVARS_DECL(TR_Tree) {};
@@ -41,11 +47,11 @@ TR_CLASSVARS_DECL(TR_Tree) {}; @@ -41,11 +47,11 @@ TR_CLASSVARS_DECL(TR_Tree) {};
41 typedef int (*TR_TreeComp)(const void *, const void *); 47 typedef int (*TR_TreeComp)(const void *, const void *);
42 typedef void (*TR_TreeAction)(const void *, const void *, const int); 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 #endif // __TR_TREE_H__ 56 #endif // __TR_TREE_H__
51 57
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 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 TRDATALIBS = cbuf/libcbuf.la \ 7 TRDATALIBS = cbuf/libcbuf.la \
7 hash/libhash.la \ 8 hash/libhash.la \
@@ -13,5 +14,6 @@ lib_LTLIBRARIES = libtrdata.la @@ -13,5 +14,6 @@ lib_LTLIBRARIES = libtrdata.la
13 libtrdata_la_SOURCES = 14 libtrdata_la_SOURCES =
14 libtrdata_la_CFLAGS = $(AM_CFLAGS) 15 libtrdata_la_CFLAGS = $(AM_CFLAGS)
15 libtrdata_la_LIBADD = $(TRDATALIBS) 16 libtrdata_la_LIBADD = $(TRDATALIBS)
  17 +libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS)
16 18
17 SUBDIRS = cbuf hash queue tree 19 SUBDIRS = cbuf hash queue tree
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 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 CB = cbuf.c read.c \ 7 CB = cbuf.c read.c \
7 get_line.c set_data.c get_data.c \ 8 get_line.c set_data.c get_data.c \
@@ -14,3 +15,4 @@ noinst_LTLIBRARIES = libcbuf.la @@ -14,3 +15,4 @@ noinst_LTLIBRARIES = libcbuf.la
14 15
15 libcbuf_la_SOURCES = $(CB) 16 libcbuf_la_SOURCES = $(CB)
16 libcbuf_la_CFLAGS = $(AM_CFLAGS) 17 libcbuf_la_CFLAGS = $(AM_CFLAGS)
  18 +libcbuf_la_LIBADD = $(AM_LDFLAGS)
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 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 HASH = hash.c add.c get.c get_first.c delete.c each.c value.c \ 7 HASH = hash.c add.c get.c get_first.c delete.c each.c value.c \
7 cleanup.c interface/hashable.c 8 cleanup.c interface/hashable.c
@@ -10,3 +11,4 @@ noinst_LTLIBRARIES = libhash.la @@ -10,3 +11,4 @@ noinst_LTLIBRARIES = libhash.la
10 11
11 libhash_la_SOURCES = $(HASH) 12 libhash_la_SOURCES = $(HASH)
12 libhash_la_CFLAGS = $(AM_CFLAGS) 13 libhash_la_CFLAGS = $(AM_CFLAGS)
  14 +libhash_la_LIBADD = $(AM_LDFLAGS)
@@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b) @@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b)
48 void * 48 void *
49 TR_hashAdd(TR_Hash this, void * operand) 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 if (NULL == found) { 53 if (NULL == found) {
54 return NULL; 54 return NULL;
@@ -36,10 +36,12 @@ void @@ -36,10 +36,12 @@ void
36 TR_hashCleanup(TR_Hash this) 36 TR_hashCleanup(TR_Hash this)
37 { 37 {
38 if (this->cleanup_no_free) { 38 if (this->cleanup_no_free) {
39 - TR_treeDestroy(&(this->root), NULL); 39 + TR_treeDestroy(this->tree, NULL);
40 } else { 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 // vim: set ts=4 sw=4: 47 // vim: set ts=4 sw=4:
@@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch) @@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch); 51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
52 void * found = NULL; 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 return found; 56 return found;
57 } 57 }
@@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch) @@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
59 void * 59 void *
60 TR_hashDeleteByVal(TR_Hash this, unsigned long hash) 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 return found; 64 return found;
65 } 65 }
@@ -34,7 +34,7 @@ walk(const void * node, const void * data, const int depth) @@ -34,7 +34,7 @@ walk(const void * node, const void * data, const int depth)
34 cb(node, data); 34 cb(node, data);
35 } 35 }
36 36
37 -void 37 +unsigned long
38 TR_hashEach( 38 TR_hashEach(
39 TR_Hash this, 39 TR_Hash this,
40 const void * data, 40 const void * data,
@@ -42,7 +42,7 @@ TR_hashEach( @@ -42,7 +42,7 @@ TR_hashEach(
42 { 42 {
43 cb = callback; 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 // vim: set ts=4 sw=4: 48 // vim: set ts=4 sw=4:
@@ -52,7 +52,7 @@ void * @@ -52,7 +52,7 @@ void *
52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch) 52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
53 { 53 {
54 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch); 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 return found; 57 return found;
58 } 58 }
@@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch) @@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
60 void * 60 void *
61 TR_hashGetByVal(TR_Hash this, unsigned long hash) 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 return found; 65 return found;
66 } 66 }
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 void * 27 void *
28 TR_hashGetFirst(TR_Hash this) 28 TR_hashGetFirst(TR_Hash this)
29 { 29 {
30 - return this->root; 30 + return this->tree->root;
31 } 31 }
32 32
33 // vim: set ts=4 sw=4: 33 // vim: set ts=4 sw=4:
@@ -31,6 +31,10 @@ static @@ -31,6 +31,10 @@ static
31 int 31 int
32 hashCtor(void * _this, va_list * params) 32 hashCtor(void * _this, va_list * params)
33 { 33 {
  34 + TR_Hash this = _this;
  35 +
  36 + this->tree = TR_new(TR_Tree);
  37 +
34 return 0; 38 return 0;
35 } 39 }
36 40
@@ -41,6 +45,8 @@ hashDtor(void * _this) @@ -41,6 +45,8 @@ hashDtor(void * _this)
41 TR_Hash this = _this; 45 TR_Hash this = _this;
42 46
43 TR_hashCleanup(this); 47 TR_hashCleanup(this);
  48 +
  49 + TR_delete(this->tree);
44 } 50 }
45 51
46 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL); 52 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL);
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 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 libqueue_la_CFLAGS = $(AM_CFLAGS) 12 libqueue_la_CFLAGS = $(AM_CFLAGS)
  13 +libqueue_la_LIBADD = $(AM_LDFLAGS)
@@ -26,9 +26,13 @@ @@ -26,9 +26,13 @@
26 void 26 void
27 TR_queueDelete(TR_Queue this, void * msg) 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 node = parent->next; 37 node = parent->next;
34 parent->next = node->next; 38 parent->next = node->next;
@@ -28,8 +28,10 @@ @@ -28,8 +28,10 @@
28 void 28 void
29 TR_queueDestroy(TR_Queue this) 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 while (NULL != node) { 35 while (NULL != node) {
34 TR_Queue next = node->next; 36 TR_Queue next = node->next;
35 if (this->free_msgs) { 37 if (this->free_msgs) {
@@ -26,7 +26,9 @@ @@ -26,7 +26,9 @@
26 void 26 void
27 TR_queuePut(TR_Queue this, void * msg) 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 node->next = TR_new(TR_Queue); 33 node->next = TR_new(TR_Queue);
32 this->last = node->next; 34 this->last = node->next;
@@ -26,7 +26,9 @@ @@ -26,7 +26,9 @@
26 void 26 void
27 TR_queuePutFirst(TR_Queue this, void * msg) 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 this->first = this->next = TR_new(TR_Queue); 33 this->first = this->next = TR_new(TR_Queue);
32 this->first->next = current_first; 34 this->first->next = current_first;
@@ -40,7 +40,9 @@ static @@ -40,7 +40,9 @@ static
40 void 40 void
41 queueDtor(void * _this) 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 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL); 48 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
  4 +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
  5 +AM_LDFLAGS += -lpthread
  6 +
4 TREE = tree.c \ 7 TREE = tree.c \
  8 + tree_node.c \
5 find.c \ 9 find.c \
6 insert.c \ 10 insert.c \
7 delete.c \ 11 delete.c \
8 walk.c \ 12 walk.c \
9 destroy.c 13 destroy.c
10 14
11 -AM_CFLAGS += -I../../include/  
12 -  
13 noinst_LTLIBRARIES = libtree.la 15 noinst_LTLIBRARIES = libtree.la
14 16
15 libtree_la_SOURCES = $(TREE) 17 libtree_la_SOURCES = $(TREE)
16 libtree_la_CFLAGS = $(AM_CFLAGS) 18 libtree_la_CFLAGS = $(AM_CFLAGS)
  19 +libtree_la_LIBADD = $(AM_LDFLAGS)
@@ -24,14 +24,15 @@ @@ -24,14 +24,15 @@
24 #include "tr/tree.h" 24 #include "tr/tree.h"
25 25
26 void * 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 TR_TREE_FIND(node, search, found, comp); 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,7 +58,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
57 * out inOrderSuccessor and remove the inOrderSuccessor. 58 * out inOrderSuccessor and remove the inOrderSuccessor.
58 */ 59 */
59 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) { 60 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) {
60 - TR_Tree successor; 61 + TR_TreeNode successor;
61 62
62 TR_TREE_INORDER_SUCC(node, successor); 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,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 * if we still have one child replace ourself with it. 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 * and finally delete the node...and prepare ourselfs 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,9 +106,10 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
105 * rebalancing process...(this does not make much sense, but 106 * rebalancing process...(this does not make much sense, but
106 * to be honest I don't know now.) 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 TR_delete(del_node); 111 TR_delete(del_node);
  112 +
111 return data; 113 return data;
112 } 114 }
113 115
@@ -24,12 +24,15 @@ @@ -24,12 +24,15 @@
24 #include "tr/tree.h" 24 #include "tr/tree.h"
25 25
26 void 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 * I think this has something like O(n+log(n)) on a ballanced 37 * I think this has something like O(n+log(n)) on a ballanced
35 * tree because I have to traverse back the rightmost leaf to 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,7 +47,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
44 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node)) 47 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node))
45 || previous == TR_TREE_RIGHT(node)) { 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 if (action) { 52 if (action) {
50 action(node->data, NULL, depth); 53 action(node->data, NULL, depth);
@@ -82,7 +85,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action) @@ -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 // vim: set ts=4 sw=4: 91 // vim: set ts=4 sw=4:
@@ -25,11 +25,15 @@ @@ -25,11 +25,15 @@
25 void * 25 void *
26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp) 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 // vim: set ts=4 sw=4: 39 // vim: set ts=4 sw=4:
@@ -24,11 +24,14 @@ @@ -24,11 +24,14 @@
24 #include "tr/tree.h" 24 #include "tr/tree.h"
25 25
26 void * 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 * insert the node or return the one in tree if comparison 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,7 +42,7 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
39 * if the root is NULL we simple add the element and set 42 * if the root is NULL we simple add the element and set
40 * node to it. 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 } else { 46 } else {
44 TR_TREE_FIND(node, search, found, comp); 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,11 +58,11 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
55 } else { 58 } else {
56 // not found 59 // not found
57 if (0 < found) { 60 if (0 < found) {
58 - node->left = TR_new(TR_Tree, search); 61 + node->left = TR_new(TR_TreeNode, search);
59 node->left->parent = node; 62 node->left->parent = node;
60 node = new_node = node->left; 63 node = new_node = node->left;
61 } else { 64 } else {
62 - node->right = TR_new(TR_Tree, search); 65 + node->right = TR_new(TR_TreeNode, search);
63 node->right->parent = node; 66 node->right->parent = node;
64 node = new_node = node->right; 67 node = new_node = node->right;
65 } 68 }
@@ -70,9 +73,10 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -70,9 +73,10 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
70 * we expect node not to be NULL and pointing to our 73 * we expect node not to be NULL and pointing to our
71 * new node at this point...now rabalance the tree 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 // vim: set ts=4 sw=4: 82 // vim: set ts=4 sw=4:
@@ -33,11 +33,7 @@ treeCtor(void * _this, va_list * params) @@ -33,11 +33,7 @@ treeCtor(void * _this, va_list * params)
33 { 33 {
34 TR_Tree this = _this; 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 return 0; 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,12 +22,16 @@
22 22
23 #include "tr/tree.h" 23 #include "tr/tree.h"
24 24
25 -void 25 +unsigned long
26 TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) 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 while (NULL != node) { 36 while (NULL != node) {
33 if (previous == TR_TREE_RIGHT(node)) { 37 if (previous == TR_TREE_RIGHT(node)) {
@@ -40,6 +44,7 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) @@ -40,6 +44,7 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
40 if (NULL == TR_TREE_LEFT(node) || previous == TR_TREE_LEFT(node)) { 44 if (NULL == TR_TREE_LEFT(node) || previous == TR_TREE_LEFT(node)) {
41 if (action) { 45 if (action) {
42 action(node->data, data, depth); 46 action(node->data, data, depth);
  47 + processed++;
43 } 48 }
44 previous = node; 49 previous = node;
45 50
@@ -56,6 +61,8 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) @@ -56,6 +61,8 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
56 depth++; 61 depth++;
57 } 62 }
58 } 63 }
  64 +
  65 + return processed;
59 } 66 }
60 67
61 // vim: set ts=4 sw=4: 68 // vim: set ts=4 sw=4:
Please register or login to post a comment