Commit c8dc541c489ddcc37d543ca9c7a3b25ad569f260

Authored by Georg Hopp
1 parent 417b9f6d

use now my own tree implementation as base for my hashes....sadly this thing is …

…leaking memory again...on the other hand I workarounded the problem of a sometimes occuring infinite loop within connect.
... ... @@ -63,5 +63,6 @@ AC_CONFIG_FILES([Makefile
63 63 src/session/Makefile
64 64 src/socket/Makefile
65 65 src/stream/Makefile
  66 + src/tree/Makefile
66 67 tests/Makefile])
67 68 AC_OUTPUT
... ...
... ... @@ -26,10 +26,11 @@
26 26 #include <sys/types.h>
27 27
28 28 #include "class.h"
  29 +#include "tree.h"
29 30
30 31
31 32 CLASS(Hash) {
32   - void * root;
  33 + Tree root;
33 34 };
34 35
35 36 void * hashAdd(Hash, void *);
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#ifndef __TREE_H__
  24 +#define __TREE_H__
  25 +
  26 +#include "class.h"
  27 +
  28 +#define TREE_RIGHT(node) (NULL!=(node)?(node)->right:NULL)
  29 +#define TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL)
  30 +#define TREE_PARENT(node) (NULL!=(node)?(node)->parent:NULL)
  31 +
  32 +#define TREE_CHILD(node) \
  33 + (NULL==TREE_RIGHT((node))?TREE_LEFT((node)):TREE_RIGHT((node)))
  34 +
  35 +#define TREE_RIGHT_LEFT(node) \
  36 + (NULL!=TREE_RIGHT((node))?TREE_LEFT(TREE_RIGHT((node))):NULL)
  37 +
  38 +#define TREE_LEFT_RIGHT(node) \
  39 + (NULL!=TREE_LEFT((node))?TREE_RIGHT(TREE_LEFT((node))):NULL)
  40 +
  41 +#define TREE_SIBLING(node) \
  42 + (NULL!=TREE_PARENT((node))? \
  43 + ((node)==TREE_PARENT((node))->left? \
  44 + TREE_PARENT((node))->right: \
  45 + TREE_PARENT((node))->left): \
  46 + NULL)
  47 +
  48 +#define TREE_GRANDPARENT(node) \
  49 + (NULL!=TREE_PARENT((node))?TREE_PARENT((node))->parent:NULL)
  50 +
  51 +#define TREE_UNCLE(node) \
  52 + (NULL!=TREE_GRANDPARENT((node))? \
  53 + (TREE_PARENT((node))==TREE_GRANDPARENT((node))->left? \
  54 + TREE_GRANDPARENT((node))->right: \
  55 + TREE_GRANDPARENT((node))->left): \
  56 + NULL)
  57 +
  58 +#define TREE_ROTATE_LEFT(root, node) \
  59 + do { \
  60 + if (NULL != TREE_RIGHT_LEFT((node))) { \
  61 + TREE_RIGHT_LEFT((node))->parent = (node); \
  62 + } \
  63 + TREE_RIGHT((node))->left = (node); \
  64 + if (NULL != TREE_PARENT((node))) { \
  65 + if (TREE_PARENT((node))->left==(node)) { \
  66 + TREE_PARENT((node))->left = (node)->right; \
  67 + } else { \
  68 + TREE_PARENT((node))->right = (node)->right; \
  69 + } \
  70 + } else { \
  71 + *(root) = (node)->right; \
  72 + } \
  73 + (node)->right = TREE_RIGHT_LEFT((node)); \
  74 + (node)->parent = (node)->right; \
  75 + TREE_RIGHT((node))->parent = (node)->parent; \
  76 + } while(0)
  77 +
  78 +#define TREE_ROTATE_RIGHT(root, node) \
  79 + do { \
  80 + if (NULL != TREE_LEFT_RIGHT((node))) { \
  81 + TREE_LEFT_RIGHT((node))->parent = (node); \
  82 + } \
  83 + TREE_LEFT((node))->right = (node); \
  84 + if (NULL != TREE_PARENT((node))) { \
  85 + if (TREE_PARENT((node))->left==(node)) { \
  86 + TREE_PARENT((node))->left = (node)->left; \
  87 + } else { \
  88 + TREE_PARENT((node))->right = (node)->left; \
  89 + } \
  90 + } else { \
  91 + *(root) = (node)->left; \
  92 + } \
  93 + TREE_LEFT((node))->parent = (node)->parent; \
  94 + (node)->left = TREE_LEFT_RIGHT((node)); \
  95 + (node)->parent = (node)->right; \
  96 + } while(0)
  97 +
  98 +#define TREE_REPLACE_NODE(root, node1, node2) \
  99 + do { \
  100 + if (NULL != TREE_PARENT((node1))) { \
  101 + if ((node1) == TREE_PARENT((node1))->left) { \
  102 + TREE_PARENT((node1))->left = (node2); \
  103 + } else { \
  104 + TREE_PARENT((node1))->right = (node2); \
  105 + } \
  106 + } else { \
  107 + *(root) = (node2); \
  108 + } \
  109 + if (NULL != (node2)) { \
  110 + (node2)->parent = (node1)->parent; \
  111 + } \
  112 + } while(0)
  113 +
  114 +
  115 +enum rbColor {rbBlack=1, rbRed=2};
  116 +
  117 +CLASS(Tree) {
  118 + void * data;
  119 +
  120 + enum rbColor color;
  121 +
  122 + Tree parent;
  123 + Tree left;
  124 + Tree right;
  125 +};
  126 +
  127 +typedef int (*TreeComp)(const void *, const void *);
  128 +typedef void (*TreeAction)(const void *, const int);
  129 +
  130 +void * treeFind(Tree, const void *, TreeComp);
  131 +void * treeInsert(Tree *, const void *, TreeComp);
  132 +void * treeDelete(Tree *, const void *, TreeComp);
  133 +void treeWalk(Tree, TreeAction);
  134 +void treeDestroy(Tree *, TreeAction);
  135 +
  136 +#endif // __TREE_H__
  137 +
  138 +// vim: set ts=4 sw=4:
... ...
... ... @@ -21,7 +21,8 @@ LIBS = ./http/libhttp.a \
21 21 ./server/libserver.a \
22 22 ./session/libsession.a \
23 23 ./socket/libsocket.a \
24   - ./stream/libstream.a
  24 + ./stream/libstream.a \
  25 + ./tree/libtree.a
25 26
26 27 AM_CFLAGS = -Wall -I ../include/
27 28
... ... @@ -33,4 +34,4 @@ taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap
33 34 #taskrambler_LDFLAGS = $(COVERAGE_LDFLAGS)
34 35
35 36 SUBDIRS = asset auth cbuf class hash queue http \
36   - logger server session socket stream
  37 + logger server session socket stream tree
... ...
... ... @@ -20,10 +20,6 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -// for debug
24   -#include <stdio.h>
25   -
26   -
27 23 #include <stdarg.h>
28 24
29 25 // for mmap
... ... @@ -105,9 +101,6 @@ assetCtor(void * _this, va_list * params)
105 101 return -1;
106 102 }
107 103
108   - printf("DEBUG file mapped from %p to %p\n",
109   - this->data, this->data + this->size);
110   -
111 104 this->ref_count = 1;
112 105
113 106 return 0;
... ...
... ... @@ -20,9 +20,6 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -// for debugging
24   -#include <stdio.h>
25   -
26 23 // for size_t
27 24 #include <sys/types.h>
28 25
... ... @@ -47,8 +44,6 @@ assetPoolGet(const char * path, size_t npath)
47 44 {
48 45 Asset asset = NULL;
49 46
50   - printf("DEBUG: pool get asset --%s--\n", path);
51   -
52 47 if (NULL == asset_pool) {
53 48 asset_pool = new(Hash);
54 49 } else {
... ... @@ -57,12 +52,9 @@ assetPoolGet(const char * path, size_t npath)
57 52
58 53 if (NULL == asset) {
59 54 asset = new(Asset, path, npath);
60   - printf("DEBUG create asset %p\n", asset);
61 55 hashAdd(asset_pool, asset);
62 56 } else {
63   - printf("DEBUG found asset %p\n", asset);
64 57 asset->ref_count++;
65   - printf("DEBUG increase ref_count to %zu\n", asset->ref_count);
66 58 }
67 59
68 60 return asset;
... ... @@ -71,19 +63,20 @@ assetPoolGet(const char * path, size_t npath)
71 63 size_t
72 64 assetPoolRelease(Asset asset)
73 65 {
74   - printf("DEBUG: pool release asset --%s--\n", asset->fname);
75   -
76 66 if (asset->ref_count > 1) {
77 67 asset->ref_count--;
78   - printf("DEBUG decrease ref_count to %zu\n", asset->ref_count);
79 68 return asset->ref_count;
80 69 }
81 70
82 71 if (NULL != asset) {
83 72 Asset found = (Asset)hashDelete(
84 73 asset_pool, asset->fname, asset->nfname);
85   - printf("DEBUG delete %p, parent was %p\n", asset, found);
86   - delete(asset);
  74 +
  75 + if (found == asset) {
  76 + delete(found);
  77 + } else {
  78 + // this should never happen....error log...
  79 + }
87 80 }
88 81
89 82 return 0;
... ...
... ... @@ -30,24 +30,35 @@ inline
30 30 int
31 31 hashAddComp(const void * a, const void * b)
32 32 {
33   - return hashableGetHash((void*)b) - hashableGetHash((void*)a);
  33 + unsigned long hash_a = hashableGetHash((void*)a);
  34 + unsigned long hash_b = hashableGetHash((void*)b);
  35 +
  36 + if (hash_a < hash_b) {
  37 + return -1;
  38 + }
  39 +
  40 + if (hash_a > hash_b) {
  41 + return 1;
  42 + }
  43 +
  44 + return 0;
34 45 }
35 46
36 47 void *
37 48 hashAdd(Hash this, void * operand)
38 49 {
39   - void * found = tsearch(operand, &(this->root), hashAddComp);
  50 + void * found = treeInsert(&this->root, operand, hashAddComp);
40 51
41 52 if (NULL == found) {
42 53 return NULL;
43 54 }
44 55
45   - if (operand != *(void**)found) {
46   - hashableHandleDouble(*(void**)found, operand);
  56 + if (operand != found) {
  57 + hashableHandleDouble(found, operand);
47 58 delete(operand);
48 59 }
49 60
50   - return *(void**)found;
  61 + return found;
51 62 }
52 63
53 64 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,9 +20,6 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <stdio.h>
24   -
25   -#include <search.h>
26 23 #include <sys/types.h>
27 24
28 25 #include "asset.h"
... ... @@ -34,59 +31,26 @@ inline
34 31 int
35 32 hashDeleteComp(const void * a, const void * b)
36 33 {
37   - if (_Asset == GET_CLASS(b)) {
38   - Asset data = (Asset)b;
39   - printf("DEBUG: search asset hash: %lu\n",
40   - *(const unsigned long*)a);
41   - printf("DEBUG: found: %lu, key: %s\n",
42   - data->hash, data->fname);
43   - }
44   -
45   - return hashableGetHash((void*)b) - *(const unsigned long*)a;
46   -}
47   -
48   -void
49   -action(const void *nodep, const VISIT which, const int depth)
50   -{
51   - void * datap = *(void **)nodep;
52   -
53   - if (_Asset == GET_CLASS(datap)) {
54   - Asset data = (Asset)datap;
  34 + unsigned long hash_a = hashableGetHash((void*)a);
55 35
56   - switch (which) {
57   - case preorder:
58   - break;
59   - case postorder:
60   - printf("DEBUG: %s(%lu) => %p\n", data->fname, data->hash, data);
61   - break;
62   - case endorder:
63   - break;
64   - case leaf:
65   - printf("DEBUG: %s(%lu) => %p\n", data->fname, data->hash, data);
66   - break;
67   - }
  36 + if (hash_a < *(const unsigned long*)b) {
  37 + return -1;
  38 + }
  39 +
  40 + if (hash_a > *(const unsigned long*)b) {
  41 + return 1;
68 42 }
  43 +
  44 + return 0;
69 45 }
70 46
71 47 void *
72 48 hashDelete(Hash this, const char * search, size_t nsearch)
73 49 {
74   - unsigned long hash = sdbm((const unsigned char *)search, nsearch);
75   - void * found = NULL;
76   - int count = 0;
  50 + unsigned long hash = sdbm((const unsigned char *)search, nsearch);
  51 + void * found = NULL;
77 52
78   - twalk(this->root, action);
79   - while (found == NULL && count < 3) {
80   - found = tdelete(&hash, &(this->root), hashDeleteComp);
81   - if (found == NULL) {
82   - puts("DEBUG: !!!!! NOT FOUND !!!!!!!");
83   - void * found = hashGet(this, search, nsearch);
84   - printf("DEBUG: find results in %p\n", found);
85   - }
86   - count++;
87   - }
88   - puts("===");
89   - twalk(this->root, action);
  53 + found = treeDelete(&(this->root), &hash, hashDeleteComp);
90 54
91 55 return found;
92 56 }
... ...
... ... @@ -29,11 +29,9 @@ static void (*cb)(const void*);
29 29 static
30 30 inline
31 31 void
32   -walk(const void * node, const VISIT which, const int depth)
  32 +walk(const void * node, const int depth)
33 33 {
34   - if (endorder == which || leaf == which) {
35   - cb(*(void**)node);
36   - }
  34 + cb(node);
37 35 }
38 36
39 37 void
... ... @@ -41,7 +39,7 @@ hashEach(Hash this, void (*callback)(const void*))
41 39 {
42 40 cb = callback;
43 41
44   - twalk(this->root, walk);
  42 + treeWalk(this->root, walk);
45 43 }
46 44
47 45 // vim: set ts=4 sw=4:
... ...
... ... @@ -26,6 +26,7 @@
26 26 #include <sys/types.h>
27 27
28 28 #include "hash.h"
  29 +#include "tree.h"
29 30 #include "utils/hash.h"
30 31
31 32 static
... ... @@ -33,16 +34,26 @@ inline
33 34 int
34 35 hashGetComp(const void * a, const void * b)
35 36 {
36   - return hashableGetHash((void*)b) - *(const unsigned long*)a;
  37 + unsigned long hash_a = hashableGetHash((void*)a);
  38 +
  39 + if (hash_a < *(const unsigned long*)b) {
  40 + return -1;
  41 + }
  42 +
  43 + if (hash_a > *(const unsigned long*)b) {
  44 + return 1;
  45 + }
  46 +
  47 + return 0;
37 48 }
38 49
39 50 void *
40 51 hashGet(Hash this, const char * search, size_t nsearch)
41 52 {
42   - unsigned long hash = sdbm((const unsigned char *)search, nsearch);
43   - void ** found = tfind(&hash, &(this->root), hashGetComp);
  53 + unsigned long hash = sdbm((const unsigned char *)search, nsearch);
  54 + void * found = treeFind(this->root, &hash, hashGetComp);
44 55
45   - return (NULL != found)? *found : NULL;
  56 + return found;
46 57 }
47 58
48 59 // vim: set ts=4 sw=4:
... ...
... ... @@ -38,7 +38,7 @@ hashCtor(void * _this, va_list * params)
38 38 static
39 39 inline
40 40 void
41   -tDelete(void * node)
  41 +tDelete(const void * node, const int depth)
42 42 {
43 43 delete(node);
44 44 }
... ... @@ -49,12 +49,7 @@ hashDtor(void * _this)
49 49 {
50 50 Hash this = _this;
51 51
52   - /**
53   - * this is a GNU extension...anyway on most non
54   - * GNUish systems i would not use tsearch anyway
55   - * as the trees will be unbalanced.
56   - */
57   - tdestroy(this->root, tDelete);
  52 + treeDestroy(&this->root, tDelete);
58 53 }
59 54
60 55 INIT_IFACE(Class, hashCtor, hashDtor, NULL);
... ...
... ... @@ -789,8 +789,8 @@ main(int argc, char * argv[])
789 789 traverse(root, printElement);
790 790 puts("");
791 791
792   - post(root, cleanup);
793   -
  792 +// post(root, cleanup);
  793 +//
794 794 return 0;
795 795 }
796 796
... ...
  1 +#include <stdio.h>
  2 +
  3 +#include "class.h"
  4 +#include "commons.h"
  5 +#include "utils/memory.h"
  6 +
  7 +#include "tree.h"
  8 +
  9 +#define NVALUES 10
  10 +
  11 +int
  12 +insertCompare(const void * tval, const void * search)
  13 +{
  14 + return *(const int *)tval - *(const int *)search;
  15 +}
  16 +
  17 +void
  18 +printNode(const void * _node, const int depth)
  19 +{
  20 + //Tree node = (Tree)_node;
  21 + //int value = *(int *)node->data;
  22 + int value = *(int *)_node;
  23 + int i;
  24 +
  25 + printf("%010d(%02d)", value, depth);
  26 +
  27 + // printf("%s %010d(%02d)",
  28 + // (node->color==rbRed)?"R":"B",
  29 + // value,
  30 + // depth);
  31 + for (i=0; i<depth; i++) printf("-");
  32 + puts("");
  33 +}
  34 +
  35 +
  36 +/**
  37 + * =======================================================================
  38 + */
  39 +int
  40 +main(int argc, char * argv[])
  41 +{
  42 + Tree root = NULL;
  43 + int * found = NULL;
  44 + int values[] = {40, 50, 60, 70, 80, 45, 75, 85};
  45 + int new50 = 50;
  46 + int new70 = 70;
  47 + int new80 = 80;
  48 + int search10 = 10;
  49 + int search64 = 64;
  50 +
  51 + treeInsert(&root, (void *)&(values[0]), insertCompare);
  52 + treeInsert(&root, (void *)&(values[1]), insertCompare);
  53 + treeInsert(&root, (void *)&(values[2]), insertCompare);
  54 + treeInsert(&root, (void *)&(values[3]), insertCompare);
  55 + treeInsert(&root, (void *)&(values[4]), insertCompare);
  56 + treeInsert(&root, (void *)&(values[5]), insertCompare);
  57 + treeInsert(&root, (void *)&(values[6]), insertCompare);
  58 + treeInsert(&root, (void *)&(values[7]), insertCompare);
  59 + puts("traverse");
  60 + treeWalk(root, printNode);
  61 + puts("");
  62 +
  63 + found = treeInsert(&root, (void *)&new70, insertCompare);
  64 + printf("insert %p(%d) got %p(%d)\n", &new70, new70, found, *found);
  65 + puts("traverse");
  66 + treeWalk(root, printNode);
  67 + puts("");
  68 +
  69 + found = treeFind(root, &search10, insertCompare);
  70 + if (NULL == found) {
  71 + printf("can't find segmenet of minimum size: %d\n", 10);
  72 + } else {
  73 + printf("found %d\n", *found);
  74 + }
  75 + puts("");
  76 +
  77 + found = treeFind(root, &search64, insertCompare);
  78 + if (NULL == found) {
  79 + printf("can't find segmenet of minimum size: %d\n", 64);
  80 + } else {
  81 + printf("found %d\n", *found);
  82 + }
  83 + puts("");
  84 +
  85 + found = treeFind(root, &new70, insertCompare);
  86 + if (NULL == found) {
  87 + printf("can't find segmenet of minimum size: %d\n", 70);
  88 + } else {
  89 + printf("found %d\n", *found);
  90 + }
  91 + puts("");
  92 +
  93 + found = treeDelete(&root, (void *)&new70, insertCompare);
  94 + printf("delete %p(%d) got %p(%d)\n", &new70, new70, found, *found);
  95 + puts("traverse");
  96 + treeWalk(root, printNode);
  97 + puts("");
  98 +
  99 + found = treeInsert(&root, (void *)&new80, insertCompare);
  100 + printf("insert %p(%d) got %p(%d)\n", &new80, new80, found, *found);
  101 + found = treeInsert(&root, (void *)&new50, insertCompare);
  102 + printf("insert %p(%d) got %p(%d)\n", &new50, new50, found, *found);
  103 + found = treeInsert(&root, (void *)&new80, insertCompare);
  104 + printf("insert %p(%d) got %p(%d)\n", &new80, new80, found, *found);
  105 +
  106 + puts("traverse");
  107 + treeWalk(root, printNode);
  108 + puts("");
  109 +
  110 + found = treeDelete(&root, (void *)&new80, insertCompare);
  111 + printf("delete %p(%d) got %p(%d)\n", &new80, new80, found, *found);
  112 + puts("traverse");
  113 + treeWalk(root, printNode);
  114 + puts("");
  115 +
  116 + found = treeDelete(&root, (void *)&new50, insertCompare);
  117 + printf("delete %p(%d) got %p(%d)\n", &new50, new50, found, *found);
  118 + puts("traverse");
  119 + treeWalk(root, printNode);
  120 + puts("");
  121 +
  122 + found = treeDelete(&root, (void *)&new70, insertCompare);
  123 + printf("delete %p(%d) got %p(%d)\n", &new70, new70, found, found?*found:-1);
  124 + puts("traverse");
  125 + treeWalk(root, printNode);
  126 + puts("");
  127 +
  128 + found = treeDelete(&root, (void *)&(values[2]), insertCompare);
  129 + printf("delete %p(%d) got %p(%d)\n",
  130 + &(values[2]),
  131 + values[2],
  132 + found,
  133 + found?*found:-1);
  134 + puts("traverse");
  135 + treeWalk(root, printNode);
  136 + puts("");
  137 +
  138 +//
  139 +// post(root, cleanup);
  140 +
  141 + return 0;
  142 +}
  143 +
  144 +// vim: set et ts=4 sw=4:
... ...
... ... @@ -43,7 +43,11 @@ serverRun(Server this)
43 43 {
44 44 unsigned int i;
45 45
46   - if (0 == events) {
  46 + if (0 <= events) {
  47 + /*
  48 + * TODO check why sometimes events is less than 0
  49 + * There is still a misshandling here.
  50 + */
47 51 events = serverPoll(this);
48 52 }
49 53
... ...
  1 +ACLOCAL_AMFLAGS = -I m4
  2 +
  3 +TREE = tree.c find.c insert.c inOrderSuccessor.c delete.c walk.c \
  4 + rotateLeft.c rotateRight.c destroy.c
  5 +
  6 +noinst_LIBRARIES = libtree.a
  7 +
  8 +libtree_a_SOURCES = $(TREE)
  9 +libtree_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +Tree inOrderSuccessor(Tree);
  26 +void treeRotateLeft(Tree *, Tree);
  27 +void treeRotateRight(Tree *, Tree);
  28 +
  29 +
  30 +void *
  31 +treeDelete(Tree * this, const void * search, TreeComp comp)
  32 +{
  33 + Tree node = *this;
  34 +
  35 + void * data;
  36 +
  37 + /*
  38 + * first search for it and if its found return the data
  39 + * and we are done...
  40 + */
  41 + while (NULL != node) {
  42 + int comparison = comp(node->data, search);
  43 +
  44 + if (0 < comparison) {
  45 + node = TREE_LEFT(node);
  46 + continue;
  47 + }
  48 +
  49 + if (0 > comparison) {
  50 + node = TREE_RIGHT(node);
  51 + continue;
  52 + }
  53 +
  54 + if (0 == comparison) {
  55 + break;
  56 + }
  57 + }
  58 +
  59 + /*
  60 + * nothing was found...return NULL to indicate this.
  61 + */
  62 + if (NULL == node) {
  63 + return NULL;
  64 + }
  65 +
  66 + /*
  67 + * we found an element, store its data pointer as we are
  68 + * up to delete it.
  69 + */
  70 + data = node->data;
  71 +
  72 + /*
  73 + * now remove the element.
  74 + */
  75 +
  76 + /*
  77 + * if we have two children replace data with the one from
  78 + * out inOrderSuccessor and remove the inOrderSuccessor.
  79 + */
  80 + if (NULL != TREE_LEFT(node) && NULL != TREE_RIGHT(node)) {
  81 + Tree successor = inOrderSuccessor(node);
  82 +
  83 + node->data = successor->data;
  84 + node = successor;
  85 + }
  86 +
  87 + {
  88 + Tree child = TREE_CHILD(node);
  89 +
  90 + /*
  91 + * if we still have one child replace ourself with it.
  92 + */
  93 + TREE_REPLACE_NODE(this, node, child);
  94 +
  95 + /*
  96 + * and finally delete the node...and prepare ourselfs
  97 + * for rebalancing.
  98 + */
  99 + if (rbBlack == node->color) {
  100 + if (NULL != child && rbRed == child->color) {
  101 + child->color = rbBlack;
  102 + delete(node);
  103 + return data;
  104 + } else {
  105 + if (NULL != child) {
  106 + node = child;
  107 + } else {
  108 + node->color = rbBlack;
  109 + node->left = NULL;
  110 + node->right = NULL;
  111 + }
  112 + }
  113 + } else {
  114 + delete(node);
  115 + return data;
  116 + }
  117 + }
  118 +
  119 + /*
  120 + * now comes rebalancing...note that if we came to this point
  121 + * the node is still not deleted.
  122 + * This is because I am not sure if it is needed during the
  123 + * rebalancing process...(this does not make much sense, but
  124 + * to be honest I don't know now.)
  125 + */
  126 + while(1) {
  127 + // case 1
  128 + if (NULL == TREE_PARENT(node)) {
  129 + break;
  130 + }
  131 +
  132 + // case 2
  133 + if (NULL != TREE_SIBLING(node)
  134 + && rbRed == TREE_SIBLING(node)->color) {
  135 +
  136 + TREE_PARENT(node)->color = rbRed;
  137 + TREE_SIBLING(node)->color = rbBlack;
  138 +
  139 + if (NULL != TREE_PARENT(node)->right &&
  140 + node != TREE_PARENT(node)->right) {
  141 +
  142 + //TREE_ROTATE_LEFT(this, TREE_PARENT(node));
  143 + treeRotateLeft(this, TREE_PARENT(node));
  144 +
  145 + } else {
  146 +
  147 + //TREE_ROTATE_RIGHT(this, TREE_PARENT(node));
  148 + treeRotateRight(this, TREE_PARENT(node));
  149 +
  150 + }
  151 + }
  152 +
  153 + // case 3 / 4
  154 + if (NULL == TREE_SIBLING(node)
  155 + || (rbBlack == TREE_SIBLING(node)->color
  156 + && (NULL == TREE_SIBLING(node)->left
  157 + || rbBlack == TREE_SIBLING(node)->left->color)
  158 + && (NULL == TREE_SIBLING(node)->right
  159 + || rbBlack == TREE_SIBLING(node)->right->color))) {
  160 +
  161 + if (NULL != TREE_SIBLING(node)) {
  162 + TREE_SIBLING(node)->color = rbRed;
  163 + }
  164 +
  165 +
  166 + /*
  167 + * this is the point where during the balancing our tree
  168 + * node can be finally deleted.
  169 + */
  170 + if (rbBlack == TREE_PARENT(node)->color) {
  171 + // case 3
  172 + Tree parent = node->parent;
  173 + delete(node);
  174 + node = parent;
  175 + continue;
  176 + } else {
  177 + // case 4
  178 + TREE_PARENT(node)->color = rbBlack;
  179 + delete(node);
  180 + break;
  181 + }
  182 + }
  183 +
  184 + // case 5
  185 + if (NULL != TREE_SIBLING(node)
  186 + && rbBlack == TREE_SIBLING(node)->color) {
  187 +
  188 + if (node == TREE_PARENT(node)->left
  189 + && (NULL == TREE_SIBLING(node)->right
  190 + || rbBlack == TREE_SIBLING(node)->right->color)
  191 + && (NULL != TREE_SIBLING(node)->left
  192 + && rbRed == TREE_SIBLING(node)->left->color)) {
  193 +
  194 + TREE_SIBLING(node)->color = rbRed;
  195 + TREE_SIBLING(node)->left->color = rbBlack;
  196 +
  197 + //TREE_ROTATE_RIGHT(this, TREE_SIBLING(node));
  198 + treeRotateRight(this, TREE_SIBLING(node));
  199 +
  200 + } else if (node == TREE_PARENT(node)->right
  201 + && (NULL == TREE_SIBLING(node)->left
  202 + || rbBlack == TREE_SIBLING(node)->left->color)
  203 + && (NULL != TREE_SIBLING(node)->right
  204 + && rbRed == TREE_SIBLING(node)->right->color)) {
  205 +
  206 + TREE_SIBLING(node)->color = rbRed;
  207 + TREE_SIBLING(node)->right->color = rbBlack;
  208 +
  209 + //TREE_ROTATE_LEFT(this, TREE_SIBLING(node));
  210 + treeRotateLeft(this, TREE_SIBLING(node));
  211 + }
  212 + }
  213 +
  214 + // case 6
  215 + if (NULL != TREE_SIBLING(node)) {
  216 + TREE_SIBLING(node)->color = TREE_PARENT(node)->color;
  217 + }
  218 +
  219 + if (NULL != node && NULL != TREE_PARENT(node)) {
  220 + TREE_PARENT(node)->color = rbBlack;
  221 +
  222 + if (NULL != TREE_PARENT(node)->right
  223 + && node != TREE_PARENT(node)->right) {
  224 +
  225 + if (NULL != TREE_SIBLING(node)->right) {
  226 + TREE_SIBLING(node)->right->color = rbBlack;
  227 + }
  228 + //TREE_ROTATE_LEFT(this, TREE_PARENT(node));
  229 + treeRotateLeft(this, TREE_PARENT(node));
  230 + } else {
  231 + if (NULL != TREE_SIBLING(node)->left) {
  232 + TREE_SIBLING(node)->left->color = rbBlack;
  233 + }
  234 + //TREE_ROTATE_RIGHT(this, TREE_PARENT(node));
  235 + treeRotateRight(this, TREE_PARENT(node));
  236 + }
  237 + }
  238 +
  239 + break;
  240 + }
  241 +
  242 + /*
  243 + * not sure if deleting here is correct.
  244 + */
  245 + return data;
  246 +}
  247 +
  248 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void
  26 +treeDestroy(Tree * this, TreeAction action)
  27 +{
  28 + Tree previous = * this;
  29 + Tree node = * this;
  30 + int depth = 1;
  31 +
  32 + /*
  33 + * I think this has something like O(n+log(n)) on a ballanced
  34 + * tree because I have to traverse back the rightmost leaf to
  35 + * the root to get a break condition.
  36 + */
  37 + while (NULL != node) {
  38 + /*
  39 + * If we come from the right so nothing and go to our
  40 + * next parent.
  41 + */
  42 + if ((NULL == TREE_LEFT(node) && NULL == TREE_RIGHT(node))
  43 + || previous == TREE_RIGHT(node)) {
  44 +
  45 + Tree parent = TREE_PARENT(node);
  46 +
  47 + action(node->data, depth);
  48 +
  49 + previous = node;
  50 + delete(node);
  51 + node = parent;
  52 + depth--;
  53 +
  54 + continue;
  55 + }
  56 +
  57 + if ((NULL == TREE_LEFT(node) || previous == TREE_LEFT(node))) {
  58 + /*
  59 + * If there are no more elements to the left or we
  60 + * came from the left, process data.
  61 + */
  62 + previous = node;
  63 +
  64 + if (NULL != TREE_RIGHT(node)) {
  65 + node = TREE_RIGHT(node);
  66 + depth++;
  67 + } else {
  68 + node = TREE_PARENT(node);
  69 + depth--;
  70 + }
  71 + } else {
  72 + /*
  73 + * if there are more elements to the left go there.
  74 + */
  75 + previous = node;
  76 + node = TREE_LEFT(node);
  77 + depth++;
  78 + }
  79 + }
  80 +
  81 + *this = NULL;
  82 +}
  83 +
  84 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void *
  26 +treeFind(Tree this, const void * search, TreeComp comp)
  27 +{
  28 + while (NULL != this) {
  29 + int comparison = comp(this->data, search);
  30 +
  31 + if (0 < comparison) {
  32 + this = TREE_LEFT(this);
  33 + continue;
  34 + }
  35 +
  36 + if (0 > comparison) {
  37 + this = TREE_RIGHT(this);
  38 + continue;
  39 + }
  40 +
  41 + if (0 == comparison) {
  42 + break;
  43 + }
  44 + }
  45 +
  46 + return NULL != this ? this->data : NULL;
  47 +}
  48 +
  49 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +Tree
  26 +inOrderSuccessor(Tree this)
  27 +{
  28 + this = TREE_RIGHT(this);
  29 +
  30 + while (NULL != TREE_LEFT(this)) {
  31 + this = TREE_LEFT(this);
  32 + }
  33 +
  34 + return this;
  35 +}
  36 +
  37 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void treeRotateLeft(Tree *, Tree);
  26 +void treeRotateRight(Tree *, Tree);
  27 +
  28 +void *
  29 +treeInsert(Tree * this, const void * search, TreeComp comp)
  30 +{
  31 + Tree node = *this;
  32 + Tree new_node = NULL;
  33 +
  34 + /*
  35 + * insert the node or return the one in tree if comparison
  36 + * succeeds.
  37 + */
  38 + if (NULL == node) {
  39 + /*
  40 + * if the root is NULL we simple add the element and set
  41 + * node to it.
  42 + */
  43 + *this = node = new_node = new(Tree, search);
  44 + } else {
  45 + /*
  46 + * first search for it and if its found return the data
  47 + * and we are done...
  48 + */
  49 + int comparison;
  50 +
  51 + while (NULL != node) {
  52 + comparison = comp(node->data, search);
  53 +
  54 + if (0 < comparison) {
  55 + if (NULL != TREE_LEFT(node)) {
  56 + node = TREE_LEFT(node);
  57 + continue;
  58 + } else {
  59 + break;
  60 + }
  61 + }
  62 +
  63 + if (0 > comparison) {
  64 + if (NULL != TREE_RIGHT(node)) {
  65 + node = TREE_RIGHT(node);
  66 + continue;
  67 + } else {
  68 + break;
  69 + }
  70 + }
  71 +
  72 + if (0 == comparison) {
  73 + return node->data;
  74 + }
  75 + }
  76 +
  77 + /*
  78 + * as we have not found it now add a new element.
  79 + */
  80 + if (0 < comparison) {
  81 + node->left = new(Tree, search);
  82 + TREE_LEFT(node)->parent = node;
  83 + node = new_node = TREE_LEFT(node);
  84 + } else {
  85 + node->right = new(Tree, search);
  86 + TREE_RIGHT(node)->parent = node;
  87 + node = new_node = TREE_RIGHT(node);
  88 + }
  89 + }
  90 +
  91 + /*
  92 + * we expect node not to be NULL and pointing to our
  93 + * new node at this point...now rabalance the tree
  94 + */
  95 + while (1) {
  96 + // case 1
  97 + if (NULL == TREE_PARENT(node)) {
  98 + node->color = rbBlack;
  99 + break;
  100 + }
  101 +
  102 + // case 2
  103 + if (rbBlack == TREE_PARENT(node)->color) {
  104 + break;
  105 + }
  106 +
  107 + // case 3
  108 + if (NULL != TREE_UNCLE(node) && rbRed == TREE_UNCLE(node)->color) {
  109 + TREE_PARENT(node)->color = rbBlack;
  110 + TREE_UNCLE(node)->color = rbBlack;
  111 + TREE_GRANDPARENT(node)->color = rbRed;
  112 +
  113 + node = TREE_GRANDPARENT(node);
  114 + continue;
  115 + }
  116 +
  117 + // case 4
  118 + if (node == TREE_PARENT(node)->right
  119 + && TREE_PARENT(node) == TREE_GRANDPARENT(node)->left) {
  120 +
  121 + //TREE_ROTATE_LEFT(this, TREE_PARENT(node));
  122 + treeRotateLeft(this, TREE_PARENT(node));
  123 + node = TREE_LEFT(node);
  124 +
  125 + } else if (node == TREE_PARENT(node)->left
  126 + && TREE_PARENT(node) == TREE_GRANDPARENT(node)->right) {
  127 +
  128 + //TREE_ROTATE_RIGHT(this, TREE_PARENT(node));
  129 + treeRotateRight(this, TREE_PARENT(node));
  130 + node = TREE_RIGHT(node);
  131 +
  132 + }
  133 +
  134 + // case 5
  135 + TREE_PARENT(node)->color = rbBlack;
  136 + TREE_GRANDPARENT(node)->color = rbRed;
  137 +
  138 + if (node == TREE_PARENT(node)->left) {
  139 + //TREE_ROTATE_RIGHT(this, TREE_GRANDPARENT(node));
  140 + treeRotateRight(this, TREE_GRANDPARENT(node));
  141 + } else {
  142 + //TREE_ROTATE_LEFT(this, TREE_GRANDPARENT(node));
  143 + treeRotateLeft(this, TREE_GRANDPARENT(node));
  144 + }
  145 +
  146 + break;
  147 + }
  148 +
  149 + return new_node->data;
  150 +}
  151 +
  152 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void
  26 +treeRotateLeft(Tree * this, Tree node)
  27 +{
  28 + Tree rightChild = TREE_RIGHT(node);
  29 + Tree rcLeftSub = TREE_RIGHT_LEFT(node);
  30 +
  31 + rightChild->left = node;
  32 + rightChild->parent = TREE_PARENT(node);
  33 + node->right = rcLeftSub;
  34 + if (NULL != rcLeftSub) {
  35 + rcLeftSub->parent = node;
  36 + }
  37 +
  38 + if (NULL != TREE_PARENT(node)) {
  39 + if (TREE_PARENT(node)->left == node) {
  40 + TREE_PARENT(node)->left = rightChild;
  41 + } else {
  42 + TREE_PARENT(node)->right = rightChild;
  43 + }
  44 + } else {
  45 + *this = rightChild;
  46 + }
  47 +
  48 + node->parent = rightChild;
  49 +}
  50 +
  51 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void
  26 +treeRotateRight(Tree * this, Tree node)
  27 +{
  28 + Tree leftChild = TREE_LEFT(node);
  29 + Tree lcRightSub = TREE_LEFT_RIGHT(node);
  30 +
  31 + leftChild->right = node;
  32 + leftChild->parent = TREE_PARENT(node);
  33 + node->left = lcRightSub;
  34 + if (NULL != lcRightSub) {
  35 + lcRightSub->parent = node;
  36 + }
  37 +
  38 + if (NULL != TREE_PARENT(node)) {
  39 + if (TREE_PARENT(node)->left == node) {
  40 + TREE_PARENT(node)->left = leftChild;
  41 + } else {
  42 + TREE_PARENT(node)->right = leftChild;
  43 + }
  44 + } else {
  45 + *this = leftChild;
  46 + }
  47 +
  48 + node->parent = leftChild;
  49 +}
  50 +
  51 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 "tree.h"
  28 +#include "class.h"
  29 +
  30 +static
  31 +int
  32 +treeCtor(void * _this, va_list * params)
  33 +{
  34 + Tree 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
  46 +void
  47 +treeDtor(void * _this)
  48 +{
  49 +}
  50 +
  51 +INIT_IFACE(Class, treeCtor, treeDtor, NULL);
  52 +CREATE_CLASS(Tree, NULL, IFACE(Class));
  53 +
  54 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 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 +#include "tree.h"
  24 +
  25 +void
  26 +treeWalk(Tree this, TreeAction action)
  27 +{
  28 + Tree previous = this;
  29 + Tree node = this;
  30 + int depth = 1;
  31 +
  32 + while (NULL != node) {
  33 + if (previous == TREE_RIGHT(node)) {
  34 + previous = node;
  35 + node = node->parent;
  36 + depth--;
  37 + continue;
  38 + }
  39 +
  40 + if (NULL == TREE_LEFT(node) || previous == TREE_LEFT(node)) {
  41 + action(node->data, depth);
  42 + previous = node;
  43 +
  44 + if (NULL != TREE_RIGHT(node)) {
  45 + node = TREE_RIGHT(node);
  46 + depth++;
  47 + } else {
  48 + node = TREE_PARENT(node);
  49 + depth--;
  50 + }
  51 + } else {
  52 + previous = node;
  53 + node = TREE_LEFT(node);
  54 + depth++;
  55 + }
  56 + }
  57 +}
  58 +
  59 +// vim: set ts=4 sw=4:
... ...
... ... @@ -54,14 +54,12 @@
54 54 #include <unistd.h>
55 55
56 56 #include "utils/memory.h"
  57 +#include "tree.h"
57 58
58 59
59 60 #define PAGE_SIZE = 32
60 61
61 62
62   -enum rbColor {rbBlack=1, rbRed=2};
63   -
64   -
65 63 struct memSegment
66 64 {
67 65 size_t size;
... ... @@ -394,8 +392,6 @@ findInOrderSuccessor(struct memSegment * tree)
394 392 return node;
395 393 }
396 394
397   -struct memSegment * deleteOneChild(struct memSegment **, struct memSegment *);
398   -
399 395 struct memSegment *
400 396 deleteElement(struct memSegment ** tree, struct memSegment * element)
401 397 {
... ... @@ -619,8 +615,6 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
619 615 break;
620 616 }
621 617
622   - //deleteOneChild(tree, node);
623   -
624 618 return del_node;
625 619 }
626 620
... ...
Please register or login to post a comment