gl_anyrbtree_list2.h 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. /* Sequential list data type implemented by a binary tree.
  2. Copyright (C) 2006-2007, 2009-2020 Free Software Foundation, Inc.
  3. Written by Bruno Haible <bruno@clisp.org>, 2006.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  14. /* Common code of gl_rbtree_list.c and gl_rbtreehash_list.c. */
  15. /* -------------------------- gl_list_t Data Type -------------------------- */
  16. /* Creates a subtree for count >= 1 elements.
  17. Its black-height bh is passed as argument, with
  18. 2^bh - 1 <= count <= 2^(bh+1) - 1. bh == 0 implies count == 1.
  19. Its height is h where 2^(h-1) <= count <= 2^h - 1.
  20. Return NULL upon out-of-memory. */
  21. static gl_list_node_t
  22. create_subtree_with_contents (unsigned int bh,
  23. size_t count, const void **contents)
  24. {
  25. size_t half1 = (count - 1) / 2;
  26. size_t half2 = count / 2;
  27. /* Note: half1 + half2 = count - 1. */
  28. gl_list_node_t node =
  29. (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
  30. if (node == NULL)
  31. return NULL;
  32. if (half1 > 0)
  33. {
  34. /* half1 > 0 implies count > 1, implies bh >= 1, implies
  35. 2^(bh-1) - 1 <= half1 <= 2^bh - 1. */
  36. node->left =
  37. create_subtree_with_contents (bh - 1, half1, contents);
  38. if (node->left == NULL)
  39. goto fail1;
  40. node->left->parent = node;
  41. }
  42. else
  43. node->left = NULL;
  44. node->value = contents[half1];
  45. if (half2 > 0)
  46. {
  47. /* half2 > 0 implies count > 1, implies bh >= 1, implies
  48. 2^(bh-1) - 1 <= half2 <= 2^bh - 1. */
  49. node->right =
  50. create_subtree_with_contents (bh - 1, half2, contents + half1 + 1);
  51. if (node->right == NULL)
  52. goto fail2;
  53. node->right->parent = node;
  54. }
  55. else
  56. node->right = NULL;
  57. node->color = (bh == 0 ? RED : BLACK);
  58. node->branch_size = count;
  59. return node;
  60. fail2:
  61. if (node->left != NULL)
  62. free_subtree (node->left);
  63. fail1:
  64. free (node);
  65. return NULL;
  66. }
  67. static gl_list_t
  68. gl_tree_nx_create (gl_list_implementation_t implementation,
  69. gl_listelement_equals_fn equals_fn,
  70. gl_listelement_hashcode_fn hashcode_fn,
  71. gl_listelement_dispose_fn dispose_fn,
  72. bool allow_duplicates,
  73. size_t count, const void **contents)
  74. {
  75. struct gl_list_impl *list =
  76. (struct gl_list_impl *) malloc (sizeof (struct gl_list_impl));
  77. if (list == NULL)
  78. return NULL;
  79. list->base.vtable = implementation;
  80. list->base.equals_fn = equals_fn;
  81. list->base.hashcode_fn = hashcode_fn;
  82. list->base.dispose_fn = dispose_fn;
  83. list->base.allow_duplicates = allow_duplicates;
  84. #if WITH_HASHTABLE
  85. {
  86. size_t estimate = xsum (count, count / 2); /* 1.5 * count */
  87. if (estimate < 10)
  88. estimate = 10;
  89. list->table_size = next_prime (estimate);
  90. if (size_overflow_p (xtimes (list->table_size, sizeof (gl_hash_entry_t))))
  91. goto fail1;
  92. list->table =
  93. (gl_hash_entry_t *) calloc (list->table_size, sizeof (gl_hash_entry_t));
  94. if (list->table == NULL)
  95. goto fail1;
  96. }
  97. #endif
  98. if (count > 0)
  99. {
  100. /* Assuming 2^bh - 1 <= count <= 2^(bh+1) - 2, we create a tree whose
  101. upper bh levels are black, and only the partially present lowest
  102. level is red. */
  103. unsigned int bh;
  104. {
  105. size_t n;
  106. for (n = count + 1, bh = 0; n > 1; n = n >> 1)
  107. bh++;
  108. }
  109. list->root = create_subtree_with_contents (bh, count, contents);
  110. if (list->root == NULL)
  111. goto fail2;
  112. list->root->parent = NULL;
  113. #if WITH_HASHTABLE
  114. /* Now that the tree is built, node_position() works. Now we can
  115. add the nodes to the hash table. */
  116. if (add_nodes_to_buckets (list) < 0)
  117. goto fail3;
  118. #endif
  119. }
  120. else
  121. list->root = NULL;
  122. return list;
  123. #if WITH_HASHTABLE
  124. fail3:
  125. free_subtree (list->root);
  126. #endif
  127. fail2:
  128. #if WITH_HASHTABLE
  129. free (list->table);
  130. fail1:
  131. #endif
  132. free (list);
  133. return NULL;
  134. }
  135. /* Rotates left a subtree.
  136. B D
  137. / \ / \
  138. A D --> B E
  139. / \ / \
  140. C E A C
  141. Changes the tree structure, updates the branch sizes.
  142. The caller must update the colors and register D as child of its parent. */
  143. static gl_list_node_t
  144. rotate_left (gl_list_node_t b_node, gl_list_node_t d_node)
  145. {
  146. gl_list_node_t a_node = b_node->left;
  147. gl_list_node_t c_node = d_node->left;
  148. gl_list_node_t e_node = d_node->right;
  149. b_node->right = c_node;
  150. d_node->left = b_node;
  151. d_node->parent = b_node->parent;
  152. b_node->parent = d_node;
  153. if (c_node != NULL)
  154. c_node->parent = b_node;
  155. b_node->branch_size =
  156. (a_node != NULL ? a_node->branch_size : 0)
  157. + 1 + (c_node != NULL ? c_node->branch_size : 0);
  158. d_node->branch_size =
  159. b_node->branch_size + 1 + (e_node != NULL ? e_node->branch_size : 0);
  160. return d_node;
  161. }
  162. /* Rotates right a subtree.
  163. D B
  164. / \ / \
  165. B E --> A D
  166. / \ / \
  167. A C C E
  168. Changes the tree structure, updates the branch sizes.
  169. The caller must update the colors and register B as child of its parent. */
  170. static gl_list_node_t
  171. rotate_right (gl_list_node_t b_node, gl_list_node_t d_node)
  172. {
  173. gl_list_node_t a_node = b_node->left;
  174. gl_list_node_t c_node = b_node->right;
  175. gl_list_node_t e_node = d_node->right;
  176. d_node->left = c_node;
  177. b_node->right = d_node;
  178. b_node->parent = d_node->parent;
  179. d_node->parent = b_node;
  180. if (c_node != NULL)
  181. c_node->parent = d_node;
  182. d_node->branch_size =
  183. (c_node != NULL ? c_node->branch_size : 0)
  184. + 1 + (e_node != NULL ? e_node->branch_size : 0);
  185. b_node->branch_size =
  186. (a_node != NULL ? a_node->branch_size : 0) + 1 + d_node->branch_size;
  187. return b_node;
  188. }
  189. /* Ensures the tree is balanced, after an insertion operation.
  190. Also assigns node->color.
  191. parent is the given node's parent, known to be non-NULL. */
  192. static void
  193. rebalance_after_add (gl_list_t list, gl_list_node_t node, gl_list_node_t parent)
  194. {
  195. for (;;)
  196. {
  197. /* At this point, parent = node->parent != NULL.
  198. Think of node->color being RED (although node->color is not yet
  199. assigned.) */
  200. gl_list_node_t grandparent;
  201. gl_list_node_t uncle;
  202. if (parent->color == BLACK)
  203. {
  204. /* A RED color for node is acceptable. */
  205. node->color = RED;
  206. return;
  207. }
  208. grandparent = parent->parent;
  209. /* Since parent is RED, we know that
  210. grandparent is != NULL and colored BLACK. */
  211. if (grandparent->left == parent)
  212. uncle = grandparent->right;
  213. else if (grandparent->right == parent)
  214. uncle = grandparent->left;
  215. else
  216. abort ();
  217. if (uncle != NULL && uncle->color == RED)
  218. {
  219. /* Change grandparent from BLACK to RED, and
  220. change parent and uncle from RED to BLACK.
  221. This makes it acceptable for node to be RED. */
  222. node->color = RED;
  223. parent->color = uncle->color = BLACK;
  224. node = grandparent;
  225. }
  226. else
  227. {
  228. /* grandparent and uncle are BLACK. parent is RED. node wants
  229. to be RED too.
  230. In this case, recoloring is not sufficient. Need to perform
  231. one or two rotations. */
  232. gl_list_node_t *grandparentp;
  233. if (grandparent->parent == NULL)
  234. grandparentp = &list->root;
  235. else if (grandparent->parent->left == grandparent)
  236. grandparentp = &grandparent->parent->left;
  237. else if (grandparent->parent->right == grandparent)
  238. grandparentp = &grandparent->parent->right;
  239. else
  240. abort ();
  241. if (grandparent->left == parent)
  242. {
  243. if (parent->right == node)
  244. {
  245. /* Rotation between node and parent. */
  246. grandparent->left = rotate_left (parent, node);
  247. node = parent;
  248. parent = grandparent->left;
  249. }
  250. /* grandparent and uncle are BLACK. parent and node want to be
  251. RED. parent = grandparent->left. node = parent->left.
  252. grandparent parent
  253. bh+1 bh+1
  254. / \ / \
  255. parent uncle --> node grandparent
  256. bh bh bh bh
  257. / \ / \
  258. node C C uncle
  259. bh bh bh bh
  260. */
  261. *grandparentp = rotate_right (parent, grandparent);
  262. parent->color = BLACK;
  263. node->color = grandparent->color = RED;
  264. }
  265. else /* grandparent->right == parent */
  266. {
  267. if (parent->left == node)
  268. {
  269. /* Rotation between node and parent. */
  270. grandparent->right = rotate_right (node, parent);
  271. node = parent;
  272. parent = grandparent->right;
  273. }
  274. /* grandparent and uncle are BLACK. parent and node want to be
  275. RED. parent = grandparent->right. node = parent->right.
  276. grandparent parent
  277. bh+1 bh+1
  278. / \ / \
  279. uncle parent --> grandparent node
  280. bh bh bh bh
  281. / \ / \
  282. C node uncle C
  283. bh bh bh bh
  284. */
  285. *grandparentp = rotate_left (grandparent, parent);
  286. parent->color = BLACK;
  287. node->color = grandparent->color = RED;
  288. }
  289. return;
  290. }
  291. /* Start again with a new (node, parent) pair. */
  292. parent = node->parent;
  293. if (parent == NULL)
  294. {
  295. /* Change node's color from RED to BLACK. This increases the
  296. tree's black-height. */
  297. node->color = BLACK;
  298. return;
  299. }
  300. }
  301. }
  302. /* Ensures the tree is balanced, after a deletion operation.
  303. CHILD was a grandchild of PARENT and is now its child. Between them,
  304. a black node was removed. CHILD is also black, or NULL.
  305. (CHILD can also be NULL. But PARENT is non-NULL.) */
  306. static void
  307. rebalance_after_remove (gl_list_t list, gl_list_node_t child, gl_list_node_t parent)
  308. {
  309. for (;;)
  310. {
  311. /* At this point, we reduced the black-height of the CHILD subtree by 1.
  312. To make up, either look for a possibility to turn a RED to a BLACK
  313. node, or try to reduce the black-height tree of CHILD's sibling
  314. subtree as well. */
  315. gl_list_node_t *parentp;
  316. if (parent->parent == NULL)
  317. parentp = &list->root;
  318. else if (parent->parent->left == parent)
  319. parentp = &parent->parent->left;
  320. else if (parent->parent->right == parent)
  321. parentp = &parent->parent->right;
  322. else
  323. abort ();
  324. if (parent->left == child)
  325. {
  326. gl_list_node_t sibling = parent->right;
  327. /* sibling's black-height is >= 1. In particular,
  328. sibling != NULL.
  329. parent
  330. / \
  331. child sibling
  332. bh bh+1
  333. */
  334. if (sibling->color == RED)
  335. {
  336. /* sibling is RED, hence parent is BLACK and sibling's children
  337. are non-NULL and BLACK.
  338. parent sibling
  339. bh+2 bh+2
  340. / \ / \
  341. child sibling --> parent SR
  342. bh bh+1 bh+1 bh+1
  343. / \ / \
  344. SL SR child SL
  345. bh+1 bh+1 bh bh+1
  346. */
  347. *parentp = rotate_left (parent, sibling);
  348. parent->color = RED;
  349. sibling->color = BLACK;
  350. /* Concentrate on the subtree of parent. The new sibling is
  351. one of the old sibling's children, and known to be BLACK. */
  352. parentp = &sibling->left;
  353. sibling = parent->right;
  354. }
  355. /* Now we know that sibling is BLACK.
  356. parent
  357. / \
  358. child sibling
  359. bh bh+1
  360. */
  361. if (sibling->right != NULL && sibling->right->color == RED)
  362. {
  363. /*
  364. parent sibling
  365. bh+1|bh+2 bh+1|bh+2
  366. / \ / \
  367. child sibling --> parent SR
  368. bh bh+1 bh+1 bh+1
  369. / \ / \
  370. SL SR child SL
  371. bh bh bh bh
  372. */
  373. *parentp = rotate_left (parent, sibling);
  374. sibling->color = parent->color;
  375. parent->color = BLACK;
  376. sibling->right->color = BLACK;
  377. return;
  378. }
  379. else if (sibling->left != NULL && sibling->left->color == RED)
  380. {
  381. /*
  382. parent parent
  383. bh+1|bh+2 bh+1|bh+2
  384. / \ / \
  385. child sibling --> child SL
  386. bh bh+1 bh bh+1
  387. / \ / \
  388. SL SR SLL sibling
  389. bh bh bh bh
  390. / \ / \
  391. SLL SLR SLR SR
  392. bh bh bh bh
  393. where SLL, SLR, SR are all black.
  394. */
  395. parent->right = rotate_right (sibling->left, sibling);
  396. /* Change sibling from BLACK to RED and SL from RED to BLACK. */
  397. sibling->color = RED;
  398. sibling = parent->right;
  399. sibling->color = BLACK;
  400. /* Now do as in the previous case. */
  401. *parentp = rotate_left (parent, sibling);
  402. sibling->color = parent->color;
  403. parent->color = BLACK;
  404. sibling->right->color = BLACK;
  405. return;
  406. }
  407. else
  408. {
  409. if (parent->color == BLACK)
  410. {
  411. /* Change sibling from BLACK to RED. Then the entire
  412. subtree at parent has decreased its black-height.
  413. parent parent
  414. bh+2 bh+1
  415. / \ / \
  416. child sibling --> child sibling
  417. bh bh+1 bh bh
  418. */
  419. sibling->color = RED;
  420. child = parent;
  421. }
  422. else
  423. {
  424. /* Change parent from RED to BLACK, but compensate by
  425. changing sibling from BLACK to RED.
  426. parent parent
  427. bh+1 bh+1
  428. / \ / \
  429. child sibling --> child sibling
  430. bh bh+1 bh bh
  431. */
  432. parent->color = BLACK;
  433. sibling->color = RED;
  434. return;
  435. }
  436. }
  437. }
  438. else if (parent->right == child)
  439. {
  440. gl_list_node_t sibling = parent->left;
  441. /* sibling's black-height is >= 1. In particular,
  442. sibling != NULL.
  443. parent
  444. / \
  445. sibling child
  446. bh+1 bh
  447. */
  448. if (sibling->color == RED)
  449. {
  450. /* sibling is RED, hence parent is BLACK and sibling's children
  451. are non-NULL and BLACK.
  452. parent sibling
  453. bh+2 bh+2
  454. / \ / \
  455. sibling child --> SR parent
  456. bh+1 ch bh+1 bh+1
  457. / \ / \
  458. SL SR SL child
  459. bh+1 bh+1 bh+1 bh
  460. */
  461. *parentp = rotate_right (sibling, parent);
  462. parent->color = RED;
  463. sibling->color = BLACK;
  464. /* Concentrate on the subtree of parent. The new sibling is
  465. one of the old sibling's children, and known to be BLACK. */
  466. parentp = &sibling->right;
  467. sibling = parent->left;
  468. }
  469. /* Now we know that sibling is BLACK.
  470. parent
  471. / \
  472. sibling child
  473. bh+1 bh
  474. */
  475. if (sibling->left != NULL && sibling->left->color == RED)
  476. {
  477. /*
  478. parent sibling
  479. bh+1|bh+2 bh+1|bh+2
  480. / \ / \
  481. sibling child --> SL parent
  482. bh+1 bh bh+1 bh+1
  483. / \ / \
  484. SL SR SR child
  485. bh bh bh bh
  486. */
  487. *parentp = rotate_right (sibling, parent);
  488. sibling->color = parent->color;
  489. parent->color = BLACK;
  490. sibling->left->color = BLACK;
  491. return;
  492. }
  493. else if (sibling->right != NULL && sibling->right->color == RED)
  494. {
  495. /*
  496. parent parent
  497. bh+1|bh+2 bh+1|bh+2
  498. / \ / \
  499. sibling child --> SR child
  500. bh+1 bh bh+1 bh
  501. / \ / \
  502. SL SR sibling SRR
  503. bh bh bh bh
  504. / \ / \
  505. SRL SRR SL SRL
  506. bh bh bh bh
  507. where SL, SRL, SRR are all black.
  508. */
  509. parent->left = rotate_left (sibling, sibling->right);
  510. /* Change sibling from BLACK to RED and SL from RED to BLACK. */
  511. sibling->color = RED;
  512. sibling = parent->left;
  513. sibling->color = BLACK;
  514. /* Now do as in the previous case. */
  515. *parentp = rotate_right (sibling, parent);
  516. sibling->color = parent->color;
  517. parent->color = BLACK;
  518. sibling->left->color = BLACK;
  519. return;
  520. }
  521. else
  522. {
  523. if (parent->color == BLACK)
  524. {
  525. /* Change sibling from BLACK to RED. Then the entire
  526. subtree at parent has decreased its black-height.
  527. parent parent
  528. bh+2 bh+1
  529. / \ / \
  530. sibling child --> sibling child
  531. bh+1 bh bh bh
  532. */
  533. sibling->color = RED;
  534. child = parent;
  535. }
  536. else
  537. {
  538. /* Change parent from RED to BLACK, but compensate by
  539. changing sibling from BLACK to RED.
  540. parent parent
  541. bh+1 bh+1
  542. / \ / \
  543. sibling child --> sibling child
  544. bh+1 bh bh bh
  545. */
  546. parent->color = BLACK;
  547. sibling->color = RED;
  548. return;
  549. }
  550. }
  551. }
  552. else
  553. abort ();
  554. /* Start again with a new (child, parent) pair. */
  555. parent = child->parent;
  556. #if 0 /* Already handled. */
  557. if (child != NULL && child->color == RED)
  558. {
  559. child->color = BLACK;
  560. return;
  561. }
  562. #endif
  563. if (parent == NULL)
  564. return;
  565. }
  566. }
  567. static void
  568. gl_tree_remove_node_from_tree (gl_list_t list, gl_list_node_t node)
  569. {
  570. gl_list_node_t parent = node->parent;
  571. if (node->left == NULL)
  572. {
  573. /* Replace node with node->right. */
  574. gl_list_node_t child = node->right;
  575. if (child != NULL)
  576. {
  577. child->parent = parent;
  578. /* Since node->left == NULL, child must be RED and of height 1,
  579. hence node must have been BLACK. Recolor the child. */
  580. child->color = BLACK;
  581. }
  582. if (parent == NULL)
  583. list->root = child;
  584. else
  585. {
  586. if (parent->left == node)
  587. parent->left = child;
  588. else /* parent->right == node */
  589. parent->right = child;
  590. /* Update branch_size fields of the parent nodes. */
  591. {
  592. gl_list_node_t p;
  593. for (p = parent; p != NULL; p = p->parent)
  594. p->branch_size--;
  595. }
  596. if (child == NULL && node->color == BLACK)
  597. rebalance_after_remove (list, child, parent);
  598. }
  599. }
  600. else if (node->right == NULL)
  601. {
  602. /* It is not absolutely necessary to treat this case. But the more
  603. general case below is more complicated, hence slower. */
  604. /* Replace node with node->left. */
  605. gl_list_node_t child = node->left;
  606. child->parent = parent;
  607. /* Since node->right == NULL, child must be RED and of height 1,
  608. hence node must have been BLACK. Recolor the child. */
  609. child->color = BLACK;
  610. if (parent == NULL)
  611. list->root = child;
  612. else
  613. {
  614. if (parent->left == node)
  615. parent->left = child;
  616. else /* parent->right == node */
  617. parent->right = child;
  618. /* Update branch_size fields of the parent nodes. */
  619. {
  620. gl_list_node_t p;
  621. for (p = parent; p != NULL; p = p->parent)
  622. p->branch_size--;
  623. }
  624. }
  625. }
  626. else
  627. {
  628. /* Replace node with the rightmost element of the node->left subtree. */
  629. gl_list_node_t subst;
  630. gl_list_node_t subst_parent;
  631. gl_list_node_t child;
  632. color_t removed_color;
  633. for (subst = node->left; subst->right != NULL; )
  634. subst = subst->right;
  635. subst_parent = subst->parent;
  636. child = subst->left;
  637. removed_color = subst->color;
  638. /* The case subst_parent == node is special: If we do nothing special,
  639. we get confusion about node->left, subst->left and child->parent.
  640. subst_parent == node
  641. <==> The 'for' loop above terminated immediately.
  642. <==> subst == subst_parent->left
  643. [otherwise subst == subst_parent->right]
  644. In this case, we would need to first set
  645. child->parent = node; node->left = child;
  646. and later - when we copy subst into node's position - again
  647. child->parent = subst; subst->left = child;
  648. Altogether a no-op. */
  649. if (subst_parent != node)
  650. {
  651. if (child != NULL)
  652. child->parent = subst_parent;
  653. subst_parent->right = child;
  654. }
  655. /* Update branch_size fields of the parent nodes. */
  656. {
  657. gl_list_node_t p;
  658. for (p = subst_parent; p != NULL; p = p->parent)
  659. p->branch_size--;
  660. }
  661. /* Copy subst into node's position.
  662. (This is safer than to copy subst's value into node, keep node in
  663. place, and free subst.) */
  664. if (subst_parent != node)
  665. {
  666. subst->left = node->left;
  667. subst->left->parent = subst;
  668. }
  669. subst->right = node->right;
  670. subst->right->parent = subst;
  671. subst->color = node->color;
  672. subst->branch_size = node->branch_size;
  673. subst->parent = parent;
  674. if (parent == NULL)
  675. list->root = subst;
  676. else if (parent->left == node)
  677. parent->left = subst;
  678. else /* parent->right == node */
  679. parent->right = subst;
  680. if (removed_color == BLACK)
  681. {
  682. if (child != NULL && child->color == RED)
  683. /* Recolor the child. */
  684. child->color = BLACK;
  685. else
  686. /* Rebalancing starts at child's parent, that is subst_parent -
  687. except when subst_parent == node. In this case, we need to use
  688. its replacement, subst. */
  689. rebalance_after_remove (list, child,
  690. subst_parent != node ? subst_parent : subst);
  691. }
  692. }
  693. }
  694. static gl_list_node_t
  695. gl_tree_nx_add_first (gl_list_t list, const void *elt)
  696. {
  697. /* Create new node. */
  698. gl_list_node_t new_node =
  699. (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
  700. if (new_node == NULL)
  701. return NULL;
  702. new_node->left = NULL;
  703. new_node->right = NULL;
  704. new_node->branch_size = 1;
  705. new_node->value = elt;
  706. #if WITH_HASHTABLE
  707. new_node->h.hashcode =
  708. (list->base.hashcode_fn != NULL
  709. ? list->base.hashcode_fn (new_node->value)
  710. : (size_t)(uintptr_t) new_node->value);
  711. #endif
  712. /* Add it to the tree. */
  713. if (list->root == NULL)
  714. {
  715. new_node->color = BLACK;
  716. list->root = new_node;
  717. new_node->parent = NULL;
  718. }
  719. else
  720. {
  721. gl_list_node_t node;
  722. for (node = list->root; node->left != NULL; )
  723. node = node->left;
  724. node->left = new_node;
  725. new_node->parent = node;
  726. /* Update branch_size fields of the parent nodes. */
  727. {
  728. gl_list_node_t p;
  729. for (p = node; p != NULL; p = p->parent)
  730. p->branch_size++;
  731. }
  732. /* Color and rebalance. */
  733. rebalance_after_add (list, new_node, node);
  734. }
  735. #if WITH_HASHTABLE
  736. /* Add node to the hash table.
  737. Note that this is only possible _after_ the node has been added to the
  738. tree structure, because add_to_bucket() uses node_position(). */
  739. if (add_to_bucket (list, new_node) < 0)
  740. {
  741. gl_tree_remove_node_from_tree (list, new_node);
  742. free (new_node);
  743. return NULL;
  744. }
  745. hash_resize_after_add (list);
  746. #endif
  747. return new_node;
  748. }
  749. static gl_list_node_t
  750. gl_tree_nx_add_last (gl_list_t list, const void *elt)
  751. {
  752. /* Create new node. */
  753. gl_list_node_t new_node =
  754. (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
  755. if (new_node == NULL)
  756. return NULL;
  757. new_node->left = NULL;
  758. new_node->right = NULL;
  759. new_node->branch_size = 1;
  760. new_node->value = elt;
  761. #if WITH_HASHTABLE
  762. new_node->h.hashcode =
  763. (list->base.hashcode_fn != NULL
  764. ? list->base.hashcode_fn (new_node->value)
  765. : (size_t)(uintptr_t) new_node->value);
  766. #endif
  767. /* Add it to the tree. */
  768. if (list->root == NULL)
  769. {
  770. new_node->color = BLACK;
  771. list->root = new_node;
  772. new_node->parent = NULL;
  773. }
  774. else
  775. {
  776. gl_list_node_t node;
  777. for (node = list->root; node->right != NULL; )
  778. node = node->right;
  779. node->right = new_node;
  780. new_node->parent = node;
  781. /* Update branch_size fields of the parent nodes. */
  782. {
  783. gl_list_node_t p;
  784. for (p = node; p != NULL; p = p->parent)
  785. p->branch_size++;
  786. }
  787. /* Color and rebalance. */
  788. rebalance_after_add (list, new_node, node);
  789. }
  790. #if WITH_HASHTABLE
  791. /* Add node to the hash table.
  792. Note that this is only possible _after_ the node has been added to the
  793. tree structure, because add_to_bucket() uses node_position(). */
  794. if (add_to_bucket (list, new_node) < 0)
  795. {
  796. gl_tree_remove_node_from_tree (list, new_node);
  797. free (new_node);
  798. return NULL;
  799. }
  800. hash_resize_after_add (list);
  801. #endif
  802. return new_node;
  803. }
  804. static gl_list_node_t
  805. gl_tree_nx_add_before (gl_list_t list, gl_list_node_t node, const void *elt)
  806. {
  807. /* Create new node. */
  808. gl_list_node_t new_node =
  809. (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
  810. if (new_node == NULL)
  811. return NULL;
  812. new_node->left = NULL;
  813. new_node->right = NULL;
  814. new_node->branch_size = 1;
  815. new_node->value = elt;
  816. #if WITH_HASHTABLE
  817. new_node->h.hashcode =
  818. (list->base.hashcode_fn != NULL
  819. ? list->base.hashcode_fn (new_node->value)
  820. : (size_t)(uintptr_t) new_node->value);
  821. #endif
  822. /* Add it to the tree. */
  823. if (node->left == NULL)
  824. node->left = new_node;
  825. else
  826. {
  827. for (node = node->left; node->right != NULL; )
  828. node = node->right;
  829. node->right = new_node;
  830. }
  831. new_node->parent = node;
  832. /* Update branch_size fields of the parent nodes. */
  833. {
  834. gl_list_node_t p;
  835. for (p = node; p != NULL; p = p->parent)
  836. p->branch_size++;
  837. }
  838. /* Color and rebalance. */
  839. rebalance_after_add (list, new_node, node);
  840. #if WITH_HASHTABLE
  841. /* Add node to the hash table.
  842. Note that this is only possible _after_ the node has been added to the
  843. tree structure, because add_to_bucket() uses node_position(). */
  844. if (add_to_bucket (list, new_node) < 0)
  845. {
  846. gl_tree_remove_node_from_tree (list, new_node);
  847. free (new_node);
  848. return NULL;
  849. }
  850. hash_resize_after_add (list);
  851. #endif
  852. return new_node;
  853. }
  854. static gl_list_node_t
  855. gl_tree_nx_add_after (gl_list_t list, gl_list_node_t node, const void *elt)
  856. {
  857. /* Create new node. */
  858. gl_list_node_t new_node =
  859. (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
  860. if (new_node == NULL)
  861. return NULL;
  862. new_node->left = NULL;
  863. new_node->right = NULL;
  864. new_node->branch_size = 1;
  865. new_node->value = elt;
  866. #if WITH_HASHTABLE
  867. new_node->h.hashcode =
  868. (list->base.hashcode_fn != NULL
  869. ? list->base.hashcode_fn (new_node->value)
  870. : (size_t)(uintptr_t) new_node->value);
  871. #endif
  872. /* Add it to the tree. */
  873. if (node->right == NULL)
  874. node->right = new_node;
  875. else
  876. {
  877. for (node = node->right; node->left != NULL; )
  878. node = node->left;
  879. node->left = new_node;
  880. }
  881. new_node->parent = node;
  882. /* Update branch_size fields of the parent nodes. */
  883. {
  884. gl_list_node_t p;
  885. for (p = node; p != NULL; p = p->parent)
  886. p->branch_size++;
  887. }
  888. /* Color and rebalance. */
  889. rebalance_after_add (list, new_node, node);
  890. #if WITH_HASHTABLE
  891. /* Add node to the hash table.
  892. Note that this is only possible _after_ the node has been added to the
  893. tree structure, because add_to_bucket() uses node_position(). */
  894. if (add_to_bucket (list, new_node) < 0)
  895. {
  896. gl_tree_remove_node_from_tree (list, new_node);
  897. free (new_node);
  898. return NULL;
  899. }
  900. hash_resize_after_add (list);
  901. #endif
  902. return new_node;
  903. }