c_rb.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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 <string.h>
  26. #include <assert.h>
  27. #define rb_sentinel &pTree->sentinel
  28. static void debug_verify_properties(struct clib_rb*);
  29. static void debug_verify_property_1(struct clib_rb*,struct clib_rb_node*);
  30. static void debug_verify_property_2(struct clib_rb*,struct clib_rb_node*);
  31. static int debug_node_color(struct clib_rb*,struct clib_rb_node* n);
  32. static void debug_verify_property_4(struct clib_rb*,struct clib_rb_node*);
  33. static void debug_verify_property_5(struct clib_rb*,struct clib_rb_node*);
  34. static void debug_verify_property_5_helper(struct clib_rb*,struct clib_rb_node*,int,int*);
  35. static void
  36. pvt_left_rotate(struct clib_rb *pTree, struct clib_rb_node *x){
  37. struct clib_rb_node *y;
  38. y = x->right;
  39. x->right = y->left;
  40. if (y->left != rb_sentinel)
  41. y->left->parent = x;
  42. if (y != rb_sentinel)
  43. y->parent = x->parent;
  44. if (x->parent){
  45. if (x == x->parent->left)
  46. x->parent->left = y;
  47. else
  48. x->parent->right = y;
  49. }
  50. else
  51. pTree->root = y;
  52. y->left = x;
  53. if (x != rb_sentinel)
  54. x->parent = y;
  55. }
  56. static void
  57. pvt_right_rotate(struct clib_rb *pTree, struct clib_rb_node *x) {
  58. struct clib_rb_node *y = x->left;
  59. x->left = y->right;
  60. if (y->right != rb_sentinel)
  61. y->right->parent = x;
  62. if (y != rb_sentinel)
  63. y->parent = x->parent;
  64. if (x->parent) {
  65. if (x == x->parent->right)
  66. x->parent->right = y;
  67. else
  68. x->parent->left = y;
  69. }
  70. else
  71. pTree->root = y;
  72. y->right = x;
  73. if (x != rb_sentinel)
  74. x->parent = y;
  75. }
  76. struct clib_rb*
  77. new_clib_rb(clib_compare fn_c,clib_destroy fn_ed, clib_destroy fn_vd ){
  78. struct clib_rb *pTree = (struct clib_rb*)malloc(sizeof(struct clib_rb));
  79. if ( pTree == (struct clib_rb*)0 )
  80. return (struct clib_rb*)0;
  81. pTree->compare_fn = fn_c;
  82. pTree->destruct_k_fn = fn_ed;
  83. pTree->destruct_v_fn = fn_vd;
  84. pTree->root = rb_sentinel;
  85. pTree->sentinel.left = rb_sentinel;
  86. pTree->sentinel.right = rb_sentinel;
  87. pTree->sentinel.parent = (struct clib_rb_node*)0 ;
  88. pTree->sentinel.color = clib_black;
  89. return pTree;
  90. }
  91. static void
  92. pvt_rb_insert_fixup( struct clib_rb *pTree, struct clib_rb_node *x ) {
  93. while (x != pTree->root && x->parent->color == clib_red) {
  94. if (x->parent == x->parent->parent->left) {
  95. struct clib_rb_node *y = x->parent->parent->right;
  96. if (y->color == clib_red) {
  97. x->parent->color = clib_black;
  98. y->color = clib_black;
  99. x->parent->parent->color = clib_red;
  100. x = x->parent->parent;
  101. } else {
  102. if (x == x->parent->right){
  103. x = x->parent;
  104. pvt_left_rotate (pTree, x);
  105. }
  106. x->parent->color = clib_black;
  107. x->parent->parent->color = clib_red;
  108. pvt_right_rotate (pTree, x->parent->parent);
  109. }
  110. } else {
  111. struct clib_rb_node *y = x->parent->parent->left;
  112. if (y->color == clib_red) {
  113. x->parent->color = clib_black;
  114. y->color = clib_black;
  115. x->parent->parent->color = clib_red;
  116. x = x->parent->parent;
  117. } else {
  118. if (x == x->parent->left) {
  119. x = x->parent;
  120. pvt_right_rotate (pTree, x);
  121. }
  122. x->parent->color = clib_black;
  123. x->parent->parent->color = clib_red;
  124. pvt_left_rotate (pTree, x->parent->parent);
  125. }
  126. }
  127. }
  128. pTree->root->color = clib_black;
  129. }
  130. struct clib_rb_node*
  131. find_clib_rb (struct clib_rb *pTree, void *key) {
  132. struct clib_rb_node *x = pTree->root;
  133. while (x != rb_sentinel) {
  134. int c = 0;
  135. void *cur_key ;
  136. get_raw_clib_object ( x->key, &cur_key );
  137. c = pTree->compare_fn (key, cur_key);
  138. free ( cur_key );
  139. if (c == 0) {
  140. break;
  141. } else {
  142. x = c < 0 ? x->left : x->right;
  143. }
  144. }
  145. if ( x == rb_sentinel )
  146. return (struct clib_rb_node*)0 ;
  147. return x;
  148. }
  149. clib_error
  150. insert_clib_rb(struct clib_rb *pTree, void *k, size_t key_size, void *v, size_t value_size) {
  151. clib_error rc = CLIB_ERROR_SUCCESS;
  152. struct clib_rb_node *x;
  153. struct clib_rb_node *y;
  154. struct clib_rb_node *z;
  155. x = (struct clib_rb_node*)malloc (sizeof(struct clib_rb_node));
  156. if ( x == (struct clib_rb_node*)0 )
  157. return CLIB_ERROR_MEMORY;
  158. x->left = rb_sentinel;
  159. x->right = rb_sentinel;
  160. x->color = clib_red;
  161. x->key = new_clib_object ( k, key_size );
  162. if ( v ) {
  163. x->value = new_clib_object ( v, value_size );
  164. } else {
  165. x->value = (struct clib_object*)0;
  166. }
  167. y = pTree->root;
  168. z = (struct clib_rb_node*)0 ;
  169. while (y != rb_sentinel) {
  170. int c = 0;
  171. void *cur_key;
  172. void* new_key;
  173. get_raw_clib_object ( y->key, &cur_key );
  174. get_raw_clib_object ( x->key, &new_key );
  175. c = (pTree->compare_fn) ( new_key , cur_key);
  176. free ( cur_key );
  177. free ( new_key );
  178. if (c == 0) {
  179. /* TODO : Delete node here */
  180. return CLIB_RBTREE_KEY_DUPLICATE;
  181. }
  182. z = y;
  183. if ( c < 0 )
  184. y = y->left;
  185. else
  186. y = y->right;
  187. }
  188. x->parent = z;
  189. if (z) {
  190. int c = 0;
  191. void *cur_key;
  192. void* new_key;
  193. get_raw_clib_object ( z->key, &cur_key );
  194. get_raw_clib_object ( x->key, &new_key );
  195. c = pTree->compare_fn( new_key, cur_key);
  196. free ( cur_key );
  197. free ( new_key );
  198. if (c < 0) {
  199. z->left = x;
  200. } else {
  201. z->right = x;
  202. }
  203. }
  204. else
  205. pTree->root = x;
  206. pvt_rb_insert_fixup (pTree, x);
  207. debug_verify_properties ( pTree);
  208. return rc;
  209. }
  210. static void
  211. pvt_rb_remove_fixup( struct clib_rb *pTree, struct clib_rb_node *x ) {
  212. while (x != pTree->root && x->color == clib_black) {
  213. if (x == x->parent->left) {
  214. struct clib_rb_node *w = x->parent->right;
  215. if (w->color == clib_red) {
  216. w->color = clib_black;
  217. x->parent->color = clib_red;
  218. pvt_left_rotate (pTree, x->parent);
  219. w = x->parent->right;
  220. }
  221. if (w->left->color == clib_black && w->right->color == clib_black) {
  222. w->color = clib_red;
  223. x = x->parent;
  224. } else {
  225. if (w->right->color == clib_black) {
  226. w->left->color = clib_black;
  227. w->color = clib_red;
  228. pvt_right_rotate (pTree, w);
  229. w = x->parent->right;
  230. }
  231. w->color = x->parent->color;
  232. x->parent->color = clib_black;
  233. w->right->color = clib_black;
  234. pvt_left_rotate (pTree, x->parent);
  235. x = pTree->root;
  236. }
  237. } else {
  238. struct clib_rb_node *w = x->parent->left;
  239. if (w->color == clib_red) {
  240. w->color = clib_black;
  241. x->parent->color = clib_red;
  242. pvt_right_rotate (pTree, x->parent);
  243. w = x->parent->left;
  244. }
  245. if (w->right->color == clib_black && w->left->color == clib_black) {
  246. w->color = clib_red;
  247. x = x->parent;
  248. } else {
  249. if (w->left->color == clib_black) {
  250. w->right->color = clib_black;
  251. w->color = clib_red;
  252. pvt_left_rotate (pTree, w);
  253. w = x->parent->left;
  254. }
  255. w->color = x->parent->color;
  256. x->parent->color = clib_black;
  257. w->left->color = clib_black;
  258. pvt_right_rotate (pTree, x->parent);
  259. x = pTree->root;
  260. }
  261. }
  262. }
  263. x->color = clib_black;
  264. }
  265. static struct clib_rb_node*
  266. pvt_remove_clib_rb(struct clib_rb *pTree, struct clib_rb_node *z ) {
  267. struct clib_rb_node *x = (struct clib_rb_node*)0 ;
  268. struct clib_rb_node *y = (struct clib_rb_node*)0 ;
  269. if (z->left == rb_sentinel || z->right == rb_sentinel)
  270. y = z;
  271. else {
  272. y = z->right;
  273. while (y->left != rb_sentinel)
  274. y = y->left;
  275. }
  276. if (y->left != rb_sentinel)
  277. x = y->left;
  278. else
  279. x = y->right;
  280. x->parent = y->parent;
  281. if (y->parent)
  282. {
  283. if (y == y->parent->left)
  284. y->parent->left = x;
  285. else
  286. y->parent->right = x;
  287. }
  288. else
  289. pTree->root = x;
  290. if (y != z) {
  291. struct clib_object* tmp;
  292. tmp = z->key;
  293. z->key = y->key;
  294. y->key = tmp;
  295. tmp = z->value;
  296. z->value = y->value;
  297. y->value = tmp;
  298. }
  299. if (y->color == clib_black)
  300. pvt_rb_remove_fixup (pTree, x);
  301. debug_verify_properties ( pTree);
  302. return y;
  303. }
  304. struct clib_rb_node*
  305. remove_clib_rb (struct clib_rb *pTree, void *key) {
  306. struct clib_rb_node *z = (struct clib_rb_node*)0 ;
  307. z = pTree->root;
  308. while (z != rb_sentinel) {
  309. int c = 0;
  310. void *cur_key;
  311. get_raw_clib_object ( z->key, &cur_key );
  312. c = pTree->compare_fn (key, cur_key);
  313. free ( cur_key );
  314. if ( c == 0) {
  315. break;
  316. }
  317. else {
  318. z = ( c < 0) ? z->left : z->right;
  319. }
  320. }
  321. if (z == rb_sentinel)
  322. return (struct clib_rb_node*)0 ;
  323. return pvt_remove_clib_rb(pTree, z );
  324. }
  325. static void
  326. pvt_delete_clib_rb_node (struct clib_rb *pTree, struct clib_rb_node *x ) {
  327. void *key;
  328. void *value;
  329. if ( pTree->destruct_k_fn ) {
  330. get_raw_clib_object ( x->key, &key );
  331. pTree->destruct_k_fn ( key );
  332. }
  333. delete_clib_object( x->key );
  334. if ( x->value ) {
  335. if ( pTree->destruct_v_fn ) {
  336. get_raw_clib_object ( x->value, &value);
  337. pTree->destruct_v_fn ( value );
  338. }
  339. delete_clib_object( x->value );
  340. }
  341. }
  342. clib_error
  343. delete_clib_rb(struct clib_rb *pTree) {
  344. clib_error rc = CLIB_ERROR_SUCCESS;
  345. struct clib_rb_node *z = pTree->root;
  346. while (z != rb_sentinel) {
  347. if (z->left != rb_sentinel)
  348. z = z->left;
  349. else if (z->right != rb_sentinel)
  350. z = z->right;
  351. else {
  352. pvt_delete_clib_rb_node ( pTree, z );
  353. if (z->parent) {
  354. z = z->parent;
  355. if (z->left != rb_sentinel){
  356. free ( z->left );
  357. z->left = rb_sentinel;
  358. }else if (z->right != rb_sentinel){
  359. free ( z->right );
  360. z->right = rb_sentinel;
  361. }
  362. } else {
  363. free ( z );
  364. z = rb_sentinel;
  365. }
  366. }
  367. }
  368. free ( pTree );
  369. return rc;
  370. }
  371. struct clib_rb_node *
  372. minimum_clib_rb( struct clib_rb *pTree, struct clib_rb_node *x ) {
  373. while ( x->left != rb_sentinel)
  374. x = x->left;
  375. return x;
  376. }
  377. struct clib_rb_node *
  378. maximum_clib_rb( struct clib_rb *pTree, struct clib_rb_node *x ) {
  379. while ( x->right != rb_sentinel)
  380. x = x->right;
  381. return x;
  382. }
  383. clib_bool
  384. empty_clib_rb(struct clib_rb *pTree) {
  385. if ( pTree->root != rb_sentinel )
  386. return clib_true;
  387. return clib_false;
  388. }
  389. struct clib_rb_node*
  390. tree_successor(struct clib_rb *pTree, struct clib_rb_node *x) {
  391. struct clib_rb_node *y = (struct clib_rb_node*)0;
  392. if ( x->right != rb_sentinel)
  393. return minimum_clib_rb( pTree, x->right);
  394. if ( x == maximum_clib_rb(pTree,pTree->root))
  395. return (struct clib_rb_node*)0;
  396. y = x->parent;
  397. while ( y != rb_sentinel && x == y->right ){
  398. x = y;
  399. y = y->parent;
  400. }
  401. return y;
  402. }
  403. void debug_verify_properties(struct clib_rb* t) {
  404. debug_verify_property_1(t,t->root);
  405. debug_verify_property_2(t,t->root);
  406. debug_verify_property_4(t,t->root);
  407. debug_verify_property_5(t,t->root);
  408. }
  409. void debug_verify_property_1(struct clib_rb *pTree,struct clib_rb_node* n) {
  410. assert(debug_node_color(pTree,n) == clib_red || debug_node_color(pTree,n) == clib_black);
  411. if (n == rb_sentinel) return;
  412. debug_verify_property_1(pTree,n->left);
  413. debug_verify_property_1(pTree,n->right);
  414. }
  415. void debug_verify_property_2(struct clib_rb *pTree,struct clib_rb_node* root) {
  416. assert(debug_node_color(pTree,root) == clib_black);
  417. }
  418. int debug_node_color(struct clib_rb *pTree,struct clib_rb_node* n) {
  419. return n == rb_sentinel ? clib_black : n->color;
  420. }
  421. void debug_verify_property_4(struct clib_rb *pTree,struct clib_rb_node* n) {
  422. if (debug_node_color(pTree,n) == clib_red) {
  423. assert (debug_node_color(pTree,n->left) == clib_black);
  424. assert (debug_node_color(pTree,n->right) == clib_black);
  425. assert (debug_node_color(pTree,n->parent) == clib_black);
  426. }
  427. if (n == rb_sentinel) return;
  428. debug_verify_property_4(pTree,n->left);
  429. debug_verify_property_4(pTree,n->right);
  430. }
  431. void debug_verify_property_5(struct clib_rb *pTree,struct clib_rb_node* root) {
  432. int black_count_path = -1;
  433. debug_verify_property_5_helper(pTree,root, 0, &black_count_path);
  434. }
  435. void debug_verify_property_5_helper(struct clib_rb *pTree,struct clib_rb_node* n, int black_count, int* path_black_count) {
  436. if (debug_node_color(pTree,n) == clib_black) {
  437. black_count++;
  438. }
  439. if (n == rb_sentinel) {
  440. if (*path_black_count == -1) {
  441. *path_black_count = black_count;
  442. } else {
  443. assert (black_count == *path_black_count);
  444. }
  445. return;
  446. }
  447. debug_verify_property_5_helper(pTree,n->left, black_count, path_black_count);
  448. debug_verify_property_5_helper(pTree,n->right, black_count, path_black_count);
  449. }