gl_anytree_list2.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. /* Sequential list data type implemented by a binary tree.
  2. Copyright (C) 2006-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_avltree_list.c, gl_rbtree_list.c,
  15. gl_avltreehash_list.c, gl_rbtreehash_list.c. */
  16. static gl_list_t
  17. gl_tree_nx_create_empty (gl_list_implementation_t implementation,
  18. gl_listelement_equals_fn equals_fn,
  19. gl_listelement_hashcode_fn hashcode_fn,
  20. gl_listelement_dispose_fn dispose_fn,
  21. bool allow_duplicates)
  22. {
  23. struct gl_list_impl *list = (struct gl_list_impl *) malloc (sizeof (struct gl_list_impl));
  24. if (list == NULL)
  25. return NULL;
  26. list->base.vtable = implementation;
  27. list->base.equals_fn = equals_fn;
  28. list->base.hashcode_fn = hashcode_fn;
  29. list->base.dispose_fn = dispose_fn;
  30. list->base.allow_duplicates = allow_duplicates;
  31. #if WITH_HASHTABLE
  32. list->table_size = 11;
  33. list->table =
  34. (gl_hash_entry_t *) calloc (list->table_size, sizeof (gl_hash_entry_t));
  35. if (list->table == NULL)
  36. goto fail;
  37. #endif
  38. list->root = NULL;
  39. return list;
  40. #if WITH_HASHTABLE
  41. fail:
  42. free (list);
  43. return NULL;
  44. #endif
  45. }
  46. static size_t _GL_ATTRIBUTE_PURE
  47. gl_tree_size (gl_list_t list)
  48. {
  49. return (list->root != NULL ? list->root->branch_size : 0);
  50. }
  51. static const void * _GL_ATTRIBUTE_PURE
  52. gl_tree_node_value (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED,
  53. gl_list_node_t node)
  54. {
  55. return node->value;
  56. }
  57. static int
  58. gl_tree_node_nx_set_value (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED,
  59. gl_list_node_t node, const void *elt)
  60. {
  61. #if WITH_HASHTABLE
  62. if (elt != node->value)
  63. {
  64. size_t new_hashcode =
  65. (list->base.hashcode_fn != NULL
  66. ? list->base.hashcode_fn (elt)
  67. : (size_t)(uintptr_t) elt);
  68. if (new_hashcode != node->h.hashcode)
  69. {
  70. remove_from_bucket (list, node);
  71. node->value = elt;
  72. node->h.hashcode = new_hashcode;
  73. if (add_to_bucket (list, node) < 0)
  74. {
  75. /* Out of memory. We removed node from a bucket but cannot add
  76. it to another bucket. In order to avoid inconsistencies, we
  77. must remove node entirely from the list. */
  78. gl_tree_remove_node_from_tree (list, node);
  79. free (node);
  80. return -1;
  81. }
  82. }
  83. else
  84. node->value = elt;
  85. }
  86. #else
  87. node->value = elt;
  88. #endif
  89. return 0;
  90. }
  91. static gl_list_node_t _GL_ATTRIBUTE_PURE
  92. gl_tree_next_node (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED,
  93. gl_list_node_t node)
  94. {
  95. if (node->right != NULL)
  96. {
  97. node = node->right;
  98. while (node->left != NULL)
  99. node = node->left;
  100. }
  101. else
  102. {
  103. while (node->parent != NULL && node->parent->right == node)
  104. node = node->parent;
  105. node = node->parent;
  106. }
  107. return node;
  108. }
  109. static gl_list_node_t _GL_ATTRIBUTE_PURE
  110. gl_tree_previous_node (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED,
  111. gl_list_node_t node)
  112. {
  113. if (node->left != NULL)
  114. {
  115. node = node->left;
  116. while (node->right != NULL)
  117. node = node->right;
  118. }
  119. else
  120. {
  121. while (node->parent != NULL && node->parent->left == node)
  122. node = node->parent;
  123. node = node->parent;
  124. }
  125. return node;
  126. }
  127. /* Returns the node at the given position < gl_tree_size (list). */
  128. static gl_list_node_t _GL_ATTRIBUTE_PURE
  129. node_at (gl_list_node_t root, size_t position)
  130. {
  131. /* Here we know that root != NULL. */
  132. gl_list_node_t node = root;
  133. for (;;)
  134. {
  135. if (node->left != NULL)
  136. {
  137. if (position < node->left->branch_size)
  138. {
  139. node = node->left;
  140. continue;
  141. }
  142. position -= node->left->branch_size;
  143. }
  144. if (position == 0)
  145. break;
  146. position--;
  147. node = node->right;
  148. }
  149. return node;
  150. }
  151. static const void * _GL_ATTRIBUTE_PURE
  152. gl_tree_get_at (gl_list_t list, size_t position)
  153. {
  154. gl_list_node_t node = list->root;
  155. if (!(node != NULL && position < node->branch_size))
  156. /* Invalid argument. */
  157. abort ();
  158. node = node_at (node, position);
  159. return node->value;
  160. }
  161. static gl_list_node_t
  162. gl_tree_nx_set_at (gl_list_t list, size_t position, const void *elt)
  163. {
  164. gl_list_node_t node = list->root;
  165. if (!(node != NULL && position < node->branch_size))
  166. /* Invalid argument. */
  167. abort ();
  168. node = node_at (node, position);
  169. #if WITH_HASHTABLE
  170. if (elt != node->value)
  171. {
  172. size_t new_hashcode =
  173. (list->base.hashcode_fn != NULL
  174. ? list->base.hashcode_fn (elt)
  175. : (size_t)(uintptr_t) elt);
  176. if (new_hashcode != node->h.hashcode)
  177. {
  178. remove_from_bucket (list, node);
  179. node->value = elt;
  180. node->h.hashcode = new_hashcode;
  181. if (add_to_bucket (list, node) < 0)
  182. {
  183. /* Out of memory. We removed node from a bucket but cannot add
  184. it to another bucket. In order to avoid inconsistencies, we
  185. must remove node entirely from the list. */
  186. gl_tree_remove_node_from_tree (list, node);
  187. free (node);
  188. return NULL;
  189. }
  190. }
  191. else
  192. node->value = elt;
  193. }
  194. #else
  195. node->value = elt;
  196. #endif
  197. return node;
  198. }
  199. #if !WITH_HASHTABLE
  200. static gl_list_node_t _GL_ATTRIBUTE_PURE
  201. gl_tree_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
  202. const void *elt)
  203. {
  204. if (!(start_index <= end_index
  205. && end_index <= (list->root != NULL ? list->root->branch_size : 0)))
  206. /* Invalid arguments. */
  207. abort ();
  208. {
  209. gl_listelement_equals_fn equals = list->base.equals_fn;
  210. /* Iterate across all elements. */
  211. gl_list_node_t node = list->root;
  212. iterstack_t stack;
  213. iterstack_item_t *stack_ptr = &stack[0];
  214. size_t index = 0;
  215. if (start_index == 0)
  216. {
  217. /* Consider all elements. */
  218. for (;;)
  219. {
  220. /* Descend on left branch. */
  221. for (;;)
  222. {
  223. if (node == NULL)
  224. break;
  225. stack_ptr->node = node;
  226. stack_ptr->rightp = 0;
  227. node = node->left;
  228. stack_ptr++;
  229. }
  230. /* Climb up again. */
  231. for (;;)
  232. {
  233. if (stack_ptr == &stack[0])
  234. return NULL;
  235. stack_ptr--;
  236. if (!stack_ptr->rightp)
  237. break;
  238. }
  239. node = stack_ptr->node;
  240. /* Test against current element. */
  241. if (equals != NULL ? equals (elt, node->value) : elt == node->value)
  242. return node;
  243. index++;
  244. if (index >= end_index)
  245. return NULL;
  246. /* Descend on right branch. */
  247. stack_ptr->rightp = 1;
  248. node = node->right;
  249. stack_ptr++;
  250. }
  251. }
  252. else
  253. {
  254. /* Consider only elements at indices >= start_index.
  255. In this case, rightp contains the difference between the start_index
  256. for the parent node and the one for the child node (0 when the child
  257. node is the parent's left child, > 0 when the child is the parent's
  258. right child). */
  259. for (;;)
  260. {
  261. /* Descend on left branch. */
  262. for (;;)
  263. {
  264. if (node == NULL)
  265. break;
  266. if (node->branch_size <= start_index)
  267. break;
  268. stack_ptr->node = node;
  269. stack_ptr->rightp = 0;
  270. node = node->left;
  271. stack_ptr++;
  272. }
  273. /* Climb up again. */
  274. for (;;)
  275. {
  276. if (stack_ptr == &stack[0])
  277. return NULL;
  278. stack_ptr--;
  279. if (!stack_ptr->rightp)
  280. break;
  281. start_index += stack_ptr->rightp;
  282. }
  283. node = stack_ptr->node;
  284. {
  285. size_t left_branch_size1 =
  286. (node->left != NULL ? node->left->branch_size : 0) + 1;
  287. if (start_index < left_branch_size1)
  288. {
  289. /* Test against current element. */
  290. if (equals != NULL ? equals (elt, node->value) : elt == node->value)
  291. return node;
  292. /* Now that we have considered all indices < left_branch_size1,
  293. we can increment start_index. */
  294. start_index = left_branch_size1;
  295. }
  296. index++;
  297. if (index >= end_index)
  298. return NULL;
  299. /* Descend on right branch. */
  300. start_index -= left_branch_size1;
  301. stack_ptr->rightp = left_branch_size1;
  302. }
  303. node = node->right;
  304. stack_ptr++;
  305. }
  306. }
  307. }
  308. }
  309. static size_t _GL_ATTRIBUTE_PURE
  310. gl_tree_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
  311. const void *elt)
  312. {
  313. if (!(start_index <= end_index
  314. && end_index <= (list->root != NULL ? list->root->branch_size : 0)))
  315. /* Invalid arguments. */
  316. abort ();
  317. {
  318. gl_listelement_equals_fn equals = list->base.equals_fn;
  319. /* Iterate across all elements. */
  320. gl_list_node_t node = list->root;
  321. iterstack_t stack;
  322. iterstack_item_t *stack_ptr = &stack[0];
  323. size_t index = 0;
  324. if (start_index == 0)
  325. {
  326. /* Consider all elements. */
  327. for (;;)
  328. {
  329. /* Descend on left branch. */
  330. for (;;)
  331. {
  332. if (node == NULL)
  333. break;
  334. stack_ptr->node = node;
  335. stack_ptr->rightp = 0;
  336. node = node->left;
  337. stack_ptr++;
  338. }
  339. /* Climb up again. */
  340. for (;;)
  341. {
  342. if (stack_ptr == &stack[0])
  343. return (size_t)(-1);
  344. stack_ptr--;
  345. if (!stack_ptr->rightp)
  346. break;
  347. }
  348. node = stack_ptr->node;
  349. /* Test against current element. */
  350. if (equals != NULL ? equals (elt, node->value) : elt == node->value)
  351. return index;
  352. index++;
  353. if (index >= end_index)
  354. return (size_t)(-1);
  355. /* Descend on right branch. */
  356. stack_ptr->rightp = 1;
  357. node = node->right;
  358. stack_ptr++;
  359. }
  360. }
  361. else
  362. {
  363. /* Consider only elements at indices >= start_index.
  364. In this case, rightp contains the difference between the start_index
  365. for the parent node and the one for the child node (0 when the child
  366. node is the parent's left child, > 0 when the child is the parent's
  367. right child). */
  368. for (;;)
  369. {
  370. /* Descend on left branch. */
  371. for (;;)
  372. {
  373. if (node == NULL)
  374. break;
  375. if (node->branch_size <= start_index)
  376. break;
  377. stack_ptr->node = node;
  378. stack_ptr->rightp = 0;
  379. node = node->left;
  380. stack_ptr++;
  381. }
  382. /* Climb up again. */
  383. for (;;)
  384. {
  385. if (stack_ptr == &stack[0])
  386. return (size_t)(-1);
  387. stack_ptr--;
  388. if (!stack_ptr->rightp)
  389. break;
  390. start_index += stack_ptr->rightp;
  391. }
  392. node = stack_ptr->node;
  393. {
  394. size_t left_branch_size1 =
  395. (node->left != NULL ? node->left->branch_size : 0) + 1;
  396. if (start_index < left_branch_size1)
  397. {
  398. /* Test against current element. */
  399. if (equals != NULL ? equals (elt, node->value) : elt == node->value)
  400. return index;
  401. /* Now that we have considered all indices < left_branch_size1,
  402. we can increment start_index. */
  403. start_index = left_branch_size1;
  404. }
  405. index++;
  406. if (index >= end_index)
  407. return (size_t)(-1);
  408. /* Descend on right branch. */
  409. start_index -= left_branch_size1;
  410. stack_ptr->rightp = left_branch_size1;
  411. }
  412. node = node->right;
  413. stack_ptr++;
  414. }
  415. }
  416. }
  417. }
  418. #endif
  419. static gl_list_node_t
  420. gl_tree_nx_add_at (gl_list_t list, size_t position, const void *elt)
  421. {
  422. size_t count = (list->root != NULL ? list->root->branch_size : 0);
  423. if (!(position <= count))
  424. /* Invalid argument. */
  425. abort ();
  426. if (position == count)
  427. return gl_tree_nx_add_last (list, elt);
  428. else
  429. return gl_tree_nx_add_before (list, node_at (list->root, position), elt);
  430. }
  431. static bool
  432. gl_tree_remove_node (gl_list_t list, gl_list_node_t node)
  433. {
  434. #if WITH_HASHTABLE
  435. /* Remove node from the hash table.
  436. Note that this is only possible _before_ the node is removed from the
  437. tree structure, because remove_from_bucket() uses node_position(). */
  438. remove_from_bucket (list, node);
  439. #endif
  440. gl_tree_remove_node_from_tree (list, node);
  441. if (list->base.dispose_fn != NULL)
  442. list->base.dispose_fn (node->value);
  443. free (node);
  444. return true;
  445. }
  446. static bool
  447. gl_tree_remove_at (gl_list_t list, size_t position)
  448. {
  449. gl_list_node_t node = list->root;
  450. if (!(node != NULL && position < node->branch_size))
  451. /* Invalid argument. */
  452. abort ();
  453. node = node_at (node, position);
  454. return gl_tree_remove_node (list, node);
  455. }
  456. static bool
  457. gl_tree_remove (gl_list_t list, const void *elt)
  458. {
  459. if (list->root != NULL)
  460. {
  461. gl_list_node_t node =
  462. gl_tree_search_from_to (list, 0, list->root->branch_size, elt);
  463. if (node != NULL)
  464. return gl_tree_remove_node (list, node);
  465. }
  466. return false;
  467. }
  468. #if !WITH_HASHTABLE
  469. static void
  470. gl_tree_list_free (gl_list_t list)
  471. {
  472. /* Iterate across all elements in post-order. */
  473. gl_list_node_t node = list->root;
  474. iterstack_t stack;
  475. iterstack_item_t *stack_ptr = &stack[0];
  476. for (;;)
  477. {
  478. /* Descend on left branch. */
  479. for (;;)
  480. {
  481. if (node == NULL)
  482. break;
  483. stack_ptr->node = node;
  484. stack_ptr->rightp = false;
  485. node = node->left;
  486. stack_ptr++;
  487. }
  488. /* Climb up again. */
  489. for (;;)
  490. {
  491. if (stack_ptr == &stack[0])
  492. goto done_iterate;
  493. stack_ptr--;
  494. node = stack_ptr->node;
  495. if (!stack_ptr->rightp)
  496. break;
  497. /* Free the current node. */
  498. if (list->base.dispose_fn != NULL)
  499. list->base.dispose_fn (node->value);
  500. free (node);
  501. }
  502. /* Descend on right branch. */
  503. stack_ptr->rightp = true;
  504. node = node->right;
  505. stack_ptr++;
  506. }
  507. done_iterate:
  508. free (list);
  509. }
  510. #endif
  511. /* --------------------- gl_list_iterator_t Data Type --------------------- */
  512. static gl_list_iterator_t _GL_ATTRIBUTE_PURE
  513. gl_tree_iterator (gl_list_t list)
  514. {
  515. gl_list_iterator_t result;
  516. gl_list_node_t node;
  517. result.vtable = list->base.vtable;
  518. result.list = list;
  519. /* Start node is the leftmost node. */
  520. node = list->root;
  521. if (node != NULL)
  522. while (node->left != NULL)
  523. node = node->left;
  524. result.p = node;
  525. /* End point is past the rightmost node. */
  526. result.q = NULL;
  527. #if defined GCC_LINT || defined lint
  528. result.i = 0;
  529. result.j = 0;
  530. result.count = 0;
  531. #endif
  532. return result;
  533. }
  534. static gl_list_iterator_t _GL_ATTRIBUTE_PURE
  535. gl_tree_iterator_from_to (gl_list_t list, size_t start_index, size_t end_index)
  536. {
  537. size_t count = (list->root != NULL ? list->root->branch_size : 0);
  538. gl_list_iterator_t result;
  539. if (!(start_index <= end_index && end_index <= count))
  540. /* Invalid arguments. */
  541. abort ();
  542. result.vtable = list->base.vtable;
  543. result.list = list;
  544. /* Start node is the node at position start_index. */
  545. result.p = (start_index < count ? node_at (list->root, start_index) : NULL);
  546. /* End point is the node at position end_index. */
  547. result.q = (end_index < count ? node_at (list->root, end_index) : NULL);
  548. #if defined GCC_LINT || defined lint
  549. result.i = 0;
  550. result.j = 0;
  551. result.count = 0;
  552. #endif
  553. return result;
  554. }
  555. static bool
  556. gl_tree_iterator_next (gl_list_iterator_t *iterator,
  557. const void **eltp, gl_list_node_t *nodep)
  558. {
  559. if (iterator->p != iterator->q)
  560. {
  561. gl_list_node_t node = (gl_list_node_t) iterator->p;
  562. *eltp = node->value;
  563. if (nodep != NULL)
  564. *nodep = node;
  565. /* Advance to the next node. */
  566. if (node->right != NULL)
  567. {
  568. node = node->right;
  569. while (node->left != NULL)
  570. node = node->left;
  571. }
  572. else
  573. {
  574. while (node->parent != NULL && node->parent->right == node)
  575. node = node->parent;
  576. node = node->parent;
  577. }
  578. iterator->p = node;
  579. return true;
  580. }
  581. else
  582. return false;
  583. }
  584. static void
  585. gl_tree_iterator_free (gl_list_iterator_t *iterator _GL_ATTRIBUTE_MAYBE_UNUSED)
  586. {
  587. }
  588. /* ---------------------- Sorted gl_list_t Data Type ---------------------- */
  589. static gl_list_node_t _GL_ATTRIBUTE_PURE
  590. gl_tree_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar,
  591. const void *elt)
  592. {
  593. gl_list_node_t node;
  594. for (node = list->root; node != NULL; )
  595. {
  596. int cmp = compar (node->value, elt);
  597. if (cmp < 0)
  598. node = node->right;
  599. else if (cmp > 0)
  600. node = node->left;
  601. else /* cmp == 0 */
  602. {
  603. /* We have an element equal to ELT. But we need the leftmost such
  604. element. */
  605. gl_list_node_t found = node;
  606. node = node->left;
  607. for (; node != NULL; )
  608. {
  609. int cmp2 = compar (node->value, elt);
  610. if (cmp2 < 0)
  611. node = node->right;
  612. else if (cmp2 > 0)
  613. /* The list was not sorted. */
  614. abort ();
  615. else /* cmp2 == 0 */
  616. {
  617. found = node;
  618. node = node->left;
  619. }
  620. }
  621. return found;
  622. }
  623. }
  624. return NULL;
  625. }
  626. static gl_list_node_t _GL_ATTRIBUTE_PURE
  627. gl_tree_sortedlist_search_from_to (gl_list_t list,
  628. gl_listelement_compar_fn compar,
  629. size_t low, size_t high,
  630. const void *elt)
  631. {
  632. gl_list_node_t node;
  633. if (!(low <= high
  634. && high <= (list->root != NULL ? list->root->branch_size : 0)))
  635. /* Invalid arguments. */
  636. abort ();
  637. for (node = list->root; node != NULL; )
  638. {
  639. size_t left_branch_size =
  640. (node->left != NULL ? node->left->branch_size : 0);
  641. if (low > left_branch_size)
  642. {
  643. low -= left_branch_size + 1;
  644. high -= left_branch_size + 1;
  645. node = node->right;
  646. }
  647. else if (high <= left_branch_size)
  648. node = node->left;
  649. else
  650. {
  651. /* Here low <= left_branch_size < high. */
  652. int cmp = compar (node->value, elt);
  653. if (cmp < 0)
  654. {
  655. low = 0;
  656. high -= left_branch_size + 1;
  657. node = node->right;
  658. }
  659. else if (cmp > 0)
  660. node = node->left;
  661. else /* cmp == 0 */
  662. {
  663. /* We have an element equal to ELT. But we need the leftmost
  664. such element. */
  665. gl_list_node_t found = node;
  666. node = node->left;
  667. for (; node != NULL; )
  668. {
  669. size_t left_branch_size2 =
  670. (node->left != NULL ? node->left->branch_size : 0);
  671. if (low > left_branch_size2)
  672. {
  673. low -= left_branch_size2 + 1;
  674. node = node->right;
  675. }
  676. else
  677. {
  678. /* Here low <= left_branch_size2. */
  679. int cmp2 = compar (node->value, elt);
  680. if (cmp2 < 0)
  681. {
  682. low = 0;
  683. node = node->right;
  684. }
  685. else if (cmp2 > 0)
  686. /* The list was not sorted. */
  687. abort ();
  688. else /* cmp2 == 0 */
  689. {
  690. found = node;
  691. node = node->left;
  692. }
  693. }
  694. }
  695. return found;
  696. }
  697. }
  698. }
  699. return NULL;
  700. }
  701. static size_t _GL_ATTRIBUTE_PURE
  702. gl_tree_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar,
  703. const void *elt)
  704. {
  705. gl_list_node_t node;
  706. size_t position;
  707. for (node = list->root, position = 0; node != NULL; )
  708. {
  709. int cmp = compar (node->value, elt);
  710. if (cmp < 0)
  711. {
  712. if (node->left != NULL)
  713. position += node->left->branch_size;
  714. position++;
  715. node = node->right;
  716. }
  717. else if (cmp > 0)
  718. node = node->left;
  719. else /* cmp == 0 */
  720. {
  721. /* We have an element equal to ELT. But we need the leftmost such
  722. element. */
  723. size_t found_position =
  724. position + (node->left != NULL ? node->left->branch_size : 0);
  725. node = node->left;
  726. for (; node != NULL; )
  727. {
  728. int cmp2 = compar (node->value, elt);
  729. if (cmp2 < 0)
  730. {
  731. if (node->left != NULL)
  732. position += node->left->branch_size;
  733. position++;
  734. node = node->right;
  735. }
  736. else if (cmp2 > 0)
  737. /* The list was not sorted. */
  738. abort ();
  739. else /* cmp2 == 0 */
  740. {
  741. found_position =
  742. position
  743. + (node->left != NULL ? node->left->branch_size : 0);
  744. node = node->left;
  745. }
  746. }
  747. return found_position;
  748. }
  749. }
  750. return (size_t)(-1);
  751. }
  752. static size_t _GL_ATTRIBUTE_PURE
  753. gl_tree_sortedlist_indexof_from_to (gl_list_t list,
  754. gl_listelement_compar_fn compar,
  755. size_t low, size_t high,
  756. const void *elt)
  757. {
  758. gl_list_node_t node;
  759. size_t position;
  760. if (!(low <= high
  761. && high <= (list->root != NULL ? list->root->branch_size : 0)))
  762. /* Invalid arguments. */
  763. abort ();
  764. for (node = list->root, position = 0; node != NULL; )
  765. {
  766. size_t left_branch_size =
  767. (node->left != NULL ? node->left->branch_size : 0);
  768. if (low > left_branch_size)
  769. {
  770. low -= left_branch_size + 1;
  771. high -= left_branch_size + 1;
  772. position += left_branch_size + 1;
  773. node = node->right;
  774. }
  775. else if (high <= left_branch_size)
  776. node = node->left;
  777. else
  778. {
  779. /* Here low <= left_branch_size < high. */
  780. int cmp = compar (node->value, elt);
  781. if (cmp < 0)
  782. {
  783. low = 0;
  784. high -= left_branch_size + 1;
  785. position += left_branch_size + 1;
  786. node = node->right;
  787. }
  788. else if (cmp > 0)
  789. node = node->left;
  790. else /* cmp == 0 */
  791. {
  792. /* We have an element equal to ELT. But we need the leftmost
  793. such element. */
  794. size_t found_position =
  795. position + (node->left != NULL ? node->left->branch_size : 0);
  796. node = node->left;
  797. for (; node != NULL; )
  798. {
  799. size_t left_branch_size2 =
  800. (node->left != NULL ? node->left->branch_size : 0);
  801. if (low > left_branch_size2)
  802. {
  803. low -= left_branch_size2 + 1;
  804. node = node->right;
  805. }
  806. else
  807. {
  808. /* Here low <= left_branch_size2. */
  809. int cmp2 = compar (node->value, elt);
  810. if (cmp2 < 0)
  811. {
  812. position += left_branch_size2 + 1;
  813. node = node->right;
  814. }
  815. else if (cmp2 > 0)
  816. /* The list was not sorted. */
  817. abort ();
  818. else /* cmp2 == 0 */
  819. {
  820. found_position = position + left_branch_size2;
  821. node = node->left;
  822. }
  823. }
  824. }
  825. return found_position;
  826. }
  827. }
  828. }
  829. return (size_t)(-1);
  830. }
  831. static gl_list_node_t
  832. gl_tree_sortedlist_nx_add (gl_list_t list, gl_listelement_compar_fn compar,
  833. const void *elt)
  834. {
  835. gl_list_node_t node = list->root;
  836. if (node == NULL)
  837. return gl_tree_nx_add_first (list, elt);
  838. for (;;)
  839. {
  840. int cmp = compar (node->value, elt);
  841. if (cmp < 0)
  842. {
  843. if (node->right == NULL)
  844. return gl_tree_nx_add_after (list, node, elt);
  845. node = node->right;
  846. }
  847. else if (cmp > 0)
  848. {
  849. if (node->left == NULL)
  850. return gl_tree_nx_add_before (list, node, elt);
  851. node = node->left;
  852. }
  853. else /* cmp == 0 */
  854. return gl_tree_nx_add_before (list, node, elt);
  855. }
  856. }
  857. static bool
  858. gl_tree_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar,
  859. const void *elt)
  860. {
  861. gl_list_node_t node = gl_tree_sortedlist_search (list, compar, elt);
  862. if (node != NULL)
  863. return gl_tree_remove_node (list, node);
  864. else
  865. return false;
  866. }