bt_utils.c 7.0 KB

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