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*50989Sbostic static char sccsid[] = "@(#)bt_utils.c 5.4 (Berkeley) 09/04/91"; 1346137Smao #endif /* LIBC_SCCS and not lint */ 1446137Smao 15*50989Sbostic #include <sys/param.h> 1646137Smao #include <db.h> 17*50989Sbostic #include <stdio.h> 1846561Sbostic #include <stdlib.h> 1946561Sbostic #include <string.h> 2046137Smao #include "btree.h" 2146137Smao 2246137Smao /* 23*50989Sbostic * __BT_RET -- Build return key/data pair as a result of search or scan. 2446137Smao * 25*50989Sbostic * Parameters: 26*50989Sbostic * t: tree 27*50989Sbostic * d: LEAF to be returned to the user. 28*50989Sbostic * key: user's key structure 29*50989Sbostic * data: user's data structure 3046137Smao * 31*50989Sbostic * Returns: 32*50989Sbostic * RET_SUCCESS, RET_ERROR. 3346137Smao */ 3446137Smao int 35*50989Sbostic __bt_ret(t, e, key, data) 36*50989Sbostic BTREE *t; 37*50989Sbostic EPG *e; 38*50989Sbostic DBT *key, *data; 3946137Smao { 40*50989Sbostic register BLEAF *bl; 4146137Smao 42*50989Sbostic bl = GETBLEAF(e->page, e->index); 43*50989Sbostic 44*50989Sbostic if (bl->flags & P_BIGKEY) { 45*50989Sbostic if (__ovfl_get(t, bl->bytes, 46*50989Sbostic &key->size, &t->bt_kbuf, &t->bt_kbufsz)) 4746137Smao return (RET_ERROR); 4846137Smao } else { 49*50989Sbostic if (bl->ksize > t->bt_kbufsz) { 50*50989Sbostic if ((t->bt_kbuf = 51*50989Sbostic realloc(t->bt_kbuf, bl->ksize)) == NULL) 5246137Smao return (RET_ERROR); 53*50989Sbostic t->bt_kbufsz = bl->ksize; 5446137Smao } 55*50989Sbostic bcopy(bl->bytes, t->bt_kbuf, t->bt_kbufsz); 56*50989Sbostic key->size = bl->ksize; 5746137Smao } 58*50989Sbostic key->data = t->bt_kbuf; 5946137Smao 60*50989Sbostic if (bl->flags & P_BIGDATA) { 61*50989Sbostic if (__ovfl_get(t, bl->bytes + bl->ksize, 62*50989Sbostic &data->size, &t->bt_dbuf, &t->bt_dbufsz)) 6346137Smao return (RET_ERROR); 6446137Smao } else { 65*50989Sbostic if (bl->dsize > t->bt_dbufsz) { 66*50989Sbostic if ((t->bt_dbuf = 67*50989Sbostic realloc(t->bt_dbuf, bl->dsize)) == NULL) 6846137Smao return (RET_ERROR); 69*50989Sbostic t->bt_dbufsz = bl->dsize; 7046137Smao } 71*50989Sbostic bcopy(bl->bytes + bl->ksize, t->bt_dbuf, t->bt_dbufsz); 72*50989Sbostic data->size = bl->dsize; 7346137Smao } 74*50989Sbostic data->data = t->bt_dbuf; 7546137Smao 7646137Smao return (RET_SUCCESS); 7746137Smao } 7846137Smao 7946137Smao /* 80*50989Sbostic * __BT_CMP -- Compare a key to a given record. 8146137Smao * 82*50989Sbostic * Parameters: 83*50989Sbostic * t: tree 84*50989Sbostic * k1: DBT pointer of first arg to comparison 85*50989Sbostic * e: pointer to EPG for comparison 8646137Smao * 87*50989Sbostic * Returns: 88*50989Sbostic * < 0 if k1 is < record 89*50989Sbostic * = 0 if k1 is = record 90*50989Sbostic * > 0 if k1 is > record 9146137Smao */ 9246137Smao int 93*50989Sbostic __bt_cmp(t, k1, e) 94*50989Sbostic BTREE *t; 95*50989Sbostic const DBT *k1; 96*50989Sbostic EPG *e; 9746137Smao { 98*50989Sbostic BINTERNAL *bi; 99*50989Sbostic BLEAF *bl; 100*50989Sbostic DBT k2; 101*50989Sbostic PAGE *h; 102*50989Sbostic void *bigkey; 10346137Smao 10446137Smao /* 105*50989Sbostic * The left-most key on internal pages, at any level of the tree, is 106*50989Sbostic * guaranteed by the following code to be less than any user key. 107*50989Sbostic * This saves us from having to update the leftmost key on an internal 108*50989Sbostic * page when the user inserts a new key in the tree smaller than 109*50989Sbostic * anything we've yet seen. 11046137Smao */ 111*50989Sbostic h = e->page; 112*50989Sbostic if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) 11346137Smao return (1); 11446137Smao 115*50989Sbostic bigkey = NULL; 116*50989Sbostic if (h->flags & P_BLEAF) { 117*50989Sbostic bl = GETBLEAF(h, e->index); 118*50989Sbostic if (bl->flags & P_BIGKEY) 119*50989Sbostic bigkey = bl->bytes; 120*50989Sbostic else { 121*50989Sbostic k2.data = bl->bytes; 122*50989Sbostic k2.size = bl->ksize; 12346137Smao } 12446137Smao } else { 125*50989Sbostic bi = GETBINTERNAL(h, e->index); 126*50989Sbostic if (bi->flags & P_BIGKEY) 127*50989Sbostic bigkey = bi->bytes; 128*50989Sbostic else { 129*50989Sbostic k2.data = bi->bytes; 130*50989Sbostic k2.size = bi->ksize; 13146137Smao } 13246137Smao } 13346137Smao 134*50989Sbostic if (bigkey) { 135*50989Sbostic if (__ovfl_get(t, bigkey, 136*50989Sbostic &k2.size, &t->bt_dbuf, &t->bt_dbufsz)) 137*50989Sbostic return (RET_ERROR); 138*50989Sbostic k2.data = t->bt_dbuf; 139*50989Sbostic } 140*50989Sbostic return((*t->bt_cmp)(k1, &k2)); 14146137Smao } 14246137Smao 14346137Smao /* 144*50989Sbostic * __BT_DEFCMP -- Default comparison routine. 14546137Smao * 146*50989Sbostic * Parameters: 147*50989Sbostic * a: DBT #1 148*50989Sbostic * b: DBT #2 14946137Smao * 150*50989Sbostic * Returns: 151*50989Sbostic * < 0 if a is < b 152*50989Sbostic * = 0 if a is = b 153*50989Sbostic * > 0 if a is > b 15446137Smao */ 15546137Smao int 156*50989Sbostic __bt_defcmp(a, b) 157*50989Sbostic const DBT *a, *b; 15846137Smao { 159*50989Sbostic register u_char *p1, *p2; 160*50989Sbostic register int diff, len; 16146137Smao 162*50989Sbostic len = MIN(a->size, b->size); 163*50989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) 164*50989Sbostic if (diff = *p1 - *p2) 165*50989Sbostic return(diff); 166*50989Sbostic return(a->size - b->size); 16746137Smao } 16846137Smao 169*50989Sbostic /* 170*50989Sbostic * __BT_DEFPFX -- Default prefix routine. 171*50989Sbostic * 172*50989Sbostic * Parameters: 173*50989Sbostic * a: DBT #1 174*50989Sbostic * b: DBT #2 175*50989Sbostic * 176*50989Sbostic * Returns: 177*50989Sbostic * Number of bytes needed to distinguish b from a. 178*50989Sbostic */ 179*50989Sbostic int 180*50989Sbostic __bt_defpfx(a, b) 181*50989Sbostic const DBT *a, *b; 18246137Smao { 183*50989Sbostic register u_char *p1, *p2; 184*50989Sbostic register int len; 185*50989Sbostic int cnt; 18646137Smao 187*50989Sbostic cnt = 1; 188*50989Sbostic len = MIN(a->size, b->size); 189*50989Sbostic for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) 190*50989Sbostic if (*p1 != *p2) 191*50989Sbostic return(cnt); 192*50989Sbostic if (a->size == b->size) 193*50989Sbostic return (a->size); 194*50989Sbostic return(a->size + 1); 19546137Smao } 196