t_c_rb.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
  2. * This file is part of clib library
  3. * Copyright (C) 2011 Avinash Dongre ( dongre.avinash@gmail.com )
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
  23. #include "c_lib.h"
  24. /*#include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <assert.h>
  28. #define BLACK 0
  29. #define RED 1
  30. #define rb_sentinel &tree->sentinel
  31. static void*
  32. get_key ( struct clib_rb* tree, struct clib_rb_node* node) {
  33. if ( node )
  34. return node->raw_data.key;
  35. return (void*)0;
  36. }
  37. static struct clib_rb_node*
  38. get_left (struct clib_rb* tree, struct clib_rb_node* node ) {
  39. if ( node->left != rb_sentinel && node->left != (struct clib_rb_node*)0 )
  40. return node->left;
  41. return (struct clib_rb_node*)0 ;
  42. }
  43. static struct clib_rb_node*
  44. get_right (struct clib_rb* tree, struct clib_rb_node* node ){
  45. if ( node->right != rb_sentinel && node->right != (struct clib_rb_node*)0 )
  46. return node->right;
  47. return (struct clib_rb_node*)0 ;
  48. }
  49. static struct clib_rb_node*
  50. get_parent ( struct clib_rb* tree,struct clib_rb_node* node ) {
  51. if ( node->parent != rb_sentinel && node->parent != (struct clib_rb_node*)0 )
  52. return node->parent;
  53. return (struct clib_rb_node*)0 ;
  54. }
  55. int
  56. compare_rb_e ( void* l, void* r ) {
  57. int left = 0;
  58. int right = 0;
  59. if ( l ) left = *(int*)l;
  60. if ( r ) right = *(int*)r;
  61. if ( left < right ) return -1;
  62. if ( left == right ) return 0;
  63. return 1;
  64. }
  65. void
  66. free_rb_e ( void* p ) {
  67. if ( p ) {
  68. free ( p );
  69. }
  70. }
  71. typedef struct test_data_tree {
  72. int element;
  73. int left;
  74. int right;
  75. int parent;
  76. int color;
  77. } TS;
  78. static struct clib_rb_node*
  79. pvt_find_clib_rb ( struct clib_rb* tree, clib_compare fn_c, void *key ) {
  80. struct clib_rb_node* node = tree->root;
  81. void* current_key = (void*)0;
  82. int compare_result = 0;
  83. current_key = (void*)malloc ( tree->size_of_key);
  84. memcpy ( current_key, key, tree->size_of_key);
  85. compare_result = (fn_c)(current_key, node->raw_data.key);
  86. while ((node != rb_sentinel) && (compare_result = (fn_c)(current_key, node->raw_data.key)) != 0 ){
  87. if ( compare_result < 0 ) {
  88. node = node->left;
  89. } else {
  90. node = node->right;
  91. }
  92. }
  93. free ( current_key );
  94. return node;
  95. }
  96. struct clib_rb_node*
  97. find(struct clib_rb* tree, void *key ) {
  98. return pvt_find_clib_rb ( tree, tree->compare_fn, key );
  99. }
  100. static void update_values ( void* v, int *l, int *r, int *p , int *e, struct clib_rb* tree ) {
  101. struct clib_rb_node *x;
  102. if ( get_key(tree,v))
  103. *e = *(int*)get_key (tree,v);
  104. x = get_left(tree,v);
  105. if ( x )
  106. *l = *(int*)get_key(tree,x);
  107. x = get_right(tree,v);
  108. if (x)
  109. *r = *(int*)get_key(tree,x);
  110. x = get_parent ( tree, v );
  111. if (x)
  112. *p = *(int*)get_key(tree,x);
  113. }
  114. static void
  115. test_each_elements(int l,int r, int p, int e,void* v, TS ts[], int i,
  116. struct clib_rb* tree) {
  117. assert ( ts[i].element == e);
  118. if (ts[i].left != 0 )
  119. assert ( ts[i].left == l);
  120. else
  121. assert ((void* )0 == (void* )get_key(tree,get_left(tree,v)));
  122. if ( ts[i].right != 0 )
  123. assert (ts[i].right == r);
  124. else
  125. assert ((void* )0 == (void* )get_key(tree,get_right(tree,v)));
  126. if (ts[i].parent != 0 )
  127. assert (ts[i].parent == p);
  128. else
  129. assert ((void* )0 == (void* )get_key(tree,get_parent(tree,v)));
  130. }
  131. static void
  132. test_all_elements(struct clib_rb* tree, TS ts[], int size) {
  133. int i = 0;
  134. for ( i = 0; i < size; i++) {
  135. void* v = (void*)0;
  136. int l,r,p,e;
  137. v = find ( tree, &ts[i].element);
  138. update_values( v, &l,&r,&p,&e, tree);
  139. test_each_elements(l,r,p,e,v, ts, i, tree);
  140. }
  141. }
  142. static struct clib_rb*
  143. create_tree(TS ts[], int size) {
  144. int i = 0;
  145. struct clib_rb* tree = new_clib_rb( compare_rb_e,free_rb_e, (void*)0, sizeof(int),0);
  146. for ( i = 0; i < size; i++) {
  147. insert_clib_rb( tree, &(ts[i].element) ,(void*)0);
  148. }
  149. return tree;
  150. }
  151. void
  152. test_clib_rb() {
  153. int size;
  154. int size_after_delete;
  155. int i = 0;
  156. struct clib_rb* tree;
  157. struct clib_rb_node* node;
  158. TS ts[] = {
  159. {15,6,18,0,BLACK},{6,3,9,15,RED},{18,17,20,15,BLACK},
  160. {3,2,4,6,BLACK},{7,0,0,9,RED},{17,0,0,18,RED},
  161. {20,0,0,18,RED},{2,0,0,3,RED},{4,0,0,3,RED},{13,0,0,9,RED},
  162. {9,7,13,6,BLACK}
  163. };
  164. TS ts_delete_leaf_13[] = {
  165. {15,6,18,0,BLACK},{6,3,9,15,RED},{18,17,20,15,BLACK},
  166. {3,2,4,6,BLACK},{7,0,0,9,RED},{17,0,0,18,RED},
  167. {20,0,0,18,RED},{2,0,0,3,RED},{4,0,0,3,RED},
  168. {9,7,0,6,BLACK}
  169. };
  170. TS ts_delete_9[] = {
  171. {15,6,18,0,BLACK},{6,3,7,15,RED},{18,17,20,15,BLACK},
  172. {3,2,4,6,RED},{7,0,0,6,RED},{17,0,0,18,RED},
  173. {20,0,0,18,RED},{2,0,0,3,RED},{4,0,0,3,RED}
  174. };
  175. TS ts_delete_15[] = {
  176. {6,3,7,17,RED},{18,0,20,17,BLACK},
  177. {3,2,4,6,RED},{7,0,0,6,RED},{17,6,18,0,RED},
  178. {20,0,0,18,RED},{2,0,0,3,RED},{4,0,0,3,RED}
  179. };
  180. TS ts_insert_1[] = {
  181. {6,3,17,0,BLACK},{18,0,20,17,BLACK},
  182. {3,2,4,6,RED},{7,0,0,17,RED},{17,7,18,6,RED},
  183. {20,0,0,18,RED},{2,1,0,3,BLACK},{4,0,0,3,BLACK},
  184. {1,0,0,2,RED}
  185. };
  186. size = (sizeof(ts)/sizeof(TS));
  187. tree = create_tree(ts,size);
  188. test_all_elements(tree, ts, size);
  189. {
  190. i = 13;
  191. size = (sizeof(ts)/sizeof(TS));
  192. size_after_delete = (sizeof(ts_delete_leaf_13)/sizeof(TS));
  193. node = remove_clib_rb( tree, &i);
  194. if ( node != (struct clib_rb_node*)0 ) {
  195. free ( node->raw_data.key);
  196. free ( node);
  197. }
  198. test_all_elements(tree, ts_delete_leaf_13, size_after_delete);
  199. }
  200. {
  201. i = 9;
  202. size_after_delete = (sizeof(ts_delete_9)/sizeof(TS));
  203. node = remove_clib_rb( tree, &i);
  204. if ( node != (struct clib_rb_node*)0 ) {
  205. free ( node->raw_data.key);
  206. free ( node);
  207. }
  208. test_all_elements(tree, ts_delete_9, size_after_delete);
  209. }
  210. {
  211. i = 15;
  212. size_after_delete = (sizeof(ts_delete_15)/sizeof(TS));
  213. node = remove_clib_rb( tree, &i);
  214. if ( node != (struct clib_rb_node*)0 ) {
  215. free ( node->raw_data.key);
  216. free ( node);
  217. }
  218. test_all_elements(tree, ts_delete_15, size_after_delete);
  219. }
  220. {
  221. int i = 1;
  222. insert_clib_rb( tree, &i, (void*)0);
  223. size_after_delete = (sizeof(ts_insert_1)/sizeof(TS));
  224. test_all_elements(tree, ts_insert_1, size_after_delete);
  225. }
  226. {
  227. delete_clib_rb(tree);
  228. }
  229. }*/