summaryrefslogtreecommitdiffstats
path: root/lib/libc/db/btree/bt_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/db/btree/bt_utils.c')
-rw-r--r--lib/libc/db/btree/bt_utils.c103
1 files changed, 58 insertions, 45 deletions
diff --git a/lib/libc/db/btree/bt_utils.c b/lib/libc/db/btree/bt_utils.c
index d2d1f73..9c1438e 100644
--- a/lib/libc/db/btree/bt_utils.c
+++ b/lib/libc/db/btree/bt_utils.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1990, 1993
+ * Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_utils.c 8.4 (Berkeley) 2/21/94";
+static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -48,78 +48,91 @@ static char sccsid[] = "@(#)bt_utils.c 8.4 (Berkeley) 2/21/94";
#include "btree.h"
/*
- * __BT_RET -- Build return key/data pair as a result of search or scan.
+ * __bt_ret --
+ * Build return key/data pair.
*
* Parameters:
* t: tree
- * d: LEAF to be returned to the user.
+ * e: key/data pair to be returned
* key: user's key structure (NULL if not to be filled in)
- * data: user's data structure
+ * rkey: memory area to hold key
+ * data: user's data structure (NULL if not to be filled in)
+ * rdata: memory area to hold data
+ * copy: always copy the key/data item
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
-__bt_ret(t, e, key, data)
+__bt_ret(t, e, key, rkey, data, rdata, copy)
BTREE *t;
EPG *e;
- DBT *key, *data;
+ DBT *key, *rkey, *data, *rdata;
+ int copy;
{
- register BLEAF *bl;
- register void *p;
+ BLEAF *bl;
+ void *p;
bl = GETBLEAF(e->page, e->index);
/*
- * We always copy big keys/data to make them contigous. Otherwise,
- * we leave the page pinned and don't copy unless the user specified
+ * We must copy big keys/data to make them contigous. Otherwise,
+ * leave the page pinned and don't copy unless the user specified
* concurrent access.
*/
- if (bl->flags & P_BIGDATA) {
- if (__ovfl_get(t, bl->bytes + bl->ksize,
- &data->size, &t->bt_dbuf, &t->bt_dbufsz))
+ if (key == NULL)
+ goto dataonly;
+
+ if (bl->flags & P_BIGKEY) {
+ if (__ovfl_get(t, bl->bytes,
+ &key->size, &rkey->data, &rkey->size))
return (RET_ERROR);
- data->data = t->bt_dbuf;
- } else if (ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (bl->dsize + 1 > t->bt_dbufsz) {
- if ((p =
- (void *)realloc(t->bt_dbuf, bl->dsize + 1)) == NULL)
+ key->data = rkey->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ if (bl->ksize > rkey->size) {
+ p = (void *)(rkey->data == NULL ?
+ malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
+ if (p == NULL)
return (RET_ERROR);
- t->bt_dbuf = p;
- t->bt_dbufsz = bl->dsize + 1;
+ rkey->data = p;
+ rkey->size = bl->ksize;
}
- memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize);
- data->size = bl->dsize;
- data->data = t->bt_dbuf;
+ memmove(rkey->data, bl->bytes, bl->ksize);
+ key->size = bl->ksize;
+ key->data = rkey->data;
} else {
- data->size = bl->dsize;
- data->data = bl->bytes + bl->ksize;
+ key->size = bl->ksize;
+ key->data = bl->bytes;
}
- if (key == NULL)
+dataonly:
+ if (data == NULL)
return (RET_SUCCESS);
- if (bl->flags & P_BIGKEY) {
- if (__ovfl_get(t, bl->bytes,
- &key->size, &t->bt_kbuf, &t->bt_kbufsz))
+ if (bl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, bl->bytes + bl->ksize,
+ &data->size, &rdata->data, &rdata->size))
return (RET_ERROR);
- key->data = t->bt_kbuf;
- } else if (ISSET(t, B_DB_LOCK)) {
- if (bl->ksize > t->bt_kbufsz) {
- if ((p =
- (void *)realloc(t->bt_kbuf, bl->ksize)) == NULL)
+ data->data = rdata->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (bl->dsize + 1 > rdata->size) {
+ p = (void *)(rdata->data == NULL ?
+ malloc(bl->dsize + 1) :
+ realloc(rdata->data, bl->dsize + 1));
+ if (p == NULL)
return (RET_ERROR);
- t->bt_kbuf = p;
- t->bt_kbufsz = bl->ksize;
+ rdata->data = p;
+ rdata->size = bl->dsize + 1;
}
- memmove(t->bt_kbuf, bl->bytes, bl->ksize);
- key->size = bl->ksize;
- key->data = t->bt_kbuf;
+ memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
+ data->size = bl->dsize;
+ data->data = rdata->data;
} else {
- key->size = bl->ksize;
- key->data = bl->bytes;
+ data->size = bl->dsize;
+ data->data = bl->bytes + bl->ksize;
}
+
return (RET_SUCCESS);
}
@@ -180,9 +193,9 @@ __bt_cmp(t, k1, e)
if (bigkey) {
if (__ovfl_get(t, bigkey,
- &k2.size, &t->bt_dbuf, &t->bt_dbufsz))
+ &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
return (RET_ERROR);
- k2.data = t->bt_dbuf;
+ k2.data = t->bt_rdata.data;
}
return ((*t->bt_cmp)(k1, &k2));
}
OpenPOWER on IntegriCloud