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*56996Sbostic static char sccsid[] = "@(#)bt_utils.c 5.8 (Berkeley) 12/04/92"; 1346137Smao #endif /* LIBC_SCCS and not lint */ 1446137Smao 1550989Sbostic #include <sys/param.h> 1656740Sbostic 1746137Smao #include <db.h> 1850989Sbostic #include <stdio.h> 1946561Sbostic #include <stdlib.h> 2046561Sbostic #include <string.h> 2156740Sbostic 2246137Smao #include "btree.h" 2346137Smao 2446137Smao /* 2550989Sbostic * __BT_RET -- Build return key/data pair as a result of search or scan. 2646137Smao * 2750989Sbostic * Parameters: 2850989Sbostic * t: tree 2950989Sbostic * d: LEAF to be returned to the user. 3051109Sbostic * key: user's key structure (NULL if not to be filled in) 3150989Sbostic * data: user's data structure 3246137Smao * 3350989Sbostic * Returns: 3450989Sbostic * RET_SUCCESS, RET_ERROR. 3546137Smao */ 3646137Smao int 3750989Sbostic __bt_ret(t, e, key, data) 3850989Sbostic BTREE *t; 3950989Sbostic EPG *e; 4050989Sbostic DBT *key, *data; 4146137Smao { 4250989Sbostic register BLEAF *bl; 4351109Sbostic register void *p; 4446137Smao 4550989Sbostic bl = GETBLEAF(e->page, e->index); 4650989Sbostic 4750989Sbostic if (bl->flags & P_BIGDATA) { 4850989Sbostic if (__ovfl_get(t, bl->bytes + bl->ksize, 4950989Sbostic &data->size, &t->bt_dbuf, &t->bt_dbufsz)) 5046137Smao return (RET_ERROR); 5146137Smao } else { 5256707Sbostic /* Use +1 in case the first record retrieved is 0 length. */ 5356707Sbostic if (bl->dsize + 1 > t->bt_dbufsz) { 5456707Sbostic if ((p = realloc(t->bt_dbuf, bl->dsize + 1)) == NULL) 5546137Smao return (RET_ERROR); 5651109Sbostic t->bt_dbuf = p; 5756707Sbostic t->bt_dbufsz = bl->dsize + 1; 5846137Smao } 59*56996Sbostic bcopy(bl->bytes + bl->ksize, t->bt_dbuf, bl->dsize); 6050989Sbostic data->size = bl->dsize; 6146137Smao } 6250989Sbostic data->data = t->bt_dbuf; 6346137Smao 6451109Sbostic if (key == NULL) 6551109Sbostic return (RET_SUCCESS); 6651109Sbostic 6751109Sbostic if (bl->flags & P_BIGKEY) { 6851109Sbostic if (__ovfl_get(t, bl->bytes, 6951109Sbostic &key->size, &t->bt_kbuf, &t->bt_kbufsz)) 7051109Sbostic return (RET_ERROR); 7151109Sbostic } else { 7251109Sbostic if (bl->ksize > t->bt_kbufsz) { 7351109Sbostic if ((p = realloc(t->bt_kbuf, bl->ksize)) == NULL) 7451109Sbostic return (RET_ERROR); 7551109Sbostic t->bt_kbuf = p; 7651109Sbostic t->bt_kbufsz = bl->ksize; 7751109Sbostic } 78*56996Sbostic bcopy(bl->bytes, t->bt_kbuf, bl->ksize); 7951109Sbostic key->size = bl->ksize; 8051109Sbostic } 8151109Sbostic key->data = t->bt_kbuf; 8246137Smao return (RET_SUCCESS); 8346137Smao } 8446137Smao 8546137Smao /* 8650989Sbostic * __BT_CMP -- Compare a key to a given record. 8746137Smao * 8850989Sbostic * Parameters: 8950989Sbostic * t: tree 9050989Sbostic * k1: DBT pointer of first arg to comparison 9150989Sbostic * e: pointer to EPG for comparison 9246137Smao * 9350989Sbostic * Returns: 9450989Sbostic * < 0 if k1 is < record 9550989Sbostic * = 0 if k1 is = record 9650989Sbostic * > 0 if k1 is > record 9746137Smao */ 9846137Smao int 9950989Sbostic __bt_cmp(t, k1, e) 10050989Sbostic BTREE *t; 10150989Sbostic const DBT *k1; 10250989Sbostic EPG *e; 10346137Smao { 10450989Sbostic BINTERNAL *bi; 10550989Sbostic BLEAF *bl; 10650989Sbostic DBT k2; 10750989Sbostic PAGE *h; 10850989Sbostic void *bigkey; 10946137Smao 11046137Smao /* 11150989Sbostic * The left-most key on internal pages, at any level of the tree, is 11250989Sbostic * guaranteed by the following code to be less than any user key. 11350989Sbostic * This saves us from having to update the leftmost key on an internal 11450989Sbostic * page when the user inserts a new key in the tree smaller than 11550989Sbostic * anything we've yet seen. 11646137Smao */ 11750989Sbostic h = e->page; 11850989Sbostic if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) 11946137Smao return (1); 12046137Smao 12150989Sbostic bigkey = NULL; 12250989Sbostic if (h->flags & P_BLEAF) { 12350989Sbostic bl = GETBLEAF(h, e->index); 12450989Sbostic if (bl->flags & P_BIGKEY) 12550989Sbostic bigkey = bl->bytes; 12650989Sbostic else { 12750989Sbostic k2.data = bl->bytes; 12850989Sbostic k2.size = bl->ksize; 12946137Smao } 13046137Smao } else { 13150989Sbostic bi = GETBINTERNAL(h, e->index); 13250989Sbostic if (bi->flags & P_BIGKEY) 13350989Sbostic bigkey = bi->bytes; 13450989Sbostic else { 13550989Sbostic k2.data = bi->bytes; 13650989Sbostic k2.size = bi->ksize; 13746137Smao } 13846137Smao } 13946137Smao 14050989Sbostic if (bigkey) { 14150989Sbostic if (__ovfl_get(t, bigkey, 14250989Sbostic &k2.size, &t->bt_dbuf, &t->bt_dbufsz)) 14350989Sbostic return (RET_ERROR); 14450989Sbostic k2.data = t->bt_dbuf; 14550989Sbostic } 14650989Sbostic return((*t->bt_cmp)(k1, &k2)); 14746137Smao } 14846137Smao 14946137Smao /* 15050989Sbostic * __BT_DEFCMP -- Default comparison routine. 15146137Smao * 15250989Sbostic * Parameters: 15350989Sbostic * a: DBT #1 15450989Sbostic * b: DBT #2 15546137Smao * 15650989Sbostic * Returns: 15750989Sbostic * < 0 if a is < b 15850989Sbostic * = 0 if a is = b 15950989Sbostic * > 0 if a is > b 16046137Smao */ 16146137Smao int 16250989Sbostic __bt_defcmp(a, b) 16350989Sbostic const DBT *a, *b; 16446137Smao { 16550989Sbostic register u_char *p1, *p2; 16650989Sbostic register int diff, len; 16746137Smao 16850989Sbostic len = MIN(a->size, b->size); 16950989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) 17050989Sbostic if (diff = *p1 - *p2) 17150989Sbostic return(diff); 17250989Sbostic return(a->size - b->size); 17346137Smao } 17446137Smao 17550989Sbostic /* 17650989Sbostic * __BT_DEFPFX -- Default prefix routine. 17750989Sbostic * 17850989Sbostic * Parameters: 17950989Sbostic * a: DBT #1 18050989Sbostic * b: DBT #2 18150989Sbostic * 18250989Sbostic * Returns: 18350989Sbostic * Number of bytes needed to distinguish b from a. 18450989Sbostic */ 18550989Sbostic int 18650989Sbostic __bt_defpfx(a, b) 18750989Sbostic const DBT *a, *b; 18846137Smao { 18950989Sbostic register u_char *p1, *p2; 19050989Sbostic register int len; 19150989Sbostic int cnt; 19246137Smao 19350989Sbostic cnt = 1; 19450989Sbostic len = MIN(a->size, b->size); 19550989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) 19650989Sbostic if (*p1 != *p2) 19750989Sbostic return(cnt); 19851109Sbostic 19951109Sbostic /* a->size must be <= b->size, or they wouldn't be in this order. */ 20051109Sbostic return (a->size < b->size ? a->size + 1 : a->size); 20146137Smao } 202