bt_utils.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*-
  2. * Copyright (c) 1990, 1993, 1994
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Mike Olson.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. All advertising materials mentioning features or use of this software
  17. * must display the following acknowledgement:
  18. * This product includes software developed by the University of
  19. * California, Berkeley and its contributors.
  20. * 4. Neither the name of the University nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. * SUCH DAMAGE.
  35. */
  36. #if defined(LIBC_SCCS) && !defined(lint)
  37. static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
  38. #endif /* LIBC_SCCS and not lint */
  39. #include <sys/param.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <db.h>
  44. #include "btree.h"
  45. /*
  46. * __bt_ret --
  47. * Build return key/data pair.
  48. *
  49. * Parameters:
  50. * t: tree
  51. * e: key/data pair to be returned
  52. * key: user's key structure (NULL if not to be filled in)
  53. * rkey: memory area to hold key
  54. * data: user's data structure (NULL if not to be filled in)
  55. * rdata: memory area to hold data
  56. * copy: always copy the key/data item
  57. *
  58. * Returns:
  59. * RET_SUCCESS, RET_ERROR.
  60. */
  61. int
  62. __bt_ret(t, e, key, rkey, data, rdata, copy)
  63. BTREE *t;
  64. EPG *e;
  65. DBT *key, *rkey, *data, *rdata;
  66. int copy;
  67. {
  68. BLEAF *bl;
  69. void *p;
  70. bl = GETBLEAF(e->page, e->index);
  71. /*
  72. * We must copy big keys/data to make them contiguous. Otherwise,
  73. * leave the page pinned and don't copy unless the user specified
  74. * concurrent access.
  75. */
  76. if (key == NULL)
  77. goto dataonly;
  78. if (bl->flags & P_BIGKEY) {
  79. if (__ovfl_get(t, bl->bytes,
  80. &key->size, &rkey->data, &rkey->size))
  81. return (RET_ERROR);
  82. key->data = rkey->data;
  83. } else if (copy || F_ISSET(t, B_DB_LOCK)) {
  84. if (bl->ksize > rkey->size) {
  85. p = (void *)(rkey->data == NULL ?
  86. malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
  87. if (p == NULL)
  88. return (RET_ERROR);
  89. rkey->data = p;
  90. rkey->size = bl->ksize;
  91. }
  92. memmove(rkey->data, bl->bytes, bl->ksize);
  93. key->size = bl->ksize;
  94. key->data = rkey->data;
  95. } else {
  96. key->size = bl->ksize;
  97. key->data = bl->bytes;
  98. }
  99. dataonly:
  100. if (data == NULL)
  101. return (RET_SUCCESS);
  102. if (bl->flags & P_BIGDATA) {
  103. if (__ovfl_get(t, bl->bytes + bl->ksize,
  104. &data->size, &rdata->data, &rdata->size))
  105. return (RET_ERROR);
  106. data->data = rdata->data;
  107. } else if (copy || F_ISSET(t, B_DB_LOCK)) {
  108. /* Use +1 in case the first record retrieved is 0 length. */
  109. if (bl->dsize + 1 > rdata->size) {
  110. p = (void *)(rdata->data == NULL ?
  111. malloc(bl->dsize + 1) :
  112. realloc(rdata->data, bl->dsize + 1));
  113. if (p == NULL)
  114. return (RET_ERROR);
  115. rdata->data = p;
  116. rdata->size = bl->dsize + 1;
  117. }
  118. memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
  119. data->size = bl->dsize;
  120. data->data = rdata->data;
  121. } else {
  122. data->size = bl->dsize;
  123. data->data = bl->bytes + bl->ksize;
  124. }
  125. return (RET_SUCCESS);
  126. }
  127. /*
  128. * __BT_CMP -- Compare a key to a given record.
  129. *
  130. * Parameters:
  131. * t: tree
  132. * k1: DBT pointer of first arg to comparison
  133. * e: pointer to EPG for comparison
  134. *
  135. * Returns:
  136. * < 0 if k1 is < record
  137. * = 0 if k1 is = record
  138. * > 0 if k1 is > record
  139. */
  140. int
  141. __bt_cmp(t, k1, e)
  142. BTREE *t;
  143. const DBT *k1;
  144. EPG *e;
  145. {
  146. BINTERNAL *bi;
  147. BLEAF *bl;
  148. DBT k2;
  149. PAGE *h;
  150. void *bigkey;
  151. /*
  152. * The left-most key on internal pages, at any level of the tree, is
  153. * guaranteed by the following code to be less than any user key.
  154. * This saves us from having to update the leftmost key on an internal
  155. * page when the user inserts a new key in the tree smaller than
  156. * anything we've yet seen.
  157. */
  158. h = e->page;
  159. if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
  160. return (1);
  161. bigkey = NULL;
  162. if (h->flags & P_BLEAF) {
  163. bl = GETBLEAF(h, e->index);
  164. if (bl->flags & P_BIGKEY)
  165. bigkey = bl->bytes;
  166. else {
  167. k2.data = bl->bytes;
  168. k2.size = bl->ksize;
  169. }
  170. } else {
  171. bi = GETBINTERNAL(h, e->index);
  172. if (bi->flags & P_BIGKEY)
  173. bigkey = bi->bytes;
  174. else {
  175. k2.data = bi->bytes;
  176. k2.size = bi->ksize;
  177. }
  178. }
  179. if (bigkey) {
  180. if (__ovfl_get(t, bigkey,
  181. &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
  182. return (RET_ERROR);
  183. k2.data = t->bt_rdata.data;
  184. }
  185. return ((*t->bt_cmp)(k1, &k2));
  186. }
  187. /*
  188. * __BT_DEFCMP -- Default comparison routine.
  189. *
  190. * Parameters:
  191. * a: DBT #1
  192. * b: DBT #2
  193. *
  194. * Returns:
  195. * < 0 if a is < b
  196. * = 0 if a is = b
  197. * > 0 if a is > b
  198. */
  199. int
  200. __bt_defcmp(a, b)
  201. const DBT *a, *b;
  202. {
  203. register size_t len;
  204. register u_char *p1, *p2;
  205. /*
  206. * XXX
  207. * If a size_t doesn't fit in an int, this routine can lose.
  208. * What we need is a integral type which is guaranteed to be
  209. * larger than a size_t, and there is no such thing.
  210. */
  211. len = MIN(a->size, b->size);
  212. for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
  213. if (*p1 != *p2)
  214. return ((int)*p1 - (int)*p2);
  215. return ((int)a->size - (int)b->size);
  216. }
  217. /*
  218. * __BT_DEFPFX -- Default prefix routine.
  219. *
  220. * Parameters:
  221. * a: DBT #1
  222. * b: DBT #2
  223. *
  224. * Returns:
  225. * Number of bytes needed to distinguish b from a.
  226. */
  227. size_t
  228. __bt_defpfx(a, b)
  229. const DBT *a, *b;
  230. {
  231. register u_char *p1, *p2;
  232. register size_t cnt, len;
  233. cnt = 1;
  234. len = MIN(a->size, b->size);
  235. for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
  236. if (*p1 != *p2)
  237. return (cnt);
  238. /* a->size must be <= b->size, or they wouldn't be in this order. */
  239. return (a->size < b->size ? a->size + 1 : a->size);
  240. }