* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)utils.c 5.3 (Berkeley) 3/3/91";
#endif /* LIBC_SCCS and not lint */
* _BT_BUILDRET -- Build return key/data pair as a result of search or scan.
* This routine manages the statically allocated buffers in which we
* return data to the user.
* t -- btree from which to return datum
* d -- DATUM to be returned to the user.
* data -- data argument supplied by user for return
* key -- key argument supplied by user for return
* RET_SUCCESS, RET_ERROR.
* May free and reallocate static buffers, if the data
* we want to return is bigger than the space we have to
_bt_buildret(t
, d
, data
, key
)
static char *_data
= (char *) NULL
;
static char *_key
= (char *) NULL
;
if (d
->d_flags
& D_BIGKEY
) {
if (_key
!= (char *) NULL
)
(void) bcopy((char *) &(d
->d_bytes
[0]),
if (_bt_getbig(t
, chain
, &_key
, &_key_s
) == RET_ERROR
)
key
->data
= (u_char
*)_key
;
/* need more space for key? */
if (d
->d_ksize
> _key_s
) {
if (_key
!= (char *) NULL
)
if ((_key
= (char *) malloc((unsigned) d
->d_ksize
))
key
->data
= (u_char
*)_key
;
if ((key
->size
= d
->d_ksize
) > 0)
(void) bcopy(&(d
->d_bytes
[0]),
if (d
->d_flags
& D_BIGDATA
) {
if (_data
!= (char *) NULL
)
(void) bcopy(&(d
->d_bytes
[d
->d_ksize
]),
if (_bt_getbig(t
, chain
, &_data
, &_data_s
) == RET_ERROR
)
data
->data
= (u_char
*)_data
;
/* need more space for data? */
if (d
->d_dsize
> _data_s
) {
if (_data
!= (char *) NULL
)
if ((_data
= (char *) malloc((unsigned) d
->d_dsize
))
data
->data
= (u_char
*)_data
;
if ((data
->size
= d
->d_dsize
) > 0)
(void) bcopy(&(d
->d_bytes
[d
->d_ksize
]),
* _BT_CMP -- Compare a key to a given item on the current page.
* This routine is a wrapper for the user's comparison function.
* t -- tree in which to do comparison
* p -- pointer to one argument for the comparison function
* n -- index of item to supply second arg to comparison function
* < 0 if p is < item at n
* = 0 if p is = item at n
* > 0 if p is > item at n
* The left-most key at any level of the tree on internal pages
* is guaranteed (artificially, by the code here) to be less than
* any user key. This saves us from having to update the leftmost
* key when the user inserts a new key in the tree smaller than
* anything we've seen yet.
if (h
->h_prevpg
== P_NONE
&& !(h
->h_flags
& F_LEAF
) && n
== 0)
if (h
->h_flags
& F_LEAF
) {
d
= (DATUM
*) GETDATUM(h
,n
);
if (d
->d_flags
& D_BIGKEY
) {
bcopy(&(d
->d_bytes
[0]), (char *) &chain
, sizeof(chain
));
if (_bt_getbig(t
, chain
, &arg
, &ignore
) == RET_ERROR
)
id
= (IDATUM
*) GETDATUM(h
,n
);
if (id
->i_flags
& D_BIGKEY
) {
if (_bt_getbig(t
, chain
, &arg
, &ignore
) == RET_ERROR
)
r
= (*(t
->bt_compare
))(p
, arg
);
* _BT_PUSH/_BT_POP -- Push/pop a parent page number on the parent stack.
* When we descend the tree, we keep track of parent pages in order
* to handle splits on insertions.
* t -- tree for which to push parent
* pgno -- page number to push (_bt_push only)
* RET_SUCCESS, RET_ERROR.
if ((new = (BTSTACK
*) malloc((unsigned) sizeof(BTSTACK
)))
new->bts_next
= t
->bt_stack
;
if ((s
= t
->bt_stack
) != (BTSTACK
*) NULL
) {
t
->bt_stack
= s
->bts_next
;
(void) free ((char *) s
);
BTREE_P t
= (BTREE_P
) tree
;
(void) printf("\"%s\" fd %d pgsz %d curpg %d @ 0x%lx",
t
->bt_fname
, t
->bt_s
.bt_d
.d_fd
,
t
->bt_psize
, t
->bt_curpage
);
(void) printf("npg %d cmp 0x%lx flags=(", npages
, t
->bt_compare
);
if (t
->bt_flags
& BTF_SEQINIT
)
(void) printf("BTF_SEQINIT");
for (i
= P_ROOT
; i
<= npages
; i
++) {
if (_bt_getpage(t
, i
) == RET_ERROR
)
(void) printf(" page %d:\n", i
);
(void) printf("\tpgno %d prev %d next %d\n",
h
->h_pgno
, h
->h_prevpg
, h
->h_nextpg
);
(void) printf("\tlower %d upper %d nextind %d flags (",
h
->h_lower
, h
->h_upper
, top
);
(void) printf("<internal>");
if (h
->h_flags
& F_DIRTY
)
(void) printf("|F_DIRTY");
if (h
->h_flags
& F_PRESERVE
)
(void) printf("|F_PRESERVE");
if (h
->h_flags
& F_CONT
) {
(void) printf("|F_CONT)");
if (h
->h_prevpg
== P_NONE
) {
(void) bcopy((char *) &(h
->h_linp
[0]),
printf("\n\t\t(chain start, data length %ld)",
for (cur
= 0; cur
< top
; cur
++) {
(void) printf("\t [%d] off %d ", cur
, h
->h_linp
[cur
]);
if (h
->h_flags
& F_LEAF
) {
d
= (DATUM
*) GETDATUM(h
,cur
);
(void) printf("ksize %d", d
->d_ksize
);
if (d
->d_flags
& D_BIGKEY
)
(void) printf(" (indirect)");
(void) printf("; dsize %d", d
->d_dsize
);
if (d
->d_flags
& D_BIGDATA
)
(void) printf(" (indirect)");
id
= (IDATUM
*) GETDATUM(h
,cur
);
(void) printf("size %d pgno %d",
if (id
->i_flags
& D_BIGKEY
)
(void) printf(" (indirect)");
(void) kill(pid
, SIGILL
);