146137Smao /*- 246137Smao * Copyright (c) 1990 The Regents of the University of California. 346137Smao * All rights reserved. 446137Smao * 546137Smao * This code is derived from software contributed to Berkeley by 646137Smao * Mike Olson. 746137Smao * 846137Smao * %sccs.include.redist.c% 946137Smao */ 1046137Smao 1146137Smao #if defined(LIBC_SCCS) && !defined(lint) 12*51109Sbostic static char sccsid[] = "@(#)bt_utils.c 5.5 (Berkeley) 09/12/91"; 1346137Smao #endif /* LIBC_SCCS and not lint */ 1446137Smao 1550989Sbostic #include <sys/param.h> 1646137Smao #include <db.h> 1750989Sbostic #include <stdio.h> 1846561Sbostic #include <stdlib.h> 1946561Sbostic #include <string.h> 2046137Smao #include "btree.h" 2146137Smao 2246137Smao /* 2350989Sbostic * __BT_RET -- Build return key/data pair as a result of search or scan. 2446137Smao * 2550989Sbostic * Parameters: 2650989Sbostic * t: tree 2750989Sbostic * d: LEAF to be returned to the user. 28*51109Sbostic * key: user's key structure (NULL if not to be filled in) 2950989Sbostic * data: user's data structure 3046137Smao * 3150989Sbostic * Returns: 3250989Sbostic * RET_SUCCESS, RET_ERROR. 3346137Smao */ 3446137Smao int 3550989Sbostic __bt_ret(t, e, key, data) 3650989Sbostic BTREE *t; 3750989Sbostic EPG *e; 3850989Sbostic DBT *key, *data; 3946137Smao { 4050989Sbostic register BLEAF *bl; 41*51109Sbostic register void *p; 4246137Smao 4350989Sbostic bl = GETBLEAF(e->page, e->index); 4450989Sbostic 4550989Sbostic if (bl->flags & P_BIGDATA) { 4650989Sbostic if (__ovfl_get(t, bl->bytes + bl->ksize, 4750989Sbostic &data->size, &t->bt_dbuf, &t->bt_dbufsz)) 4846137Smao return (RET_ERROR); 4946137Smao } else { 5050989Sbostic if (bl->dsize > t->bt_dbufsz) { 51*51109Sbostic if ((p = realloc(t->bt_dbuf, bl->dsize)) == NULL) 5246137Smao return (RET_ERROR); 53*51109Sbostic t->bt_dbuf = p; 5450989Sbostic t->bt_dbufsz = bl->dsize; 5546137Smao } 5650989Sbostic bcopy(bl->bytes + bl->ksize, t->bt_dbuf, t->bt_dbufsz); 5750989Sbostic data->size = bl->dsize; 5846137Smao } 5950989Sbostic data->data = t->bt_dbuf; 6046137Smao 61*51109Sbostic if (key == NULL) 62*51109Sbostic return (RET_SUCCESS); 63*51109Sbostic 64*51109Sbostic if (bl->flags & P_BIGKEY) { 65*51109Sbostic if (__ovfl_get(t, bl->bytes, 66*51109Sbostic &key->size, &t->bt_kbuf, &t->bt_kbufsz)) 67*51109Sbostic return (RET_ERROR); 68*51109Sbostic } else { 69*51109Sbostic if (bl->ksize > t->bt_kbufsz) { 70*51109Sbostic if ((p = realloc(t->bt_kbuf, bl->ksize)) == NULL) 71*51109Sbostic return (RET_ERROR); 72*51109Sbostic t->bt_kbuf = p; 73*51109Sbostic t->bt_kbufsz = bl->ksize; 74*51109Sbostic } 75*51109Sbostic bcopy(bl->bytes, t->bt_kbuf, t->bt_kbufsz); 76*51109Sbostic key->size = bl->ksize; 77*51109Sbostic } 78*51109Sbostic key->data = t->bt_kbuf; 7946137Smao return (RET_SUCCESS); 8046137Smao } 8146137Smao 8246137Smao /* 8350989Sbostic * __BT_CMP -- Compare a key to a given record. 8446137Smao * 8550989Sbostic * Parameters: 8650989Sbostic * t: tree 8750989Sbostic * k1: DBT pointer of first arg to comparison 8850989Sbostic * e: pointer to EPG for comparison 8946137Smao * 9050989Sbostic * Returns: 9150989Sbostic * < 0 if k1 is < record 9250989Sbostic * = 0 if k1 is = record 9350989Sbostic * > 0 if k1 is > record 9446137Smao */ 9546137Smao int 9650989Sbostic __bt_cmp(t, k1, e) 9750989Sbostic BTREE *t; 9850989Sbostic const DBT *k1; 9950989Sbostic EPG *e; 10046137Smao { 10150989Sbostic BINTERNAL *bi; 10250989Sbostic BLEAF *bl; 10350989Sbostic DBT k2; 10450989Sbostic PAGE *h; 10550989Sbostic void *bigkey; 10646137Smao 10746137Smao /* 10850989Sbostic * The left-most key on internal pages, at any level of the tree, is 10950989Sbostic * guaranteed by the following code to be less than any user key. 11050989Sbostic * This saves us from having to update the leftmost key on an internal 11150989Sbostic * page when the user inserts a new key in the tree smaller than 11250989Sbostic * anything we've yet seen. 11346137Smao */ 11450989Sbostic h = e->page; 11550989Sbostic if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) 11646137Smao return (1); 11746137Smao 11850989Sbostic bigkey = NULL; 11950989Sbostic if (h->flags & P_BLEAF) { 12050989Sbostic bl = GETBLEAF(h, e->index); 12150989Sbostic if (bl->flags & P_BIGKEY) 12250989Sbostic bigkey = bl->bytes; 12350989Sbostic else { 12450989Sbostic k2.data = bl->bytes; 12550989Sbostic k2.size = bl->ksize; 12646137Smao } 12746137Smao } else { 12850989Sbostic bi = GETBINTERNAL(h, e->index); 12950989Sbostic if (bi->flags & P_BIGKEY) 13050989Sbostic bigkey = bi->bytes; 13150989Sbostic else { 13250989Sbostic k2.data = bi->bytes; 13350989Sbostic k2.size = bi->ksize; 13446137Smao } 13546137Smao } 13646137Smao 13750989Sbostic if (bigkey) { 13850989Sbostic if (__ovfl_get(t, bigkey, 13950989Sbostic &k2.size, &t->bt_dbuf, &t->bt_dbufsz)) 14050989Sbostic return (RET_ERROR); 14150989Sbostic k2.data = t->bt_dbuf; 14250989Sbostic } 14350989Sbostic return((*t->bt_cmp)(k1, &k2)); 14446137Smao } 14546137Smao 14646137Smao /* 14750989Sbostic * __BT_DEFCMP -- Default comparison routine. 14846137Smao * 14950989Sbostic * Parameters: 15050989Sbostic * a: DBT #1 15150989Sbostic * b: DBT #2 15246137Smao * 15350989Sbostic * Returns: 15450989Sbostic * < 0 if a is < b 15550989Sbostic * = 0 if a is = b 15650989Sbostic * > 0 if a is > b 15746137Smao */ 15846137Smao int 15950989Sbostic __bt_defcmp(a, b) 16050989Sbostic const DBT *a, *b; 16146137Smao { 16250989Sbostic register u_char *p1, *p2; 16350989Sbostic register int diff, len; 16446137Smao 16550989Sbostic len = MIN(a->size, b->size); 16650989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) 16750989Sbostic if (diff = *p1 - *p2) 16850989Sbostic return(diff); 16950989Sbostic return(a->size - b->size); 17046137Smao } 17146137Smao 17250989Sbostic /* 17350989Sbostic * __BT_DEFPFX -- Default prefix routine. 17450989Sbostic * 17550989Sbostic * Parameters: 17650989Sbostic * a: DBT #1 17750989Sbostic * b: DBT #2 17850989Sbostic * 17950989Sbostic * Returns: 18050989Sbostic * Number of bytes needed to distinguish b from a. 18150989Sbostic */ 18250989Sbostic int 18350989Sbostic __bt_defpfx(a, b) 18450989Sbostic const DBT *a, *b; 18546137Smao { 18650989Sbostic register u_char *p1, *p2; 18750989Sbostic register int len; 18850989Sbostic int cnt; 18946137Smao 19050989Sbostic cnt = 1; 19150989Sbostic len = MIN(a->size, b->size); 19250989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) 19350989Sbostic if (*p1 != *p2) 19450989Sbostic return(cnt); 195*51109Sbostic 196*51109Sbostic /* a->size must be <= b->size, or they wouldn't be in this order. */ 197*51109Sbostic return (a->size < b->size ? a->size + 1 : a->size); 19846137Smao } 199