1*0a6a1f1dSLionel Sambuc /* $NetBSD: rec_utils.c,v 1.14 2013/12/14 18:04:56 christos Exp $ */
22639ae9bSBen Gras
32639ae9bSBen Gras /*-
42639ae9bSBen Gras * Copyright (c) 1990, 1993, 1994
52639ae9bSBen Gras * The Regents of the University of California. All rights reserved.
62639ae9bSBen Gras *
72639ae9bSBen Gras * Redistribution and use in source and binary forms, with or without
82639ae9bSBen Gras * modification, are permitted provided that the following conditions
92639ae9bSBen Gras * are met:
102639ae9bSBen Gras * 1. Redistributions of source code must retain the above copyright
112639ae9bSBen Gras * notice, this list of conditions and the following disclaimer.
122639ae9bSBen Gras * 2. Redistributions in binary form must reproduce the above copyright
132639ae9bSBen Gras * notice, this list of conditions and the following disclaimer in the
142639ae9bSBen Gras * documentation and/or other materials provided with the distribution.
152639ae9bSBen Gras * 3. Neither the name of the University nor the names of its contributors
162639ae9bSBen Gras * may be used to endorse or promote products derived from this software
172639ae9bSBen Gras * without specific prior written permission.
182639ae9bSBen Gras *
192639ae9bSBen Gras * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
202639ae9bSBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
212639ae9bSBen Gras * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
222639ae9bSBen Gras * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
232639ae9bSBen Gras * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
242639ae9bSBen Gras * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
252639ae9bSBen Gras * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
262639ae9bSBen Gras * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
272639ae9bSBen Gras * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
282639ae9bSBen Gras * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
292639ae9bSBen Gras * SUCH DAMAGE.
302639ae9bSBen Gras */
312639ae9bSBen Gras
322639ae9bSBen Gras #if HAVE_NBTOOL_CONFIG_H
332639ae9bSBen Gras #include "nbtool_config.h"
342639ae9bSBen Gras #endif
352639ae9bSBen Gras
362639ae9bSBen Gras #include <sys/cdefs.h>
37*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: rec_utils.c,v 1.14 2013/12/14 18:04:56 christos Exp $");
382639ae9bSBen Gras
392639ae9bSBen Gras #include <sys/param.h>
402639ae9bSBen Gras
412639ae9bSBen Gras #include <assert.h>
422639ae9bSBen Gras #include <stdio.h>
432639ae9bSBen Gras #include <stdlib.h>
442639ae9bSBen Gras #include <string.h>
452639ae9bSBen Gras
462639ae9bSBen Gras #include <db.h>
472639ae9bSBen Gras #include "recno.h"
482639ae9bSBen Gras
492639ae9bSBen Gras /*
502639ae9bSBen Gras * __rec_ret --
512639ae9bSBen Gras * Build return data.
522639ae9bSBen Gras *
532639ae9bSBen Gras * Parameters:
542639ae9bSBen Gras * t: tree
552639ae9bSBen Gras * e: key/data pair to be returned
562639ae9bSBen Gras * nrec: record number
572639ae9bSBen Gras * key: user's key structure
582639ae9bSBen Gras * data: user's data structure
592639ae9bSBen Gras *
602639ae9bSBen Gras * Returns:
612639ae9bSBen Gras * RET_SUCCESS, RET_ERROR.
622639ae9bSBen Gras */
632639ae9bSBen Gras int
__rec_ret(BTREE * t,EPG * e,recno_t nrec,DBT * key,DBT * data)642639ae9bSBen Gras __rec_ret(BTREE *t, EPG *e, recno_t nrec, DBT *key, DBT *data)
652639ae9bSBen Gras {
662639ae9bSBen Gras RLEAF *rl;
672639ae9bSBen Gras void *p;
682639ae9bSBen Gras
692639ae9bSBen Gras if (key == NULL)
702639ae9bSBen Gras goto dataonly;
712639ae9bSBen Gras
722639ae9bSBen Gras /* We have to copy the key, it's not on the page. */
7384d9c625SLionel Sambuc if (sizeof(nrec) > t->bt_rkey.size) {
74*0a6a1f1dSLionel Sambuc p = realloc(t->bt_rkey.data, sizeof(nrec));
752639ae9bSBen Gras if (p == NULL)
762639ae9bSBen Gras return (RET_ERROR);
772639ae9bSBen Gras t->bt_rkey.data = p;
7884d9c625SLionel Sambuc t->bt_rkey.size = sizeof(nrec);
792639ae9bSBen Gras }
8084d9c625SLionel Sambuc memmove(t->bt_rkey.data, &nrec, sizeof(nrec));
8184d9c625SLionel Sambuc key->size = sizeof(nrec);
822639ae9bSBen Gras key->data = t->bt_rkey.data;
832639ae9bSBen Gras
842639ae9bSBen Gras dataonly:
852639ae9bSBen Gras if (data == NULL)
862639ae9bSBen Gras return (RET_SUCCESS);
872639ae9bSBen Gras
882639ae9bSBen Gras /*
892639ae9bSBen Gras * We must copy big keys/data to make them contigous. Otherwise,
902639ae9bSBen Gras * leave the page pinned and don't copy unless the user specified
912639ae9bSBen Gras * concurrent access.
922639ae9bSBen Gras */
932639ae9bSBen Gras rl = GETRLEAF(e->page, e->index);
942639ae9bSBen Gras if (rl->flags & P_BIGDATA) {
952639ae9bSBen Gras if (__ovfl_get(t, rl->bytes,
962639ae9bSBen Gras &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
972639ae9bSBen Gras return (RET_ERROR);
982639ae9bSBen Gras data->data = t->bt_rdata.data;
992639ae9bSBen Gras } else if (F_ISSET(t, B_DB_LOCK)) {
1002639ae9bSBen Gras /* Use +1 in case the first record retrieved is 0 length. */
1012639ae9bSBen Gras if (rl->dsize + 1 > t->bt_rdata.size) {
102*0a6a1f1dSLionel Sambuc p = realloc(t->bt_rdata.data, rl->dsize + 1);
1032639ae9bSBen Gras if (p == NULL)
1042639ae9bSBen Gras return (RET_ERROR);
1052639ae9bSBen Gras t->bt_rdata.data = p;
1062639ae9bSBen Gras t->bt_rdata.size = rl->dsize + 1;
1072639ae9bSBen Gras }
1082639ae9bSBen Gras memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
1092639ae9bSBen Gras data->size = rl->dsize;
1102639ae9bSBen Gras data->data = t->bt_rdata.data;
1112639ae9bSBen Gras } else {
1122639ae9bSBen Gras data->size = rl->dsize;
1132639ae9bSBen Gras data->data = rl->bytes;
1142639ae9bSBen Gras }
1152639ae9bSBen Gras return (RET_SUCCESS);
1162639ae9bSBen Gras }
117