Commit daaa2133b298e6fe27c3a20dd0b297463b2e84af
1 parent
21cf5258
use threadsave libc. Prepare code for locks. Separate tree and tree elements. Use c99 standard.
Showing
27 changed files
with
188 additions
and
88 deletions
@@ -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 | } |
@@ -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 | } |
src/tree/tree_node.c
0 → 100644
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