bintree_insert.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*********************** -*- Mode: C -*- ***********************
  2. * File : bintree_insert.c
  3. *---------------------------------------------------------------
  4. * Description
  5. * ===========
  6. * This operation adds a client node to the specified tree.
  7. *
  8. * tree - the "tree" instance to invoke this operation upon
  9. * clientnode - a pointer to a client node. NB the tree can find the
  10. * necessary util_BintreeNodeT from it's stored offset.
  11. *
  12. * RETURNS
  13. * 0 if the "clientnode" is added correctly to the tree.
  14. *
  15. * If another "clientnode" already exists in the tree with the same key, then
  16. * -1 is returned, and the tree remains unchanged.
  17. *
  18. * If the "clientnode" had not been initialised, then an assert will fire.
  19. *
  20. * If the bintree "node" is already part of a tree, then an assert will fire.
  21. *
  22. *---------------------------------------------------------------
  23. * Author : Graeme McKerrell
  24. * Created On : Wed Jan 28 10:05:11 2004
  25. * Status : TESTED
  26. *---------------------------------------------------------------
  27. * HISTORY
  28. * 7-Dec-2004 Graeme McKerrell
  29. * Renamed to the "lub_" namespace
  30. * 5-May-2004 Graeme McKerrell
  31. * updates following review
  32. * 2-Mar-2004 Graeme McKerrell
  33. * fixed so that the insertion order is correct
  34. * 9-Feb-2004 Graeme McKerrell
  35. * updated to use the new getkey prototype and new node, key ordering
  36. * 28-Jan-2004 Graeme McKerrell
  37. * Initial version
  38. *---------------------------------------------------------------
  39. * Copyright (C) 2004 3Com Corporation. All Rights Reserved.
  40. **************************************************************** */
  41. #include <assert.h>
  42. #include "private.h"
  43. /*--------------------------------------------------------- */
  44. int
  45. lub_bintree_insert(lub_bintree_t *this,
  46. void *clientnode)
  47. {
  48. int result = -1;
  49. lub_bintree_node_t *new;
  50. lub_bintree_key_t key;
  51. assert(clientnode);
  52. if( NULL != clientnode)
  53. {
  54. /* obtain the control block from the clientnode */
  55. new = lub_bintree_getnode(this,clientnode);
  56. /* check this node is not currently in another tree */
  57. assert(new->left == NULL);
  58. assert(new->right == NULL);
  59. /* add this node to the splay tree */
  60. /* Insert "node" into the tree , unless it's already there. */
  61. if (NULL == this->root)
  62. {
  63. this->root = new;
  64. this->root->left = this->root->right = NULL;
  65. result = 0;
  66. }
  67. else
  68. {
  69. int comp;
  70. /* get a key from the node */
  71. this->getkeyFn(clientnode,&key);
  72. /* do the biz */
  73. this->root = lub_bintree_splay(this,this->root,&key);
  74. /*
  75. * compare the new key with the detail found
  76. * in the tree
  77. */
  78. comp = lub_bintree_compare(this,this->root,&key);
  79. if (comp > 0)
  80. {
  81. new->left = this->root->left;
  82. new->right = this->root;
  83. this->root->left = NULL;
  84. result = 0;
  85. }
  86. else if (comp < 0)
  87. {
  88. new->right = this->root->right;
  89. new->left = this->root;
  90. this->root->right = NULL;
  91. result = 0;
  92. }
  93. else
  94. {
  95. /* We get here if it's already in the tree */
  96. }
  97. }
  98. if(0 == result)
  99. {
  100. /* update the tree root */
  101. this->root = new;
  102. }
  103. }
  104. /* added OK */
  105. return result;
  106. }
  107. /*--------------------------------------------------------- */