b_tree.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /*!
  2. Temelia - B-tree implementation source file.
  3. Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/b_tree.h"
  18. #include "include/vector.h"
  19. #include <stdlib.h>
  20. /*
  21. * The source file contains, for the most important functions: search, insert
  22. * and delete; the pseudo code is taken from
  23. * http://cs-netlab-01.lynchburg.edu/courses/DataStII/BTreeOps.htm
  24. */
  25. struct _b_tree_t
  26. {
  27. /*! reference to root */
  28. b_tree_node_t root;
  29. /*! degree - maximum children number */
  30. int degree;
  31. int size;
  32. };
  33. struct _b_tree_node_t
  34. {
  35. /*! reference to parent */
  36. struct _b_tree_node_t *parent;
  37. /*! reference to children */
  38. vector_t children;
  39. /*! keys in current node */
  40. vector_t keys;
  41. };
  42. static b_tree_node_t _b_tree_new_node(int degree);
  43. static void _b_tree_delete(b_tree_node_t node);
  44. static void _b_tree_delete_node(b_tree_node_t node);
  45. static b_tree_node_t _b_tree_search(b_tree_node_t b_tree, void *key,
  46. int compare(void *x, void *y, void *context), void *context);
  47. static void _b_tree_divide(int degree, b_tree_node_t x, int index,
  48. b_tree_node_t y);
  49. static b_tree_node_t _b_tree_insert(b_tree_node_t root, void *key, int compare(
  50. void *x, void *y, void *context), void *context, int degree);
  51. static void _b_tree_show_indented(b_tree_node_t root, void key_handler(
  52. void *key, int level, void *fout), int level, void *fout);
  53. static void _b_tree_level_order(b_tree_node_t root, int level,
  54. void key_handler(void *x, void *fout), void *fout);
  55. static int _b_tree_get_height(b_tree_node_t node);
  56. static void
  57. *_b_tree_remove(b_tree_t b_tree, b_tree_node_t node, void *key, int compare(
  58. void *x, void *y, void *context), void *context, int degree);
  59. static INLINE void *_b_tree_node_find_predecesor(b_tree_node_t node);
  60. b_tree_t b_tree_new(int degree)
  61. {
  62. b_tree_t b_tree;
  63. /*
  64. * Allocate memory for a new B-tree, set it's root to NULL and degree
  65. * to the given value.
  66. */
  67. b_tree = (struct _b_tree_t *) _new(sizeof(struct _b_tree_t));
  68. b_tree->root = NULL;
  69. b_tree->degree = degree;
  70. b_tree->size = 0;
  71. return b_tree;
  72. }
  73. void b_tree_delete(b_tree_t b_tree)
  74. {
  75. _ASSERT(b_tree, ==, NULL, NULL_POINTER,);
  76. /*
  77. * If the root is not empty, then start deleting the root.
  78. * For this purpose, I created the function _b_tree_delete.
  79. */
  80. if (b_tree->root)
  81. _b_tree_delete(b_tree->root);
  82. /*
  83. * Set B-tree's root to NULL and degree to 0.
  84. */
  85. b_tree->root = NULL;
  86. b_tree->degree = 0;
  87. b_tree->size = 0;
  88. _delete(b_tree);
  89. }
  90. b_tree_node_t b_tree_get_root(b_tree_t b_tree)
  91. {
  92. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  93. return b_tree->root;
  94. }
  95. int b_tree_get_degree(b_tree_t b_tree)
  96. {
  97. _ASSERT(b_tree, ==, NULL, NULL_POINTER, -1);
  98. return b_tree->degree;
  99. }
  100. int b_tree_get_height(b_tree_t b_tree)
  101. {
  102. _ASSERT(b_tree, ==, NULL, NULL_POINTER, -1);
  103. return _b_tree_get_height(b_tree->root);
  104. }
  105. int b_tree_node_get_depth(b_tree_node_t node)
  106. {
  107. int i = 0;
  108. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  109. /*
  110. * The algorithm is very simple and checks for a superior limit.
  111. * If i is too big, then it will become negative and the loop will be broken.
  112. * The result will be a negative number.
  113. */
  114. while ((node = node->parent) && ++i > 0)
  115. ;
  116. return i;
  117. }
  118. b_tree_node_t b_tree_node_get_parent(b_tree_node_t node)
  119. {
  120. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  121. return node->parent;
  122. }
  123. int b_tree_node_get_children_number(b_tree_node_t node)
  124. {
  125. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  126. return vector_get_size(node->children);
  127. }
  128. b_tree_node_t b_tree_node_get_child(b_tree_node_t node, int index)
  129. {
  130. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  131. return vector_get_key_at(node->children, index);
  132. }
  133. int b_tree_node_get_keys_number(b_tree_node_t node)
  134. {
  135. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  136. return vector_get_size(node->keys);
  137. }
  138. void *b_tree_node_get_key(b_tree_node_t node, int index)
  139. {
  140. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  141. return vector_get_key_at(node->keys, index);
  142. }
  143. b_tree_node_t b_tree_search(b_tree_t b_tree, void *key, int compare(void *x,
  144. void *y, void *context), void *context)
  145. {
  146. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  147. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  148. _ASSERT(b_tree->size, <=, 0, INVALID_INPUT, NULL);
  149. /*
  150. * Search(btree, k)
  151. * //Search a B-tree, btree, for a key, k.
  152. * //if found k then return pointer to node containing k
  153. * //else return NULL
  154. *
  155. * current_node = root(btree)
  156. *
  157. * while current_node is not NULL
  158. * Search through keys in current_node until
  159. * 1. found k
  160. * 2. found first key (ki) larger than k or
  161. * 3. passed last key in current_node
  162. *
  163. * Case 1.
  164. * return pointer to current_node
  165. *
  166. * Case 2.
  167. * current_node = ith child of current_node
  168. *
  169. * Case 3.
  170. * current_node = last child of current_node
  171. * end while
  172. *
  173. * return NULL
  174. */
  175. return _b_tree_search(b_tree->root, key, compare, context);
  176. }
  177. b_tree_node_t b_tree_insert(b_tree_t b_tree, void *key, int compare(void *x,
  178. void *y, void *context), void *context, int add_if_exists)
  179. {
  180. b_tree_node_t root = NULL, add = NULL;
  181. int degree = 0;
  182. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  183. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  184. /*
  185. * B-Tree-Insert(void *, k)
  186. * //Insert the key, k, into tree, void *.
  187. * r = root[void *]
  188. * if the root is full (i.e., has 2t-1 keys) then
  189. * Allocate a new node and call it s. //s will be the new root.
  190. * root[void *] = s //make s the root. r still points to original root.
  191. * set the number of nodes in s to 0.
  192. * set the only child pointer of s (c1[s]) to point to r.
  193. * //r is now the child of s.
  194. * call B-Tree-Split-Child(s, 1, r) to split r and move its middle key up into s.
  195. * call B-Tree-Insert-NonFull(s, k) to insert the key, k, into the B-Tree
  196. * with root, s.
  197. * else //root is not full
  198. * call B-Tree-Insert-NonFull(r, k) to insert the key, k, into
  199. * the B-Tree with root, r.
  200. * end if
  201. *
  202. *
  203. * B-Tree-Insert-NonFull(x, k)
  204. * //Inserts the key, k, into a B-Tree. (k will ultimately be inserted into a leaf).
  205. * //Begin by attempting to insert k into nonfull node, x.
  206. * i = the number of keys in x.
  207. *
  208. * if x is a leaf then
  209. * since x is not full insert k into its proper place in x.
  210. * add one to the number of keys in x and update x on disk.
  211. * else //x is not a leaf
  212. * Move back from the last key of x until find child pointer to node
  213. * that is root of subtree in which k should be placed.
  214. *
  215. * if this child node is full then call B-Tree-Split-Child(x, i, ci[x])
  216. * //Note: we split full nodes on the way down the tree so that
  217. * // if a child of that node needs to be split its parent will
  218. * // be able to accept the middle key.
  219. * set i = index of whichever child of x is root of subtree in which
  220. * k should be placed.
  221. * call B-Tree-Insert-NonFull(ci[x], k) //Note: Recursive call
  222. * end if
  223. */
  224. root = b_tree->root;
  225. degree = b_tree->degree;
  226. if (root == NULL)
  227. {
  228. root = _b_tree_new_node(degree);
  229. vector_push_back(root->keys, key);
  230. b_tree->root = root;
  231. b_tree->size = 1;
  232. return root;
  233. }
  234. if (!add_if_exists && b_tree_search(b_tree, key, compare, context) != NULL)
  235. return NULL;
  236. b_tree->size++;
  237. if (vector_get_size(root->keys) == (2 * degree - 1))
  238. {
  239. add = _b_tree_new_node(degree);
  240. b_tree->root = add;
  241. root->parent = add;
  242. vector_push_back(add->children, root);
  243. _b_tree_divide(degree, add, 0, root);
  244. return _b_tree_insert(add, key, compare, context, degree);
  245. }
  246. return _b_tree_insert(root, key, compare, context, degree);
  247. }
  248. int b_tree_remove(b_tree_t b_tree, void *key, int compare(void *x, void *y,
  249. void *context), void *context)
  250. {
  251. int result;
  252. _ASSERT(b_tree, ==, NULL, NULL_POINTER, -1);
  253. _ASSERT(compare, ==, NULL, NULL_POINTER, -1);
  254. _ASSERT(b_tree->size, <=, 0, INVALID_INPUT, -1);
  255. /*
  256. * The algorithm is : B-Tree-Delete(x, k)
  257. * k is the key to be deleted and
  258. * x is the root of the subtree from which k is to be deleted.
  259. * B-Tree-Delete returns true if it successfully deletes k else it returns false.
  260. *
  261. * if x is a leaf then
  262. * if k is in x then
  263. * delete k from x and return true
  264. * else return false //k is not in subtree
  265. *
  266. * else //x is an internal node
  267. * if k is in x then
  268. * y = the child of x that precedes k
  269. *
  270. * if y has at least t keys then
  271. * k' = the predecessor of k (use B-Tree-FindLargest)
  272. * Copy k' over k //i.e., replace k with k'
  273. * B-Tree-Delete(y, k') //Note: recursive call
  274. *
  275. * else //y has t-1 keys
  276. * z = the child of x that follows k
  277. *
  278. * if z has at least t keys then
  279. * k' = the successor of k
  280. * Copy k' over k //i.e., replace k with k'
  281. * B-Tree-Delete(z, k');
  282. *
  283. * else //both y and z have t-1 keys
  284. * merge k and all of z into y //y now contains 2t-1 keys.
  285. * //k and the pointer to z will be deleted from x.
  286. * B-Tree-Delete(y, k) //Note: recursive call
  287. *
  288. * else //k is not in internal node x.
  289. * ci[x] points to the root, c, of the subtree that could contain k.
  290. *
  291. * if c has t-1 keys then
  292. *
  293. * if c has an immediate left/right sibling, z, with t or more keys
  294. * then
  295. * Let k1 be the key in x that precedes/follows c.
  296. * Move k1 into c as the first/last key in c.
  297. * Let k2 be the last/first key in the immediate left/right
  298. * sibling, z.
  299. * Replace k1 in x with k2 from z (i.e., move k2 up into x).
  300. * Move the last/first child subtree of z to be the first/last
  301. * child subtree of c.
  302. *
  303. * else //c and both of its immediate siblings have t-1 keys.
  304. * //we cannot descend to a child node with only t-1 keys so
  305. * merge c with one of its immediate siblings and
  306. * make the appropriate key of x the middle key of the new node, c.
  307. * //Note: This may cause the root to collapse, thus making c the
  308. * new root.
  309. * B-Tree-Delete(c, k)
  310. */
  311. result = _b_tree_remove(b_tree, b_tree->root, key, compare, context,
  312. b_tree->degree) != NULL;
  313. if (result)
  314. b_tree->size--;
  315. return result;
  316. }
  317. b_tree_node_t b_tree_get_min(b_tree_t b_tree)
  318. {
  319. b_tree_node_t root = NULL;
  320. /*
  321. * The minimum node is the left-most node.
  322. * current_node = root;
  323. * while(current_node is not leaf)
  324. * current_node = first child of current_node;
  325. */
  326. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  327. _ASSERT(b_tree->root, ==, NULL, NULL_POINTER, NULL);
  328. root = b_tree->root;
  329. while (vector_get_size(root->children) > 0)
  330. root = vector_get_key_at(root->children, 0);
  331. return root;
  332. }
  333. void *b_tree_get_min_key(b_tree_t b_tree)
  334. {
  335. b_tree_node_t node = b_tree_get_min(b_tree);
  336. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  337. /*
  338. * The minimum key is in the left-most node.
  339. * I find the left-most node, calling b_tree_get_min,
  340. * and then I return the first key contained by it.
  341. */
  342. return vector_get_key_at(node->keys, 0);
  343. }
  344. b_tree_node_t b_tree_get_max(b_tree_t b_tree)
  345. {
  346. b_tree_node_t root = NULL;
  347. /*
  348. * The maximum node is the right-most node.
  349. * current_node = root;
  350. * while(current_node is not leaf)
  351. * current_node = last child of current_node;
  352. */
  353. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  354. _ASSERT(b_tree->root, ==, NULL, NULL_POINTER, NULL);
  355. root = b_tree->root;
  356. while (vector_get_size(root->children) > 0)
  357. root = vector_get_key_at(root->children,
  358. vector_get_size(root->children) - 1);
  359. return root;
  360. }
  361. void *b_tree_get_max_key(b_tree_t b_tree)
  362. {
  363. b_tree_node_t node = b_tree_get_max(b_tree);
  364. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  365. /*
  366. * The maximum key is in the right-most node.
  367. * I find the right-most node, calling b_tree_get_max,
  368. * and then I return the last key contained by it.
  369. */
  370. return vector_get_key_at(node->keys, vector_get_size(node->keys) - 1);
  371. }
  372. void b_tree_level_order(b_tree_t b_tree, void key_handler(void *x,
  373. void *context), void *context)
  374. {
  375. _ASSERT(b_tree, ==, NULL, NULL_POINTER,);
  376. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  377. _b_tree_level_order(b_tree->root, 0, key_handler, context);
  378. }
  379. void b_tree_show_indented(b_tree_t b_tree, void key_handler(void *key,
  380. int level, void *context), void *context)
  381. {
  382. _ASSERT(b_tree, ==, NULL, NULL_POINTER,);
  383. _ASSERT(b_tree->root, ==, NULL, NULL_POINTER,);
  384. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  385. _b_tree_show_indented(b_tree->root, key_handler, 0, context);
  386. }
  387. static b_tree_node_t _b_tree_new_node(int degree)
  388. {
  389. b_tree_node_t node;
  390. /*
  391. * An empty node has :
  392. * - NULL parent
  393. * - 2 * degree -1 maximum keys; initial 0 keys
  394. * - 2 * degree maximum children; initial 0 children
  395. */
  396. node = (struct _b_tree_node_t *) _new(sizeof(struct _b_tree_node_t));
  397. node->parent = NULL;
  398. node->keys = vector_new(2 * degree - 1);
  399. node->children = vector_new(2 * degree);
  400. return node;
  401. }
  402. static b_tree_node_t _b_tree_search(b_tree_node_t b_tree, void *key,
  403. int compare(void *x, void *y, void *context), void *context)
  404. {
  405. int i = 0, n = 0;
  406. _ASSERT(b_tree, ==, NULL, NULL_POINTER, NULL);
  407. n = vector_get_size(b_tree->keys);
  408. while (i < n && compare(key, vector_get_key_at(b_tree->keys, i), context)
  409. > 0)
  410. i++;
  411. if (i < n && compare(key, vector_get_key_at(b_tree->keys, i), context) == 0)
  412. return b_tree;
  413. if (vector_get_size(b_tree->children) == 0)
  414. return NULL;
  415. else
  416. return _b_tree_search(vector_get_key_at(b_tree->children, i), key,
  417. compare, context);
  418. }
  419. static void _b_tree_divide(int degree, b_tree_node_t x, int index,
  420. b_tree_node_t y)
  421. {
  422. int j;
  423. b_tree_node_t z;
  424. void *median = NULL;
  425. /*
  426. * //Splits a node, y, in a B-Tree and moves y's median key up to y's parent, x.
  427. * //y is the ith child of x.
  428. * //This function will only be called if y is full; i.e., has 2t-1 keys.
  429. *
  430. * 1. Allocate a new node and call it z. //z will be the new sibling of y.
  431. * 2. If y is a leaf then mark z as a leaf, else mark z as an internal node.
  432. * 3. set the number of keys in z to t-1
  433. * 4. copy the last t-1 keys of y into z.
  434. * 5. if z is not a leaf then copy the last t pointers of y into z.
  435. * 6. set the number of keys in y to t-1.
  436. * 7. insert a (child) pointer to node z into node x.
  437. * 8. insert the original middle key of node y up into node x, moving other keys
  438. * and pointers as necessary
  439. * 9. increment the number of keys in x by one.
  440. * 10. Update x, y and z on disk.
  441. */
  442. z = _b_tree_new_node(degree);
  443. // Divide keys
  444. for (j = 0; j < degree - 1; j++)
  445. vector_push_back(z->keys, vector_get_key_at(y->keys, j + degree));
  446. // Divide children references
  447. if (vector_get_size(y->children) > 0)
  448. for (j = 0; j < degree; j++)
  449. vector_push_back(z->children, vector_get_key_at(y->children, j
  450. + degree));
  451. median = vector_get_key_at(y->keys, degree - 1);
  452. vector_set_size(y->keys, degree - 1);
  453. if (vector_get_size(y->children) > degree)
  454. vector_set_size(y->children, degree);
  455. // Adjust the x, the parent of y and z
  456. vector_push_back(x->keys, NULL);
  457. for (j = vector_get_size(x->keys) - 2; j >= index; j--)
  458. vector_set_key_at(x->keys, j + 1, vector_get_key_at(x->keys, j));
  459. vector_set_key_at(x->keys, index, median);
  460. vector_push_after(x->children, z, y, compare_pointers, NULL);
  461. z->parent = x;
  462. }
  463. static b_tree_node_t _b_tree_insert(b_tree_node_t root, void *key, int compare(
  464. void *x, void *y, void *context), void *context, int degree)
  465. {
  466. int i = vector_get_size(root->keys);
  467. b_tree_node_t child = NULL;
  468. if (vector_get_size(root->children) == 0)
  469. {
  470. // I'm in a leaf node.
  471. vector_push_back(root->keys, NULL);
  472. while (i > 0 && compare(key, vector_get_key_at(root->keys, i - 1),
  473. context) < 0)
  474. {
  475. vector_set_key_at(root->keys, i, vector_get_key_at(root->keys, i
  476. - 1));
  477. i--;
  478. }
  479. vector_set_key_at(root->keys, i, key);
  480. return root;
  481. }
  482. else
  483. {
  484. // I may use a binary search, but i don't think it's useful because
  485. // the degree of a b-tree is small, in general.
  486. while (i > 0 && compare(key, vector_get_key_at(root->keys, i - 1),
  487. context) < 0)
  488. i--;
  489. child = vector_get_key_at(root->children, i);
  490. if (vector_get_size(child->keys) == (2 * degree - 1))
  491. {
  492. _b_tree_divide(degree, root, i, child);
  493. if (compare(key, vector_get_key_at(root->keys, i), context) > 0)
  494. return _b_tree_insert(vector_get_key_at(root->children, i + 1),
  495. key, compare, context, degree);
  496. }
  497. return _b_tree_insert(child, key, compare, context, degree);
  498. }
  499. }
  500. static void _b_tree_delete(b_tree_node_t node)
  501. {
  502. int i = 0;
  503. /*
  504. * Free the memory occupied by the children then
  505. * free current node.
  506. */
  507. for (; i < vector_get_size(node->children); i++)
  508. _b_tree_delete(vector_get_key_at(node->children, i));
  509. vector_delete(node->keys);
  510. vector_delete(node->children);
  511. node->keys = node->children = NULL;
  512. node->parent = NULL;
  513. _delete(node);
  514. }
  515. static void _b_tree_delete_node(b_tree_node_t node)
  516. {
  517. /*
  518. * Deleting a node implies :
  519. * - deleting the keys's vector
  520. * - deleting the children's vector
  521. * - setting keys, children and parent to NULL
  522. */
  523. vector_delete(node->keys);
  524. vector_delete(node->children);
  525. node->keys = node->children = NULL;
  526. node->parent = NULL;
  527. _delete(node);
  528. }
  529. static void _b_tree_show_indented(b_tree_node_t root, void key_handler(
  530. void *key, int level, void *context), int level, void *context)
  531. {
  532. int i = 0, n = 0;
  533. if (root == NULL)
  534. return;
  535. n = vector_get_size(root->keys);
  536. LOGGER("[_b_tree_show_indented] node %p has %d keys and %d children\n",
  537. root, vector_get_size(root->keys), vector_get_size(root->children));
  538. /*
  539. * for index in 0 to keys_number
  540. * call _b_tree_show_indented for the current node (addressable by index)
  541. * call key_handler for the current key (addressable by index)
  542. * call _b_tree_show_indented for the last node
  543. */
  544. for (; i < n; i++)
  545. {
  546. if (vector_get_size(root->children) > i)
  547. _b_tree_show_indented(vector_get_key_at(root->children, i),
  548. key_handler, level + 1, context);
  549. key_handler(vector_get_key_at(root->keys, i), level, context);
  550. }
  551. if (vector_get_size(root->children) > i)
  552. _b_tree_show_indented(vector_get_key_at(root->children, i),
  553. key_handler, level + 1, context);
  554. }
  555. static void _b_tree_level_order(b_tree_node_t root, int level,
  556. void key_handler(void *x, void *context), void *context)
  557. {
  558. int i;
  559. for (i = 0; i < level; i++)
  560. LOGGER(" ");
  561. LOGGER("( ");
  562. for (i = 0; i < vector_get_size(root->keys); i++)
  563. {
  564. /*
  565. * Calls key_handler for each key in the current node.
  566. */
  567. key_handler(vector_get_key_at(root->keys, i), context);
  568. LOGGER(" ");
  569. }
  570. LOGGER(")\n");
  571. for (i = 0; i < vector_get_size(root->children); i++)
  572. /*
  573. * Calls _b_tree_level_order for each children of the current node.
  574. */
  575. _b_tree_level_order(vector_get_key_at(root->children, i), level + 1,
  576. key_handler, context);
  577. }
  578. static int _b_tree_get_height(b_tree_node_t node)
  579. {
  580. int i = 1, max_height = 0;
  581. _ASSERT(node, ==, NULL, NOT_EXCEPTION, 0);
  582. _ASSERT(vector_get_size(node->children), ==, 0, NOT_EXCEPTION, 1);
  583. /*
  584. * height(NULL) = 0
  585. * height(node) = 1 + MAX(child_node | child_node is a child of node)
  586. */
  587. max_height = _b_tree_get_height(vector_get_key_at(node->children, 0));
  588. for (; i < vector_get_size(node->children) - 1; i++)
  589. max_height = MAX(max_height, _b_tree_get_height(vector_get_key_at(
  590. node->children, i)));
  591. return 1 + max_height;
  592. }
  593. static INLINE void *_b_tree_node_find_predecesor(b_tree_node_t node)
  594. {
  595. /*
  596. * Move to the right-most node, starting from the current node
  597. * and then return the last key stored in it.
  598. */
  599. while (b_tree_node_get_children_number(node))
  600. node = vector_get_key_at(node->children,
  601. vector_get_size(node->children) - 1);
  602. return vector_get_key_at(node->keys, vector_get_size(node->keys) - 1);
  603. }
  604. static INLINE void *_b_tree_node_find_successor(b_tree_node_t node, void *key)
  605. {
  606. int i = vector_search(node->keys, key, compare_pointers, NULL);
  607. b_tree_node_t child = NULL;
  608. /*
  609. * If there is a key after current key, then return it,
  610. * else return the first key stored in the next node.
  611. */
  612. if (i < vector_get_size(node->keys) - 1)
  613. return vector_get_key_at(node->keys, i + 1);
  614. child = vector_get_key_at(node->children, i + 1);
  615. if (child)
  616. return vector_get_key_at(child->keys, 0);
  617. return NULL;
  618. }
  619. static void *_b_tree_remove(b_tree_t b_tree, b_tree_node_t node, void *key,
  620. int compare(void *x, void *y, void *context), void *context, int degree)
  621. {
  622. int i = 0, j = 0;
  623. b_tree_node_t child = NULL, left = NULL, right = NULL;
  624. void *new_key = NULL;
  625. if (b_tree_node_get_children_number(node) == 0)
  626. {
  627. LOGGER("[_b_tree_remove] on leaf node %p\n", node);
  628. // Current node is leaf
  629. i = vector_search(node->keys, key, compare, context);
  630. if (i == -1)
  631. return NULL;
  632. vector_remove_key_at(node->keys, i);
  633. return key;
  634. }
  635. else
  636. {
  637. // Current node is internal node
  638. i = vector_search(node->keys, key, compare, context);
  639. if (i != -1)
  640. {
  641. LOGGER(
  642. "[_b_tree_remove] key is in an internal node %p at position %d\n",
  643. node, i);
  644. // Key is in current node
  645. left = vector_get_key_at(node->children, i);
  646. right = vector_get_key_at(node->children, i + 1);
  647. LOGGER("[_b_tree_remove] left node %p, right node %p\n", left,
  648. right);
  649. if (left && vector_get_size(left->keys) >= degree)
  650. {
  651. LOGGER("[_b_tree_remove] left node %p has %d keys\n", node,
  652. vector_get_size(left->keys));
  653. new_key = _b_tree_node_find_predecesor(left);
  654. LOGGER("[_b_tree_remove] successor %p, keys %d, position %d\n",
  655. new_key, vector_get_size(node->keys), i);
  656. if (new_key)
  657. {
  658. vector_set_key_at(node->keys, i, new_key);
  659. return _b_tree_remove(b_tree, left, new_key, compare,
  660. context, degree);
  661. }
  662. }
  663. else if (right && vector_get_size(right->keys) >= degree)
  664. {
  665. LOGGER("[_b_tree_remove] right node %p has %d keys\n", node,
  666. vector_get_size(right->keys));
  667. new_key = _b_tree_node_find_successor(right, key);
  668. LOGGER("[_b_tree_remove] successor %p, keys %d, position %d\n",
  669. new_key, vector_get_size(node->keys), i);
  670. if (new_key)
  671. {
  672. vector_set_key_at(node->keys, i, new_key);
  673. return _b_tree_remove(b_tree, right, new_key, compare,
  674. context, degree);
  675. }
  676. }
  677. else
  678. {
  679. LOGGER(
  680. "[_b_tree_remove] merging left node %p and right node %p\n",
  681. left, right);
  682. _ASSERT(left, ==, NULL, NULL_POINTER, NULL);
  683. // Both nodes have degree keys, so I have to merge them.
  684. vector_push_back(left->keys, key);
  685. for (i = 0; right && i < vector_get_size(right->keys); i++)
  686. vector_push_back(left->keys, vector_get_key_at(right->keys,
  687. i));
  688. for (i = 0; right && i < vector_get_size(right->children); i++)
  689. vector_push_back(left->children, vector_get_key_at(
  690. right->children, i));
  691. if (right)
  692. {
  693. vector_remove_key(node->children, right, compare_pointers,
  694. NULL);
  695. _b_tree_delete_node(right);
  696. }
  697. vector_remove_key(node->keys, key, compare_pointers, NULL);
  698. return _b_tree_remove(b_tree, left, key, compare, context,
  699. degree);
  700. }
  701. }
  702. else
  703. {
  704. i = vector_get_size(node->keys);
  705. // Key isn't in current node
  706. while (i > 0 && compare(key, vector_get_key_at(node->keys, i - 1),
  707. context) < 0)
  708. i--;
  709. LOGGER("[_b_tree_remove] keys %d, children %d, position %d\n",
  710. vector_get_size(node->keys),
  711. vector_get_size(node->children), i);
  712. child = vector_get_key_at(node->children, i);
  713. if (child)
  714. LOGGER(
  715. "[_b_tree_remove] child %p at position %d and %d keys\n",
  716. child, i, vector_get_size(child->keys));
  717. else
  718. LOGGER("[_b_tree_remove] child %p at position %d\n", child, i);
  719. if (child && vector_get_size(child->keys) == degree - 1)
  720. {
  721. if (i > 0)
  722. left = vector_get_key_at(node->children, i - 1);
  723. else
  724. left = NULL;
  725. if (i < vector_get_size(node->children) - 1)
  726. right = vector_get_key_at(node->children, i + 1);
  727. else
  728. right = NULL;
  729. LOGGER(
  730. "[_b_tree_remove] left child %p, right child %p, degree %d\n",
  731. left, right, degree);
  732. if (left)
  733. LOGGER("[_b_tree_remove] left node has %d keys\n",
  734. vector_get_size(left->keys));
  735. if (right)
  736. LOGGER("[_b_tree_remove] right node has %d keys\n",
  737. vector_get_size(right->keys));
  738. if ((left && vector_get_size(left->keys) >= degree) || (right
  739. && vector_get_size(right->keys) >= degree))
  740. {
  741. if (left && vector_get_size(left->keys) >= degree)
  742. {
  743. if (vector_get_size(node->keys) > i - 1)
  744. {
  745. vector_push_front(child->keys, vector_get_key_at(
  746. node->keys, i - 1));
  747. vector_push_before(node->keys,
  748. vector_get_key_at(left->keys,
  749. vector_get_size(left->keys) - 1),
  750. vector_get_key_at(node->keys, i - 1),
  751. compare_pointers, NULL);
  752. vector_remove_key_at(node->keys, i);
  753. vector_remove_key_at(left->keys, vector_get_size(
  754. left->keys) - 1);
  755. }
  756. }
  757. if (right && vector_get_size(right->keys) >= degree)
  758. {
  759. if (vector_get_size(node->keys) > i)
  760. {
  761. vector_push_back(child->keys, vector_get_key_at(
  762. node->keys, i));
  763. vector_push_after(node->keys, vector_get_key_at(
  764. right->keys, 0), vector_get_key_at(
  765. node->keys, i), compare_pointers, NULL);
  766. vector_remove_key_at(node->keys, i);
  767. vector_remove_key_at(right->keys, 0);
  768. }
  769. }
  770. }
  771. else
  772. {
  773. if (left)
  774. {
  775. vector_push_front(child->keys, vector_get_key_at(
  776. node->keys, i - 1));
  777. vector_remove_key_at(node->children, i - 1);
  778. vector_remove_key_at(node->keys, i - 1);
  779. for (j = vector_get_size(left->keys) - 1; j >= 0; j--)
  780. vector_push_front(child->keys, vector_get_key_at(
  781. left->keys, j));
  782. for (j = vector_get_size(left->children) - 1; j >= 0; j--)
  783. {
  784. vector_push_front(child->children,
  785. vector_get_key_at(left->children, j));
  786. ((b_tree_node_t) vector_get_key_at(left->children,
  787. j))->parent = child;
  788. }
  789. _b_tree_delete_node(left);
  790. }
  791. else if (right)
  792. {
  793. vector_push_back(child->keys, vector_get_key_at(
  794. node->keys, i));
  795. vector_remove_key_at(node->children, i + 1);
  796. vector_remove_key_at(node->keys, i);
  797. for (j = 0; j < vector_get_size(right->keys); j++)
  798. vector_push_back(child->keys, vector_get_key_at(
  799. right->keys, j));
  800. for (j = 0; j < vector_get_size(right->children); j++)
  801. {
  802. vector_push_back(child->children,
  803. vector_get_key_at(right->children, j));
  804. ((b_tree_node_t) vector_get_key_at(right->children,
  805. j))->parent = child;
  806. }
  807. _b_tree_delete_node(right);
  808. }
  809. // The root may collapse
  810. if (vector_get_size(node->keys) == 0)
  811. {
  812. if (node == b_tree->root)
  813. {
  814. _b_tree_delete_node(b_tree->root);
  815. b_tree->root = child;
  816. child->parent = NULL;
  817. }
  818. else if (node->parent)
  819. {
  820. i = vector_search(node->parent->children, node,
  821. compare_pointers, NULL);
  822. vector_set_key_at(node->parent->children, i, child);
  823. child->parent = node->parent;
  824. }
  825. }
  826. }
  827. }
  828. if (child)
  829. return _b_tree_remove(b_tree, child, key, compare, context,
  830. degree);
  831. }
  832. }
  833. return NULL;
  834. }
  835. int b_tree_get_size(b_tree_t btree)
  836. {
  837. _ASSERT(btree, ==, NULL, NULL_POINTER, -1);
  838. LOGGER("[b_tree_get_size] b-tree %p with size %d\n", btree, btree->size);
  839. return btree->size;
  840. }