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*56707Sbostic static char sccsid[] = "@(#)bt_utils.c 5.6 (Berkeley) 11/10/92"; 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. 2851109Sbostic * 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; 4151109Sbostic 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 { 50*56707Sbostic /* Use +1 in case the first record retrieved is 0 length. */ 51*56707Sbostic if (bl->dsize + 1 > t->bt_dbufsz) { 52*56707Sbostic if ((p = realloc(t->bt_dbuf, bl->dsize + 1)) == NULL) 5346137Smao return (RET_ERROR); 5451109Sbostic t->bt_dbuf = p; 55*56707Sbostic t->bt_dbufsz = bl->dsize + 1; 5646137Smao } 5750989Sbostic bcopy(bl->bytes + bl->ksize, t->bt_dbuf, t->bt_dbufsz); 5850989Sbostic data->size = bl->dsize; 5946137Smao } 6050989Sbostic data->data = t->bt_dbuf; 6146137Smao 6251109Sbostic if (key == NULL) 6351109Sbostic return (RET_SUCCESS); 6451109Sbostic 6551109Sbostic if (bl->flags & P_BIGKEY) { 6651109Sbostic if (__ovfl_get(t, bl->bytes, 6751109Sbostic &key->size, &t->bt_kbuf, &t->bt_kbufsz)) 6851109Sbostic return (RET_ERROR); 6951109Sbostic } else { 7051109Sbostic if (bl->ksize > t->bt_kbufsz) { 7151109Sbostic if ((p = realloc(t->bt_kbuf, bl->ksize)) == NULL) 7251109Sbostic return (RET_ERROR); 7351109Sbostic t->bt_kbuf = p; 7451109Sbostic t->bt_kbufsz = bl->ksize; 7551109Sbostic } 7651109Sbostic bcopy(bl->bytes, t->bt_kbuf, t->bt_kbufsz); 7751109Sbostic key->size = bl->ksize; 7851109Sbostic } 7951109Sbostic key->data = t->bt_kbuf; 8046137Smao return (RET_SUCCESS); 8146137Smao } 8246137Smao 8346137Smao /* 8450989Sbostic * __BT_CMP -- Compare a key to a given record. 8546137Smao * 8650989Sbostic * Parameters: 8750989Sbostic * t: tree 8850989Sbostic * k1: DBT pointer of first arg to comparison 8950989Sbostic * e: pointer to EPG for comparison 9046137Smao * 9150989Sbostic * Returns: 9250989Sbostic * < 0 if k1 is < record 9350989Sbostic * = 0 if k1 is = record 9450989Sbostic * > 0 if k1 is > record 9546137Smao */ 9646137Smao int 9750989Sbostic __bt_cmp(t, k1, e) 9850989Sbostic BTREE *t; 9950989Sbostic const DBT *k1; 10050989Sbostic EPG *e; 10146137Smao { 10250989Sbostic BINTERNAL *bi; 10350989Sbostic BLEAF *bl; 10450989Sbostic DBT k2; 10550989Sbostic PAGE *h; 10650989Sbostic void *bigkey; 10746137Smao 10846137Smao /* 10950989Sbostic * The left-most key on internal pages, at any level of the tree, is 11050989Sbostic * guaranteed by the following code to be less than any user key. 11150989Sbostic * This saves us from having to update the leftmost key on an internal 11250989Sbostic * page when the user inserts a new key in the tree smaller than 11350989Sbostic * anything we've yet seen. 11446137Smao */ 11550989Sbostic h = e->page; 11650989Sbostic if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) 11746137Smao return (1); 11846137Smao 11950989Sbostic bigkey = NULL; 12050989Sbostic if (h->flags & P_BLEAF) { 12150989Sbostic bl = GETBLEAF(h, e->index); 12250989Sbostic if (bl->flags & P_BIGKEY) 12350989Sbostic bigkey = bl->bytes; 12450989Sbostic else { 12550989Sbostic k2.data = bl->bytes; 12650989Sbostic k2.size = bl->ksize; 12746137Smao } 12846137Smao } else { 12950989Sbostic bi = GETBINTERNAL(h, e->index); 13050989Sbostic if (bi->flags & P_BIGKEY) 13150989Sbostic bigkey = bi->bytes; 13250989Sbostic else { 13350989Sbostic k2.data = bi->bytes; 13450989Sbostic k2.size = bi->ksize; 13546137Smao } 13646137Smao } 13746137Smao 13850989Sbostic if (bigkey) { 13950989Sbostic if (__ovfl_get(t, bigkey, 14050989Sbostic &k2.size, &t->bt_dbuf, &t->bt_dbufsz)) 14150989Sbostic return (RET_ERROR); 14250989Sbostic k2.data = t->bt_dbuf; 14350989Sbostic } 14450989Sbostic return((*t->bt_cmp)(k1, &k2)); 14546137Smao } 14646137Smao 14746137Smao /* 14850989Sbostic * __BT_DEFCMP -- Default comparison routine. 14946137Smao * 15050989Sbostic * Parameters: 15150989Sbostic * a: DBT #1 15250989Sbostic * b: DBT #2 15346137Smao * 15450989Sbostic * Returns: 15550989Sbostic * < 0 if a is < b 15650989Sbostic * = 0 if a is = b 15750989Sbostic * > 0 if a is > b 15846137Smao */ 15946137Smao int 16050989Sbostic __bt_defcmp(a, b) 16150989Sbostic const DBT *a, *b; 16246137Smao { 16350989Sbostic register u_char *p1, *p2; 16450989Sbostic register int diff, len; 16546137Smao 16650989Sbostic len = MIN(a->size, b->size); 16750989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) 16850989Sbostic if (diff = *p1 - *p2) 16950989Sbostic return(diff); 17050989Sbostic return(a->size - b->size); 17146137Smao } 17246137Smao 17350989Sbostic /* 17450989Sbostic * __BT_DEFPFX -- Default prefix routine. 17550989Sbostic * 17650989Sbostic * Parameters: 17750989Sbostic * a: DBT #1 17850989Sbostic * b: DBT #2 17950989Sbostic * 18050989Sbostic * Returns: 18150989Sbostic * Number of bytes needed to distinguish b from a. 18250989Sbostic */ 18350989Sbostic int 18450989Sbostic __bt_defpfx(a, b) 18550989Sbostic const DBT *a, *b; 18646137Smao { 18750989Sbostic register u_char *p1, *p2; 18850989Sbostic register int len; 18950989Sbostic int cnt; 19046137Smao 19150989Sbostic cnt = 1; 19250989Sbostic len = MIN(a->size, b->size); 19350989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) 19450989Sbostic if (*p1 != *p2) 19550989Sbostic return(cnt); 19651109Sbostic 19751109Sbostic /* a->size must be <= b->size, or they wouldn't be in this order. */ 19851109Sbostic return (a->size < b->size ? a->size + 1 : a->size); 19946137Smao } 200