rec_search.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*-
  2. * Copyright (c) 1990, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the University of
  16. * California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. #if defined(LIBC_SCCS) && !defined(lint)
  34. static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
  35. #endif /* LIBC_SCCS and not lint */
  36. #include <sys/types.h>
  37. #include <errno.h>
  38. #include <stdio.h>
  39. #include "../include/db.h"
  40. #include "recno.h"
  41. /*
  42. * __REC_SEARCH -- Search a btree for a key.
  43. *
  44. * Parameters:
  45. * t: tree to search
  46. * recno: key to find
  47. * op: search operation
  48. *
  49. * Returns:
  50. * EPG for matching record, if any, or the EPG for the location of the
  51. * key, if it were inserted into the tree.
  52. *
  53. * Returns:
  54. * The EPG for matching record, if any, or the EPG for the location
  55. * of the key, if it were inserted into the tree, is entered into
  56. * the bt_cur field of the tree. A pointer to the field is returned.
  57. */
  58. EPG *
  59. __rec_search(t, recno, op)
  60. BTREE *t;
  61. recno_t recno;
  62. enum SRCHOP op;
  63. {
  64. register indx_t index;
  65. register PAGE *h;
  66. EPGNO *parent;
  67. RINTERNAL *r;
  68. pgno_t pg;
  69. indx_t top;
  70. recno_t total;
  71. int sverrno;
  72. BT_CLR(t);
  73. for (pg = P_ROOT, total = 0;;) {
  74. if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
  75. goto err;
  76. if (h->flags & P_RLEAF) {
  77. t->bt_cur.page = h;
  78. t->bt_cur.index = recno - total;
  79. return (&t->bt_cur);
  80. }
  81. for (index = 0, top = NEXTINDEX(h);;) {
  82. r = GETRINTERNAL(h, index);
  83. if (++index == top || total + r->nrecs > recno)
  84. break;
  85. total += r->nrecs;
  86. }
  87. BT_PUSH(t, pg, index - 1);
  88. pg = r->pgno;
  89. switch (op) {
  90. case SDELETE:
  91. --GETRINTERNAL(h, (index - 1))->nrecs;
  92. mpool_put(t->bt_mp, h, MPOOL_DIRTY);
  93. break;
  94. case SINSERT:
  95. ++GETRINTERNAL(h, (index - 1))->nrecs;
  96. mpool_put(t->bt_mp, h, MPOOL_DIRTY);
  97. break;
  98. case SEARCH:
  99. mpool_put(t->bt_mp, h, 0);
  100. break;
  101. }
  102. }
  103. /* Try and recover the tree. */
  104. err: sverrno = errno;
  105. if (op != SEARCH)
  106. while ((parent = BT_POP(t)) != NULL) {
  107. if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
  108. break;
  109. if (op == SINSERT)
  110. --GETRINTERNAL(h, parent->index)->nrecs;
  111. else
  112. ++GETRINTERNAL(h, parent->index)->nrecs;
  113. mpool_put(t->bt_mp, h, MPOOL_DIRTY);
  114. }
  115. errno = sverrno;
  116. return (NULL);
  117. }