aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-01-02 06:01:06 +0000
committerUlrich Drepper <drepper@redhat.com>2000-01-02 06:01:06 +0000
commit8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3 (patch)
tree099a250d7366aef2ab028fdb24f0d692cd784b4a
parent9a6450d578556c11e7c173d2f28362345b8f1258 (diff)
downloadglibc-8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3.zip
glibc-8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3.tar.gz
glibc-8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3.tar.bz2
Update.
* Makeconfig (all-subdirs): Remove db and db2. * db/*: Removed. * db2/*: Removed.
-rw-r--r--ChangeLog4
-rw-r--r--Makeconfig4
-rw-r--r--db/Makefile73
-rw-r--r--db/Versions10
-rw-r--r--db/btree/bt_close.c182
-rw-r--r--db/btree/bt_conv.c221
-rw-r--r--db/btree/bt_debug.c329
-rw-r--r--db/btree/bt_delete.c657
-rw-r--r--db/btree/bt_get.c105
-rw-r--r--db/btree/bt_open.c458
-rw-r--r--db/btree/bt_overflow.c228
-rw-r--r--db/btree/bt_page.c100
-rw-r--r--db/btree/bt_put.c321
-rw-r--r--db/btree/bt_search.c213
-rw-r--r--db/btree/bt_seq.c460
-rw-r--r--db/btree/bt_split.c829
-rw-r--r--db/btree/bt_utils.c260
-rw-r--r--db/btree/btree.h395
-rw-r--r--db/btree/extern.h70
-rw-r--r--db/compat.h49
-rw-r--r--db/db.h238
-rw-r--r--db/db/db.c113
-rw-r--r--db/hash/extern.h65
-rw-r--r--db/hash/hash.c999
-rw-r--r--db/hash/hash.h293
-rw-r--r--db/hash/hash_bigkey.c668
-rw-r--r--db/hash/hash_buf.c355
-rw-r--r--db/hash/hash_func.c212
-rw-r--r--db/hash/hash_log2.c56
-rw-r--r--db/hash/hash_page.c944
-rw-r--r--db/hash/ndbm.c215
-rw-r--r--db/hash/page.h92
-rw-r--r--db/mpool.h112
-rw-r--r--db/mpool/mpool.c493
-rw-r--r--db/ndbm.h79
-rw-r--r--db/recno/extern.h54
-rw-r--r--db/recno/rec_close.c183
-rw-r--r--db/recno/rec_delete.c197
-rw-r--r--db/recno/rec_get.c311
-rw-r--r--db/recno/rec_open.c241
-rw-r--r--db/recno/rec_put.c280
-rw-r--r--db/recno/rec_search.c126
-rw-r--r--db/recno/rec_seq.c131
-rw-r--r--db/recno/rec_utils.c122
-rw-r--r--db/recno/recno.h39
-rw-r--r--db2/LICENSE116
-rw-r--r--db2/Makefile126
-rw-r--r--db2/README13
-rw-r--r--db2/Versions58
-rw-r--r--db2/btree/bt_compare.c195
-rw-r--r--db2/btree/bt_conv.c94
-rw-r--r--db2/btree/bt_curadj.c272
-rw-r--r--db2/btree/bt_cursor.c1913
-rw-r--r--db2/btree/bt_delete.c589
-rw-r--r--db2/btree/bt_open.c310
-rw-r--r--db2/btree/bt_page.c317
-rw-r--r--db2/btree/bt_put.c831
-rw-r--r--db2/btree/bt_rec.c903
-rw-r--r--db2/btree/bt_recno.c1356
-rw-r--r--db2/btree/bt_rsearch.c391
-rw-r--r--db2/btree/bt_search.c369
-rw-r--r--db2/btree/bt_split.c966
-rw-r--r--db2/btree/bt_stat.c198
-rw-r--r--db2/btree/btree_auto.c1508
-rw-r--r--db2/clib/getlong.c48
-rw-r--r--db2/common/db_appinit.c734
-rw-r--r--db2/common/db_apprec.c247
-rw-r--r--db2/common/db_byteorder.c63
-rw-r--r--db2/common/db_err.c211
-rw-r--r--db2/common/db_log2.c69
-rw-r--r--db2/common/db_region.c873
-rw-r--r--db2/common/db_salloc.c302
-rw-r--r--db2/common/db_shash.c126
-rw-r--r--db2/compat.h19
-rw-r--r--db2/config.h150
-rw-r--r--db2/db.h1033
-rw-r--r--db2/db/db.c791
-rw-r--r--db2/db/db_am.c430
-rw-r--r--db2/db/db_auto.c1357
-rw-r--r--db2/db/db_conv.c255
-rw-r--r--db2/db/db_dispatch.c316
-rw-r--r--db2/db/db_dup.c947
-rw-r--r--db2/db/db_iface.c488
-rw-r--r--db2/db/db_join.c271
-rw-r--r--db2/db/db_overflow.c407
-rw-r--r--db2/db/db_pr.c831
-rw-r--r--db2/db/db_rec.c616
-rw-r--r--db2/db/db_ret.c153
-rw-r--r--db2/db185/db185.c493
-rw-r--r--db2/db185/db185_int.h138
-rw-r--r--db2/db_185.h178
-rw-r--r--db2/db_int.h407
-rw-r--r--db2/hash/hash.c1337
-rw-r--r--db2/hash/hash.src231
-rw-r--r--db2/hash/hash_auto.c1554
-rw-r--r--db2/hash/hash_conv.c109
-rw-r--r--db2/hash/hash_dup.c656
-rw-r--r--db2/hash/hash_func.c219
-rw-r--r--db2/hash/hash_page.c1929
-rw-r--r--db2/hash/hash_rec.c986
-rw-r--r--db2/hash/hash_stat.c44
-rw-r--r--db2/include/btree.h263
-rw-r--r--db2/include/btree_auto.h127
-rw-r--r--db2/include/btree_ext.h132
-rw-r--r--db2/include/clib_ext.h59
-rw-r--r--db2/include/common_ext.h34
-rw-r--r--db2/include/cxx_int.h118
-rw-r--r--db2/include/db_185.h.src178
-rw-r--r--db2/include/db_am.h86
-rw-r--r--db2/include/db_auto.h111
-rw-r--r--db2/include/db_cxx.h861
-rw-r--r--db2/include/db_dispatch.h77
-rw-r--r--db2/include/db_ext.h132
-rw-r--r--db2/include/db_join.h23
-rw-r--r--db2/include/db_page.h512
-rw-r--r--db2/include/db_shash.h106
-rw-r--r--db2/include/db_swap.h105
-rw-r--r--db2/include/hash.h199
-rw-r--r--db2/include/hash_auto.h132
-rw-r--r--db2/include/hash_ext.h130
-rw-r--r--db2/include/lock.h197
-rw-r--r--db2/include/lock_ext.h20
-rw-r--r--db2/include/log.h204
-rw-r--r--db2/include/log_auto.h18
-rw-r--r--db2/include/log_ext.h26
-rw-r--r--db2/include/mp.h299
-rw-r--r--db2/include/mp_ext.h21
-rw-r--r--db2/include/mutex_ext.h7
-rw-r--r--db2/include/os.h24
-rw-r--r--db2/include/os_ext.h40
-rw-r--r--db2/include/os_jump.h40
-rw-r--r--db2/include/queue.h275
-rw-r--r--db2/include/shqueue.h334
-rw-r--r--db2/include/txn.h148
-rw-r--r--db2/include/txn_auto.h51
-rw-r--r--db2/include/txn_ext.h41
-rw-r--r--db2/include/xa.h179
-rw-r--r--db2/include/xa_ext.h13
-rw-r--r--db2/lock/lock.c1034
-rw-r--r--db2/lock/lock_conflict.c39
-rw-r--r--db2/lock/lock_deadlock.c502
-rw-r--r--db2/lock/lock_region.c743
-rw-r--r--db2/lock/lock_util.c152
-rw-r--r--db2/log/log.c540
-rw-r--r--db2/log/log.src19
-rw-r--r--db2/log/log_archive.c417
-rw-r--r--db2/log/log_auto.c231
-rw-r--r--db2/log/log_compare.c34
-rw-r--r--db2/log/log_findckp.c141
-rw-r--r--db2/log/log_get.c330
-rw-r--r--db2/log/log_put.c603
-rw-r--r--db2/log/log_rec.c398
-rw-r--r--db2/log/log_register.c208
-rw-r--r--db2/makedb.c387
-rw-r--r--db2/mp/mp_bh.c592
-rw-r--r--db2/mp/mp_fget.c352
-rw-r--r--db2/mp/mp_fopen.c560
-rw-r--r--db2/mp/mp_fput.c153
-rw-r--r--db2/mp/mp_fset.c83
-rw-r--r--db2/mp/mp_open.c221
-rw-r--r--db2/mp/mp_pr.c304
-rw-r--r--db2/mp/mp_region.c330
-rw-r--r--db2/mp/mp_sync.c549
-rw-r--r--db2/mutex/68020.gcc18
-rw-r--r--db2/mutex/README105
-rw-r--r--db2/mutex/alpha.h26
-rw-r--r--db2/mutex/mutex.c318
-rw-r--r--db2/mutex/parisc.gcc36
-rw-r--r--db2/mutex/sco.cc24
-rw-r--r--db2/mutex/sparc.gcc31
-rw-r--r--db2/mutex/tsl_parisc.s65
-rw-r--r--db2/mutex/uts4_cc.s21
-rw-r--r--db2/mutex/x86.gcc17
-rw-r--r--db2/os/os_abs.c31
-rw-r--r--db2/os/os_alloc.c219
-rw-r--r--db2/os/os_config.c153
-rw-r--r--db2/os/os_dir.c101
-rw-r--r--db2/os/os_fid.c76
-rw-r--r--db2/os/os_fsync.c59
-rw-r--r--db2/os/os_map.c447
-rw-r--r--db2/os/os_oflags.c99
-rw-r--r--db2/os/os_open.c152
-rw-r--r--db2/os/os_rpath.c42
-rw-r--r--db2/os/os_rw.c136
-rw-r--r--db2/os/os_seek.c52
-rw-r--r--db2/os/os_sleep.c59
-rw-r--r--db2/os/os_spin.c107
-rw-r--r--db2/os/os_stat.c99
-rw-r--r--db2/os/os_tmpdir.c113
-rw-r--r--db2/os/os_unlink.c39
-rw-r--r--db2/progs/db_archive/db_archive.c156
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c263
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c245
-rw-r--r--db2/progs/db_dump/db_dump.c260
-rw-r--r--db2/progs/db_dump185/db_dump185.c353
-rw-r--r--db2/progs/db_load/db_load.c571
-rw-r--r--db2/progs/db_printlog/README22
-rw-r--r--db2/progs/db_printlog/commit.awk7
-rw-r--r--db2/progs/db_printlog/count.awk9
-rw-r--r--db2/progs/db_printlog/db_printlog.c192
-rw-r--r--db2/progs/db_printlog/pgno.awk43
-rw-r--r--db2/progs/db_printlog/range.awk27
-rw-r--r--db2/progs/db_printlog/status.awk26
-rw-r--r--db2/progs/db_printlog/txn.awk30
-rw-r--r--db2/progs/db_recover/db_recover.c147
-rw-r--r--db2/progs/db_stat/db_stat.c621
-rw-r--r--db2/txn/txn.c1046
-rw-r--r--db2/txn/txn.src55
-rw-r--r--db2/txn/txn_auto.c621
-rw-r--r--db2/txn/txn_rec.c296
-rw-r--r--db2/xa/xa.c682
-rw-r--r--db2/xa/xa_db.c308
-rw-r--r--db2/xa/xa_map.c305
213 files changed, 6 insertions, 64297 deletions
diff --git a/ChangeLog b/ChangeLog
index 79bd787..fc8fe01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2000-01-01 Ulrich Drepper <drepper@cygnus.com>
+ * Makeconfig (all-subdirs): Remove db and db2.
+ * db/*: Removed.
+ * db2/*: Removed.
+
* nss/nss_db/db-XXX.c: Move internal_setent and internal_endent
functions from here...
* nss/db-alias.c: ...and here...
diff --git a/Makeconfig b/Makeconfig
index a2efb41..47d3f3f 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1,4 +1,4 @@
-# Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+# Copyright (C) 1991-1999,2000 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -779,7 +779,7 @@ endif
# is more or less arbitrary. The sorting step will take care of the
# dependencies. Only the $(binfmt-subdir) should always be kept at the
# end of the list.
-all-subdirs = csu assert ctype db db2 locale intl catgets math setjmp signal\
+all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
stdlib stdio-common $(stdio) malloc string wcsmbs time dirent \
grp pwd posix io termios resource misc socket sysvipc gmon \
gnulib iconv iconvdata wctype manual shadow md5-crypt po argp \
diff --git a/db/Makefile b/db/Makefile
deleted file mode 100644
index ac08e78..0000000
--- a/db/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-# Makefile for 4.4BSD db code in GNU C library.
-# This code is taken verbatim from the BSD db 1.85 package. Only this
-# Makefile and compat.h were written for GNU libc, and the header files
-# moved up to this directory.
-
-subdir = db
-
-subdir-dirs = btree db hash mpool recno
-vpath %.c $(subdir-dirs)
-
-extra-libs := libdb1
-extra-libs-others := $(extra-libs)
-libdb1-routines := bt_close bt_conv bt_debug bt_delete bt_get \
- bt_open bt_overflow bt_page bt_put bt_search \
- bt_seq bt_split bt_utils \
- db \
- hash hash_bigkey hash_buf hash_func hash_log2 hash_page \
- ndbm \
- mpool \
- rec_close rec_delete rec_get rec_open rec_put rec_search \
- rec_seq rec_utils
-
-db1-headers := db.h mpool.h ndbm.h
-distribute := compat.h \
- btree/btree.h btree/extern.h \
- hash/extern.h hash/hash.h hash/page.h \
- recno/extern.h recno/recno.h \
- $(db1-headers)
-
-include ../Makeconfig
-
-install-others := $(db1-headers:%=$(inst_includedir)/db1/%)
-
-ifeq (yes,$(build-shared))
-install-others += $(inst_slibdir)/libdb.so$(libdb1.so-version)
-endif
-
-$(inst_slibdir)/libdb.so$(libdb1.so-version): $(inst_slibdir)/libdb1-$(version).so $(+force)
- rm -f $@
- $(LN_S) $(<F) $@
-
-$(db1-headers:%=$(inst_includedir)/db1/%): $(inst_includedir)/db1/%: % $(+force)
- $(do-install)
-
-include ../Rules
-
-CPPFLAGS += -D__DBINTERFACE_PRIVATE -DUSE_LIBDB1
-
-# This file defines some static functions for alternative hash algorithms
-# that are not actually used.
-CFLAGS-hash_func.c := -Wno-unused
-
-# The db code outsmarts the compiler frequently.
-override CFLAGS += -Wno-uninitialized
-
-# Force the soname to be libdb.so for compatibility.
-LDFLAGS-db1.so = -Wl,-soname=lib$(libprefix)db.so$($(@F)-version)
-
-# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
-# This ensures they will load libc.so for needed symbols if loaded by
-# a statically-linked program that hasn't already loaded it.
-$(objpfx)libdb1.so: $(objpfx)libdb1_pic.a $(+preinit) $(+postinit) $(+interp) \
- $(common-objpfx)libc.so
-
-#subdir_install: $(inst_libdir)/libndbm.a
-#$(inst_libdir)/libndbm.a: $(inst_libdir)/libdb1.a $(+force)
-# $(make-link)
-#
-#ifeq ($(build-shared),yes)
-#subdir_install: $(inst_libdir)/libndbm.so
-#$(inst_libdir)/libndbm.so: $(inst_libdir)/libdb1.so $(+force)
-# $(make-link)
-#endif
diff --git a/db/Versions b/db/Versions
deleted file mode 100644
index 479604e..0000000
--- a/db/Versions
+++ /dev/null
@@ -1,10 +0,0 @@
-libdb1 {
- GLIBC_2.0 {
- # the real DB entry point.
- dbopen; __dbopen;
-
- # The compatibility functions.
- dbm_clearerr; dbm_close; dbm_delete; dbm_dirfno; dbm_error;
- dbm_fetch; dbm_firstkey; dbm_nextkey; dbm_open; dbm_store;
- }
-}
diff --git a/db/btree/bt_close.c b/db/btree/bt_close.c
deleted file mode 100644
index 27f9ab6..0000000
--- a/db/btree/bt_close.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int bt_meta __P((BTREE *));
-
-/*
- * BT_CLOSE -- Close a btree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int fd;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync the tree. */
- if (__bt_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Close the memory pool. */
- if (mpool_close(t->bt_mp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Free random memory. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- if (t->bt_rkey.data) {
- free(t->bt_rkey.data);
- t->bt_rkey.size = 0;
- t->bt_rkey.data = NULL;
- }
- if (t->bt_rdata.data) {
- free(t->bt_rdata.data);
- t->bt_rdata.size = 0;
- t->bt_rdata.data = NULL;
- }
-
- fd = t->bt_fd;
- free(t);
- free(dbp);
- return (close(fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-/*
- * BT_SYNC -- sync the btree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync doesn't currently take any flags. */
- if (flags != 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
- return (RET_SUCCESS);
-
- if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
- return (RET_ERROR);
-
- if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
- F_CLR(t, B_MODIFIED);
-
- return (status);
-}
-
-/*
- * BT_META -- write the tree meta data to disk.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_meta(t)
- BTREE *t;
-{
- BTMETA m;
- void *p;
-
- if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
- return (RET_ERROR);
-
- /* Fill in metadata. */
- m.magic = BTREEMAGIC;
- m.version = BTREEVERSION;
- m.psize = t->bt_psize;
- m.free = t->bt_free;
- m.nrecs = t->bt_nrecs;
- m.flags = F_ISSET(t, SAVEMETA);
-
- memmove(p, &m, sizeof(BTMETA));
- mpool_put(t->bt_mp, p, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
diff --git a/db/btree/bt_conv.c b/db/btree/bt_conv.c
deleted file mode 100644
index 1cb208b..0000000
--- a/db/btree/bt_conv.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-static void mswap __P((PAGE *));
-
-/*
- * __BT_BPGIN, __BT_BPGOUT --
- * Convert host-specific number layout to/from the host-independent
- * format stored on disk.
- *
- * Parameters:
- * t: tree
- * pg: page number
- * h: page to convert
- */
-void
-__bt_pgin(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- }
-}
-
-void
-__bt_pgout(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- M_16_SWAP(h->linp[i]);
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- M_16_SWAP(h->linp[i]);
- }
-
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-}
-
-/*
- * MSWAP -- Actually swap the bytes on the meta page.
- *
- * Parameters:
- * p: page to convert
- */
-static void
-mswap(pg)
- PAGE *pg;
-{
- char *p;
-
- p = (char *)pg;
- P_32_SWAP(p); /* magic */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* version */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* psize */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* free */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* nrecs */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* flags */
- p += sizeof(u_int32_t);
-}
diff --git a/db/btree/bt_debug.c b/db/btree/bt_debug.c
deleted file mode 100644
index 3aefbe7..0000000
--- a/db/btree/bt_debug.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-#ifdef DEBUG
-/*
- * BT_DUMP -- Dump the tree
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_dump(dbp)
- DB *dbp;
-{
- BTREE *t;
- PAGE *h;
- pgno_t i;
- char *sep;
-
- t = dbp->internal;
- (void)fprintf(stderr, "%s: pgsz %d",
- F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
-#undef X
-#define X(flag, name) \
- if (F_ISSET(t, flag)) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (t->flags != 0) {
- sep = " flags (";
- X(R_FIXLEN, "FIXLEN");
- X(B_INMEM, "INMEM");
- X(B_NODUPS, "NODUPS");
- X(B_RDONLY, "RDONLY");
- X(R_RECNO, "RECNO");
- X(B_METADIRTY,"METADIRTY");
- (void)fprintf(stderr, ")\n");
- }
-#undef X
-
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DMPAGE -- Dump the meta page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dmpage(h)
- PAGE *h;
-{
- BTMETA *m;
- char *sep;
-
- m = (BTMETA *)h;
- (void)fprintf(stderr, "magic %lx\n", m->magic);
- (void)fprintf(stderr, "version %lu\n", m->version);
- (void)fprintf(stderr, "psize %lu\n", m->psize);
- (void)fprintf(stderr, "free %lu\n", m->free);
- (void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
- (void)fprintf(stderr, "flags %lu", m->flags);
-#undef X
-#define X(flag, name) \
- if (m->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (m->flags) {
- sep = " (";
- X(B_NODUPS, "NODUPS");
- X(R_RECNO, "RECNO");
- (void)fprintf(stderr, ")");
- }
-}
-
-/*
- * BT_DNPAGE -- Dump the page
- *
- * Parameters:
- * n: page number to dump.
- */
-void
-__bt_dnpage(dbp, pgno)
- DB *dbp;
- pgno_t pgno;
-{
- BTREE *t;
- PAGE *h;
-
- t = dbp->internal;
- if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DPAGE -- Dump the page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dpage(h)
- PAGE *h;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- RINTERNAL *ri;
- RLEAF *rl;
- indx_t cur, top;
- char *sep;
-
- (void)fprintf(stderr, " page %d: (", h->pgno);
-#undef X
-#define X(flag, name) \
- if (h->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- sep = "";
- X(P_BINTERNAL, "BINTERNAL") /* types */
- X(P_BLEAF, "BLEAF")
- X(P_RINTERNAL, "RINTERNAL") /* types */
- X(P_RLEAF, "RLEAF")
- X(P_OVERFLOW, "OVERFLOW")
- X(P_PRESERVE, "PRESERVE");
- (void)fprintf(stderr, ")\n");
-#undef X
-
- (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
- if (h->flags & P_OVERFLOW)
- return;
-
- top = NEXTINDEX(h);
- (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
- h->lower, h->upper, top);
- for (cur = 0; cur < top; cur++) {
- (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(h, cur);
- (void)fprintf(stderr,
- "size %03d pgno %03d", bi->ksize, bi->pgno);
- if (bi->flags & P_BIGKEY)
- (void)fprintf(stderr, " (indirect)");
- else if (bi->ksize)
- (void)fprintf(stderr,
- " {%.*s}", (int)bi->ksize, bi->bytes);
- break;
- case P_RINTERNAL:
- ri = GETRINTERNAL(h, cur);
- (void)fprintf(stderr, "entries %03d pgno %03d",
- ri->nrecs, ri->pgno);
- break;
- case P_BLEAF:
- bl = GETBLEAF(h, cur);
- if (bl->flags & P_BIGKEY)
- (void)fprintf(stderr,
- "big key page %lu size %u/",
- *(pgno_t *)bl->bytes,
- *(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
- else if (bl->ksize)
- (void)fprintf(stderr, "%s/", bl->bytes);
- if (bl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)(bl->bytes + bl->ksize),
- *(u_int32_t *)(bl->bytes + bl->ksize +
- sizeof(pgno_t)));
- else if (bl->dsize)
- (void)fprintf(stderr, "%.*s",
- (int)bl->dsize, bl->bytes + bl->ksize);
- break;
- case P_RLEAF:
- rl = GETRLEAF(h, cur);
- if (rl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)rl->bytes,
- *(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
- else if (rl->dsize)
- (void)fprintf(stderr,
- "%.*s", (int)rl->dsize, rl->bytes);
- break;
- }
- (void)fprintf(stderr, "\n");
- }
-}
-#endif
-
-#ifdef STATISTICS
-/*
- * BT_STAT -- Gather/print the tree statistics
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_stat(dbp)
- DB *dbp;
-{
- extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
- extern u_long bt_sortsplit, bt_split;
- BTREE *t;
- PAGE *h;
- pgno_t i, pcont, pinternal, pleaf;
- u_long ifree, lfree, nkeys;
- int levels;
-
- t = dbp->internal;
- pcont = pinternal = pleaf = 0;
- nkeys = ifree = lfree = 0;
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- case P_RINTERNAL:
- ++pinternal;
- ifree += h->upper - h->lower;
- break;
- case P_BLEAF:
- case P_RLEAF:
- ++pleaf;
- lfree += h->upper - h->lower;
- nkeys += NEXTINDEX(h);
- break;
- case P_OVERFLOW:
- ++pcont;
- break;
- }
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- /* Count the levels of the tree. */
- for (i = P_ROOT, levels = 0 ;; ++levels) {
- h = mpool_get(t->bt_mp, i, 0);
- if (h->flags & (P_BLEAF|P_RLEAF)) {
- if (levels == 0)
- levels = 1;
- (void)mpool_put(t->bt_mp, h, 0);
- break;
- }
- i = F_ISSET(t, R_RECNO) ?
- GETRINTERNAL(h, 0)->pgno :
- GETBINTERNAL(h, 0)->pgno;
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- (void)fprintf(stderr, "%d level%s with %ld keys",
- levels, levels == 1 ? "" : "s", nkeys);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
- (void)fprintf(stderr,
- "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
- pinternal + pleaf + pcont, pleaf, pinternal, pcont);
- (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
- bt_cache_hit, bt_cache_miss);
- (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
- bt_split, bt_rootsplit, bt_sortsplit);
- pleaf *= t->bt_psize - BTDATAOFF;
- if (pleaf)
- (void)fprintf(stderr,
- "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
- ((double)(pleaf - lfree) / pleaf) * 100,
- pleaf - lfree, lfree);
- pinternal *= t->bt_psize - BTDATAOFF;
- if (pinternal)
- (void)fprintf(stderr,
- "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
- ((double)(pinternal - ifree) / pinternal) * 100,
- pinternal - ifree, ifree);
- if (bt_pfxsaved)
- (void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
- bt_pfxsaved);
-}
-#endif
diff --git a/db/btree/bt_delete.c b/db/btree/bt_delete.c
deleted file mode 100644
index b654c9f..0000000
--- a/db/btree/bt_delete.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_bdelete __P((BTREE *, const DBT *));
-static int __bt_curdel __P((BTREE *, const DBT *, PAGE *, u_int));
-static int __bt_pdelete __P((BTREE *, PAGE *));
-static int __bt_relink __P((BTREE *, PAGE *));
-static int __bt_stkacq __P((BTREE *, PAGE **, CURSOR *));
-
-/*
- * __bt_delete
- * Delete the item(s) referenced by a key.
- *
- * Return RET_SPECIAL if the key is not found.
- */
-int
-__bt_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- CURSOR *c;
- PAGE *h;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- status = __bt_bdelete(t, key);
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, delete the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT)) {
- if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * If the page is about to be emptied, we'll need to
- * delete it, which means we have to acquire a stack.
- */
- if (NEXTINDEX(h) == 1)
- if (__bt_stkacq(t, &h, &t->bt_cursor))
- return (RET_ERROR);
-
- status = __bt_dleaf(t, NULL, h, c->pg.index);
-
- if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp,
- h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
- break;
- }
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED);
- return (status);
-}
-
-/*
- * __bt_stkacq --
- * Acquire a stack so we can delete a cursor entry.
- *
- * Parameters:
- * t: tree
- * hp: pointer to current, pinned PAGE pointer
- * c: pointer to the cursor
- *
- * Returns:
- * 0 on success, 1 on failure
- */
-static int
-__bt_stkacq(t, hp, c)
- BTREE *t;
- PAGE **hp;
- CURSOR *c;
-{
- BINTERNAL *bi;
- EPG *e;
- EPGNO *parent;
- PAGE *h;
- indx_t index;
- pgno_t pgno;
- recno_t nextpg, prevpg;
- int exact, level;
-
- /*
- * Find the first occurrence of the key in the tree. Toss the
- * currently locked page so we don't hit an already-locked page.
- */
- h = *hp;
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /* See if we got it in one shot. */
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /*
- * Move right, looking for the page. At each move we have to move
- * up the stack until we don't have to move to the next page. If
- * we have to change pages at an internal level, we have to fix the
- * stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((nextpg = h->nextpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != NEXTINDEX(h) - 1) {
- index = parent->index + 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
- BT_PUSH(t, pgno, 0);
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
- index = 0;
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
- return (1);
- }
-
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /* Reacquire the original stack. */
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /*
- * Move left, looking for the page. At each move we have to move
- * up the stack until we don't have to change pages to move to the
- * next page. If we have to change pages at an internal level, we
- * have to fix the stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((prevpg = h->prevpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != 0) {
- index = parent->index - 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
-
- index = NEXTINDEX(h) - 1;
- BT_PUSH(t, pgno, index);
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
- return (1);
- }
-
-
-ret: mpool_put(t->bt_mp, h, 0);
- return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
-}
-
-/*
- * __bt_bdelete --
- * Delete all key/data pairs matching the specified key.
- *
- * Parameters:
- * t: tree
- * key: key to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-__bt_bdelete(t, key)
- BTREE *t;
- const DBT *key;
-{
- EPG *e;
- PAGE *h;
- int deleted, exact, redo;
-
- deleted = 0;
-
- /* Find any matching record; __bt_search pins the page. */
-loop: if ((e = __bt_search(t, key, &exact)) == NULL)
- return (deleted ? RET_SUCCESS : RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (deleted ? RET_SUCCESS : RET_SPECIAL);
- }
-
- /*
- * Delete forward, then delete backward, from the found key. If
- * there are duplicates and we reach either side of the page, do
- * the key search again, so that we get them all.
- */
- redo = 0;
- h = e->page;
- do {
- if (__bt_dleaf(t, key, h, e->index)) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (F_ISSET(t, B_NODUPS)) {
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- deleted = 1;
- } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
-
- /* Check for right-hand edge of the page. */
- if (e->index == NEXTINDEX(h))
- redo = 1;
-
- /* Delete from the key to the beginning of the page. */
- while (e->index-- > 0) {
- if (__bt_cmp(t, key, e) != 0)
- break;
- if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (e->index == 0)
- redo = 1;
- }
-
- /* Check for an empty page. */
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- goto loop;
- }
-
- /* Put the page. */
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- if (redo)
- goto loop;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_pdelete --
- * Delete a single page from the tree.
- *
- * Parameters:
- * t: tree
- * h: leaf page
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- *
- * Side-effects:
- * mpool_put's the page
- */
-static int
-__bt_pdelete(t, h)
- BTREE *t;
- PAGE *h;
-{
- BINTERNAL *bi;
- PAGE *pg;
- EPGNO *parent;
- indx_t cnt, index, *ip, offset;
- u_int32_t nksize;
- char *from;
-
- /*
- * Walk the parent page stack -- a LIFO stack of the pages that were
- * traversed when we searched for the page where the delete occurred.
- * Each stack entry is a page number and a page index offset. The
- * offset is for the page traversed on the search. We've just deleted
- * a page, so we have to delete the key from the parent page.
- *
- * If the delete from the parent page makes it empty, this process may
- * continue all the way up the tree. We stop if we reach the root page
- * (which is never deleted, it's just not worth the effort) or if the
- * delete does not empty the page.
- */
- while ((parent = BT_POP(t)) != NULL) {
- /* Get the parent page. */
- if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (RET_ERROR);
-
- index = parent->index;
- bi = GETBINTERNAL(pg, index);
-
- /* Free any overflow pages. */
- if (bi->flags & P_BIGKEY &&
- __ovfl_delete(t, bi->bytes) == RET_ERROR) {
- mpool_put(t->bt_mp, pg, 0);
- return (RET_ERROR);
- }
-
- /*
- * Free the parent if it has only the one key and it's not the
- * root page. If it's the rootpage, turn it back into an empty
- * leaf page.
- */
- if (NEXTINDEX(pg) == 1) {
- if (pg->pgno == P_ROOT) {
- pg->lower = BTDATAOFF;
- pg->upper = t->bt_psize;
- pg->flags = P_BLEAF;
- } else {
- if (__bt_relink(t, pg) || __bt_free(t, pg))
- return (RET_ERROR);
- continue;
- }
- } else {
- /* Pack remaining key items at the end of the page. */
- nksize = NBINTERNAL(bi->ksize);
- from = (char *)pg + pg->upper;
- memmove(from + nksize, from, (char *)bi - from);
- pg->upper += nksize;
-
- /* Adjust indices' offsets, shift the indices down. */
- offset = pg->linp[index];
- for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nksize;
- for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
- pg->lower -= sizeof(indx_t);
- }
-
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- break;
- }
-
- /* Free the leaf page, as long as it wasn't the root. */
- if (h->pgno == P_ROOT) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- return (__bt_relink(t, h) || __bt_free(t, h));
-}
-
-/*
- * __bt_dleaf --
- * Delete a single record from a leaf page.
- *
- * Parameters:
- * t: tree
- * key: referenced key
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_dleaf(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- BLEAF *bl;
- indx_t cnt, *ip, offset;
- u_int32_t nbytes;
- void *to;
- char *from;
-
- /* If this record is referenced by the cursor, delete the cursor. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
- __bt_curdel(t, key, h, index))
- return (RET_ERROR);
-
- /* If the entry uses overflow pages, make them available for reuse. */
- to = bl = GETBLEAF(h, index);
- if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- if (bl->flags & P_BIGDATA &&
- __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
- return (RET_ERROR);
-
- /* Pack the remaining key/data items at the end of the page. */
- nbytes = NBLEAF(bl);
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- /* Adjust the indices' offsets, shift the indices down. */
- offset = h->linp[index];
- for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
- --t->bt_cursor.pg.index;
-
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_curdel --
- * Delete the cursor.
- *
- * Parameters:
- * t: tree
- * key: referenced key (or NULL)
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-__bt_curdel(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- CURSOR *c;
- EPG e;
- PAGE *pg;
- int curcopy, status;
-
- /*
- * If there are duplicates, move forward or backward to one.
- * Otherwise, copy the key into the cursor area.
- */
- c = &t->bt_cursor;
- F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
-
- curcopy = 0;
- if (!F_ISSET(t, B_NODUPS)) {
- /*
- * We're going to have to do comparisons. If we weren't
- * provided a copy of the key, i.e. the user is deleting
- * the current cursor position, get one.
- */
- if (key == NULL) {
- e.page = h;
- e.index = index;
- if ((status = __bt_ret(t, &e,
- &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
- return (status);
- curcopy = 1;
- key = &c->key;
- }
- /* Check previous key, if not at the beginning of the page. */
- if (index > 0) {
- e.page = h;
- e.index = index - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup2;
- }
- }
- /* Check next key, if not at the end of the page. */
- if (index < NEXTINDEX(h) - 1) {
- e.page = h;
- e.index = index + 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
- goto dup2;
- }
- }
- /* Check previous key if at the beginning of the page. */
- if (index == 0 && h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = NEXTINDEX(pg) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup1;
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- /* Check next key if at the end of the page. */
- if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
-dup1: mpool_put(t->bt_mp, pg, 0);
-dup2: c->pg.pgno = e.page->pgno;
- c->pg.index = e.index;
- return (RET_SUCCESS);
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- }
- e.page = h;
- e.index = index;
- if (curcopy || (status =
- __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
- F_SET(c, CURS_ACQUIRE);
- return (RET_SUCCESS);
- }
- return (status);
-}
-
-/*
- * __bt_relink --
- * Link around a deleted page.
- *
- * Parameters:
- * t: tree
- * h: page to be deleted
- */
-static int
-__bt_relink(t, h)
- BTREE *t;
- PAGE *h;
-{
- PAGE *pg;
-
- if (h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- pg->prevpg = h->prevpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- if (h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- pg->nextpg = h->nextpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- return (0);
-}
diff --git a/db/btree/bt_get.c b/db/btree/bt_get.c
deleted file mode 100644
index 74824c7..0000000
--- a/db/btree/bt_get.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __BT_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__bt_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- int exact, status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags. */
- if (flags) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (RET_SPECIAL);
- }
-
- status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
diff --git a/db/btree/bt_open.c b/db/btree/bt_open.c
deleted file mode 100644
index 8c2f48e..0000000
--- a/db/btree/bt_open.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Implementation of btree access method for 4.4BSD.
- *
- * The design here was originally based on that of the btree access method
- * used in the Postgres database system at UC Berkeley. This implementation
- * is wholly independent of the Postgres code.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "btree.h"
-
-#ifdef DEBUG
-#undef MINPSIZE
-#define MINPSIZE 128
-#endif
-
-static int byteorder __P((void));
-static int nroot __P((BTREE *));
-static int tmp __P((void));
-
-/*
- * __BT_OPEN -- Open a btree.
- *
- * Creates and fills a DB struct, and calls the routine that actually
- * opens the btree.
- *
- * Parameters:
- * fname: filename (NULL for in-memory trees)
- * flags: open flag bits
- * mode: open permission bits
- * b: BTREEINFO pointer
- *
- * Returns:
- * NULL on failure, pointer to DB on success.
- *
- */
-DB *
-__bt_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const BTREEINFO *openinfo;
-{
- struct stat sb;
- BTMETA m;
- BTREE *t;
- BTREEINFO b;
- DB *dbp;
- pgno_t ncache;
- ssize_t nr;
- int machine_lorder;
-
- t = NULL;
-
- /*
- * Intention is to make sure all of the user's selections are okay
- * here and then use them without checking. Can't be complete, since
- * we don't know the right page size, lorder or flags until the backing
- * file is opened. Also, the file's page size can cause the cachesize
- * to change.
- */
- machine_lorder = byteorder();
- if (openinfo) {
- b = *openinfo;
-
- /* Flags: R_DUP. */
- if (b.flags & ~(R_DUP))
- goto einval;
-
- /*
- * Page size must be indx_t aligned and >= MINPSIZE. Default
- * page size is set farther on, based on the underlying file
- * transfer size.
- */
- if (b.psize &&
- (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
- b.psize & (sizeof(indx_t) - 1)))
- goto einval;
-
- /* Minimum number of keys per page; absolute minimum is 2. */
- if (b.minkeypage) {
- if (b.minkeypage < 2)
- goto einval;
- } else
- b.minkeypage = DEFMINKEYPAGE;
-
- /* If no comparison, use default comparison and prefix. */
- if (b.compare == NULL) {
- b.compare = __bt_defcmp;
- if (b.prefix == NULL)
- b.prefix = __bt_defpfx;
- }
-
- if (b.lorder == 0)
- b.lorder = machine_lorder;
- } else {
- b.compare = __bt_defcmp;
- b.cachesize = 0;
- b.flags = 0;
- b.lorder = machine_lorder;
- b.minkeypage = DEFMINKEYPAGE;
- b.prefix = __bt_defpfx;
- b.psize = 0;
- }
-
- /* Check for the ubiquitous PDP-11. */
- if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
- goto einval;
-
- /* Allocate and initialize DB and BTREE structures. */
- if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
- goto err;
- memset(t, 0, sizeof(BTREE));
- t->bt_fd = -1; /* Don't close unopened fd on error. */
- t->bt_lorder = b.lorder;
- t->bt_order = NOT;
- t->bt_cmp = b.compare;
- t->bt_pfx = b.prefix;
- t->bt_rfd = -1;
-
- if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
- goto err;
- memset(t->bt_dbp, 0, sizeof(DB));
- if (t->bt_lorder != machine_lorder)
- F_SET(t, B_NEEDSWAP);
-
- dbp->type = DB_BTREE;
- dbp->internal = t;
- dbp->close = __bt_close;
- dbp->del = __bt_delete;
- dbp->fd = __bt_fd;
- dbp->get = __bt_get;
- dbp->put = __bt_put;
- dbp->seq = __bt_seq;
- dbp->sync = __bt_sync;
-
- /*
- * If no file name was supplied, this is an in-memory btree and we
- * open a backing temporary file. Otherwise, it's a disk-based tree.
- */
- if (fname) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, B_RDONLY);
- break;
- case O_RDWR:
- break;
- case O_WRONLY:
- default:
- goto einval;
- }
-
- if ((t->bt_fd = open(fname, flags, mode)) < 0)
- goto err;
-
- } else {
- if ((flags & O_ACCMODE) != O_RDWR)
- goto einval;
- if ((t->bt_fd = tmp()) == -1)
- goto err;
- F_SET(t, B_INMEM);
- }
-
- if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
- goto err;
-
- if (fstat(t->bt_fd, &sb))
- goto err;
- if (sb.st_size) {
- if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
- goto err;
- if (nr != sizeof(BTMETA))
- goto eftype;
-
- /*
- * Read in the meta-data. This can change the notion of what
- * the lorder, page size and flags are, and, when the page size
- * changes, the cachesize value can change too. If the user
- * specified the wrong byte order for an existing database, we
- * don't bother to return an error, we just clear the NEEDSWAP
- * bit.
- */
- if (m.magic == BTREEMAGIC)
- F_CLR(t, B_NEEDSWAP);
- else {
- F_SET(t, B_NEEDSWAP);
- M_32_SWAP(m.magic);
- M_32_SWAP(m.version);
- M_32_SWAP(m.psize);
- M_32_SWAP(m.free);
- M_32_SWAP(m.nrecs);
- M_32_SWAP(m.flags);
- }
- if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
- goto eftype;
- if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
- m.psize & (sizeof(indx_t) - 1))
- goto eftype;
- if (m.flags & ~SAVEMETA)
- goto eftype;
- b.psize = m.psize;
- F_SET(t, m.flags);
- t->bt_free = m.free;
- t->bt_nrecs = m.nrecs;
- } else {
- /*
- * Set the page size to the best value for I/O to this file.
- * Don't overflow the page offset type.
- */
- if (b.psize == 0) {
-#ifdef _STATBUF_ST_BLKSIZE
- b.psize = sb.st_blksize;
-#endif
- if (b.psize < MINPSIZE)
- b.psize = MINPSIZE;
- if (b.psize > MAX_PAGE_OFFSET + 1)
- b.psize = MAX_PAGE_OFFSET + 1;
- }
-
- /* Set flag if duplicates permitted. */
- if (!(b.flags & R_DUP))
- F_SET(t, B_NODUPS);
-
- t->bt_free = P_INVALID;
- t->bt_nrecs = 0;
- F_SET(t, B_METADIRTY);
- }
-
- t->bt_psize = b.psize;
-
- /* Set the cache size; must be a multiple of the page size. */
- if (b.cachesize && b.cachesize & (b.psize - 1))
- b.cachesize += (~b.cachesize & (b.psize - 1)) + 1;
- if (b.cachesize < b.psize * MINCACHE)
- b.cachesize = b.psize * MINCACHE;
-
- /* Calculate number of pages to cache. */
- ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
-
- /*
- * The btree data structure requires that at least two keys can fit on
- * a page, but other than that there's no fixed requirement. The user
- * specified a minimum number per page, and we translated that into the
- * number of bytes a key/data pair can use before being placed on an
- * overflow page. This calculation includes the page header, the size
- * of the index referencing the leaf item and the size of the leaf item
- * structure. Also, don't let the user specify a minkeypage such that
- * a key/data pair won't fit even if both key and data are on overflow
- * pages.
- */
- t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
- (sizeof(indx_t) + NBLEAFDBT(0, 0));
- if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
- t->bt_ovflsize =
- NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
-
- /* Initialize the buffer pool. */
- if ((t->bt_mp =
- mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
- goto err;
- if (!F_ISSET(t, B_INMEM))
- mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
-
- /* Create a root page if new tree. */
- if (nroot(t) == RET_ERROR)
- goto err;
-
- /* Global flags. */
- if (dflags & DB_LOCK)
- F_SET(t, B_DB_LOCK);
- if (dflags & DB_SHMEM)
- F_SET(t, B_DB_SHMEM);
- if (dflags & DB_TXN)
- F_SET(t, B_DB_TXN);
-
- return (dbp);
-
-einval: errno = EINVAL;
- goto err;
-
-eftype: errno = EFTYPE;
- goto err;
-
-err: if (t) {
- if (t->bt_dbp)
- free(t->bt_dbp);
- if (t->bt_fd != -1)
- (void)close(t->bt_fd);
- free(t);
- }
- return (NULL);
-}
-
-/*
- * NROOT -- Create the root of a new tree.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-nroot(t)
- BTREE *t;
-{
- PAGE *meta, *root;
- pgno_t npg;
-
- if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
- mpool_put(t->bt_mp, meta, 0);
- return (RET_SUCCESS);
- }
- if (errno != EINVAL) /* It's OK to not exist. */
- return (RET_ERROR);
- errno = 0;
-
- if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if (npg != P_ROOT)
- return (RET_ERROR);
- root->pgno = npg;
- root->prevpg = root->nextpg = P_INVALID;
- root->lower = BTDATAOFF;
- root->upper = t->bt_psize;
- root->flags = P_BLEAF;
- memset(meta, 0, t->bt_psize);
- mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
- mpool_put(t->bt_mp, root, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-static int
-tmp()
-{
- sigset_t set, oset;
- int fd;
- const char *envtmp;
- char *path;
- static const char fmt[] = "%s/bt.XXXXXX";
- size_t n;
-
- envtmp = getenv("TMPDIR");
- if (!envtmp)
- envtmp = "/tmp";
- n = strlen (envtmp) + sizeof fmt;
-#ifdef __GNUC__
- path = __builtin_alloca(n);
-#else
- path = malloc(n);
-#endif
- (void)snprintf(path, n, fmt, envtmp ? envtmp : "/tmp");
-
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((fd = mkstemp(path)) != -1)
- (void)unlink(path);
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
-#ifndef __GNUC__
- free(path);
-#endif
- return(fd);
-}
-
-static int
-byteorder()
-{
- u_int32_t x;
- u_char *p;
-
- x = 0x01020304;
- p = (u_char *)&x;
- switch (*p) {
- case 1:
- return (BIG_ENDIAN);
- case 4:
- return (LITTLE_ENDIAN);
- default:
- return (0);
- }
-}
-
-int
-__bt_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, B_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_fd);
-}
diff --git a/db/btree/bt_overflow.c b/db/btree/bt_overflow.c
deleted file mode 100644
index b28b8e0..0000000
--- a/db/btree/bt_overflow.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * Big key/data code.
- *
- * Big key and data entries are stored on linked lists of pages. The initial
- * reference is byte string stored with the key or data and is the page number
- * and size. The actual record is stored in a chain of pages linked by the
- * nextpg field of the PAGE header.
- *
- * The first page of the chain has a special property. If the record is used
- * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
- * in the header.
- *
- * XXX
- * A single DBT is written to each chain, so a lot of space on the last page
- * is wasted. This is a fairly major bug for some data sets.
- */
-
-/*
- * __OVFL_GET -- Get an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- * buf: storage address
- * bufsz: storage size
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_get(t, p, ssz, buf, bufsz)
- BTREE *t;
- void *p;
- size_t *ssz;
- void **buf;
- size_t *bufsz;
-{
- PAGE *h;
- pgno_t pg;
- size_t nb, plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
- *ssz = sz;
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- /* Make the buffer bigger as necessary. */
- if (*bufsz < sz) {
- *buf = (char *)(*buf == NULL ? malloc(sz) : realloc(*buf, sz));
- if (*buf == NULL)
- return (RET_ERROR);
- *bufsz = sz;
- }
-
- /*
- * Step through the linked list of pages, copying the data on each one
- * into the buffer. Never copy more than the data's length.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- nb = MIN(sz, plen);
- memmove(p, (char *)h + BTDATAOFF, nb);
- mpool_put(t->bt_mp, h, 0);
-
- if ((sz -= nb) == 0)
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_PUT -- Store an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * data: DBT to store
- * pgno: storage page number
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_put(t, dbt, pg)
- BTREE *t;
- const DBT *dbt;
- pgno_t *pg;
-{
- PAGE *h, *last;
- void *p;
- pgno_t npg;
- size_t nb, plen;
- u_int32_t sz;
-
- /*
- * Allocate pages and copy the key/data record into them. Store the
- * number of the first page in the chain.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (last = NULL, p = dbt->data, sz = dbt->size;;
- p = (char *)p + plen, last = h) {
- if ((h = __bt_new(t, &npg)) == NULL)
- return (RET_ERROR);
-
- h->pgno = npg;
- h->nextpg = h->prevpg = P_INVALID;
- h->flags = P_OVERFLOW;
- h->lower = h->upper = 0;
-
- nb = MIN(sz, plen);
- memmove((char *)h + BTDATAOFF, p, nb);
-
- if (last) {
- last->nextpg = h->pgno;
- mpool_put(t->bt_mp, last, MPOOL_DIRTY);
- } else
- *pg = h->pgno;
-
- if ((sz -= nb) == 0) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_DELETE -- Delete an overflow chain.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_delete(t, p)
- BTREE *t;
- void *p;
-{
- PAGE *h;
- pgno_t pg;
- size_t plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Don't delete chains used by internal pages. */
- if (h->flags & P_PRESERVE) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SUCCESS);
- }
-
- /* Step through the chain, calling the free routine for each page. */
- for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
- pg = h->nextpg;
- __bt_free(t, h);
- if (sz <= plen)
- break;
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- }
- return (RET_SUCCESS);
-}
diff --git a/db/btree/bt_page.c b/db/btree/bt_page.c
deleted file mode 100644
index ce9cbf1..0000000
--- a/db/btree/bt_page.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __bt_free --
- * Put a page on the freelist.
- *
- * Parameters:
- * t: tree
- * h: page to free
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- *
- * Side-effect:
- * mpool_put's the page.
- */
-int
-__bt_free(t, h)
- BTREE *t;
- PAGE *h;
-{
- /* Insert the page at the head of the free list. */
- h->prevpg = P_INVALID;
- h->nextpg = t->bt_free;
- t->bt_free = h->pgno;
- F_SET(t, B_METADIRTY);
-
- /* Make sure the page gets written back. */
- return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
-}
-
-/*
- * __bt_new --
- * Get a new page, preferably from the freelist.
- *
- * Parameters:
- * t: tree
- * npg: storage for page number.
- *
- * Returns:
- * Pointer to a page, NULL on error.
- */
-PAGE *
-__bt_new(t, npg)
- BTREE *t;
- pgno_t *npg;
-{
- PAGE *h;
-
- if (t->bt_free != P_INVALID &&
- (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
- *npg = t->bt_free;
- t->bt_free = h->nextpg;
- F_SET(t, B_METADIRTY);
- return (h);
- }
- return (mpool_new(t->bt_mp, npg));
-}
diff --git a/db/btree/bt_put.c b/db/btree/bt_put.c
deleted file mode 100644
index 15309c6..0000000
--- a/db/btree/bt_put.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *));
-
-/*
- * __BT_PUT -- Add a btree item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
- * tree and R_NOOVERWRITE specified.
- */
-int
-__bt_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT tkey, tdata;
- EPG *e;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, exact, status;
- char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- case R_NOOVERWRITE:
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, put the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor,
- CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- break;
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If the key/data pair won't fit on a page, store it on overflow
- * pages. Only put the key on the overflow page if the pair are
- * still too big after moving the data to an overflow page.
- *
- * XXX
- * If the insert fails later on, the overflow pages aren't recovered.
- */
- dflags = 0;
- if (key->size + data->size > t->bt_ovflsize) {
- if (key->size > t->bt_ovflsize) {
-storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
- return (RET_ERROR);
- tkey.data = kb;
- tkey.size = NOVFLSIZE;
- memmove(kb, &pg, sizeof(pgno_t));
- memmove(kb + sizeof(pgno_t),
- &key->size, sizeof(u_int32_t));
- dflags |= P_BIGKEY;
- key = &tkey;
- }
- if (key->size + data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- memmove(db, &pg, sizeof(pgno_t));
- memmove(db + sizeof(pgno_t),
- &data->size, sizeof(u_int32_t));
- dflags |= P_BIGDATA;
- data = &tdata;
- }
- if (key->size + data->size > t->bt_ovflsize)
- goto storekey;
- }
-
- /* Replace the cursor. */
- if (flags == R_CURSOR) {
- if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
- return (RET_ERROR);
- index = t->bt_cursor.pg.index;
- goto delete;
- }
-
- /*
- * Find the key to delete, or, the location at which to insert.
- * Bt_fast and __bt_search both pin the returned page.
- */
- if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- h = e->page;
- index = e->index;
-
- /*
- * Add the key/data pair to the tree. If an identical key is already
- * in the tree, and R_NOOVERWRITE is set, an error is returned. If
- * R_NOOVERWRITE is not set, the key is either added (if duplicates are
- * permitted) or an error is returned.
- */
- switch (flags) {
- case R_NOOVERWRITE:
- if (!exact)
- break;
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- default:
- if (!exact || !F_ISSET(t, B_NODUPS))
- break;
- /*
- * !!!
- * Note, the delete may empty the page, so we need to put a
- * new entry into the page immediately.
- */
-delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, or the user has put a ceiling on the number of
- * keys permitted in the page, split the page. The split code will
- * insert the key and data and unpin the current page. If inserting
- * into the offset array, shift the pointers up.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t)) {
- if ((status = __bt_split(t, h, key,
- data, dflags, nbytes, index)) != RET_SUCCESS)
- return (status);
- goto success;
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BLEAF(dest, key, data, dflags);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
- ++t->bt_cursor.pg.index;
-
- if (t->bt_order == NOT) {
- if (h->nextpg == P_INVALID) {
- if (index == NEXTINDEX(h) - 1) {
- t->bt_order = FORWARD;
- t->bt_last.index = index;
- t->bt_last.pgno = h->pgno;
- }
- } else if (h->prevpg == P_INVALID) {
- if (index == 0) {
- t->bt_order = BACK;
- t->bt_last.index = 0;
- t->bt_last.pgno = h->pgno;
- }
- }
- }
-
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
-success:
- if (flags == R_SETCURSOR)
- __bt_setcur(t, e->page->pgno, e->index);
-
- F_SET(t, B_MODIFIED);
- return (RET_SUCCESS);
-}
-
-#ifdef STATISTICS
-u_long bt_cache_hit, bt_cache_miss;
-#endif
-
-/*
- * BT_FAST -- Do a quick check for sorted data.
- *
- * Parameters:
- * t: tree
- * key: key to insert
- *
- * Returns:
- * EPG for new record or NULL if not found.
- */
-static EPG *
-bt_fast(t, key, data, exactp)
- BTREE *t;
- const DBT *key, *data;
- int *exactp;
-{
- PAGE *h;
- u_int32_t nbytes;
- int cmp;
-
- if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
- t->bt_order = NOT;
- return (NULL);
- }
- t->bt_cur.page = h;
- t->bt_cur.index = t->bt_last.index;
-
- /*
- * If won't fit in this page or have too many keys in this page,
- * have to search to get split stack.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t))
- goto miss;
-
- if (t->bt_order == FORWARD) {
- if (t->bt_cur.page->nextpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != NEXTINDEX(h) - 1)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
- goto miss;
- t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
- } else {
- if (t->bt_cur.page->prevpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != 0)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
- goto miss;
- t->bt_last.index = 0;
- }
- *exactp = cmp == 0;
-#ifdef STATISTICS
- ++bt_cache_hit;
-#endif
- return (&t->bt_cur);
-
-miss:
-#ifdef STATISTICS
- ++bt_cache_miss;
-#endif
- t->bt_order = NOT;
- mpool_put(t->bt_mp, h, 0);
- return (NULL);
-}
diff --git a/db/btree/bt_search.c b/db/btree/bt_search.c
deleted file mode 100644
index 485afcb..0000000
--- a/db/btree/bt_search.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
-static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
-
-/*
- * __bt_search --
- * Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * key: key to find
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__bt_search(t, key, exactp)
- BTREE *t;
- const DBT *key;
- int *exactp;
-{
- PAGE *h;
- indx_t base, index, lim;
- pgno_t pg;
- int cmp;
-
- BT_CLR(t);
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (NULL);
-
- /* Do a binary search on the current page. */
- t->bt_cur.page = h;
- for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
- t->bt_cur.index = index = base + (lim >> 1);
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
- if (h->flags & P_BLEAF) {
- *exactp = 1;
- return (&t->bt_cur);
- }
- goto next;
- }
- if (cmp > 0) {
- base = index + 1;
- --lim;
- }
- }
-
- /*
- * If it's a leaf page, we're almost done. If no duplicates
- * are allowed, or we have an exact match, we're done. Else,
- * it's possible that there were matching keys on this page,
- * which later deleted, and we're on a page with no matches
- * while there are matches on other pages. If at the start or
- * end of a page, check the adjacent page.
- */
- if (h->flags & P_BLEAF) {
- if (!F_ISSET(t, B_NODUPS)) {
- if (base == 0 &&
- h->prevpg != P_INVALID &&
- __bt_sprev(t, h, key, exactp))
- return (&t->bt_cur);
- if (base == NEXTINDEX(h) &&
- h->nextpg != P_INVALID &&
- __bt_snext(t, h, key, exactp))
- return (&t->bt_cur);
- }
- *exactp = 0;
- t->bt_cur.index = base;
- return (&t->bt_cur);
- }
-
- /*
- * No match found. Base is the smallest index greater than
- * key and may be zero or a last + 1 index. If it's non-zero,
- * decrement by one, and record the internal page which should
- * be a parent page for the key. If a split later occurs, the
- * inserted page will be to the right of the saved page.
- */
- index = base ? base - 1 : base;
-
-next: BT_PUSH(t, h->pgno, index);
- pg = GETBINTERNAL(h, index)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * __bt_snext --
- * Check for an exact match after the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_snext(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the next page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (0);
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
-
-/*
- * __bt_sprev --
- * Check for an exact match before the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_sprev(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the previous page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (0);
- e.index = NEXTINDEX(e.page) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
diff --git a/db/btree/bt_seq.c b/db/btree/bt_seq.c
deleted file mode 100644
index 90f8960..0000000
--- a/db/btree/bt_seq.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_first __P((BTREE *, const DBT *, EPG *, int *));
-static int __bt_seqadv __P((BTREE *, EPG *, int));
-static int __bt_seqset __P((BTREE *, EPG *, DBT *, int));
-
-/*
- * Sequential scan support.
- *
- * The tree can be scanned sequentially, starting from either end of the
- * tree or from any specific key. A scan request before any scanning is
- * done is initialized as starting from the least node.
- */
-
-/*
- * __bt_seq --
- * Btree sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__bt_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG e;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If scan uninitialized as yet, or starting at a specific record, set
- * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
- * the page the cursor references if they're successful.
- */
- switch (flags) {
- case R_NEXT:
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- status = __bt_seqadv(t, &e, flags);
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- case R_LAST:
- case R_CURSOR:
- status = __bt_seqset(t, &e, key, flags);
- break;
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS) {
- __bt_setcur(t, e.page->pgno, e.index);
-
- status =
- __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e.page, 0);
- else
- t->bt_pinned = e.page;
- }
- return (status);
-}
-
-/*
- * __bt_seqset --
- * Set the sequential scan to a specific key.
- *
- * Parameters:
- * t: tree
- * ep: storage for returned key
- * key: key for initial scan position
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the cursor references.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqset(t, ep, key, flags)
- BTREE *t;
- EPG *ep;
- DBT *key;
- int flags;
-{
- PAGE *h;
- pgno_t pg;
- int exact;
-
- /*
- * Find the first, last or specific key in the tree and point the
- * cursor at it. The cursor may not be moved until a new key has
- * been found.
- */
- switch (flags) {
- case R_CURSOR: /* Keyed scan. */
- /*
- * Find the first instance of the key or the smallest key
- * which is greater than or equal to the specified key.
- */
- if (key->data == NULL || key->size == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
- return (__bt_first(t, key, ep, &exact));
- case R_FIRST: /* First record. */
- case R_NEXT:
- /* Walk down the left-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, 0)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
- ep->page = h;
- ep->index = 0;
- break;
- case R_LAST: /* Last record. */
- case R_PREV:
- /* Walk down the right-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-
- ep->page = h;
- ep->index = NEXTINDEX(h) - 1;
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_seqadvance --
- * Advance the sequential scan.
- *
- * Parameters:
- * t: tree
- * flags: R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the new key/data record is on.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqadv(t, ep, flags)
- BTREE *t;
- EPG *ep;
- int flags;
-{
- CURSOR *c;
- PAGE *h;
- indx_t index;
- pgno_t pg;
- int exact;
-
- /*
- * There are a couple of states that we can be in. The cursor has
- * been initialized by the time we get here, but that's all we know.
- */
- c = &t->bt_cursor;
-
- /*
- * The cursor was deleted where there weren't any duplicate records,
- * so the key was saved. Find out where that key would go in the
- * current tree. It doesn't matter if the returned key is an exact
- * match or not -- if it's an exact match, the record was added after
- * the delete so we can just return it. If not, as long as there's
- * a record there, return it.
- */
- if (F_ISSET(c, CURS_ACQUIRE))
- return (__bt_first(t, &c->key, ep, &exact));
-
- /* Get the page referenced by the cursor. */
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * Find the next/previous record in the tree and point the cursor at
- * it. The cursor may not be moved until a new key has been found.
- */
- switch (flags) {
- case R_NEXT: /* Next record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * forward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_AFTER))
- goto usecurrent;
- index = c->pg.index;
- if (++index == NEXTINDEX(h)) {
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = 0;
- }
- break;
- case R_PREV: /* Previous record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * backward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_BEFORE)) {
-usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
- ep->page = h;
- ep->index = c->pg.index;
- return (RET_SUCCESS);
- }
- index = c->pg.index;
- if (index == 0) {
- pg = h->prevpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = NEXTINDEX(h) - 1;
- } else
- --index;
- break;
- }
-
- ep->page = h;
- ep->index = index;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_first --
- * Find the first entry.
- *
- * Parameters:
- * t: the tree
- * key: the key
- * erval: return EPG
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The first entry in the tree greater than or equal to key,
- * or RET_SPECIAL if no such key exists.
- */
-static int
-__bt_first(t, key, erval, exactp)
- BTREE *t;
- const DBT *key;
- EPG *erval;
- int *exactp;
-{
- PAGE *h;
- EPG *ep, save;
- pgno_t pg;
-
- /*
- * Find any matching record; __bt_search pins the page.
- *
- * If it's an exact match and duplicates are possible, walk backwards
- * in the tree until we find the first one. Otherwise, make sure it's
- * a valid key (__bt_search may return an index just past the end of a
- * page) and return it.
- */
- if ((ep = __bt_search(t, key, exactp)) == NULL)
- return (RET_SPECIAL);
- if (*exactp) {
- if (F_ISSET(t, B_NODUPS)) {
- *erval = *ep;
- return (RET_SUCCESS);
- }
-
- /*
- * Walk backwards, as long as the entry matches and there are
- * keys left in the tree. Save a copy of each match in case
- * we go too far.
- */
- save = *ep;
- h = ep->page;
- do {
- if (save.page->pgno != ep->page->pgno) {
- mpool_put(t->bt_mp, save.page, 0);
- save = *ep;
- } else
- save.index = ep->index;
-
- /*
- * Don't unpin the page the last (or original) match
- * was on, but make sure it's unpinned if an error
- * occurs.
- */
- if (ep->index == 0) {
- if (h->prevpg == P_INVALID)
- break;
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp,
- h->prevpg, 0)) == NULL) {
- if (h->pgno == save.page->pgno)
- mpool_put(t->bt_mp,
- save.page, 0);
- return (RET_ERROR);
- }
- ep->page = h;
- ep->index = NEXTINDEX(h);
- }
- --ep->index;
- } while (__bt_cmp(t, key, ep) == 0);
-
- /*
- * Reach here with the last page that was looked at pinned,
- * which may or may not be the same as the last (or original)
- * match page. If it's not useful, release it.
- */
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
-
- *erval = save;
- return (RET_SUCCESS);
- }
-
- /* If at the end of a page, find the next entry. */
- if (ep->index == NEXTINDEX(ep->page)) {
- h = ep->page;
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- ep->index = 0;
- ep->page = h;
- }
- *erval = *ep;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_setcur --
- * Set the cursor to an entry in the tree.
- *
- * Parameters:
- * t: the tree
- * pgno: page number
- * index: page index
- */
-void
-__bt_setcur(t, pgno, index)
- BTREE *t;
- pgno_t pgno;
- u_int index;
-{
- /* Lose any already deleted key. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
-
- /* Update the cursor. */
- t->bt_cursor.pg.pgno = pgno;
- t->bt_cursor.pg.index = index;
- F_SET(&t->bt_cursor, CURS_INIT);
-}
diff --git a/db/btree/bt_split.c b/db/btree/bt_split.c
deleted file mode 100644
index 4119ccb..0000000
--- a/db/btree/bt_split.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *));
-static PAGE *bt_page
- __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
-static int bt_preserve __P((BTREE *, pgno_t));
-static PAGE *bt_psplit
- __P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t));
-static PAGE *bt_root
- __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
-static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *));
-static recno_t rec_total __P((PAGE *));
-
-#ifdef STATISTICS
-u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
-#endif
-
-/*
- * __BT_SPLIT -- Split the tree.
- *
- * Parameters:
- * t: tree
- * sp: page to split
- * key: key to insert
- * data: data to insert
- * flags: BIGKEY/BIGDATA flags
- * ilen: insert length
- * skip: index to leave open
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_split(t, sp, key, data, flags, ilen, argskip)
- BTREE *t;
- PAGE *sp;
- const DBT *key, *data;
- int flags;
- size_t ilen;
- u_int32_t argskip;
-{
- BINTERNAL *bi;
- BLEAF *bl, *tbl;
- DBT a, b;
- EPGNO *parent;
- PAGE *h, *l, *r, *lchild, *rchild;
- indx_t nxtindex;
- u_int16_t skip;
- u_int32_t n, nbytes, nksize;
- int parentsplit;
- char *dest;
-
- /*
- * Split the page into two pages, l and r. The split routines return
- * a pointer to the page into which the key should be inserted and with
- * skip set to the offset which should be used. Additionally, l and r
- * are pinned.
- */
- skip = argskip;
- h = sp->pgno == P_ROOT ?
- bt_root(t, sp, &l, &r, &skip, ilen) :
- bt_page(t, sp, &l, &r, &skip, ilen);
- if (h == NULL)
- return (RET_ERROR);
-
- /*
- * Insert the new key/data pair into the leaf page. (Key inserts
- * always cause a leaf page to split first.)
- */
- h->linp[skip] = h->upper -= ilen;
- dest = (char *)h + h->upper;
- if (F_ISSET(t, R_RECNO))
- WR_RLEAF(dest, data, flags)
- else
- WR_BLEAF(dest, key, data, flags)
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err2;
-
- /*
- * Now we walk the parent page stack -- a LIFO stack of the pages that
- * were traversed when we searched for the page that split. Each stack
- * entry is a page number and a page index offset. The offset is for
- * the page traversed on the search. We've just split a page, so we
- * have to insert a new key into the parent page.
- *
- * If the insert into the parent page causes it to split, may have to
- * continue splitting all the way up the tree. We stop if the root
- * splits or the page inserted into didn't have to split to hold the
- * new key. Some algorithms replace the key for the old page as well
- * as the new page. We don't, as there's no reason to believe that the
- * first key on the old page is any better than the key we have, and,
- * in the case of a key being placed at index 0 causing the split, the
- * key is unavailable.
- *
- * There are a maximum of 5 pages pinned at any time. We keep the left
- * and right pages pinned while working on the parent. The 5 are the
- * two children, left parent and right parent (when the parent splits)
- * and the root page or the overflow key page when calling bt_preserve.
- * This code must make sure that all pins are released other than the
- * root page or overflow page which is unlocked elsewhere.
- */
- while ((parent = BT_POP(t)) != NULL) {
- lchild = l;
- rchild = r;
-
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- goto err2;
-
- /*
- * The new key goes ONE AFTER the index, because the split
- * was to the right.
- */
- skip = parent->index + 1;
-
- /*
- * Calculate the space needed on the parent page.
- *
- * Prefix trees: space hack when inserting into BINTERNAL
- * pages. Retain only what's needed to distinguish between
- * the new entry and the LAST entry on the page to its left.
- * If the keys compare equal, retain the entire key. Note,
- * we don't touch overflow keys, and the entire key must be
- * retained for the next-to-left most key on the leftmost
- * page of each level, or the search will fail. Applicable
- * ONLY to internal pages that have leaf pages as children.
- * Further reduction of the key between pairs of internal
- * pages loses too much information.
- */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(rchild, 0);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- bl = GETBLEAF(rchild, 0);
- nbytes = NBINTERNAL(bl->ksize);
- if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
- (h->prevpg != P_INVALID || skip > 1)) {
- tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
- a.size = tbl->ksize;
- a.data = tbl->bytes;
- b.size = bl->ksize;
- b.data = bl->bytes;
- nksize = t->bt_pfx(&a, &b);
- n = NBINTERNAL(nksize);
- if (n < nbytes) {
-#ifdef STATISTICS
- bt_pfxsaved += nbytes - n;
-#endif
- nbytes = n;
- } else
- nksize = 0;
- } else
- nksize = 0;
- break;
- case P_RINTERNAL:
- case P_RLEAF:
- nbytes = NRINTERNAL;
- break;
- default:
- abort();
- }
-
- /* Split the parent page if necessary or shift the indices. */
- if ((u_int32_t) (h->upper - h->lower)
- < nbytes + sizeof(indx_t)) {
- sp = h;
- h = h->pgno == P_ROOT ?
- bt_root(t, h, &l, &r, &skip, nbytes) :
- bt_page(t, h, &l, &r, &skip, nbytes);
- if (h == NULL)
- goto err1;
- parentsplit = 1;
- } else {
- if (skip < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + skip + 1, h->linp + skip,
- (nxtindex - skip) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
- parentsplit = 0;
- }
-
- /* Insert the key into the parent page. */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_BLEAF:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
- rchild->pgno, bl->flags & P_BIGKEY);
- memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- goto err1;
- break;
- case P_RINTERNAL:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = rec_total(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = rec_total(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_RLEAF:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- default:
- abort();
- }
-
- /* Unpin the held pages. */
- if (!parentsplit) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err1;
-
- mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
- }
-
- /* Unpin the held pages. */
- mpool_put(t->bt_mp, l, MPOOL_DIRTY);
- mpool_put(t->bt_mp, r, MPOOL_DIRTY);
-
- /* Clear any pages left on the stack. */
- return (RET_SUCCESS);
-
- /*
- * If something fails in the above loop we were already walking back
- * up the tree and the tree is now inconsistent. Nothing much we can
- * do about it but release any memory we're holding.
- */
-err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
-
-err2: mpool_put(t->bt_mp, l, 0);
- mpool_put(t->bt_mp, r, 0);
- __dbpanic(t->bt_dbp);
- return (RET_ERROR);
-}
-
-/*
- * BT_PAGE -- Split a non-root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_page(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t npg;
-
-#ifdef STATISTICS
- ++bt_split;
-#endif
- /* Put the new right page for the split into place. */
- if ((r = __bt_new(t, &npg)) == NULL)
- return (NULL);
- r->pgno = npg;
- r->lower = BTDATAOFF;
- r->upper = t->bt_psize;
- r->nextpg = h->nextpg;
- r->prevpg = h->pgno;
- r->flags = h->flags & P_TYPE;
-
- /*
- * If we're splitting the last page on a level because we're appending
- * a key to it (skip is NEXTINDEX()), it's likely that the data is
- * sorted. Adding an empty page on the side of the level is less work
- * and can push the fill factor much higher than normal. If we're
- * wrong it's no big deal, we'll just do the split the right way next
- * time. It may look like it's equally easy to do a similar hack for
- * reverse sorted data, that is, split the tree left, but it's not.
- * Don't even try.
- */
- if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
-#ifdef STATISTICS
- ++bt_sortsplit;
-#endif
- h->nextpg = r->pgno;
- r->lower = BTDATAOFF + sizeof(indx_t);
- *skip = 0;
- *lp = h;
- *rp = r;
- return (r);
- }
-
- /* Put the new left page for the split into place. */
- if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
- mpool_put(t->bt_mp, r, 0);
- return (NULL);
- }
-#ifdef PURIFY
- memset(l, 0xff, t->bt_psize);
-#endif
- l->pgno = h->pgno;
- l->nextpg = r->pgno;
- l->prevpg = h->prevpg;
- l->lower = BTDATAOFF;
- l->upper = t->bt_psize;
- l->flags = h->flags & P_TYPE;
-
- /* Fix up the previous pointer of the page after the split page. */
- if (h->nextpg != P_INVALID) {
- if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
- free(l);
- /* XXX mpool_free(t->bt_mp, r->pgno); */
- return (NULL);
- }
- tp->prevpg = r->pgno;
- mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
- }
-
- /*
- * Split right. The key/data pairs aren't sorted in the btree page so
- * it's simpler to copy the data from the split page onto two new pages
- * instead of copying half the data to the right page and compacting
- * the left page in place. Since the left page can't change, we have
- * to swap the original and the allocated left page after the split.
- */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- /* Move the new left page onto the old left page. */
- memmove(h, l, t->bt_psize);
- if (tp == l)
- tp = h;
- free(l);
-
- *lp = h;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_ROOT -- Split the root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_root(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t lnpg, rnpg;
-
-#ifdef STATISTICS
- ++bt_split;
- ++bt_rootsplit;
-#endif
- /* Put the new left and right pages for the split into place. */
- if ((l = __bt_new(t, &lnpg)) == NULL ||
- (r = __bt_new(t, &rnpg)) == NULL)
- return (NULL);
- l->pgno = lnpg;
- r->pgno = rnpg;
- l->nextpg = r->pgno;
- r->prevpg = l->pgno;
- l->prevpg = r->nextpg = P_INVALID;
- l->lower = r->lower = BTDATAOFF;
- l->upper = r->upper = t->bt_psize;
- l->flags = r->flags = h->flags & P_TYPE;
-
- /* Split the root page. */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- *lp = l;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_RROOT -- Fix up the recno root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_rroot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- char *dest;
-
- /* Insert the left and right keys, set the header information. */
- h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
-
- h->linp[1] = h->upper -= NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
-
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to recno internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_RINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_BROOT -- Fix up the btree root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_broot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- u_int32_t nbytes;
- char *dest;
-
- /*
- * If the root page was a leaf page, change it into an internal page.
- * We copy the key we split on (but not the key's data, in the case of
- * a leaf page) to the new root page.
- *
- * The btree comparison code guarantees that the left-most key on any
- * level of the tree is never used, so it doesn't need to be filled in.
- */
- nbytes = NBINTERNAL(0);
- h->linp[0] = h->upper = t->bt_psize - nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, 0, l->pgno, 0);
-
- switch (h->flags & P_TYPE) {
- case P_BLEAF:
- bl = GETBLEAF(r, 0);
- nbytes = NBINTERNAL(bl->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
- memmove(dest, bl->bytes, bl->ksize);
-
- /*
- * If the key is on an overflow page, mark the overflow chain
- * so it isn't deleted when the leaf copy of the key is deleted.
- */
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- break;
- case P_BINTERNAL:
- bi = GETBINTERNAL(r, 0);
- nbytes = NBINTERNAL(bi->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = r->pgno;
- break;
- default:
- abort();
- }
-
- /* There are two keys on the page. */
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to btree internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_BINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_PSPLIT -- Do the real work of splitting the page.
- *
- * Parameters:
- * t: tree
- * h: page to be split
- * l: page to put lower half of data
- * r: page to put upper half of data
- * pskip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert.
- */
-static PAGE *
-bt_psplit(t, h, l, r, pskip, ilen)
- BTREE *t;
- PAGE *h, *l, *r;
- indx_t *pskip;
- size_t ilen;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- CURSOR *c;
- RLEAF *rl;
- PAGE *rval;
- void *src;
- indx_t full, half, nxt, off, skip, top, used;
- u_int32_t nbytes;
- int bigkeycnt, isbigkey;
-
- /*
- * Split the data to the left and right pages. Leave the skip index
- * open. Additionally, make some effort not to split on an overflow
- * key. This makes internal page processing faster and can save
- * space as overflow keys used by internal pages are never deleted.
- */
- bigkeycnt = 0;
- skip = *pskip;
- full = t->bt_psize - BTDATAOFF;
- half = full / 2;
- used = 0;
- for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
- if (skip == off) {
- nbytes = ilen;
- isbigkey = 0; /* XXX: not really known. */
- } else
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- isbigkey = bi->flags & P_BIGKEY;
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- isbigkey = bl->flags & P_BIGKEY;
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- isbigkey = 0;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- isbigkey = 0;
- break;
- default:
- abort();
- }
-
- /*
- * If the key/data pairs are substantial fractions of the max
- * possible size for the page, it's possible to get situations
- * where we decide to try and copy too much onto the left page.
- * Make sure that doesn't happen.
- */
- if ((skip <= off && used + nbytes + sizeof(indx_t) >= full)
- || nxt == top - 1) {
- --off;
- break;
- }
-
- /* Copy the key/data pair, if not the skipped index. */
- if (skip != off) {
- ++nxt;
-
- l->linp[off] = l->upper -= nbytes;
- memmove((char *)l + l->upper, src, nbytes);
- }
-
- used += nbytes + sizeof(indx_t);
- if (used >= half) {
- if (!isbigkey || bigkeycnt == 3)
- break;
- else
- ++bigkeycnt;
- }
- }
-
- /*
- * Off is the last offset that's valid for the left page.
- * Nxt is the first offset to be placed on the right page.
- */
- l->lower += (off + 1) * sizeof(indx_t);
-
- /*
- * If splitting the page that the cursor was on, the cursor has to be
- * adjusted to point to the same record as before the split. If the
- * cursor is at or past the skipped slot, the cursor is incremented by
- * one. If the cursor is on the right page, it is decremented by the
- * number of records split to the left page.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
- if (c->pg.index >= skip)
- ++c->pg.index;
- if (c->pg.index < nxt) /* Left page. */
- c->pg.pgno = l->pgno;
- else { /* Right page. */
- c->pg.pgno = r->pgno;
- c->pg.index -= nxt;
- }
- }
-
- /*
- * If the skipped index was on the left page, just return that page.
- * Otherwise, adjust the skip index to reflect the new position on
- * the right page.
- */
- if (skip <= off) {
- skip = 0;
- rval = l;
- } else {
- rval = r;
- *pskip -= nxt;
- }
-
- for (off = 0; nxt < top; ++off) {
- if (skip == nxt) {
- ++off;
- skip = 0;
- }
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- break;
- default:
- abort();
- }
- ++nxt;
- r->linp[off] = r->upper -= nbytes;
- memmove((char *)r + r->upper, src, nbytes);
- }
- r->lower += off * sizeof(indx_t);
-
- /* If the key is being appended to the page, adjust the index. */
- if (skip == top)
- r->lower += sizeof(indx_t);
-
- return (rval);
-}
-
-/*
- * BT_PRESERVE -- Mark a chain of pages as used by an internal node.
- *
- * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
- * record that references them gets deleted. Chains pointed to by internal
- * pages never get deleted. This routine marks a chain as pointed to by an
- * internal page.
- *
- * Parameters:
- * t: tree
- * pg: page number of first page in the chain.
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-bt_preserve(t, pg)
- BTREE *t;
- pgno_t pg;
-{
- PAGE *h;
-
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- h->flags |= P_PRESERVE;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * REC_TOTAL -- Return the number of recno entries below a page.
- *
- * Parameters:
- * h: page
- *
- * Returns:
- * The number of recno entries below a page.
- *
- * XXX
- * These values could be set by the bt_psplit routine. The problem is that the
- * entry has to be popped off of the stack etc. or the values have to be passed
- * all the way back to bt_split/bt_rroot and it's not very clean.
- */
-static recno_t
-rec_total(h)
- PAGE *h;
-{
- recno_t recs;
- indx_t nxt, top;
-
- for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
- recs += GETRINTERNAL(h, nxt)->nrecs;
- return (recs);
-}
diff --git a/db/btree/bt_utils.c b/db/btree/bt_utils.c
deleted file mode 100644
index 1416c78..0000000
--- a/db/btree/bt_utils.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __bt_ret --
- * Build return key/data pair.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * key: user's key structure (NULL if not to be filled in)
- * 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, rkey, data, rdata, copy)
- BTREE *t;
- EPG *e;
- DBT *key, *rkey, *data, *rdata;
- int copy;
-{
- BLEAF *bl;
- void *p;
-
- bl = GETBLEAF(e->page, e->index);
-
- /*
- * We must copy big keys/data to make them contiguous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- 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);
- 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);
- rkey->data = p;
- rkey->size = bl->ksize;
- }
- memmove(rkey->data, bl->bytes, bl->ksize);
- key->size = bl->ksize;
- key->data = rkey->data;
- } else {
- key->size = bl->ksize;
- key->data = bl->bytes;
- }
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- if (bl->flags & P_BIGDATA) {
- if (__ovfl_get(t, bl->bytes + bl->ksize,
- &data->size, &rdata->data, &rdata->size))
- return (RET_ERROR);
- 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);
- rdata->data = p;
- rdata->size = bl->dsize + 1;
- }
- memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
- data->size = bl->dsize;
- data->data = rdata->data;
- } else {
- data->size = bl->dsize;
- data->data = bl->bytes + bl->ksize;
- }
-
- return (RET_SUCCESS);
-}
-
-/*
- * __BT_CMP -- Compare a key to a given record.
- *
- * Parameters:
- * t: tree
- * k1: DBT pointer of first arg to comparison
- * e: pointer to EPG for comparison
- *
- * Returns:
- * < 0 if k1 is < record
- * = 0 if k1 is = record
- * > 0 if k1 is > record
- */
-int
-__bt_cmp(t, k1, e)
- BTREE *t;
- const DBT *k1;
- EPG *e;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- DBT k2;
- PAGE *h;
- void *bigkey;
-
- /*
- * The left-most key on internal pages, at any level of the tree, is
- * guaranteed by the following code to be less than any user key.
- * This saves us from having to update the leftmost key on an internal
- * page when the user inserts a new key in the tree smaller than
- * anything we've yet seen.
- */
- h = e->page;
- if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
- return (1);
-
- bigkey = NULL;
- if (h->flags & P_BLEAF) {
- bl = GETBLEAF(h, e->index);
- if (bl->flags & P_BIGKEY)
- bigkey = bl->bytes;
- else {
- k2.data = bl->bytes;
- k2.size = bl->ksize;
- }
- } else {
- bi = GETBINTERNAL(h, e->index);
- if (bi->flags & P_BIGKEY)
- bigkey = bi->bytes;
- else {
- k2.data = bi->bytes;
- k2.size = bi->ksize;
- }
- }
-
- if (bigkey) {
- if (__ovfl_get(t, bigkey,
- &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- k2.data = t->bt_rdata.data;
- }
- return ((*t->bt_cmp)(k1, &k2));
-}
-
-/*
- * __BT_DEFCMP -- Default comparison routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * < 0 if a is < b
- * = 0 if a is = b
- * > 0 if a is > b
- */
-int
-__bt_defcmp(a, b)
- const DBT *a, *b;
-{
- register size_t len;
- register u_char *p1, *p2;
-
- /*
- * XXX
- * If a size_t doesn't fit in an int, this routine can lose.
- * What we need is a integral type which is guaranteed to be
- * larger than a size_t, and there is no such thing.
- */
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
- if (*p1 != *p2)
- return ((int)*p1 - (int)*p2);
- return ((int)a->size - (int)b->size);
-}
-
-/*
- * __BT_DEFPFX -- Default prefix routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * Number of bytes needed to distinguish b from a.
- */
-size_t
-__bt_defpfx(a, b)
- const DBT *a, *b;
-{
- register u_char *p1, *p2;
- register size_t cnt, len;
-
- cnt = 1;
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
- if (*p1 != *p2)
- return (cnt);
-
- /* a->size must be <= b->size, or they wouldn't be in this order. */
- return (a->size < b->size ? a->size + 1 : a->size);
-}
diff --git a/db/btree/btree.h b/db/btree/btree.h
deleted file mode 100644
index 45f7c94..0000000
--- a/db/btree/btree.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)btree.h 8.11 (Berkeley) 8/17/94
- */
-
-/* Macros to set/clear/test flags. */
-#define F_SET(p, f) (p)->flags |= (f)
-#define F_CLR(p, f) (p)->flags &= ~(f)
-#define F_ISSET(p, f) ((p)->flags & (f))
-
-#include <mpool.h>
-
-#ifdef _LIBC
-/* In the GNU C library we must not pollute the namespace because libdb is
- needed by libnss_db. */
-#define mpool_open __mpool_open
-#define mpool_filter __mpool_filter
-#define mpool_new __mpool_new
-#define mpool_get __mpool_get
-#define mpool_put __mpool_put
-#define mpool_sync __mpool_sync
-#define mpool_close __mpool_close
-#endif
-
-#define DEFMINKEYPAGE (2) /* Minimum keys per page */
-#define MINCACHE (5) /* Minimum cached pages */
-#define MINPSIZE (512) /* Minimum page size */
-
-/*
- * Page 0 of a btree file contains a copy of the meta-data. This page is also
- * used as an out-of-band page, i.e. page pointers that point to nowhere point
- * to page 0. Page 1 is the root of the btree.
- */
-#define P_INVALID 0 /* Invalid tree page number. */
-#define P_META 0 /* Tree metadata page number. */
-#define P_ROOT 1 /* Tree root page number. */
-
-/*
- * There are five page layouts in the btree: btree internal pages (BINTERNAL),
- * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
- * (RLEAF) and overflow pages. All five page types have a page header (PAGE).
- * This implementation requires that values within structures NOT be padded.
- * (ANSI C permits random padding.) If your compiler pads randomly you'll have
- * to do some work to get this package to run.
- */
-typedef struct _page {
- pgno_t pgno; /* this page's page number */
- pgno_t prevpg; /* left sibling */
- pgno_t nextpg; /* right sibling */
-
-#define P_BINTERNAL 0x01 /* btree internal page */
-#define P_BLEAF 0x02 /* leaf page */
-#define P_OVERFLOW 0x04 /* overflow page */
-#define P_RINTERNAL 0x08 /* recno internal page */
-#define P_RLEAF 0x10 /* leaf page */
-#define P_TYPE 0x1f /* type mask */
-#define P_PRESERVE 0x20 /* never delete this chain of pages */
- u_int32_t flags;
-
- indx_t lower; /* lower bound of free space on page */
- indx_t upper; /* upper bound of free space on page */
- indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
-} PAGE;
-
-/* First and next index. */
-#define BTDATAOFF \
- (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
- sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
-#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
-
-/*
- * For pages other than overflow pages, there is an array of offsets into the
- * rest of the page immediately following the page header. Each offset is to
- * an item which is unique to the type of page. The h_lower offset is just
- * past the last filled-in index. The h_upper offset is the first item on the
- * page. Offsets are from the beginning of the page.
- *
- * If an item is too big to store on a single page, a flag is set and the item
- * is a { page, size } pair such that the page is the first page of an overflow
- * chain with size bytes of item. Overflow pages are simply bytes without any
- * external structure.
- *
- * The page number and size fields in the items are pgno_t-aligned so they can
- * be manipulated without copying. (This presumes that 32 bit items can be
- * manipulated on this system.)
- */
-#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
-#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
-
-/*
- * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
- * pairs, such that the key compares less than or equal to all of the records
- * on that page. For a tree without duplicate keys, an internal page with two
- * consecutive keys, a and b, will have all records greater than or equal to a
- * and less than b stored on the page associated with a. Duplicate keys are
- * somewhat special and can cause duplicate internal and leaf page records and
- * some minor modifications of the above rule.
- */
-typedef struct _binternal {
- u_int32_t ksize; /* key size */
- pgno_t pgno; /* page number stored on */
-#define P_BIGDATA 0x01 /* overflow data */
-#define P_BIGKEY 0x02 /* overflow key */
- u_char flags;
- char bytes[1]; /* data */
-} BINTERNAL;
-
-/* Get the page's BINTERNAL structure at index indx. */
-#define GETBINTERNAL(pg, indx) \
- ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBINTERNAL(len) \
- LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
-
-/* Copy a BINTERNAL entry to the page. */
-#define WR_BINTERNAL(p, size, pgno, flags) { \
- *(u_int32_t *)p = size; \
- p += sizeof(u_int32_t); \
- *(pgno_t *)p = pgno; \
- p += sizeof(pgno_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
-}
-
-/*
- * For the recno internal pages, the item is a page number with the number of
- * keys found on that page and below.
- */
-typedef struct _rinternal {
- recno_t nrecs; /* number of records */
- pgno_t pgno; /* page number stored below */
-} RINTERNAL;
-
-/* Get the page's RINTERNAL structure at index indx. */
-#define GETRINTERNAL(pg, indx) \
- ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRINTERNAL \
- LALIGN(sizeof(recno_t) + sizeof(pgno_t))
-
-/* Copy a RINTERNAL entry to the page. */
-#define WR_RINTERNAL(p, nrecs, pgno) { \
- *(recno_t *)p = nrecs; \
- p += sizeof(recno_t); \
- *(pgno_t *)p = pgno; \
-}
-
-/* For the btree leaf pages, the item is a key and data pair. */
-typedef struct _bleaf {
- u_int32_t ksize; /* size of key */
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA, P_BIGKEY */
- char bytes[1]; /* data */
-} BLEAF;
-
-/* Get the page's BLEAF structure at index indx. */
-#define GETBLEAF(pg, indx) \
- ((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
-
-/* Get the number of bytes in the user's key/data pair. */
-#define NBLEAFDBT(ksize, dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
- (ksize) + (dsize))
-
-/* Copy a BLEAF entry to the page. */
-#define WR_BLEAF(p, key, data, flags) { \
- *(u_int32_t *)p = key->size; \
- p += sizeof(u_int32_t); \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, key->data, key->size); \
- p += key->size; \
- memmove(p, data->data, data->size); \
-}
-
-/* For the recno leaf pages, the item is a data entry. */
-typedef struct _rleaf {
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA */
- char bytes[1];
-} RLEAF;
-
-/* Get the page's RLEAF structure at index indx. */
-#define GETRLEAF(pg, indx) \
- ((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRLEAF(p) NRLEAFDBT((p)->dsize)
-
-/* Get the number of bytes from the user's data. */
-#define NRLEAFDBT(dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
-
-/* Copy a RLEAF entry to the page. */
-#define WR_RLEAF(p, data, flags) { \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, data->data, data->size); \
-}
-
-/*
- * A record in the tree is either a pointer to a page and an index in the page
- * or a page number and an index. These structures are used as a cursor, stack
- * entry and search returns as well as to pass records to other routines.
- *
- * One comment about searches. Internal page searches must find the largest
- * record less than key in the tree so that descents work. Leaf page searches
- * must find the smallest record greater than key so that the returned index
- * is the record's correct position for insertion.
- */
-typedef struct _epgno {
- pgno_t pgno; /* the page number */
- indx_t index; /* the index on the page */
-} EPGNO;
-
-typedef struct _epg {
- PAGE *page; /* the (pinned) page */
- indx_t index; /* the index on the page */
-} EPG;
-
-/*
- * About cursors. The cursor (and the page that contained the key/data pair
- * that it referenced) can be deleted, which makes things a bit tricky. If
- * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
- * or there simply aren't any duplicates of the key) we copy the key that it
- * referenced when it's deleted, and reacquire a new cursor key if the cursor
- * is used again. If there are duplicates keys, we move to the next/previous
- * key, and set a flag so that we know what happened. NOTE: if duplicate (to
- * the cursor) keys are added to the tree during this process, it is undefined
- * if they will be returned or not in a cursor scan.
- *
- * The flags determine the possible states of the cursor:
- *
- * CURS_INIT The cursor references *something*.
- * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
- * we can reacquire the right position in the tree.
- * CURS_AFTER, CURS_BEFORE
- * The cursor was deleted, and now references a key/data pair
- * that has not yet been returned, either before or after the
- * deleted key/data pair.
- * XXX
- * This structure is broken out so that we can eventually offer multiple
- * cursors as part of the DB interface.
- */
-typedef struct _cursor {
- EPGNO pg; /* B: Saved tree reference. */
- DBT key; /* B: Saved key, or key.data == NULL. */
- recno_t rcursor; /* R: recno cursor (1-based) */
-
-#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
-#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
-#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
-#define CURS_INIT 0x08 /* RB: Cursor initialized. */
- u_int8_t flags;
-} CURSOR;
-
-/*
- * The metadata of the tree. The nrecs field is used only by the RECNO code.
- * This is because the btree doesn't really need it and it requires that every
- * put or delete call modify the metadata.
- */
-typedef struct _btmeta {
- u_int32_t magic; /* magic number */
- u_int32_t version; /* version */
- u_int32_t psize; /* page size */
- u_int32_t free; /* page number of first free page */
- u_int32_t nrecs; /* R: number of records */
-
-#define SAVEMETA (B_NODUPS | R_RECNO)
- u_int32_t flags; /* bt_flags & SAVEMETA */
-} BTMETA;
-
-/* The in-memory btree/recno data structure. */
-typedef struct _btree {
- MPOOL *bt_mp; /* memory pool cookie */
-
- DB *bt_dbp; /* pointer to enclosing DB */
-
- EPG bt_cur; /* current (pinned) page */
- PAGE *bt_pinned; /* page pinned across calls */
-
- CURSOR bt_cursor; /* cursor */
-
-#define BT_PUSH(t, p, i) { \
- t->bt_sp->pgno = p; \
- t->bt_sp->index = i; \
- ++t->bt_sp; \
-}
-#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
-#define BT_CLR(t) (t->bt_sp = t->bt_stack)
- EPGNO bt_stack[50]; /* stack of parent pages */
- EPGNO *bt_sp; /* current stack pointer */
-
- DBT bt_rkey; /* returned key */
- DBT bt_rdata; /* returned data */
-
- int bt_fd; /* tree file descriptor */
-
- pgno_t bt_free; /* next free page */
- u_int32_t bt_psize; /* page size */
- indx_t bt_ovflsize; /* cut-off for key/data overflow */
- int bt_lorder; /* byte order */
- /* sorted order */
- enum { NOT, BACK, FORWARD } bt_order;
- EPGNO bt_last; /* last insert */
-
- /* B: key comparison function */
- int (*bt_cmp) __P((const DBT *, const DBT *));
- /* B: prefix comparison function */
- size_t (*bt_pfx) __P((const DBT *, const DBT *));
- /* R: recno input function */
- int (*bt_irec) __P((struct _btree *, recno_t));
-
- FILE *bt_rfp; /* R: record FILE pointer */
- int bt_rfd; /* R: record file descriptor */
-
- caddr_t bt_cmap; /* R: current point in mapped space */
- caddr_t bt_smap; /* R: start of mapped space */
- caddr_t bt_emap; /* R: end of mapped space */
- size_t bt_msize; /* R: size of mapped region. */
-
- recno_t bt_nrecs; /* R: number of records */
- size_t bt_reclen; /* R: fixed record length */
- u_char bt_bval; /* R: delimiting byte/pad character */
-
-/*
- * NB:
- * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
- */
-#define B_INMEM 0x00001 /* in-memory tree */
-#define B_METADIRTY 0x00002 /* need to write metadata */
-#define B_MODIFIED 0x00004 /* tree modified */
-#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
-#define B_RDONLY 0x00010 /* read-only tree */
-
-#define B_NODUPS 0x00020 /* no duplicate keys permitted */
-#define R_RECNO 0x00080 /* record oriented tree */
-
-#define R_CLOSEFP 0x00040 /* opened a file pointer */
-#define R_EOF 0x00100 /* end of input file reached. */
-#define R_FIXLEN 0x00200 /* fixed length records */
-#define R_MEMMAPPED 0x00400 /* memory mapped file. */
-#define R_INMEM 0x00800 /* in-memory file */
-#define R_MODIFIED 0x01000 /* modified file */
-#define R_RDONLY 0x02000 /* read-only file */
-
-#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
-#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
-#define B_DB_TXN 0x10000 /* DB_TXN specified. */
- u_int32_t flags;
-} BTREE;
-
-#include "extern.h"
diff --git a/db/btree/extern.h b/db/btree/extern.h
deleted file mode 100644
index ebd9c54..0000000
--- a/db/btree/extern.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.10 (Berkeley) 7/20/94
- */
-
-int __bt_close __P((DB *));
-int __bt_cmp __P((BTREE *, const DBT *, EPG *));
-int __bt_crsrdel __P((BTREE *, EPGNO *));
-int __bt_defcmp __P((const DBT *, const DBT *));
-size_t __bt_defpfx __P((const DBT *, const DBT *));
-int __bt_delete __P((const DB *, const DBT *, u_int));
-int __bt_dleaf __P((BTREE *, const DBT *, PAGE *, u_int));
-int __bt_fd __P((const DB *));
-int __bt_free __P((BTREE *, PAGE *));
-int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
-PAGE *__bt_new __P((BTREE *, pgno_t *));
-void __bt_pgin __P((void *, pgno_t, void *));
-void __bt_pgout __P((void *, pgno_t, void *));
-int __bt_push __P((BTREE *, pgno_t, int));
-int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
-int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int));
-EPG *__bt_search __P((BTREE *, const DBT *, int *));
-int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
-void __bt_setcur __P((BTREE *, pgno_t, u_int));
-int __bt_split __P((BTREE *, PAGE *,
- const DBT *, const DBT *, int, size_t, u_int32_t));
-int __bt_sync __P((const DB *, u_int));
-
-int __ovfl_delete __P((BTREE *, void *));
-int __ovfl_get __P((BTREE *, void *, size_t *, void **, size_t *));
-int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
-
-#ifdef DEBUG
-void __bt_dnpage __P((DB *, pgno_t));
-void __bt_dpage __P((PAGE *));
-void __bt_dump __P((DB *));
-#endif
-#ifdef STATISTICS
-void __bt_stat __P((DB *));
-#endif
diff --git a/db/compat.h b/db/compat.h
deleted file mode 100644
index 706e582..0000000
--- a/db/compat.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Values for building 4.4 BSD db routines in the GNU C library. */
-
-#ifndef _compat_h_
-#define _compat_h_
-
-#include <fcntl.h>
-
-/*
- * If you can't provide lock values in the open(2) call. Note, this
- * allows races to happen.
- */
-#ifndef O_EXLOCK /* 4.4BSD extension. */
-#define O_EXLOCK 0
-#endif
-
-#ifndef O_SHLOCK /* 4.4BSD extension. */
-#define O_SHLOCK 0
-#endif
-
-#include <errno.h>
-
-#ifndef EFTYPE
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
-#endif
-
-#include <unistd.h>
-#include <limits.h>
-
-#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */
-#define _POSIX_VDISABLE 0 /* Some systems used 0. */
-#endif
-
-#include <termios.h>
-
-#ifndef TCSASOFT /* 4.4BSD extension. */
-#define TCSASOFT 0
-#endif
-
-#include <sys/param.h>
-
-#ifndef MAX /* Usually found in <sys/param.h>. */
-#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
-#endif
-#ifndef MIN /* Usually found in <sys/param.h>. */
-#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
-#endif
-
-
-#endif /* compat.h */
diff --git a/db/db.h b/db/db.h
deleted file mode 100644
index 183501c..0000000
--- a/db/db.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db.h 8.7 (Berkeley) 6/16/94
- */
-
-#ifndef _DB_H
-#define _DB_H 1
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#include <limits.h>
-
-#ifdef __DBINTERFACE_PRIVATE
-#include <compat.h>
-#endif
-
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-typedef __signed char int8_t;
-typedef unsigned char u_int8_t;
-typedef short int16_t;
-typedef unsigned short u_int16_t;
-typedef int int32_t;
-typedef unsigned int u_int32_t;
-#ifdef WE_DONT_NEED_QUADS
-typedef long long int64_t;
-typedef unsigned long long u_int64_t;
-#endif
-#endif
-
-#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
-typedef u_int32_t pgno_t;
-#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
-typedef u_int16_t indx_t;
-#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
-typedef u_int32_t recno_t;
-
-/* Key/data structure -- a Data-Base Thang. */
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT;
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-/*
- * !!!
- * The following flags are included in the dbopen(3) call as part of the
- * open(2) flags. In order to avoid conflicts with the open flags, start
- * at the top of the 16 or 32-bit number space and work our way down. If
- * the open flags were significantly expanded in the future, it could be
- * a problem. Wish I'd left another flags word in the dbopen call.
- *
- * !!!
- * None of this stuff is implemented yet. The only reason that it's here
- * is so that the access methods can skip copying the key/data pair when
- * the DB_LOCK flag isn't set.
- */
-#if UINT_MAX > 65535
-#define DB_LOCK 0x20000000 /* Do locking. */
-#define DB_SHMEM 0x40000000 /* Use shared memory. */
-#define DB_TXN 0x80000000 /* Do transactions. */
-#else
-#define DB_LOCK 0x2000 /* Do locking. */
-#define DB_SHMEM 0x4000 /* Use shared memory. */
-#define DB_TXN 0x8000 /* Do transactions. */
-#endif
-
-/* Access method description structure. */
-typedef struct __db {
- DBTYPE type; /* Underlying db type. */
- int (*close) (struct __db *);
- int (*del) (const struct __db *, const DBT *, u_int);
- int (*get) (const struct __db *, const DBT *, DBT *, u_int);
- int (*put) (const struct __db *, DBT *, const DBT *, u_int);
- int (*seq) (const struct __db *, DBT *, DBT *, u_int);
- int (*sync) (const struct __db *, u_int);
- void *internal; /* Access method private. */
- int (*fd) (const struct __db *);
-} DB;
-
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_long flags;
- u_int cachesize; /* bytes to cache */
- int maxkeypage; /* maximum keys per page */
- int minkeypage; /* minimum keys per page */
- u_int psize; /* page size */
- int (*compare) /* comparison function */
- (const DBT *, const DBT *);
- size_t (*prefix) /* prefix function */
- (const DBT *, const DBT *);
- int lorder; /* byte order */
-} BTREEINFO;
-
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int bsize; /* bucket size */
- u_int ffactor; /* fill factor */
- u_int nelem; /* number of elements */
- u_int cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) (const void *, size_t);
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_long flags;
- u_int cachesize; /* bytes to cache */
- u_int psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-#ifdef __DBINTERFACE_PRIVATE
-/*
- * Little endian <==> big endian 32-bit swap macros.
- * M_32_SWAP swap a memory location
- * P_32_SWAP swap a referenced memory location
- * P_32_COPY swap from one location to another
- */
-#define M_32_SWAP(a) { \
- u_int32_t _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[3]; \
- ((char *)&a)[1] = ((char *)&_tmp)[2]; \
- ((char *)&a)[2] = ((char *)&_tmp)[1]; \
- ((char *)&a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_SWAP(a) { \
- u_int32_t _tmp = *(u_int32_t *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[3]; \
- ((char *)a)[1] = ((char *)&_tmp)[2]; \
- ((char *)a)[2] = ((char *)&_tmp)[1]; \
- ((char *)a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[3]; \
- ((char *)&(b))[1] = ((char *)&(a))[2]; \
- ((char *)&(b))[2] = ((char *)&(a))[1]; \
- ((char *)&(b))[3] = ((char *)&(a))[0]; \
-}
-
-/*
- * Little endian <==> big endian 16-bit swap macros.
- * M_16_SWAP swap a memory location
- * P_16_SWAP swap a referenced memory location
- * P_16_COPY swap from one location to another
- */
-#define M_16_SWAP(a) { \
- u_int16_t _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[1]; \
- ((char *)&a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_SWAP(a) { \
- u_int16_t _tmp = *(u_int16_t *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[1]; \
- ((char *)a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[1]; \
- ((char *)&(b))[1] = ((char *)&(a))[0]; \
-}
-#endif
-
-__BEGIN_DECLS
-DB *__dbopen (const char *, int, int, DBTYPE, const void *) __THROW;
-DB *dbopen (const char *, int, int, DBTYPE, const void *) __THROW;
-
-#ifdef __DBINTERFACE_PRIVATE
-DB *__bt_open (const char *, int, int, const BTREEINFO *, int) __THROW;
-DB *__hash_open (const char *, int, int, const HASHINFO *, int) __THROW;
-DB *__rec_open (const char *, int, int, const RECNOINFO *, int) __THROW;
-void __dbpanic (DB *dbp) __THROW;
-#endif
-__END_DECLS
-
-#endif /* db.h */
diff --git a/db/db/db.c b/db/db/db.c
deleted file mode 100644
index 49f6124..0000000
--- a/db/db/db.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include <db.h>
-
-#ifdef _LIBC
-/* In the GNU C library we must not pollute the namespace, because libdb
- is needed by libnss_db. */
-#define dbopen __dbopen
-#endif
-
-DB *
-dbopen(fname, flags, mode, type, openinfo)
- const char *fname;
- int flags, mode;
- DBTYPE type;
- const void *openinfo;
-{
-
-#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
-#define USE_OPEN_FLAGS \
- (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
- O_RDWR | O_SHLOCK | O_TRUNC)
-
- if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
- switch (type) {
- case DB_BTREE:
- return (__bt_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_HASH:
- return (__hash_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_RECNO:
- return (__rec_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- }
- errno = EINVAL;
- return (NULL);
-}
-#ifdef _LIBC
-#undef dbopen
-weak_alias (__dbopen, dbopen)
-#endif
-
-static int
-__dberr __P((void))
-{
- return (RET_ERROR);
-}
-
-/*
- * __DBPANIC -- Stop.
- *
- * Parameters:
- * dbp: pointer to the DB structure.
- */
-void
-__dbpanic(dbp)
- DB *dbp;
-{
- /* The only thing that can succeed is a close. */
- dbp->del = (int (*)__P((const struct __db *,
- const DBT *, u_int))) __dberr;
- dbp->get = (int (*)__P((const struct __db *,
- const DBT *, DBT *, u_int))) __dberr;
- dbp->put = (int (*)__P((const struct __db *,
- DBT *, const DBT *, u_int))) __dberr;
- dbp->seq = (int (*)__P((const struct __db *,
- DBT *, DBT *, u_int))) __dberr;
- dbp->sync = (int (*)__P((const struct __db *, u_int))) __dberr;
- dbp->fd = (int (*)__P((const struct __db *))) __dberr;
-}
diff --git a/db/hash/extern.h b/db/hash/extern.h
deleted file mode 100644
index 4f1f23d..0000000
--- a/db/hash/extern.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.4 (Berkeley) 6/16/94
- */
-
-BUFHEAD *__add_ovflpage __P((HTAB *, BUFHEAD *));
-int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
-int __big_delete __P((HTAB *, BUFHEAD *));
-int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
-int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int));
-int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int));
-int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
- int, u_int32_t, SPLIT_RETURN *));
-int __buf_free __P((HTAB *, int, int));
-void __buf_init __P((HTAB *, int));
-u_int32_t __call_hash __P((HTAB *, char *, int));
-int __delpair __P((HTAB *, BUFHEAD *, int));
-int __expand_table __P((HTAB *));
-int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int));
-u_int16_t __find_last_page __P((HTAB *, BUFHEAD **));
-void __free_ovflpage __P((HTAB *, BUFHEAD *));
-BUFHEAD *__get_buf __P((HTAB *, u_int32_t, BUFHEAD *, int));
-int __get_page __P((HTAB *, char *, u_int32_t, int, int, int));
-int __ibitmap __P((HTAB *, int, int, int));
-u_int32_t __hash_log2 __P((u_int32_t));
-int __put_page __P((HTAB *, char *, u_int32_t, int, int));
-void __reclaim_buf __P((HTAB *, BUFHEAD *));
-int __split_page __P((HTAB *, u_int32_t, u_int32_t));
-
-/* Default hash routine. */
-extern u_int32_t (*__default_hash) __P((const void *, size_t));
-
-#ifdef HASH_STATISTICS
-extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
diff --git a/db/hash/hash.c b/db/hash/hash.c
deleted file mode 100644
index 99592ea..0000000
--- a/db/hash/hash.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int alloc_segs __P((HTAB *, int));
-static int flush_meta __P((HTAB *));
-static int hash_access __P((HTAB *, ACTION, DBT *, DBT *));
-static int hash_close __P((DB *));
-static int hash_delete __P((const DB *, const DBT *, u_int32_t));
-static int hash_fd __P((const DB *));
-static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t));
-static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t));
-static void *hash_realloc __P((SEGMENT **, int, int));
-static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t));
-static int hash_sync __P((const DB *, u_int32_t));
-static int hdestroy __P((HTAB *));
-static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *));
-static int init_htab __P((HTAB *, int));
-#if BYTE_ORDER == LITTLE_ENDIAN
-static void swap_header __P((HTAB *));
-static void swap_header_copy __P((HASHHDR *, HASHHDR *));
-#endif
-
-/* Fast arithmetic, relying on powers of 2, */
-#define MOD(x, y) ((x) & ((y) - 1))
-
-#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
-
-/* Return values */
-#define SUCCESS (0)
-#define ERROR (-1)
-#define ABNORMAL (1)
-
-#ifdef HASH_STATISTICS
-int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
-
-/************************** INTERFACE ROUTINES ***************************/
-/* OPEN/CLOSE */
-
-extern DB *
-__hash_open(file, flags, mode, info, dflags)
- const char *file;
- int flags, mode, dflags;
- const HASHINFO *info; /* Special directives for create */
-{
- HTAB *hashp;
- struct stat statbuf;
- DB *dbp;
- int bpages, hdrsize, new_table, nsegs, save_errno;
-
- if ((flags & O_ACCMODE) == O_WRONLY) {
- errno = EINVAL;
- return (NULL);
- }
-
- if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
- return (NULL);
- hashp->fp = -1;
-
- /*
- * Even if user wants write only, we need to be able to read
- * the actual file, so we need to open it read/write. But, the
- * field in the hashp structure needs to be accurate so that
- * we can check accesses.
- */
- hashp->flags = flags;
-
- new_table = 0;
- if (!file || (flags & O_TRUNC) ||
- (stat(file, &statbuf) && (errno == ENOENT))) {
- if (errno == ENOENT)
- errno = 0; /* Just in case someone looks at errno */
- new_table = 1;
- }
- if (file) {
- if ((hashp->fp = open(file, flags, mode)) == -1)
- RETURN_ERROR(errno, error0);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- if (new_table) {
- if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
- RETURN_ERROR(errno, error1);
- } else {
- /* Table already exists */
- if (info && info->hash)
- hashp->hash = info->hash;
- else
- hashp->hash = __default_hash;
-
- hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
-#if BYTE_ORDER == LITTLE_ENDIAN
- swap_header(hashp);
-#endif
- if (hdrsize == -1)
- RETURN_ERROR(errno, error1);
- if (hdrsize != sizeof(HASHHDR))
- RETURN_ERROR(EFTYPE, error1);
- /* Verify file type, versions and hash function */
- if (hashp->MAGIC != HASHMAGIC)
- RETURN_ERROR(EFTYPE, error1);
-#define OLDHASHVERSION 1
- if (hashp->VERSION != HASHVERSION &&
- hashp->VERSION != OLDHASHVERSION)
- RETURN_ERROR(EFTYPE, error1);
- if (hashp->hash(CHARKEY, sizeof(CHARKEY))
- != (u_int32_t) hashp->H_CHARKEY)
- RETURN_ERROR(EFTYPE, error1);
- /*
- * Figure out how many segments we need. Max_Bucket is the
- * maximum bucket number, so the number of buckets is
- * max_bucket + 1.
- */
- nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
- hashp->SGSIZE;
- hashp->nsegs = 0;
- if (alloc_segs(hashp, nsegs))
- /*
- * If alloc_segs fails, table will have been destroyed
- * and errno will have been set.
- */
- return (NULL);
- /* Read in bitmaps */
- bpages = (hashp->SPARES[hashp->OVFL_POINT] +
- (hashp->BSIZE << BYTE_SHIFT) - 1) >>
- (hashp->BSHIFT + BYTE_SHIFT);
-
- hashp->nmaps = bpages;
- (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
- }
-
- /* Initialize Buffer Manager */
- if (info && info->cachesize)
- __buf_init(hashp, info->cachesize);
- else
- __buf_init(hashp, DEF_BUFSIZE);
-
- hashp->new_file = new_table;
- hashp->save_file = file && (hashp->flags & O_ACCMODE) != O_RDONLY;
- hashp->cbucket = -1;
- if (!(dbp = (DB *)malloc(sizeof(DB)))) {
- save_errno = errno;
- hdestroy(hashp);
- errno = save_errno;
- return (NULL);
- }
- dbp->internal = hashp;
- dbp->close = hash_close;
- dbp->del = hash_delete;
- dbp->fd = hash_fd;
- dbp->get = hash_get;
- dbp->put = hash_put;
- dbp->seq = hash_seq;
- dbp->sync = hash_sync;
- dbp->type = DB_HASH;
-
-#ifdef DEBUG
- (void)fprintf(stderr,
-"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
- "init_htab:",
- "TABLE POINTER ", hashp,
- "BUCKET SIZE ", hashp->BSIZE,
- "BUCKET SHIFT ", hashp->BSHIFT,
- "DIRECTORY SIZE ", hashp->DSIZE,
- "SEGMENT SIZE ", hashp->SGSIZE,
- "SEGMENT SHIFT ", hashp->SSHIFT,
- "FILL FACTOR ", hashp->FFACTOR,
- "MAX BUCKET ", hashp->MAX_BUCKET,
- "OVFL POINT ", hashp->OVFL_POINT,
- "LAST FREED ", hashp->LAST_FREED,
- "HIGH MASK ", hashp->HIGH_MASK,
- "LOW MASK ", hashp->LOW_MASK,
- "NSEGS ", hashp->nsegs,
- "NKEYS ", hashp->NKEYS);
-#endif
-#ifdef HASH_STATISTICS
- hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
-#endif
- return (dbp);
-
-error1:
- if (hashp != NULL)
- (void)close(hashp->fp);
-
-error0:
- free(hashp);
- errno = save_errno;
- return (NULL);
-}
-
-static int
-hash_close(dbp)
- DB *dbp;
-{
- HTAB *hashp;
- int retval;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- retval = hdestroy(hashp);
- free(dbp);
- return (retval);
-}
-
-static int
-hash_fd(dbp)
- const DB *dbp;
-{
- HTAB *hashp;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (hashp->fp == -1) {
- errno = ENOENT;
- return (-1);
- }
- return (hashp->fp);
-}
-
-/************************** LOCAL CREATION ROUTINES **********************/
-static HTAB *
-init_hash(hashp, file, info)
- HTAB *hashp;
- const char *file;
- HASHINFO *info;
-{
-#ifdef _STATBUF_ST_BLKSIZE
- struct stat statbuf;
-#endif
- int nelem;
-
- nelem = 1;
- hashp->NKEYS = 0;
- hashp->LORDER = BYTE_ORDER;
- hashp->BSIZE = DEF_BUCKET_SIZE;
- hashp->BSHIFT = DEF_BUCKET_SHIFT;
- hashp->SGSIZE = DEF_SEGSIZE;
- hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
- hashp->DSIZE = DEF_DIRSIZE;
- hashp->FFACTOR = DEF_FFACTOR;
- hashp->hash = __default_hash;
- memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
- memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
-
- /* Fix bucket size to be optimal for file system */
-#ifdef _STATBUF_ST_BLKSIZE
- if (file != NULL) {
- if (stat(file, &statbuf))
- return (NULL);
- hashp->BSIZE = statbuf.st_blksize;
- hashp->BSHIFT = __hash_log2(hashp->BSIZE);
- }
-#endif
-
- if (info) {
- if (info->bsize) {
- /* Round pagesize up to power of 2 */
- hashp->BSHIFT = __hash_log2(info->bsize);
- hashp->BSIZE = 1 << hashp->BSHIFT;
- if (hashp->BSIZE > MAX_BSIZE) {
- errno = EINVAL;
- return (NULL);
- }
- }
- if (info->ffactor)
- hashp->FFACTOR = info->ffactor;
- if (info->hash)
- hashp->hash = info->hash;
- if (info->nelem)
- nelem = info->nelem;
- if (info->lorder) {
- if (info->lorder != BIG_ENDIAN &&
- info->lorder != LITTLE_ENDIAN) {
- errno = EINVAL;
- return (NULL);
- }
- hashp->LORDER = info->lorder;
- }
- }
- /* init_htab should destroy the table and set errno if it fails */
- if (init_htab(hashp, nelem))
- return (NULL);
- else
- return (hashp);
-}
-/*
- * This calls alloc_segs which may run out of memory. Alloc_segs will destroy
- * the table and set errno, so we just pass the error information along.
- *
- * Returns 0 on No Error
- */
-static int
-init_htab(hashp, nelem)
- HTAB *hashp;
- int nelem;
-{
- register int nbuckets, nsegs;
- int l2;
-
- /*
- * Divide number of elements by the fill factor and determine a
- * desired number of buckets. Allocate space for the next greater
- * power of two number of buckets.
- */
- nelem = (nelem - 1) / hashp->FFACTOR + 1;
-
- l2 = __hash_log2(MAX(nelem, 2));
- nbuckets = 1 << l2;
-
- hashp->SPARES[l2] = l2 + 1;
- hashp->SPARES[l2 + 1] = l2 + 1;
- hashp->OVFL_POINT = l2;
- hashp->LAST_FREED = 2;
-
- /* First bitmap page is at: splitpoint l2 page offset 1 */
- if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
- return (-1);
-
- hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
- hashp->HIGH_MASK = (nbuckets << 1) - 1;
- hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
- hashp->BSHIFT) + 1;
-
- nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
- nsegs = 1 << __hash_log2(nsegs);
-
- if (nsegs > hashp->DSIZE)
- hashp->DSIZE = nsegs;
- return (alloc_segs(hashp, nsegs));
-}
-
-/********************** DESTROY/CLOSE ROUTINES ************************/
-
-/*
- * Flushes any changes to the file if necessary and destroys the hashp
- * structure, freeing all allocated space.
- */
-static int
-hdestroy(hashp)
- HTAB *hashp;
-{
- int i, save_errno;
-
- save_errno = 0;
-
-#ifdef HASH_STATISTICS
- (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
- hash_accesses, hash_collisions);
- (void)fprintf(stderr, "hdestroy: expansions %ld\n",
- hash_expansions);
- (void)fprintf(stderr, "hdestroy: overflows %ld\n",
- hash_overflows);
- (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
- hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
-
- for (i = 0; i < NCACHED; i++)
- (void)fprintf(stderr,
- "spares[%d] = %d\n", i, hashp->SPARES[i]);
-#endif
- /*
- * Call on buffer manager to free buffers, and if required,
- * write them to disk.
- */
- if (__buf_free(hashp, 1, hashp->save_file))
- save_errno = errno;
- if (hashp->dir) {
- free(*hashp->dir); /* Free initial segments */
- /* Free extra segments */
- while (hashp->exsegs--)
- free(hashp->dir[--hashp->nsegs]);
- free(hashp->dir);
- }
- if (flush_meta(hashp) && !save_errno)
- save_errno = errno;
- /* Free Bigmaps */
- for (i = 0; i < hashp->nmaps; i++)
- if (hashp->mapp[i])
- free(hashp->mapp[i]);
-
- if (hashp->fp != -1)
- (void)close(hashp->fp);
-
- free(hashp);
-
- if (save_errno) {
- errno = save_errno;
- return (ERROR);
- }
- return (SUCCESS);
-}
-/*
- * Write modified pages to disk
- *
- * Returns:
- * 0 == OK
- * -1 ERROR
- */
-static int
-hash_sync(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- HTAB *hashp;
-
- if (flags != 0) {
- errno = EINVAL;
- return (ERROR);
- }
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp->save_file)
- return (0);
- if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
- return (ERROR);
- hashp->new_file = 0;
- return (0);
-}
-
-/*
- * Returns:
- * 0 == OK
- * -1 indicates that errno should be set
- */
-static int
-flush_meta(hashp)
- HTAB *hashp;
-{
- HASHHDR *whdrp;
-#if BYTE_ORDER == LITTLE_ENDIAN
- HASHHDR whdr;
-#endif
- int fp, i, wsize;
-
- if (!hashp->save_file)
- return (0);
- hashp->MAGIC = HASHMAGIC;
- hashp->VERSION = HASHVERSION;
- hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
-
- fp = hashp->fp;
- whdrp = &hashp->hdr;
-#if BYTE_ORDER == LITTLE_ENDIAN
- whdrp = &whdr;
- swap_header_copy(&hashp->hdr, whdrp);
-#endif
- if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
- ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))
- return (-1);
- else
- if (wsize != sizeof(HASHHDR)) {
- errno = EFTYPE;
- hashp->errnum = errno;
- return (-1);
- }
- for (i = 0; i < NCACHED; i++)
- if (hashp->mapp[i])
- if (__put_page(hashp, (char *)hashp->mapp[i],
- hashp->BITMAPS[i], 0, 1))
- return (-1);
- return (0);
-}
-
-/*******************************SEARCH ROUTINES *****************************/
-/*
- * All the access routines return
- *
- * Returns:
- * 0 on SUCCESS
- * 1 to indicate an external ERROR (i.e. key not found, etc)
- * -1 to indicate an internal ERROR (i.e. out of memory, etc)
- */
-static int
-hash_get(dbp, key, data, flag)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_GET, (DBT *)key, data));
-}
-
-static int
-hash_put(dbp, key, data, flag)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_NOOVERWRITE) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errnum = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, flag == R_NOOVERWRITE ?
- HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
-}
-
-static int
-hash_delete(dbp, key, flag)
- const DB *dbp;
- const DBT *key;
- u_int32_t flag; /* Ignored */
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_CURSOR) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errnum = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
-}
-
-/*
- * Assume that hashp has been set in wrapper routine.
- */
-static int
-hash_access(hashp, action, key, val)
- HTAB *hashp;
- ACTION action;
- DBT *key, *val;
-{
- register BUFHEAD *rbufp;
- BUFHEAD *bufp, *save_bufp;
- register u_int16_t *bp;
- register int n, ndx, off, size;
- register char *kp;
- u_int16_t pageno;
-
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
-
- off = hashp->BSIZE;
- size = key->size;
- kp = (char *)key->data;
- rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
- if (!rbufp)
- return (ERROR);
- save_bufp = rbufp;
-
- /* Pin the bucket chain */
- rbufp->flags |= BUF_PIN;
- for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
- if (bp[1] >= REAL_KEY) {
- /* Real key/data pair */
- if (size == off - *bp &&
- memcmp(kp, rbufp->page + *bp, size) == 0)
- goto found;
- off = bp[1];
-#ifdef HASH_STATISTICS
- hash_collisions++;
-#endif
- bp += 2;
- ndx += 2;
- } else if (bp[1] == OVFLPAGE) {
- rbufp = __get_buf(hashp, *bp, rbufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else if (bp[1] < REAL_KEY) {
- if ((ndx =
- __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
- goto found;
- if (ndx == -2) {
- bufp = rbufp;
- if (!(pageno =
- __find_last_page(hashp, &bufp))) {
- ndx = 0;
- rbufp = bufp;
- break; /* FOR */
- }
- rbufp = __get_buf(hashp, pageno, bufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- }
-
- /* Not found */
- switch (action) {
- case HASH_PUT:
- case HASH_PUTNEW:
- if (__addel(hashp, rbufp, key, val)) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
- }
- case HASH_GET:
- case HASH_DELETE:
- default:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- }
-
-found:
- switch (action) {
- case HASH_PUTNEW:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- case HASH_GET:
- bp = (u_int16_t *)rbufp->page;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_return(hashp, rbufp, ndx, val, 0))
- return (ERROR);
- } else {
- val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
- val->size = bp[ndx] - bp[ndx + 1];
- }
- break;
- case HASH_PUT:
- if ((__delpair(hashp, rbufp, ndx)) ||
- (__addel(hashp, rbufp, key, val))) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- break;
- case HASH_DELETE:
- if (__delpair(hashp, rbufp, ndx))
- return (ERROR);
- break;
- default:
- abort();
- }
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
-}
-
-static int
-hash_seq(dbp, key, data, flag)
- const DB *dbp;
- DBT *key, *data;
- u_int32_t flag;
-{
- register u_int32_t bucket;
- register BUFHEAD *bufp;
- HTAB *hashp;
- u_int16_t *bp, ndx;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_FIRST && flag != R_NEXT) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
- if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
- hashp->cbucket = 0;
- hashp->cndx = 1;
- hashp->cpage = NULL;
- }
-
- for (bp = NULL; !bp || !bp[0]; ) {
- if (!(bufp = hashp->cpage)) {
- for (bucket = hashp->cbucket;
- bucket <= (u_int32_t) hashp->MAX_BUCKET;
- bucket++, hashp->cndx = 1) {
- bufp = __get_buf(hashp, bucket, NULL, 0);
- if (!bufp)
- return (ERROR);
- hashp->cpage = bufp;
- bp = (u_int16_t *)bufp->page;
- if (bp[0])
- break;
- }
- hashp->cbucket = bucket;
- if (hashp->cbucket > hashp->MAX_BUCKET) {
- hashp->cbucket = -1;
- return (ABNORMAL);
- }
- } else
- bp = (u_int16_t *)hashp->cpage->page;
-
-#ifdef DEBUG
- assert(bp);
- assert(bufp);
-#endif
- while (bp[hashp->cndx + 1] == OVFLPAGE) {
- bufp = hashp->cpage =
- __get_buf(hashp, bp[hashp->cndx], bufp, 0);
- if (!bufp)
- return (ERROR);
- bp = (u_int16_t *)(bufp->page);
- hashp->cndx = 1;
- }
- if (!bp[0]) {
- hashp->cpage = NULL;
- ++hashp->cbucket;
- }
- }
- ndx = hashp->cndx;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_keydata(hashp, bufp, key, data, 1))
- return (ERROR);
- } else {
- key->data = (u_char *)hashp->cpage->page + bp[ndx];
- key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
- data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
- data->size = bp[ndx] - bp[ndx + 1];
- ndx += 2;
- if (ndx > bp[0]) {
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else
- hashp->cndx = ndx;
- }
- return (SUCCESS);
-}
-
-/********************************* UTILITIES ************************/
-
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__expand_table(hashp)
- HTAB *hashp;
-{
- u_int32_t old_bucket, new_bucket;
- int dirsize, new_segnum, spare_ndx;
-
-#ifdef HASH_STATISTICS
- hash_expansions++;
-#endif
- new_bucket = ++hashp->MAX_BUCKET;
- old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
-
- new_segnum = new_bucket >> hashp->SSHIFT;
-
- /* Check if we need a new segment */
- if (new_segnum >= hashp->nsegs) {
- /* Check if we need to expand directory */
- if (new_segnum >= hashp->DSIZE) {
- /* Reallocate directory */
- dirsize = hashp->DSIZE * sizeof(SEGMENT *);
- if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
- return (-1);
- hashp->DSIZE = dirsize << 1;
- }
- if ((hashp->dir[new_segnum] =
- (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
- return (-1);
- hashp->exsegs++;
- hashp->nsegs++;
- }
- /*
- * If the split point is increasing (MAX_BUCKET's log base 2
- * * increases), we need to copy the current contents of the spare
- * split bucket to the next bucket.
- */
- spare_ndx = __hash_log2(hashp->MAX_BUCKET + 1);
- if (spare_ndx > hashp->OVFL_POINT) {
- hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
- hashp->OVFL_POINT = spare_ndx;
- }
-
- if (new_bucket > (u_int32_t) hashp->HIGH_MASK) {
- /* Starting a new doubling */
- hashp->LOW_MASK = hashp->HIGH_MASK;
- hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
- }
- /* Relocate records to the new bucket */
- return (__split_page(hashp, old_bucket, new_bucket));
-}
-
-/*
- * If realloc guarantees that the pointer is not destroyed if the realloc
- * fails, then this routine can go away.
- */
-static void *
-hash_realloc(p_ptr, oldsize, newsize)
- SEGMENT **p_ptr;
- int oldsize, newsize;
-{
- register void *p;
-
- if ((p = malloc(newsize))) {
- memmove(p, *p_ptr, oldsize);
- memset((char *)p + oldsize, 0, newsize - oldsize);
- free(*p_ptr);
- *p_ptr = p;
- }
- return (p);
-}
-
-extern u_int32_t
-__call_hash(hashp, k, len)
- HTAB *hashp;
- char *k;
- int len;
-{
- int n, bucket;
-
- n = hashp->hash(k, len);
- bucket = n & hashp->HIGH_MASK;
- if (bucket > hashp->MAX_BUCKET)
- bucket = bucket & hashp->LOW_MASK;
- return (bucket);
-}
-
-/*
- * Allocate segment table. On error, destroy the table and set errno.
- *
- * Returns 0 on success
- */
-static int
-alloc_segs(hashp, nsegs)
- HTAB *hashp;
- int nsegs;
-{
- register int i;
- register SEGMENT store;
-
- int save_errno;
-
- if ((hashp->dir =
- (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- /* Allocate segments */
- if ((store =
- (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- for (i = 0; i < nsegs; i++, hashp->nsegs++)
- hashp->dir[i] = &store[i << hashp->SSHIFT];
- return (0);
-}
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-/*
- * Hashp->hdr needs to be byteswapped.
- */
-static void
-swap_header_copy(srcp, destp)
- HASHHDR *srcp, *destp;
-{
- int i;
-
- P_32_COPY(srcp->magic, destp->magic);
- P_32_COPY(srcp->version, destp->version);
- P_32_COPY(srcp->lorder, destp->lorder);
- P_32_COPY(srcp->bsize, destp->bsize);
- P_32_COPY(srcp->bshift, destp->bshift);
- P_32_COPY(srcp->dsize, destp->dsize);
- P_32_COPY(srcp->ssize, destp->ssize);
- P_32_COPY(srcp->sshift, destp->sshift);
- P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
- P_32_COPY(srcp->last_freed, destp->last_freed);
- P_32_COPY(srcp->max_bucket, destp->max_bucket);
- P_32_COPY(srcp->high_mask, destp->high_mask);
- P_32_COPY(srcp->low_mask, destp->low_mask);
- P_32_COPY(srcp->ffactor, destp->ffactor);
- P_32_COPY(srcp->nkeys, destp->nkeys);
- P_32_COPY(srcp->hdrpages, destp->hdrpages);
- P_32_COPY(srcp->h_charkey, destp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- P_32_COPY(srcp->spares[i], destp->spares[i]);
- P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
- }
-}
-
-static void
-swap_header(hashp)
- HTAB *hashp;
-{
- HASHHDR *hdrp;
- int i;
-
- hdrp = &hashp->hdr;
-
- M_32_SWAP(hdrp->magic);
- M_32_SWAP(hdrp->version);
- M_32_SWAP(hdrp->lorder);
- M_32_SWAP(hdrp->bsize);
- M_32_SWAP(hdrp->bshift);
- M_32_SWAP(hdrp->dsize);
- M_32_SWAP(hdrp->ssize);
- M_32_SWAP(hdrp->sshift);
- M_32_SWAP(hdrp->ovfl_point);
- M_32_SWAP(hdrp->last_freed);
- M_32_SWAP(hdrp->max_bucket);
- M_32_SWAP(hdrp->high_mask);
- M_32_SWAP(hdrp->low_mask);
- M_32_SWAP(hdrp->ffactor);
- M_32_SWAP(hdrp->nkeys);
- M_32_SWAP(hdrp->hdrpages);
- M_32_SWAP(hdrp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- M_32_SWAP(hdrp->spares[i]);
- M_16_SWAP(hdrp->bitmaps[i]);
- }
-}
-#endif
diff --git a/db/hash/hash.h b/db/hash/hash.h
deleted file mode 100644
index d07db6f..0000000
--- a/db/hash/hash.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)hash.h 8.3 (Berkeley) 5/31/94
- */
-
-/* Operations */
-typedef enum {
- HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
-} ACTION;
-
-/* Buffer Management structures */
-typedef struct _bufhead BUFHEAD;
-
-struct _bufhead {
- BUFHEAD *prev; /* LRU links */
- BUFHEAD *next; /* LRU links */
- BUFHEAD *ovfl; /* Overflow page buffer header */
- u_int32_t addr; /* Address of this page */
- char *page; /* Actual page data */
- char flags;
-#define BUF_MOD 0x0001
-#define BUF_DISK 0x0002
-#define BUF_BUCKET 0x0004
-#define BUF_PIN 0x0008
-};
-
-#define IS_BUCKET(X) ((X) & BUF_BUCKET)
-
-typedef BUFHEAD **SEGMENT;
-
-/* Hash Table Information */
-typedef struct hashhdr { /* Disk resident portion */
- int magic; /* Magic NO for hash tables */
- int version; /* Version ID */
- u_int32_t lorder; /* Byte Order */
- int bsize; /* Bucket/Page Size */
- int bshift; /* Bucket shift */
- int dsize; /* Directory Size */
- int ssize; /* Segment Size */
- int sshift; /* Segment shift */
- int ovfl_point; /* Where overflow pages are being
- * allocated */
- int last_freed; /* Last overflow page freed */
- int max_bucket; /* ID of Maximum bucket in use */
- int high_mask; /* Mask to modulo into entire table */
- int low_mask; /* Mask to modulo into lower half of
- * table */
- int ffactor; /* Fill factor */
- int nkeys; /* Number of keys in hash table */
- int hdrpages; /* Size of table header */
- int h_charkey; /* value of hash(CHARKEY) */
-#define NCACHED 32 /* number of bit maps and spare
- * points */
- int spares[NCACHED];/* spare pages for overflow */
- u_int16_t bitmaps[NCACHED]; /* address of overflow page
- * bitmaps */
-} HASHHDR;
-
-typedef struct htab { /* Memory resident data structure */
- HASHHDR hdr; /* Header */
- int nsegs; /* Number of allocated segments */
- int exsegs; /* Number of extra allocated
- * segments */
- u_int32_t /* Hash function */
- (*hash)__P((const void *, size_t));
- int flags; /* Flag values */
- int fp; /* File pointer */
- char *tmp_buf; /* Temporary Buffer for BIG data */
- char *tmp_key; /* Temporary Buffer for BIG keys */
- BUFHEAD *cpage; /* Current page */
- int cbucket; /* Current bucket */
- int cndx; /* Index of next item on cpage */
- int errnum; /* Error Number -- for DBM
- * compatibility */
- int new_file; /* Indicates if fd is backing store
- * or no */
- int save_file; /* Indicates whether we need to flush
- * file at
- * exit */
- u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
- int nmaps; /* Initial number of bitmaps */
- int nbufs; /* Number of buffers left to
- * allocate */
- BUFHEAD bufhead; /* Header of buffer lru list */
- SEGMENT *dir; /* Hash Bucket directory */
-} HTAB;
-
-/*
- * Constants
- */
-#define MAX_BSIZE 65536 /* 2^16 */
-#define MIN_BUFFERS 6
-#define MINHDRSIZE 512
-#define DEF_BUFSIZE 65536 /* 64 K */
-#define DEF_BUCKET_SIZE 4096
-#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
-#define DEF_SEGSIZE 256
-#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
-#define DEF_DIRSIZE 256
-#define DEF_FFACTOR 65536
-#define MIN_FFACTOR 4
-#define SPLTMAX 8
-#define CHARKEY "%$sniglet^&"
-#define NUMKEY 1038583
-#define BYTE_SHIFT 3
-#define INT_TO_BYTE 2
-#define INT_BYTE_SHIFT 5
-#define ALL_SET ((u_int32_t)0xFFFFFFFF)
-#define ALL_CLEAR 0
-
-#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
-#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
-#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
-#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
-#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
-
-#define BITS_PER_MAP 32
-
-/* Given the address of the beginning of a big map, clear/set the nth bit */
-#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
-#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
-#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
-
-/* Overflow management */
-/*
- * Overflow page numbers are allocated per split point. At each doubling of
- * the table, we can allocate extra pages. So, an overflow page number has
- * the top 5 bits indicate which split point and the lower 11 bits indicate
- * which page at that split point is indicated (pages within split points are
- * numberered starting with 1).
- */
-
-#define SPLITSHIFT 11
-#define SPLITMASK 0x7FF
-#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
-#define OPAGENUM(N) ((N) & SPLITMASK)
-#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
-
-#define BUCKET_TO_PAGE(B) \
- (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__hash_log2((B)+1)-1] : 0)
-#define OADDR_TO_PAGE(B) \
- BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
-
-/*
- * page.h contains a detailed description of the page format.
- *
- * Normally, keys and data are accessed from offset tables in the top of
- * each page which point to the beginning of the key and data. There are
- * four flag values which may be stored in these offset tables which indicate
- * the following:
- *
- *
- * OVFLPAGE Rather than a key data pair, this pair contains
- * the address of an overflow page. The format of
- * the pair is:
- * OVERFLOW_PAGE_NUMBER OVFLPAGE
- *
- * PARTIAL_KEY This must be the first key/data pair on a page
- * and implies that page contains only a partial key.
- * That is, the key is too big to fit on a single page
- * so it starts on this page and continues on the next.
- * The format of the page is:
- * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * PARTIAL_KEY -- 1
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY This must be the first key/data pair on the page. It
- * is used in two cases.
- *
- * Case 1:
- * There is a complete key on the page but no data
- * (because it wouldn't fit). The next page contains
- * the data.
- *
- * Page format it:
- * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * Case 2:
- * This page contains no key, but part of a large
- * data field, which is continued on the next page.
- *
- * Page format it:
- * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY_DATA
- * This must be the first key/data pair on the page.
- * There are two cases:
- *
- * Case 1:
- * This page contains a key and the beginning of the
- * data field, but the data field is continued on the
- * next page.
- *
- * Page format is:
- * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * DATA_OFF -- offset of the beginning of the data
- *
- * Case 2:
- * This page contains the last page of a big data pair.
- * There is no key, only the tail end of the data
- * on this page.
- *
- * Page format is:
- * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
- *
- * DATA_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * OVFL_PAGENO and OVFLPAGE are optional (they are
- * not present if there is no next page).
- */
-
-#define OVFLPAGE 0
-#define PARTIAL_KEY 1
-#define FULL_KEY 2
-#define FULL_KEY_DATA 3
-#define REAL_KEY 4
-
-/* Short hands for accessing structure */
-#define BSIZE hdr.bsize
-#define BSHIFT hdr.bshift
-#define DSIZE hdr.dsize
-#define SGSIZE hdr.ssize
-#define SSHIFT hdr.sshift
-#define LORDER hdr.lorder
-#define OVFL_POINT hdr.ovfl_point
-#define LAST_FREED hdr.last_freed
-#define MAX_BUCKET hdr.max_bucket
-#define FFACTOR hdr.ffactor
-#define HIGH_MASK hdr.high_mask
-#define LOW_MASK hdr.low_mask
-#define NKEYS hdr.nkeys
-#define HDRPAGES hdr.hdrpages
-#define SPARES hdr.spares
-#define BITMAPS hdr.bitmaps
-#define VERSION hdr.version
-#define MAGIC hdr.magic
-#define NEXT_FREE hdr.next_free
-#define H_CHARKEY hdr.h_charkey
diff --git a/db/hash/hash_bigkey.c b/db/hash/hash_bigkey.c
deleted file mode 100644
index 94c6408..0000000
--- a/db/hash/hash_bigkey.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hash
- * DESCRIPTION:
- * Big key/data handling for the hashing package.
- *
- * ROUTINES:
- * External
- * __big_keydata
- * __big_split
- * __big_insert
- * __big_return
- * __big_delete
- * __find_last_page
- * Internal
- * collect_key
- * collect_data
- */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int));
-static int collect_data __P((HTAB *, BUFHEAD *, int, int));
-
-/*
- * Big_insert
- *
- * You need to do an insert and the key/data pair is too big
- *
- * Returns:
- * 0 ==> OK
- *-1 ==> ERROR
- */
-extern int
-__big_insert(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- register u_int16_t *p;
- int key_size, n, val_size;
- u_int16_t space, move_bytes, off;
- char *cp, *key_data, *val_data;
-
- cp = bufp->page; /* Character pointer of p. */
- p = (u_int16_t *)cp;
-
- key_data = (char *)key->data;
- key_size = key->size;
- val_data = (char *)val->data;
- val_size = val->size;
-
- /* First move the Key */
- for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, key_size);
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, key_data, move_bytes);
- key_size -= move_bytes;
- key_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- p[n] = PARTIAL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- n = p[0];
- if (!key_size) {
- if (FREESPACE(p)) {
- move_bytes = MIN(FREESPACE(p), val_size);
- off = OFFSET(p) - move_bytes;
- p[n] = off;
- memmove(cp + off, val_data, move_bytes);
- val_data += move_bytes;
- val_size -= move_bytes;
- p[n - 2] = FULL_KEY_DATA;
- FREESPACE(p) = FREESPACE(p) - move_bytes;
- OFFSET(p) = off;
- } else
- p[n - 2] = FULL_KEY;
- }
- p = (u_int16_t *)bufp->page;
- cp = bufp->page;
- bufp->flags |= BUF_MOD;
- }
-
- /* Now move the data */
- for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, val_size);
- /*
- * Here's the hack to make sure that if the data ends on the
- * same page as the key ends, FREESPACE is at least one.
- */
- if ((int) space == val_size && (size_t) val_size == val->size)
- move_bytes--;
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, val_data, move_bytes);
- val_size -= move_bytes;
- val_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- if (val_size) {
- p[n] = FULL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- cp = bufp->page;
- p = (u_int16_t *)cp;
- } else
- p[n] = FULL_KEY_DATA;
- bufp->flags |= BUF_MOD;
- }
- return (0);
-}
-
-/*
- * Called when bufp's page contains a partial key (index should be 1)
- *
- * All pages in the big key/data pair except bufp are freed. We cannot
- * free bufp because the page pointing to it is lost and we can't get rid
- * of its pointer.
- *
- * Returns:
- * 0 => OK
- *-1 => ERROR
- */
-extern int
-__big_delete(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- register BUFHEAD *last_bfp, *rbufp;
- u_int16_t *bp, pageno;
- int key_done, n;
-
- rbufp = bufp;
- last_bfp = NULL;
- bp = (u_int16_t *)bufp->page;
- pageno = 0;
- key_done = 0;
-
- while (!key_done || (bp[2] != FULL_KEY_DATA)) {
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
- key_done = 1;
-
- /*
- * If there is freespace left on a FULL_KEY_DATA page, then
- * the data is short and fits entirely on this page, and this
- * is the last page.
- */
- if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
- break;
- pageno = bp[bp[0] - 1];
- rbufp->flags |= BUF_MOD;
- rbufp = __get_buf(hashp, pageno, rbufp, 0);
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = rbufp;
- if (!rbufp)
- return (-1); /* Error. */
- bp = (u_int16_t *)rbufp->page;
- }
-
- /*
- * If we get here then rbufp points to the last page of the big
- * key/data pair. Bufp points to the first one -- it should now be
- * empty pointing to the next page after this pair. Can't free it
- * because we don't have the page pointing to it.
- */
-
- /* This is information from the last page of the pair. */
- n = bp[0];
- pageno = bp[n - 1];
-
- /* Now, bp is the first page of the pair. */
- bp = (u_int16_t *)bufp->page;
- if (n > 2) {
- /* There is an overflow page. */
- bp[1] = pageno;
- bp[2] = OVFLPAGE;
- bufp->ovfl = rbufp->ovfl;
- } else
- /* This is the last page. */
- bufp->ovfl = NULL;
- n -= 2;
- bp[0] = n;
- FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
- OFFSET(bp) = hashp->BSIZE - 1;
-
- bufp->flags |= BUF_MOD;
- if (rbufp)
- __free_ovflpage(hashp, rbufp);
- if (last_bfp && last_bfp != rbufp)
- __free_ovflpage(hashp, last_bfp);
-
- hashp->NKEYS--;
- return (0);
-}
-/*
- * Returns:
- * 0 = key not found
- * -1 = get next overflow page
- * -2 means key not found and this is big key/data
- * -3 error
- */
-extern int
-__find_bigpair(hashp, bufp, ndx, key, size)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- char *key;
- int size;
-{
- register u_int16_t *bp;
- register char *p;
- int ksize;
- u_int16_t bytes;
- char *kkey;
-
- bp = (u_int16_t *)bufp->page;
- p = bufp->page;
- ksize = size;
- kkey = key;
-
- for (bytes = hashp->BSIZE - bp[ndx];
- bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
- bytes = hashp->BSIZE - bp[ndx]) {
- if (memcmp(p + bp[ndx], kkey, bytes))
- return (-2);
- kkey += bytes;
- ksize -= bytes;
- bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
- if (!bufp)
- return (-3);
- p = bufp->page;
- bp = (u_int16_t *)p;
- ndx = 1;
- }
-
- if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
-#ifdef HASH_STATISTICS
- ++hash_collisions;
-#endif
- return (-2);
- } else
- return (ndx);
-}
-
-/*
- * Given the buffer pointer of the first overflow page of a big pair,
- * find the end of the big pair
- *
- * This will set bpp to the buffer header of the last page of the big pair.
- * It will return the pageno of the overflow page following the last page
- * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
- * bucket)
- */
-extern u_int16_t
-__find_last_page(hashp, bpp)
- HTAB *hashp;
- BUFHEAD **bpp;
-{
- BUFHEAD *bufp;
- u_int16_t *bp, pageno;
- int n;
-
- bufp = *bpp;
- bp = (u_int16_t *)bufp->page;
- for (;;) {
- n = bp[0];
-
- /*
- * This is the last page if: the tag is FULL_KEY_DATA and
- * either only 2 entries OVFLPAGE marker is explicit there
- * is freespace on the page.
- */
- if (bp[2] == FULL_KEY_DATA &&
- ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
- break;
-
- pageno = bp[n - 1];
- bufp = __get_buf(hashp, pageno, bufp, 0);
- if (!bufp)
- return (0); /* Need to indicate an error! */
- bp = (u_int16_t *)bufp->page;
- }
-
- *bpp = bufp;
- if (bp[0] > 2)
- return (bp[3]);
- else
- return (0);
-}
-
-/*
- * Return the data for the key/data pair that begins on this page at this
- * index (index should always be 1).
- */
-extern int
-__big_return(hashp, bufp, ndx, val, set_current)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- DBT *val;
- int set_current;
-{
- BUFHEAD *save_p;
- u_int16_t *bp, len, off, save_addr;
- char *tp;
-
- bp = (u_int16_t *)bufp->page;
- while (bp[ndx + 1] == PARTIAL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- ndx = 1;
- }
-
- if (bp[ndx + 1] == FULL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- save_p = bufp;
- save_addr = save_p->addr;
- off = bp[1];
- len = 0;
- } else
- if (!FREESPACE(bp)) {
- /*
- * This is a hack. We can't distinguish between
- * FULL_KEY_DATA that contains complete data or
- * incomplete data, so we require that if the data
- * is complete, there is at least 1 byte of free
- * space left.
- */
- off = bp[bp[0]];
- len = bp[1] - off;
- save_p = bufp;
- save_addr = bufp->addr;
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else {
- /* The data is all on one page. */
- tp = (char *)bp;
- off = bp[bp[0]];
- val->data = (u_char *)tp + off;
- val->size = bp[1] - off;
- if (set_current) {
- if (bp[0] == 2) { /* No more buckets in
- * chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else {
- hashp->cpage = __get_buf(hashp,
- bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- hashp->cndx = 1;
- if (!((u_int16_t *)
- hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- return (0);
- }
-
- val->size = collect_data(hashp, bufp, (int)len, set_current);
- if (val->size == (size_t) -1)
- return (-1);
- if (save_p->addr != save_addr) {
- /* We are pretty short on buffers. */
- errno = EINVAL; /* OUT OF BUFFERS */
- return (-1);
- }
- memmove(hashp->tmp_buf, (save_p->page) + off, len);
- val->data = (u_char *)hashp->tmp_buf;
- return (0);
-}
-/*
- * Count how big the total datasize is by recursing through the pages. Then
- * allocate a buffer and copy the data as you recurse up.
- */
-static int
-collect_data(hashp, bufp, len, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len, set;
-{
- register u_int16_t *bp;
- register char *p;
- BUFHEAD *xbp;
- u_int16_t save_addr;
- int mylen, totlen;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
- save_addr = bufp->addr;
-
- if (bp[2] == FULL_KEY_DATA) { /* End of Data */
- totlen = len + mylen;
- if (hashp->tmp_buf)
- free(hashp->tmp_buf);
- if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (set) {
- hashp->cndx = 1;
- if (bp[0] == 2) { /* No more buckets in chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- } else {
- hashp->cpage =
- __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- else if (!((u_int16_t *)hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_data(hashp, xbp, len + mylen, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* Out of buffers. */
- return (-1);
- }
- memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Fill in the key and data for this big pair.
- */
-extern int
-__big_keydata(hashp, bufp, key, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- DBT *key, *val;
- int set;
-{
- key->size = collect_key(hashp, bufp, 0, val, set);
- if (key->size == (size_t) -1)
- return (-1);
- key->data = (u_char *)hashp->tmp_key;
- return (0);
-}
-
-/*
- * Count how big the total key size is by recursing through the pages. Then
- * collect the data, allocate a buffer and copy the key as you recurse up.
- */
-static int
-collect_key(hashp, bufp, len, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len;
- DBT *val;
- int set;
-{
- BUFHEAD *xbp;
- char *p;
- int mylen, totlen;
- u_int16_t *bp, save_addr;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
-
- save_addr = bufp->addr;
- totlen = len + mylen;
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
- if (hashp->tmp_key != NULL)
- free(hashp->tmp_key);
- if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (__big_return(hashp, bufp, 1, val, set))
- return (-1);
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_key(hashp, xbp, totlen, val, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* MIS -- OUT OF BUFFERS */
- return (-1);
- }
- memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Returns:
- * 0 => OK
- * -1 => error
- */
-extern int
-__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
- HTAB *hashp;
- BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
- BUFHEAD *np; /* Pointer to new bucket page */
- /* Pointer to first page containing the big key/data */
- BUFHEAD *big_keyp;
- int addr; /* Address of big_keyp */
- u_int32_t obucket;/* Old Bucket */
- SPLIT_RETURN *ret;
-{
- register BUFHEAD *tmpp;
- register u_int16_t *tp;
- BUFHEAD *bp;
- DBT key, val;
- u_int32_t change;
- u_int16_t free_space, n, off;
-
- bp = big_keyp;
-
- /* Now figure out where the big key/data goes */
- if (__big_keydata(hashp, big_keyp, &key, &val, 0))
- return (-1);
- change = (__call_hash(hashp, key.data, key.size) != obucket);
-
- if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) {
- if (!(ret->nextp =
- __get_buf(hashp, ret->next_addr, big_keyp, 0)))
- return (-1);;
- } else
- ret->nextp = NULL;
-
- /* Now make one of np/op point to the big key/data pair */
-#ifdef DEBUG
- assert(np->ovfl == NULL);
-#endif
- if (change)
- tmpp = np;
- else
- tmpp = op;
-
- tmpp->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr,
- "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
- (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
-#endif
- tmpp->ovfl = bp; /* one of op/np point to big_keyp */
- tp = (u_int16_t *)tmpp->page;
-#ifdef DEBUG
- assert(FREESPACE(tp) >= OVFLSIZE);
-#endif
- n = tp[0];
- off = OFFSET(tp);
- free_space = FREESPACE(tp);
- tp[++n] = (u_int16_t)addr;
- tp[++n] = OVFLPAGE;
- tp[0] = n;
- OFFSET(tp) = off;
- FREESPACE(tp) = free_space - OVFLSIZE;
-
- /*
- * Finally, set the new and old return values. BIG_KEYP contains a
- * pointer to the last page of the big key_data pair. Make sure that
- * big_keyp has no following page (2 elements) or create an empty
- * following page.
- */
-
- ret->newp = np;
- ret->oldp = op;
-
- tp = (u_int16_t *)big_keyp->page;
- big_keyp->flags |= BUF_MOD;
- if (tp[0] > 2) {
- /*
- * There may be either one or two offsets on this page. If
- * there is one, then the overflow page is linked on normally
- * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
- * the second offset and needs to get stuffed in after the
- * next overflow page is added.
- */
- n = tp[4];
- free_space = FREESPACE(tp);
- off = OFFSET(tp);
- tp[0] -= 2;
- FREESPACE(tp) = free_space + OVFLSIZE;
- OFFSET(tp) = off;
- tmpp = __add_ovflpage(hashp, big_keyp);
- if (!tmpp)
- return (-1);
- tp[4] = n;
- } else
- tmpp = big_keyp;
-
- if (change)
- ret->newp = tmpp;
- else
- ret->oldp = tmpp;
- return (0);
-}
diff --git a/db/hash/hash_buf.c b/db/hash/hash_buf.c
deleted file mode 100644
index 92e1f93..0000000
--- a/db/hash/hash_buf.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hash
- *
- * DESCRIPTION:
- * Contains buffer management
- *
- * ROUTINES:
- * External
- * __buf_init
- * __get_buf
- * __buf_free
- * __reclaim_buf
- * Internal
- * newbuf
- */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static BUFHEAD *newbuf __P((HTAB *, u_int32_t, BUFHEAD *));
-
-/* Unlink B from its place in the lru */
-#define BUF_REMOVE(B) { \
- (B)->prev->next = (B)->next; \
- (B)->next->prev = (B)->prev; \
-}
-
-/* Insert B after P */
-#define BUF_INSERT(B, P) { \
- (B)->next = (P)->next; \
- (B)->prev = (P); \
- (P)->next = (B); \
- (B)->next->prev = (B); \
-}
-
-#define MRU hashp->bufhead.next
-#define LRU hashp->bufhead.prev
-
-#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
-#define LRU_INSERT(B) BUF_INSERT((B), LRU)
-
-/*
- * We are looking for a buffer with address "addr". If prev_bp is NULL, then
- * address is a bucket index. If prev_bp is not NULL, then it points to the
- * page previous to an overflow page that we are trying to find.
- *
- * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
- * be valid. Therefore, you must always verify that its address matches the
- * address you are seeking.
- */
-extern BUFHEAD *
-__get_buf(hashp, addr, prev_bp, newpage)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
- int newpage; /* If prev_bp set, indicates a new overflow page. */
-{
- register BUFHEAD *bp;
- register u_int32_t is_disk_mask;
- register int is_disk, segment_ndx;
- SEGMENT segp;
-
- is_disk = 0;
- is_disk_mask = 0;
- if (prev_bp) {
- bp = prev_bp->ovfl;
- if (!bp || (bp->addr != addr))
- bp = NULL;
- if (!newpage)
- is_disk = BUF_DISK;
- } else {
- /* Grab buffer out of directory */
- segment_ndx = addr & (hashp->SGSIZE - 1);
-
- /* valid segment ensured by __call_hash() */
- segp = hashp->dir[addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
- bp = PTROF(segp[segment_ndx]);
- is_disk_mask = ISDISK(segp[segment_ndx]);
- is_disk = is_disk_mask || !hashp->new_file;
- }
-
- if (!bp) {
- bp = newbuf(hashp, addr, prev_bp);
- if (!bp ||
- __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
- return (NULL);
- if (!prev_bp)
- segp[segment_ndx] =
- (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
- } else {
- BUF_REMOVE(bp);
- MRU_INSERT(bp);
- }
- return (bp);
-}
-
-/*
- * We need a buffer for this page. Either allocate one, or evict a resident
- * one (if we have as many buffers as we're allowed) and put this one in.
- *
- * If newbuf finds an error (returning NULL), it also sets errno.
- */
-static BUFHEAD *
-newbuf(hashp, addr, prev_bp)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
-{
- register BUFHEAD *bp; /* The buffer we're going to use */
- register BUFHEAD *xbp; /* Temp pointer */
- register BUFHEAD *next_xbp;
- SEGMENT segp;
- int segment_ndx;
- u_int16_t oaddr, *shortp;
-
- oaddr = 0;
- bp = LRU;
- /*
- * If LRU buffer is pinned, the buffer pool is too small. We need to
- * allocate more buffers.
- */
- if (hashp->nbufs || (bp->flags & BUF_PIN)) {
- /* Allocate a new one */
- if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
- return (NULL);
-#ifdef PURIFY
- memset(bp, 0xff, sizeof(BUFHEAD));
-#endif
- if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
- free(bp);
- return (NULL);
- }
-#ifdef PURIFY
- memset(bp->page, 0xff, hashp->BSIZE);
-#endif
- if (hashp->nbufs)
- hashp->nbufs--;
- } else {
- /* Kick someone out */
- BUF_REMOVE(bp);
- /*
- * If this is an overflow page with addr 0, it's already been
- * flushed back in an overflow chain and initialized.
- */
- if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
- /*
- * Set oaddr before __put_page so that you get it
- * before bytes are swapped.
- */
- shortp = (u_int16_t *)bp->page;
- if (shortp[0])
- oaddr = shortp[shortp[0] - 1];
- if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
- bp->addr, (int)IS_BUCKET(bp->flags), 0))
- return (NULL);
- /*
- * Update the pointer to this page (i.e. invalidate it).
- *
- * If this is a new file (i.e. we created it at open
- * time), make sure that we mark pages which have been
- * written to disk so we retrieve them from disk later,
- * rather than allocating new pages.
- */
- if (IS_BUCKET(bp->flags)) {
- segment_ndx = bp->addr & (hashp->SGSIZE - 1);
- segp = hashp->dir[bp->addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
-
- if (hashp->new_file &&
- ((bp->flags & BUF_MOD) ||
- ISDISK(segp[segment_ndx])))
- segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
- else
- segp[segment_ndx] = NULL;
- }
- /*
- * Since overflow pages can only be access by means of
- * their bucket, free overflow pages associated with
- * this bucket.
- */
- for (xbp = bp; xbp->ovfl;) {
- next_xbp = xbp->ovfl;
- xbp->ovfl = 0;
- xbp = next_xbp;
-
- /* Check that ovfl pointer is up date. */
- if (IS_BUCKET(xbp->flags) ||
- (oaddr != xbp->addr))
- break;
-
- shortp = (u_int16_t *)xbp->page;
- if (shortp[0])
- /* set before __put_page */
- oaddr = shortp[shortp[0] - 1];
- if ((xbp->flags & BUF_MOD) && __put_page(hashp,
- xbp->page, xbp->addr, 0, 0))
- return (NULL);
- xbp->addr = 0;
- xbp->flags = 0;
- BUF_REMOVE(xbp);
- LRU_INSERT(xbp);
- }
- }
- }
-
- /* Now assign this buffer */
- bp->addr = addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
- bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
-#endif
- bp->ovfl = NULL;
- if (prev_bp) {
- /*
- * If prev_bp is set, this is an overflow page, hook it in to
- * the buffer overflow links.
- */
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
- prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
- (bp ? bp->addr : 0));
-#endif
- prev_bp->ovfl = bp;
- bp->flags = 0;
- } else
- bp->flags = BUF_BUCKET;
- MRU_INSERT(bp);
- return (bp);
-}
-
-extern void
-__buf_init(hashp, nbytes)
- HTAB *hashp;
- int nbytes;
-{
- BUFHEAD *bfp;
- int npages;
-
- bfp = &(hashp->bufhead);
- npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
- npages = MAX(npages, MIN_BUFFERS);
-
- hashp->nbufs = npages;
- bfp->next = bfp;
- bfp->prev = bfp;
- /*
- * This space is calloc'd so these are already null.
- *
- * bfp->ovfl = NULL;
- * bfp->flags = 0;
- * bfp->page = NULL;
- * bfp->addr = 0;
- */
-}
-
-extern int
-__buf_free(hashp, do_free, to_disk)
- HTAB *hashp;
- int do_free, to_disk;
-{
- BUFHEAD *bp;
-
- /* Need to make sure that buffer manager has been initialized */
- if (!LRU)
- return (0);
- for (bp = LRU; bp != &hashp->bufhead;) {
- /* Check that the buffer is valid */
- if (bp->addr || IS_BUCKET(bp->flags)) {
- if (to_disk && (bp->flags & BUF_MOD) &&
- __put_page(hashp, bp->page,
- bp->addr, IS_BUCKET(bp->flags), 0))
- return (-1);
- }
- /* Check if we are freeing stuff */
- if (do_free) {
- if (bp->page)
- free(bp->page);
- BUF_REMOVE(bp);
- free(bp);
- bp = LRU;
- } else
- bp = bp->prev;
- }
- return (0);
-}
-
-extern void
-__reclaim_buf(hashp, bp)
- HTAB *hashp;
- BUFHEAD *bp;
-{
- bp->ovfl = 0;
- bp->addr = 0;
- bp->flags = 0;
- BUF_REMOVE(bp);
- LRU_INSERT(bp);
-}
diff --git a/db/hash/hash_func.c b/db/hash/hash_func.c
deleted file mode 100644
index a5ec434..0000000
--- a/db/hash/hash_func.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static u_int32_t hash1 __P((const void *, size_t));
-static u_int32_t hash2 __P((const void *, size_t));
-static u_int32_t hash3 __P((const void *, size_t));
-static u_int32_t hash4 __P((const void *, size_t));
-
-/* Global default hash function */
-u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4;
-
-/*
- * HASH FUNCTIONS
- *
- * Assume that we've already split the bucket to which this key hashes,
- * calculate that bucket, and check that in fact we did already split it.
- *
- * This came from ejb's hsearch.
- */
-
-#define PRIME1 37
-#define PRIME2 1048583
-
-static u_int32_t
-hash1(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register u_int32_t h;
-
- /* Convert string to integer */
- for (key = keyarg, h = 0; len--;)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
- return (h);
-}
-
-/*
- * Phong's linear congruential hash
- */
-#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
-
-static u_int32_t
-hash2(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- register const u_char *e, *key;
- register u_int32_t h;
- register u_char c;
-
- key = keyarg;
- e = key + len;
- for (h = 0; key != e;) {
- c = *key++;
- if (!c && key > e)
- break;
- dcharhash(h, c);
- }
- return (h);
-}
-
-/*
- * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
- * units. On the first time through the loop we get the "leftover bytes"
- * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
- * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
- * this routine is heavily used enough, it's worth the ugly coding.
- *
- * OZ's original sdbm hash
- */
-static u_int32_t
-hash3(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register size_t loop;
- register u_int32_t h;
-
-#define HASHC h = *key++ + 65599 * h
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASHC;
- /* FALLTHROUGH */
- case 7:
- HASHC;
- /* FALLTHROUGH */
- case 6:
- HASHC;
- /* FALLTHROUGH */
- case 5:
- HASHC;
- /* FALLTHROUGH */
- case 4:
- HASHC;
- /* FALLTHROUGH */
- case 3:
- HASHC;
- /* FALLTHROUGH */
- case 2:
- HASHC;
- /* FALLTHROUGH */
- case 1:
- HASHC;
- } while (--loop);
- }
- }
- return (h);
-}
-
-/* Hash function from Chris Torek. */
-static u_int32_t
-hash4(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register size_t loop;
- register u_int32_t h;
-
-#define HASH4a h = (h << 5) - h + *key++;
-#define HASH4b h = (h << 5) + h + *key++;
-#define HASH4 HASH4b
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASH4;
- /* FALLTHROUGH */
- case 7:
- HASH4;
- /* FALLTHROUGH */
- case 6:
- HASH4;
- /* FALLTHROUGH */
- case 5:
- HASH4;
- /* FALLTHROUGH */
- case 4:
- HASH4;
- /* FALLTHROUGH */
- case 3:
- HASH4;
- /* FALLTHROUGH */
- case 2:
- HASH4;
- /* FALLTHROUGH */
- case 1:
- HASH4;
- } while (--loop);
- }
- }
- return (h);
-}
diff --git a/db/hash/hash_log2.c b/db/hash/hash_log2.c
deleted file mode 100644
index 6bcf9c1..0000000
--- a/db/hash/hash_log2.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <db.h>
-
-u_int32_t __hash_log2 __P((u_int32_t));
-
-u_int32_t
-__hash_log2(num)
- u_int32_t num;
-{
- register u_int32_t i, limit;
-
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++);
- return (i);
-}
diff --git a/db/hash/hash_page.c b/db/hash/hash_page.c
deleted file mode 100644
index e1dfe6b..0000000
--- a/db/hash/hash_page.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hashing
- *
- * DESCRIPTION:
- * Page manipulation for hashing package.
- *
- * ROUTINES:
- *
- * External
- * __get_page
- * __add_ovflpage
- * Internal
- * overflow_page
- * open_temp
- */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static u_int32_t *fetch_bitmap __P((HTAB *, int));
-static u_int32_t first_free __P((u_int32_t));
-static int open_temp __P((HTAB *));
-static u_int16_t overflow_page __P((HTAB *));
-static void putpair __P((char *, const DBT *, const DBT *));
-static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *));
-static int ugly_split
- __P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int));
-
-#define PAGE_INIT(P) { \
- ((u_int16_t *)(P))[0] = 0; \
- ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
- ((u_int16_t *)(P))[2] = hashp->BSIZE; \
-}
-
-/*
- * This is called AFTER we have verified that there is room on the page for
- * the pair (PAIRFITS has returned true) so we go right ahead and start moving
- * stuff on.
- */
-static void
-putpair(p, key, val)
- char *p;
- const DBT *key, *val;
-{
- register u_int16_t *bp, n, off;
-
- bp = (u_int16_t *)p;
-
- /* Enter the key first. */
- n = bp[0];
-
- off = OFFSET(bp) - key->size;
- memmove(p + off, key->data, key->size);
- bp[++n] = off;
-
- /* Now the data. */
- off -= val->size;
- memmove(p + off, val->data, val->size);
- bp[++n] = off;
-
- /* Adjust page info. */
- bp[0] = n;
- bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
- bp[n + 2] = off;
-}
-
-/*
- * Returns:
- * 0 OK
- * -1 error
- */
-extern int
-__delpair(hashp, bufp, ndx)
- HTAB *hashp;
- BUFHEAD *bufp;
- register int ndx;
-{
- register u_int16_t *bp, newoff;
- register int n;
- u_int16_t pairlen;
-
- bp = (u_int16_t *)bufp->page;
- n = bp[0];
-
- if (bp[ndx + 1] < REAL_KEY)
- return (__big_delete(hashp, bufp));
- if (ndx != 1)
- newoff = bp[ndx - 1];
- else
- newoff = hashp->BSIZE;
- pairlen = newoff - bp[ndx + 1];
-
- if (ndx != (n - 1)) {
- /* Hard Case -- need to shuffle keys */
- register int i;
- register char *src = bufp->page + (int)OFFSET(bp);
- register char *dst = src + (int)pairlen;
- memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
-
- /* Now adjust the pointers */
- for (i = ndx + 2; i <= n; i += 2) {
- if (bp[i + 1] == OVFLPAGE) {
- bp[i - 2] = bp[i];
- bp[i - 1] = bp[i + 1];
- } else {
- bp[i - 2] = bp[i] + pairlen;
- bp[i - 1] = bp[i + 1] + pairlen;
- }
- }
- }
- /* Finally adjust the page data */
- bp[n] = OFFSET(bp) + pairlen;
- bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
- bp[0] = n - 2;
- hashp->NKEYS--;
-
- bufp->flags |= BUF_MOD;
- return (0);
-}
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__split_page(hashp, obucket, nbucket)
- HTAB *hashp;
- u_int32_t obucket, nbucket;
-{
- register BUFHEAD *new_bufp, *old_bufp;
- register u_int16_t *ino;
- register char *np;
- DBT key, val;
- int n, ndx, retval;
- u_int16_t copyto, diff, off, moved;
- char *op;
-
- copyto = (u_int16_t)hashp->BSIZE;
- off = (u_int16_t)hashp->BSIZE;
- old_bufp = __get_buf(hashp, obucket, NULL, 0);
- if (old_bufp == NULL)
- return (-1);
- new_bufp = __get_buf(hashp, nbucket, NULL, 0);
- if (new_bufp == NULL)
- return (-1);
-
- old_bufp->flags |= (BUF_MOD | BUF_PIN);
- new_bufp->flags |= (BUF_MOD | BUF_PIN);
-
- ino = (u_int16_t *)(op = old_bufp->page);
- np = new_bufp->page;
-
- moved = 0;
-
- for (n = 1, ndx = 1; n < ino[0]; n += 2) {
- if (ino[n + 1] < REAL_KEY) {
- retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
- (int)copyto, (int)moved);
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (retval);
-
- }
- key.data = (u_char *)op + ino[n];
- key.size = off - ino[n];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Don't switch page */
- diff = copyto - off;
- if (diff) {
- copyto = ino[n + 1] + diff;
- memmove(op + copyto, op + ino[n + 1],
- off - ino[n + 1]);
- ino[ndx] = copyto + ino[n] - ino[n + 1];
- ino[ndx + 1] = copyto;
- } else
- copyto = ino[n + 1];
- ndx += 2;
- } else {
- /* Switch page */
- val.data = (u_char *)op + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- putpair(np, &key, &val);
- moved += 2;
- }
-
- off = ino[n + 1];
- }
-
- /* Now clean up the page */
- ino[0] -= moved;
- FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = copyto;
-
-#ifdef DEBUG3
- (void)fprintf(stderr, "split %d/%d\n",
- ((u_int16_t *)np)[0] / 2,
- ((u_int16_t *)op)[0] / 2);
-#endif
- /* unpin both pages */
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (0);
-}
-
-/*
- * Called when we encounter an overflow or big key/data page during split
- * handling. This is special cased since we have to begin checking whether
- * the key/data pairs fit on their respective pages and because we may need
- * overflow pages for both the old and new pages.
- *
- * The first page might be a page with regular key/data pairs in which case
- * we have a regular overflow condition and just need to go on to the next
- * page or it might be a big key/data pair in which case we need to fix the
- * big key/data pair.
- *
- * Returns:
- * 0 ==> success
- * -1 ==> failure
- */
-static int
-ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
- HTAB *hashp;
- u_int32_t obucket; /* Same as __split_page. */
- BUFHEAD *old_bufp, *new_bufp;
- int copyto; /* First byte on page which contains key/data values. */
- int moved; /* Number of pairs moved to new page. */
-{
- register BUFHEAD *bufp; /* Buffer header for ino */
- register u_int16_t *ino; /* Page keys come off of */
- register u_int16_t *np; /* New page */
- register u_int16_t *op; /* Page keys go on to if they aren't moving */
-
- BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
- DBT key, val;
- SPLIT_RETURN ret;
- u_int16_t n, off, ov_addr, scopyto;
- char *cino; /* Character value of ino */
-
- bufp = old_bufp;
- ino = (u_int16_t *)old_bufp->page;
- np = (u_int16_t *)new_bufp->page;
- op = (u_int16_t *)old_bufp->page;
- last_bfp = NULL;
- scopyto = (u_int16_t)copyto; /* ANSI */
-
- n = ino[0] - 1;
- while (n < ino[0]) {
- if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
- if (__big_split(hashp, old_bufp,
- new_bufp, bufp, bufp->addr, obucket, &ret))
- return (-1);
- old_bufp = ret.oldp;
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- new_bufp = ret.newp;
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- bufp = ret.nextp;
- if (!bufp)
- return (0);
- cino = (char *)bufp->page;
- ino = (u_int16_t *)cino;
- last_bfp = ret.nextp;
- } else if (ino[n + 1] == OVFLPAGE) {
- ov_addr = ino[n];
- /*
- * Fix up the old page -- the extra 2 are the fields
- * which contained the overflow information.
- */
- ino[0] -= (moved + 2);
- FREESPACE(ino) =
- scopyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = scopyto;
-
- bufp = __get_buf(hashp, ov_addr, bufp, 0);
- if (!bufp)
- return (-1);
-
- ino = (u_int16_t *)bufp->page;
- n = 1;
- scopyto = hashp->BSIZE;
- moved = 0;
-
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = bufp;
- }
- /* Move regular sized pairs of there are any */
- off = hashp->BSIZE;
- for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
- cino = (char *)ino;
- key.data = (u_char *)cino + ino[n];
- key.size = off - ino[n];
- val.data = (u_char *)cino + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- off = ino[n + 1];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Keep on old page */
- if (PAIRFITS(op, (&key), (&val)))
- putpair((char *)op, &key, &val);
- else {
- old_bufp =
- __add_ovflpage(hashp, old_bufp);
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- putpair((char *)op, &key, &val);
- }
- old_bufp->flags |= BUF_MOD;
- } else {
- /* Move to new page */
- if (PAIRFITS(np, (&key), (&val)))
- putpair((char *)np, &key, &val);
- else {
- new_bufp =
- __add_ovflpage(hashp, new_bufp);
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- putpair((char *)np, &key, &val);
- }
- new_bufp->flags |= BUF_MOD;
- }
- }
- }
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- return (0);
-}
-
-/*
- * Add the given pair to the page
- *
- * Returns:
- * 0 ==> OK
- * 1 ==> failure
- */
-extern int
-__addel(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- register u_int16_t *bp, *sop;
- int do_expand;
-
- bp = (u_int16_t *)bufp->page;
- do_expand = 0;
- while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
- /* Exception case */
- if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
- /* This is the last page of a big key/data pair
- and we need to add another page */
- break;
- else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else
- /* Try to squeeze key on this page */
- if (FREESPACE(bp) > PAIRSIZE(key, val)) {
- squeeze_key(bp, key, val);
- return (0);
- } else {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- }
-
- if (PAIRFITS(bp, key, val))
- putpair(bufp->page, key, val);
- else {
- do_expand = 1;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- sop = (u_int16_t *)bufp->page;
-
- if (PAIRFITS(sop, key, val))
- putpair((char *)sop, key, val);
- else
- if (__big_insert(hashp, bufp, key, val))
- return (-1);
- }
- bufp->flags |= BUF_MOD;
- /*
- * If the average number of keys per bucket exceeds the fill factor,
- * expand the table.
- */
- hashp->NKEYS++;
- if (do_expand ||
- (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
- return (__expand_table(hashp));
- return (0);
-}
-
-/*
- *
- * Returns:
- * pointer on success
- * NULL on error
- */
-extern BUFHEAD *
-__add_ovflpage(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- register u_int16_t *sp;
- u_int16_t ndx, ovfl_num;
-#ifdef DEBUG1
- int tmp1, tmp2;
-#endif
- sp = (u_int16_t *)bufp->page;
-
- /* Check if we are dynamically determining the fill factor */
- if (hashp->FFACTOR == DEF_FFACTOR) {
- hashp->FFACTOR = sp[0] >> 1;
- if (hashp->FFACTOR < MIN_FFACTOR)
- hashp->FFACTOR = MIN_FFACTOR;
- }
- bufp->flags |= BUF_MOD;
- ovfl_num = overflow_page(hashp);
-#ifdef DEBUG1
- tmp1 = bufp->addr;
- tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
-#endif
- if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
- return (NULL);
- bufp->ovfl->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
- tmp1, tmp2, bufp->ovfl->addr);
-#endif
- ndx = sp[0];
- /*
- * Since a pair is allocated on a page only if there's room to add
- * an overflow page, we know that the OVFL information will fit on
- * the page.
- */
- sp[ndx + 4] = OFFSET(sp);
- sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
- sp[ndx + 1] = ovfl_num;
- sp[ndx + 2] = OVFLPAGE;
- sp[0] = ndx + 2;
-#ifdef HASH_STATISTICS
- hash_overflows++;
-#endif
- return (bufp->ovfl);
-}
-
-/*
- * Returns:
- * 0 indicates SUCCESS
- * -1 indicates FAILURE
- */
-extern int
-__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_disk, is_bitmap;
-{
- register int fd, page, size;
- int rsize;
- u_int16_t *bp;
-
- fd = hashp->fp;
- size = hashp->BSIZE;
-
- if ((fd == -1) || !is_disk) {
- PAGE_INIT(p);
- return (0);
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((rsize = read(fd, p, size)) == -1))
- return (-1);
- bp = (u_int16_t *)p;
- if (!rsize)
- bp[0] = 0; /* We hit the EOF, so initialize a new page */
- else
- if (rsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- if (!is_bitmap && !bp[0]) {
- PAGE_INIT(p);
- } else
- if (hashp->LORDER != BYTE_ORDER) {
- register int i, max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- M_16_SWAP(bp[0]);
- max = bp[0] + 2;
- for (i = 1; i <= max; i++)
- M_16_SWAP(bp[i]);
- }
- }
- return (0);
-}
-
-/*
- * Write page p to disk
- *
- * Returns:
- * 0 ==> OK
- * -1 ==>failure
- */
-extern int
-__put_page(hashp, p, bucket, is_bucket, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_bitmap;
-{
- register int fd, page, size;
- int wsize;
-
- size = hashp->BSIZE;
- if ((hashp->fp == -1) && open_temp(hashp))
- return (-1);
- fd = hashp->fp;
-
- if (hashp->LORDER != BYTE_ORDER) {
- register int i;
- register int max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- max = ((u_int16_t *)p)[0] + 2;
- for (i = 0; i <= max; i++)
- M_16_SWAP(((u_int16_t *)p)[i]);
- }
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((wsize = write(fd, p, size)) == -1))
- /* Errno is set */
- return (-1);
- if (wsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- return (0);
-}
-
-#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
-/*
- * Initialize a new bitmap page. Bitmap pages are left in memory
- * once they are read in.
- */
-extern int
-__ibitmap(hashp, pnum, nbits, ndx)
- HTAB *hashp;
- int pnum, nbits, ndx;
-{
- u_int32_t *ip;
- int clearbytes, clearints;
-
- if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (1);
- hashp->nmaps++;
- clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
- clearbytes = clearints << INT_TO_BYTE;
- (void)memset((char *)ip, 0, clearbytes);
- (void)memset(((char *)ip) + clearbytes, 0xFF,
- hashp->BSIZE - clearbytes);
- ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
- SETBIT(ip, 0);
- hashp->BITMAPS[ndx] = (u_int16_t)pnum;
- hashp->mapp[ndx] = ip;
- return (0);
-}
-
-static u_int32_t
-first_free(map)
- u_int32_t map;
-{
- register u_int32_t i, mask;
-
- mask = 0x1;
- for (i = 0; i < BITS_PER_MAP; i++) {
- if (!(mask & map))
- return (i);
- mask = mask << 1;
- }
- return (i);
-}
-
-static u_int16_t
-overflow_page(hashp)
- HTAB *hashp;
-{
- register u_int32_t *freep;
- register int max_free, offset, splitnum;
- u_int16_t addr;
- int bit, first_page, free_bit, free_page, i, in_use_bits, j;
-#ifdef DEBUG2
- int tmp1, tmp2;
-#endif
- splitnum = hashp->OVFL_POINT;
- max_free = hashp->SPARES[splitnum];
-
- free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
- free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- /* Look through all the free maps to find the first free block */
- first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
- for ( i = first_page; i <= free_page; i++ ) {
- if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
- !(freep = fetch_bitmap(hashp, i)))
- return (0);
- if (i == free_page)
- in_use_bits = free_bit;
- else
- in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
-
- if (i == first_page) {
- bit = hashp->LAST_FREED &
- ((hashp->BSIZE << BYTE_SHIFT) - 1);
- j = bit / BITS_PER_MAP;
- bit = bit & ~(BITS_PER_MAP - 1);
- } else {
- bit = 0;
- j = 0;
- }
- for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
- if (freep[j] != ALL_SET)
- goto found;
- }
-
- /* No Free Page Found */
- hashp->LAST_FREED = hashp->SPARES[splitnum];
- hashp->SPARES[splitnum]++;
- offset = hashp->SPARES[splitnum] -
- (splitnum ? hashp->SPARES[splitnum - 1] : 0);
-
-#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 1;
- }
-
- /* Check if we need to allocate a new bitmap page */
- if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
- free_page++;
- if (free_page >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- /*
- * This is tricky. The 1 indicates that you want the new page
- * allocated with 1 clear bit. Actually, you are going to
- * allocate 2 pages from this map. The first is going to be
- * the map page, the second is the overflow page we were
- * looking for. The init_bitmap routine automatically, sets
- * the first bit of itself to indicate that the bitmap itself
- * is in use. We would explicitly set the second bit, but
- * don't have to if we tell init_bitmap not to leave it clear
- * in the first place.
- */
- if (__ibitmap(hashp,
- (int)OADDR_OF(splitnum, offset), 1, free_page))
- return (0);
- hashp->SPARES[splitnum]++;
-#ifdef DEBUG2
- free_bit = 2;
-#endif
- offset++;
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG,
- sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 0;
- }
- } else {
- /*
- * Free_bit addresses the last used bit. Bump it to address
- * the first available bit.
- */
- free_bit++;
- SETBIT(freep, free_bit);
- }
-
- /* Calculate address of the new overflow page */
- addr = OADDR_OF(splitnum, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, free_bit, free_page);
-#endif
- return (addr);
-
-found:
- bit = bit + first_free(freep[j]);
- SETBIT(freep, bit);
-#ifdef DEBUG2
- tmp1 = bit;
- tmp2 = i;
-#endif
- /*
- * Bits are addressed starting with 0, but overflow pages are addressed
- * beginning at 1. Bit is a bit addressnumber, so we need to increment
- * it to convert it to a page number.
- */
- bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
- if (bit >= hashp->LAST_FREED)
- hashp->LAST_FREED = bit - 1;
-
- /* Calculate the split number for this page */
- for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
- offset = (i ? bit - hashp->SPARES[i - 1] : bit);
- if (offset >= SPLITMASK)
- return (0); /* Out of overflow pages */
- addr = OADDR_OF(i, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, tmp1, tmp2);
-#endif
-
- /* Allocate and return the overflow page */
- return (addr);
-}
-
-/*
- * Mark this overflow page as free.
- */
-extern void
-__free_ovflpage(hashp, obufp)
- HTAB *hashp;
- BUFHEAD *obufp;
-{
- register u_int16_t addr;
- u_int32_t *freep;
- int bit_address, free_page, free_bit;
- u_int16_t ndx;
-
- addr = obufp->addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "Freeing %d\n", addr);
-#endif
- ndx = (((u_int16_t)addr) >> SPLITSHIFT);
- bit_address =
- (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
- if (bit_address < hashp->LAST_FREED)
- hashp->LAST_FREED = bit_address;
- free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
- free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- if (!(freep = hashp->mapp[free_page]))
- freep = fetch_bitmap(hashp, free_page);
-#ifdef DEBUG
- /*
- * This had better never happen. It means we tried to read a bitmap
- * that has already had overflow pages allocated off it, and we
- * failed to read it from the file.
- */
- if (!freep)
- assert(0);
-#endif
- CLRBIT(freep, free_bit);
-#ifdef DEBUG2
- (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
- obufp->addr, free_bit, free_page);
-#endif
- __reclaim_buf(hashp, obufp);
-}
-
-/*
- * Returns:
- * 0 success
- * -1 failure
- */
-static int
-open_temp(hashp)
- HTAB *hashp;
-{
- sigset_t set, oset;
- static char namestr[] = "_hashXXXXXX";
-
- /* Block signals; make sure file goes away at process exit. */
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((hashp->fp = mkstemp(namestr)) != -1) {
- (void)unlink(namestr);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
- return (hashp->fp != -1 ? 0 : -1);
-}
-
-/*
- * We have to know that the key will fit, but the last entry on the page is
- * an overflow pair, so we need to shift things.
- */
-static void
-squeeze_key(sp, key, val)
- u_int16_t *sp;
- const DBT *key, *val;
-{
- register char *p;
- u_int16_t free_space, n, off, pageno;
-
- p = (char *)sp;
- n = sp[0];
- free_space = FREESPACE(sp);
- off = OFFSET(sp);
-
- pageno = sp[n - 1];
- off -= key->size;
- sp[n - 1] = off;
- memmove(p + off, key->data, key->size);
- off -= val->size;
- sp[n] = off;
- memmove(p + off, val->data, val->size);
- sp[0] = n + 2;
- sp[n + 1] = pageno;
- sp[n + 2] = OVFLPAGE;
- FREESPACE(sp) = free_space - PAIRSIZE(key, val);
- OFFSET(sp) = off;
-}
-
-static u_int32_t *
-fetch_bitmap(hashp, ndx)
- HTAB *hashp;
- int ndx;
-{
- if (ndx >= hashp->nmaps)
- return (NULL);
- if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (NULL);
- if (__get_page(hashp,
- (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
- free(hashp->mapp[ndx]);
- return (NULL);
- }
- return (hashp->mapp[ndx]);
-}
-
-#ifdef DEBUG4
-int
-print_chain(addr)
- int addr;
-{
- BUFHEAD *bufp;
- short *bp, oaddr;
-
- (void)fprintf(stderr, "%d ", addr);
- bufp = __get_buf(hashp, addr, NULL, 0);
- bp = (short *)bufp->page;
- while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
- ((bp[0] > 2) && bp[2] < REAL_KEY))) {
- oaddr = bp[bp[0] - 1];
- (void)fprintf(stderr, "%d ", (int)oaddr);
- bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
- bp = (short *)bufp->page;
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
diff --git a/db/hash/ndbm.c b/db/hash/ndbm.c
deleted file mode 100644
index 83aa766..0000000
--- a/db/hash/ndbm.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * This package provides a dbm compatible interface to the new hashing
- * package described in db(3).
- */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <ndbm.h>
-#include "hash.h"
-
-/*
- * Returns:
- * *DBM on success
- * NULL on failure
- */
-extern DBM *
-dbm_open(file, flags, mode)
- const char *file;
- int flags, mode;
-{
- DBM *db;
- HASHINFO info;
- const size_t len = strlen(file) + sizeof (DBM_SUFFIX);
-#ifdef __GNUC__
- char path[len];
-#else
- char *path = malloc(len);
- if (path == NULL)
- return NULL;
-#endif
-
- info.bsize = 4096;
- info.ffactor = 40;
- info.nelem = 1;
- info.cachesize = 0;
- info.hash = NULL;
- info.lorder = 0;
- (void)strcpy(path, file);
- (void)strcat(path, DBM_SUFFIX);
- db = (DBM *)__hash_open(path, flags, mode, &info, 0);
-#ifndef __GNUC__
- free(path);
-#endif
- return db;
-}
-
-extern void
-dbm_close(db)
- DBM *db;
-{
- (void)(db->close)(db);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_fetch(db, key)
- DBM *db;
- datum key;
-{
- datum retval;
- int status;
-
- status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
- if (status) {
- retval.dptr = NULL;
- retval.dsize = 0;
- }
- return (retval);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_firstkey(db)
- DBM *db;
-{
- int status;
- datum retdata, retkey;
-
- status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
- if (status)
- retkey.dptr = NULL;
- return (retkey);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_nextkey(db)
- DBM *db;
-{
- int status;
- datum retdata, retkey;
-
- status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
- if (status)
- retkey.dptr = NULL;
- return (retkey);
-}
-/*
- * Returns:
- * 0 on success
- * <0 failure
- */
-extern int
-dbm_delete(db, key)
- DBM *db;
- datum key;
-{
- int status;
-
- status = (db->del)(db, (DBT *)&key, 0);
- if (status)
- return (-1);
- else
- return (0);
-}
-
-/*
- * Returns:
- * 0 on success
- * <0 failure
- * 1 if DBM_INSERT and entry exists
- */
-extern int
-dbm_store(db, key, content, flags)
- DBM *db;
- datum key, content;
- int flags;
-{
- return ((db->put)(db, (DBT *)&key, (DBT *)&content,
- (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
-}
-
-extern int
-dbm_error(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- return (hp->errnum);
-}
-
-extern int
-dbm_clearerr(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- hp->errnum = 0;
- return (0);
-}
-
-extern int
-dbm_dirfno(db)
- DBM *db;
-{
- return(((HTAB *)db->internal)->fp);
-}
diff --git a/db/hash/page.h b/db/hash/page.h
deleted file mode 100644
index 0fc0d5a..0000000
--- a/db/hash/page.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)page.h 8.2 (Berkeley) 5/31/94
- */
-
-/*
- * Definitions for hashing page file format.
- */
-
-/*
- * routines dealing with a data page
- *
- * page format:
- * +------------------------------+
- * p | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | free | ptr | --> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
- *
- * Pointer to the free space is always: p[p[0] + 2]
- * Amount of free space on the page is: p[p[0] + 1]
- */
-
-/*
- * How many bytes required for this pair?
- * 2 shorts in the table at the top of the page + room for the
- * key and room for the data
- *
- * We prohibit entering a pair on a page unless there is also room to append
- * an overflow page. The reason for this it that you can get in a situation
- * where a single key/data pair fits on a page, but you can't append an
- * overflow page and later you'd have to split the key/data and handle like
- * a big pair.
- * You might as well do this up front.
- */
-
-#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
-#define BIGOVERHEAD (4*sizeof(u_int16_t))
-#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
-#define OVFLSIZE (2*sizeof(u_int16_t))
-#define FREESPACE(P) ((P)[(P)[0]+1])
-#define OFFSET(P) ((P)[(P)[0]+2])
-#define PAIRFITS(P,K,D) \
- (((P)[2] >= REAL_KEY) && \
- (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
-#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
-
-typedef struct {
- BUFHEAD *newp;
- BUFHEAD *oldp;
- BUFHEAD *nextp;
- u_int16_t next_addr;
-} SPLIT_RETURN;
diff --git a/db/mpool.h b/db/mpool.h
deleted file mode 100644
index 22c9fea..0000000
--- a/db/mpool.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)mpool.h 8.2 (Berkeley) 7/14/94
- */
-
-#ifndef _MPOOL_H
-#define _MPOOL_H 1
-
-#include <sys/queue.h>
-
-/*
- * The memory pool scheme is a simple one. Each in-memory page is referenced
- * by a bucket which is threaded in up to two of three ways. All active pages
- * are threaded on a hash chain (hashed by page number) and an lru chain.
- * Inactive pages are threaded on a free chain. Each reference to a memory
- * pool is handed an opaque MPOOL cookie which stores all of this information.
- */
-#define HASHSIZE 128
-#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
-
-/* The BKT structures are the elements of the queues. */
-typedef struct _bkt {
- CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */
- CIRCLEQ_ENTRY(_bkt) q; /* lru queue */
- void *page; /* page */
- pgno_t pgno; /* page number */
-
-#define MPOOL_DIRTY 0x01 /* page needs to be written */
-#define MPOOL_PINNED 0x02 /* page is pinned into memory */
- u_int8_t flags; /* flags */
-} BKT;
-
-typedef struct MPOOL {
- CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
- /* hash queue array */
- CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
- pgno_t curcache; /* current number of cached pages */
- pgno_t maxcache; /* max number of cached pages */
- pgno_t npages; /* number of pages in the file */
- u_long pagesize; /* file page size */
- int fd; /* file descriptor */
- /* page in conversion routine */
- void (*pgin) __PMT((void *, pgno_t, void *));
- /* page out conversion routine */
- void (*pgout) __PMT((void *, pgno_t, void *));
- void *pgcookie; /* cookie for page in/out routines */
-#ifdef STATISTICS
- u_long cachehit;
- u_long cachemiss;
- u_long pagealloc;
- u_long pageflush;
- u_long pageget;
- u_long pagenew;
- u_long pageput;
- u_long pageread;
- u_long pagewrite;
-#endif
-} MPOOL;
-
-__BEGIN_DECLS
-MPOOL *__mpool_open __P((void *, int, pgno_t, pgno_t));
-MPOOL *mpool_open __P((void *, int, pgno_t, pgno_t));
-void __mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
- void (*)(void *, pgno_t, void *), void *));
-void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
- void (*)(void *, pgno_t, void *), void *));
-void *__mpool_new __P((MPOOL *, pgno_t *));
-void *mpool_new __P((MPOOL *, pgno_t *));
-void *__mpool_get __P((MPOOL *, pgno_t, u_int));
-void *mpool_get __P((MPOOL *, pgno_t, u_int));
-int __mpool_put __P((MPOOL *, void *, u_int));
-int mpool_put __P((MPOOL *, void *, u_int));
-int __mpool_sync __P((MPOOL *));
-int mpool_sync __P((MPOOL *));
-int __mpool_close __P((MPOOL *));
-int mpool_close __P((MPOOL *));
-#ifdef STATISTICS
-void mpool_stat __P((MPOOL *));
-#endif
-__END_DECLS
-
-#endif /* mpool.h */
diff --git a/db/mpool/mpool.c b/db/mpool/mpool.c
deleted file mode 100644
index 7ced76f..0000000
--- a/db/mpool/mpool.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-
-#define __MPOOLINTERFACE_PRIVATE
-#include <mpool.h>
-
-#ifdef _LIBC
-/* In the GNU C library we must not pollute the namespace because libdb is
- needed by libnss_db. */
-#define mpool_open __mpool_open
-#define mpool_filter __mpool_filter
-#define mpool_new __mpool_new
-#define mpool_get __mpool_get
-#define mpool_put __mpool_put
-#define mpool_sync __mpool_sync
-#define mpool_close __mpool_close
-#endif
-
-static BKT *mpool_bkt __P((MPOOL *));
-static BKT *mpool_look __P((MPOOL *, pgno_t));
-static int mpool_write __P((MPOOL *, BKT *));
-
-/*
- * mpool_open --
- * Initialize a memory pool.
- */
-MPOOL *
-mpool_open(key, fd, pagesize, maxcache)
- void *key;
- int fd;
- pgno_t pagesize, maxcache;
-{
- struct stat sb;
- MPOOL *mp;
- int entry;
-
- /*
- * Get information about the file.
- *
- * XXX
- * We don't currently handle pipes, although we should.
- */
- if (fstat(fd, &sb))
- return (NULL);
- if (!S_ISREG(sb.st_mode)) {
- errno = ESPIPE;
- return (NULL);
- }
-
- /* Allocate and initialize the MPOOL cookie. */
- if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
- return (NULL);
- CIRCLEQ_INIT(&mp->lqh);
- for (entry = 0; entry < HASHSIZE; ++entry)
- CIRCLEQ_INIT(&mp->hqh[entry]);
- mp->maxcache = maxcache;
- mp->npages = sb.st_size / pagesize;
- mp->pagesize = pagesize;
- mp->fd = fd;
- return (mp);
-}
-
-/*
- * mpool_filter --
- * Initialize input/output filters.
- */
-void
-mpool_filter(mp, pgin, pgout, pgcookie)
- MPOOL *mp;
- void (*pgin) __P((void *, pgno_t, void *));
- void (*pgout) __P((void *, pgno_t, void *));
- void *pgcookie;
-{
- mp->pgin = pgin;
- mp->pgout = pgout;
- mp->pgcookie = pgcookie;
-}
-
-/*
- * mpool_new --
- * Get a new page of memory.
- */
-void *
-mpool_new(mp, pgnoaddr)
- MPOOL *mp;
- pgno_t *pgnoaddr;
-{
- struct _hqh *head;
- BKT *bp;
-
- if (mp->npages == MAX_PAGE_NUMBER) {
- (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
- abort();
- }
-#ifdef STATISTICS
- ++mp->pagenew;
-#endif
- /*
- * Get a BKT from the cache. Assign a new page number, attach
- * it to the head of the hash chain, the tail of the lru chain,
- * and return.
- */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
- *pgnoaddr = bp->pgno = mp->npages++;
- bp->flags = MPOOL_PINNED;
-
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
- return (bp->page);
-}
-
-/*
- * mpool_get
- * Get a page.
- */
-void *
-mpool_get(mp, pgno, flags)
- MPOOL *mp;
- pgno_t pgno;
- u_int flags; /* XXX not used? */
-{
- struct _hqh *head;
- BKT *bp;
- off_t off;
- int nr;
-
- /* Check for attempt to retrieve a non-existent page. */
- if (pgno >= mp->npages) {
- errno = EINVAL;
- return (NULL);
- }
-
-#ifdef STATISTICS
- ++mp->pageget;
-#endif
-
- /* Check for a page that is cached. */
- if ((bp = mpool_look(mp, pgno)) != NULL) {
-#ifdef DEBUG
- if (bp->flags & MPOOL_PINNED) {
- (void)fprintf(stderr,
- "mpool_get: page %d already pinned\n", bp->pgno);
- abort();
- }
-#endif
- /*
- * Move the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Return a pinned page. */
- bp->flags |= MPOOL_PINNED;
- return (bp->page);
- }
-
- /* Get a page from the cache. */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
-
- /* Read in the contents. */
-#ifdef STATISTICS
- ++mp->pageread;
-#endif
- off = mp->pagesize * pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (NULL);
- if ((u_long) (nr = read(mp->fd, bp->page, mp->pagesize))
- != mp->pagesize) {
- if (nr >= 0)
- errno = EFTYPE;
- return (NULL);
- }
-
- /* Set the page number, pin the page. */
- bp->pgno = pgno;
- bp->flags = MPOOL_PINNED;
-
- /*
- * Add the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Run through the user's filter. */
- if (mp->pgin != NULL)
- (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
-
- return (bp->page);
-}
-
-/*
- * mpool_put
- * Return a page.
- */
-int
-mpool_put(mp, page, flags)
- MPOOL *mp;
- void *page;
- u_int flags;
-{
- BKT *bp;
-
-#ifdef STATISTICS
- ++mp->pageput;
-#endif
- bp = (BKT *)((char *)page - sizeof(BKT));
-#ifdef DEBUG
- if (!(bp->flags & MPOOL_PINNED)) {
- (void)fprintf(stderr,
- "mpool_put: page %d not pinned\n", bp->pgno);
- abort();
- }
-#endif
- bp->flags &= ~MPOOL_PINNED;
- bp->flags |= flags & MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_close
- * Close the buffer pool.
- */
-int
-mpool_close(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Free up any space allocated to the lru pages. */
- while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
- CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
- free(bp);
- }
-
- /* Free the MPOOL cookie. */
- free(mp);
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_sync
- * Sync the pool to disk.
- */
-int
-mpool_sync(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Walk the lru chain, flushing any dirty pages to disk. */
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Sync the file descriptor. */
- return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-#ifdef _LIBC
-#undef mpool_open
-#undef mpool_filter
-#undef mpool_new
-#undef mpool_get
-#undef mpool_put
-#undef mpool_close
-#undef mpool_sync
-weak_alias (__mpool_open, mpool_open)
-weak_alias (__mpool_filter, mpool_filter)
-weak_alias (__mpool_new, mpool_new)
-weak_alias (__mpool_get, mpool_get)
-weak_alias (__mpool_put, mpool_put)
-weak_alias (__mpool_close, mpool_close)
-weak_alias (__mpool_sync, mpool_sync)
-#endif
-
-/*
- * mpool_bkt
- * Get a page from the cache (or create one).
- */
-static BKT *
-mpool_bkt(mp)
- MPOOL *mp;
-{
- struct _hqh *head;
- BKT *bp;
-
- /* If under the max cached, always create a new page. */
- if (mp->curcache < mp->maxcache)
- goto new;
-
- /*
- * If the cache is max'd out, walk the lru list for a buffer we
- * can flush. If we find one, write it (if necessary) and take it
- * off any lists. If we don't find anything we grow the cache anyway.
- * The cache never shrinks.
- */
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
- if (!(bp->flags & MPOOL_PINNED)) {
- /* Flush if dirty. */
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pageflush;
-#endif
- /* Remove from the hash and lru queues. */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
-#ifdef DEBUG
- { void *spage;
- spage = bp->page;
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
- bp->page = spage;
- }
-#endif
- return (bp);
- }
-
-new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pagealloc;
-#endif
-#if defined(DEBUG) || defined(PURIFY)
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
-#endif
- bp->page = (char *)bp + sizeof(BKT);
- ++mp->curcache;
- return (bp);
-}
-
-/*
- * mpool_write
- * Write a page to disk.
- */
-static int
-mpool_write(mp, bp)
- MPOOL *mp;
- BKT *bp;
-{
- off_t off;
-
-#ifdef STATISTICS
- ++mp->pagewrite;
-#endif
-
- /* Run through the user's filter. */
- if (mp->pgout)
- (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
-
- off = mp->pagesize * bp->pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (RET_ERROR);
- if ((u_long) write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
- return (RET_ERROR);
-
- bp->flags &= ~MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_look
- * Lookup a page in the cache.
- */
-static BKT *
-mpool_look(mp, pgno)
- MPOOL *mp;
- pgno_t pgno;
-{
- struct _hqh *head;
- BKT *bp;
-
- head = &mp->hqh[HASHKEY(pgno)];
- for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
- if (bp->pgno == pgno) {
-#ifdef STATISTICS
- ++mp->cachehit;
-#endif
- return (bp);
- }
-#ifdef STATISTICS
- ++mp->cachemiss;
-#endif
- return (NULL);
-}
-
-#ifdef STATISTICS
-/*
- * mpool_stat
- * Print out cache statistics.
- */
-void
-mpool_stat(mp)
- MPOOL *mp;
-{
- BKT *bp;
- int cnt;
- char *sep;
-
- (void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
- (void)fprintf(stderr,
- "page size %lu, cacheing %lu pages of %lu page max cache\n",
- mp->pagesize, mp->curcache, mp->maxcache);
- (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
- mp->pageput, mp->pageget, mp->pagenew);
- (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
- mp->pagealloc, mp->pageflush);
- if (mp->cachehit + mp->cachemiss)
- (void)fprintf(stderr,
- "%.0f%% cache hit rate (%lu hits, %lu misses)\n",
- ((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
- * 100, mp->cachehit, mp->cachemiss);
- (void)fprintf(stderr, "%lu page reads, %lu page writes\n",
- mp->pageread, mp->pagewrite);
-
- sep = "";
- cnt = 0;
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
- (void)fprintf(stderr, "%s%d", sep, bp->pgno);
- if (bp->flags & MPOOL_DIRTY)
- (void)fprintf(stderr, "d");
- if (bp->flags & MPOOL_PINNED)
- (void)fprintf(stderr, "P");
- if (++cnt == 10) {
- sep = "\n";
- cnt = 0;
- } else
- sep = ", ";
-
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
diff --git a/db/ndbm.h b/db/ndbm.h
deleted file mode 100644
index b05aa56..0000000
--- a/db/ndbm.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)ndbm.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _NDBM_H
-#define _NDBM_H 1
-
-#include <db.h>
-
-/* Map dbm interface onto db(3). */
-#define DBM_RDONLY O_RDONLY
-
-/* Flags to dbm_store(). */
-#define DBM_INSERT 0
-#define DBM_REPLACE 1
-
-/*
- * The db(3) support for ndbm(3) always appends this suffix to the
- * file name to avoid overwriting the user's original database.
- */
-#define DBM_SUFFIX ".db"
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-
-typedef DB DBM;
-#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
-
-__BEGIN_DECLS
-void dbm_close (DBM *);
-int dbm_delete (DBM *, datum);
-datum dbm_fetch (DBM *, datum);
-datum dbm_firstkey (DBM *);
-long dbm_forder (DBM *, datum);
-datum dbm_nextkey (DBM *);
-DBM *dbm_open (const char *, int, int);
-int dbm_store (DBM *, datum, datum, int);
-int dbm_dirfno (DBM *);
-int dbm_error (DBM *);
-int dbm_clearerr (DBM *);
-__END_DECLS
-
-#endif /* ndbm.h */
diff --git a/db/recno/extern.h b/db/recno/extern.h
deleted file mode 100644
index feed434..0000000
--- a/db/recno/extern.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.3 (Berkeley) 6/4/94
- */
-
-#include "../btree/extern.h"
-
-int __rec_close __P((DB *));
-int __rec_delete __P((const DB *, const DBT *, u_int));
-int __rec_dleaf __P((BTREE *, PAGE *, u_int32_t));
-int __rec_fd __P((const DB *));
-int __rec_fmap __P((BTREE *, recno_t));
-int __rec_fout __P((BTREE *));
-int __rec_fpipe __P((BTREE *, recno_t));
-int __rec_get __P((const DB *, const DBT *, DBT *, u_int));
-int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int));
-int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int));
-int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *));
-EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP));
-int __rec_seq __P((const DB *, DBT *, DBT *, u_int));
-int __rec_sync __P((const DB *, u_int));
-int __rec_vmap __P((BTREE *, recno_t));
-int __rec_vout __P((BTREE *));
-int __rec_vpipe __P((BTREE *, recno_t));
diff --git a/db/recno/rec_close.c b/db/recno/rec_close.c
deleted file mode 100644
index 8a3c4d7..0000000
--- a/db/recno/rec_close.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_CLOSE -- Close a recno tree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (__rec_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Committed to closing. */
- status = RET_SUCCESS;
- if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
- status = RET_ERROR;
-
- if (!F_ISSET(t, R_INMEM)) {
- if (F_ISSET(t, R_CLOSEFP)) {
- if (fclose(t->bt_rfp))
- status = RET_ERROR;
- } else
- if (close(t->bt_rfd))
- status = RET_ERROR;
- }
-
- if (__bt_close(dbp) == RET_ERROR)
- status = RET_ERROR;
-
- return (status);
-}
-
-/*
- * __REC_SYNC -- sync the recno tree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- struct iovec iov[2];
- BTREE *t;
- DBT data, key;
- off_t off;
- recno_t scursor, trec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (flags == R_RECNOSYNC)
- return (__bt_sync(dbp, 0));
-
- if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
- return (RET_SUCCESS);
-
- /* Read any remaining records into the tree. */
- if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
-
- /* Rewind the file descriptor. */
- if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
- return (RET_ERROR);
-
- /* Save the cursor. */
- scursor = t->bt_cursor.rcursor;
-
- key.size = sizeof(recno_t);
- key.data = &trec;
-
- if (F_ISSET(t, R_FIXLEN)) {
- /*
- * We assume that fixed length records are all fixed length.
- * Any that aren't are either EINVAL'd or corrected by the
- * record put code.
- */
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- if ((size_t) write(t->bt_rfd, data.data, data.size) != data.size)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- } else {
- iov[1].iov_base = &t->bt_bval;
- iov[1].iov_len = 1;
-
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- iov[0].iov_base = data.data;
- iov[0].iov_len = data.size;
- if ((size_t) writev(t->bt_rfd, iov, 2) != data.size + 1)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- }
-
- /* Restore the cursor. */
- t->bt_cursor.rcursor = scursor;
-
- if (status == RET_ERROR)
- return (RET_ERROR);
- if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
- return (RET_ERROR);
- if (ftruncate(t->bt_rfd, off))
- return (RET_ERROR);
- F_CLR(t, R_MODIFIED);
- return (RET_SUCCESS);
-}
diff --git a/db/recno/rec_delete.c b/db/recno/rec_delete.c
deleted file mode 100644
index a16593d..0000000
--- a/db/recno/rec_delete.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-static int rec_rdelete __P((BTREE *, recno_t));
-
-/*
- * __REC_DELETE -- Delete the item(s) referenced by a key.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to delete
- * flags: R_CURSOR if deleting what the cursor references
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case 0:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- --nrec;
- status = rec_rdelete(t, nrec);
- break;
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- if (t->bt_nrecs == 0)
- return (RET_SPECIAL);
- status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
- if (status == RET_SUCCESS)
- --t->bt_cursor.rcursor;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED | R_MODIFIED);
- return (status);
-}
-
-/*
- * REC_RDELETE -- Delete the data matching the specified key.
- *
- * Parameters:
- * tree: tree
- * nrec: record to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-rec_rdelete(t, nrec)
- BTREE *t;
- recno_t nrec;
-{
- EPG *e;
- PAGE *h;
- int status;
-
- /* Find the record; __rec_search pins the page. */
- if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
- return (RET_ERROR);
-
- /* Delete the record. */
- h = e->page;
- status = __rec_dleaf(t, h, e->index);
- if (status != RET_SUCCESS) {
- mpool_put(t->bt_mp, h, 0);
- return (status);
- }
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_DLEAF -- Delete a single record from a recno leaf page.
- *
- * Parameters:
- * t: tree
- * index: index on current page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_dleaf(t, h, index)
- BTREE *t;
- PAGE *h;
- u_int32_t index;
-{
- RLEAF *rl;
- indx_t *ip, cnt, offset;
- u_int32_t nbytes;
- char *from;
- void *to;
-
- /*
- * Delete a record from a recno leaf page. Internal records are never
- * deleted from internal pages, regardless of the records that caused
- * them to be added being deleted. Pages made empty by deletion are
- * not reclaimed. They are, however, made available for reuse.
- *
- * Pack the remaining entries at the end of the page, shift the indices
- * down, overwriting the deleted record and its index. If the record
- * uses overflow pages, make them available for reuse.
- */
- to = rl = GETRLEAF(h, index);
- if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
- return (RET_ERROR);
- nbytes = NRLEAF(rl);
-
- /*
- * Compress the key/data pairs. Compress and adjust the [BR]LEAF
- * offsets. Reset the headers.
- */
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- offset = h->linp[index];
- for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
- --t->bt_nrecs;
- return (RET_SUCCESS);
-}
diff --git a/db/recno/rec_get.c b/db/recno/rec_get.c
deleted file mode 100644
index 47dd773..0000000
--- a/db/recno/rec_get.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags, and keys of 0 are illegal. */
- if (flags || (nrec = *(recno_t *)key->data) == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If we haven't seen this record yet, try to find it in the
- * original file.
- */
- if (nrec > t->bt_nrecs) {
- if (F_ISSET(t, R_EOF | R_INMEM))
- return (RET_SPECIAL);
- if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- }
-
- --nrec;
- if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
- return (RET_ERROR);
-
- status = __rec_ret(t, e, 0, NULL, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
-
-/*
- * __REC_FPIPE -- Get fixed length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- size_t len;
- int ch;
- u_char *p;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- for (nrec = t->bt_nrecs; nrec < top;) {
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;; *p++ = ch)
- if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
- if (ch != EOF)
- *p = ch;
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t,
- nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++nrec;
- break;
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VPIPE -- Get variable length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- indx_t len;
- size_t sz;
- int bval, ch;
- u_char *p;
-
- bval = t->bt_bval;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- for (p = t->bt_rdata.data,
- sz = t->bt_rdata.size;; *p++ = ch, --sz) {
- if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
- data.data = t->bt_rdata.data;
- data.size = p - (u_char *)t->bt_rdata.data;
- if (ch == EOF && data.size == 0)
- break;
- if (__rec_iput(t, nrec, &data, 0)
- != RET_SUCCESS)
- return (RET_ERROR);
- break;
- }
- if (sz == 0) {
- len = p - (u_char *)t->bt_rdata.data;
- t->bt_rdata.size += (sz = 256);
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_rdata.size) :
- realloc(t->bt_rdata.data, t->bt_rdata.size);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- p = (u_char *)t->bt_rdata.data + len;
- }
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_FMAP -- Get fixed length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- u_char *sp, *ep, *p;
- size_t len;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;
- sp < ep && len > 0; *p++ = *sp++, --len);
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VMAP -- Get variable length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- u_char *sp, *ep;
- recno_t nrec;
- int bval;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- bval = t->bt_bval;
-
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- for (data.data = sp; sp < ep && *sp != bval; ++sp);
- data.size = sp - (u_char *)data.data;
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++sp;
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
diff --git a/db/recno/rec_open.c b/db/recno/rec_open.c
deleted file mode 100644
index 51d8a3c..0000000
--- a/db/recno/rec_open.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-DB *
-__rec_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const RECNOINFO *openinfo;
-{
- BTREE *t;
- BTREEINFO btopeninfo;
- DB *dbp;
- PAGE *h;
- struct stat sb;
- int rfd, sverrno;
-
- /* Open the user's file -- if this fails, we're done. */
- if (fname != NULL && (rfd = open(fname, flags, mode)) < 0)
- return (NULL);
-
- /* Create a btree in memory (backed by disk). */
- dbp = NULL;
- if (openinfo) {
- if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
- goto einval;
- btopeninfo.flags = 0;
- btopeninfo.cachesize = openinfo->cachesize;
- btopeninfo.maxkeypage = 0;
- btopeninfo.minkeypage = 0;
- btopeninfo.psize = openinfo->psize;
- btopeninfo.compare = NULL;
- btopeninfo.prefix = NULL;
- btopeninfo.lorder = openinfo->lorder;
- dbp = __bt_open(openinfo->bfname,
- O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
- } else
- dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
- if (dbp == NULL)
- goto err;
-
- /*
- * Some fields in the tree structure are recno specific. Fill them
- * in and make the btree structure look like a recno structure. We
- * don't change the bt_ovflsize value, it's close enough and slightly
- * bigger.
- */
- t = dbp->internal;
- if (openinfo) {
- if (openinfo->flags & R_FIXEDLEN) {
- F_SET(t, R_FIXLEN);
- t->bt_reclen = openinfo->reclen;
- if (t->bt_reclen == 0)
- goto einval;
- }
- t->bt_bval = openinfo->bval;
- } else
- t->bt_bval = '\n';
-
- F_SET(t, R_RECNO);
- if (fname == NULL)
- F_SET(t, R_EOF | R_INMEM);
- else
- t->bt_rfd = rfd;
-
- if (fname != NULL) {
- /*
- * In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
- * Unfortunately, that's not portable, so we use lseek
- * and check the errno values.
- */
- errno = 0;
- if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- default:
- goto einval;
- }
-slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
- goto err;
- F_SET(t, R_CLOSEFP);
- t->bt_irec =
- F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
- } else {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- case O_RDWR:
- break;
- default:
- goto einval;
- }
-
- if (fstat(rfd, &sb))
- goto err;
- /*
- * Kluge -- we'd like to test to see if the file is too
- * big to mmap. Since, we don't know what size or type
- * off_t's or size_t's are, what the largest unsigned
- * integral type is, or what random insanity the local
- * C compiler will perpetrate, doing the comparison in
- * a portable way is flatly impossible. Hope that mmap
- * fails if the file is too large.
- */
- if (sb.st_size == 0)
- F_SET(t, R_EOF);
- else {
-#ifdef MMAP_NOT_AVAILABLE
- /*
- * XXX
- * Mmap doesn't work correctly on many current
- * systems. In particular, it can fail subtly,
- * with cache coherency problems. Don't use it
- * for now.
- */
- t->bt_msize = sb.st_size;
- if ((t->bt_smap = mmap(NULL, t->bt_msize,
- PROT_READ, MAP_PRIVATE, rfd,
- (off_t)0)) == (caddr_t)-1)
- goto slow;
- t->bt_cmap = t->bt_smap;
- t->bt_emap = t->bt_smap + sb.st_size;
- t->bt_irec = F_ISSET(t, R_FIXLEN) ?
- __rec_fmap : __rec_vmap;
- F_SET(t, R_MEMMAPPED);
-#else
- goto slow;
-#endif
- }
- }
- }
-
- /* Use the recno routines. */
- dbp->close = __rec_close;
- dbp->del = __rec_delete;
- dbp->fd = __rec_fd;
- dbp->get = __rec_get;
- dbp->put = __rec_put;
- dbp->seq = __rec_seq;
- dbp->sync = __rec_sync;
-
- /* If the root page was created, reset the flags. */
- if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
- goto err;
- if ((h->flags & P_TYPE) == P_BLEAF) {
- F_CLR(h, P_TYPE);
- F_SET(h, P_RLEAF);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- } else
- mpool_put(t->bt_mp, h, 0);
-
- if (openinfo && openinfo->flags & R_SNAPSHOT &&
- !F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- goto err;
- return (dbp);
-
-einval: errno = EINVAL;
-err: sverrno = errno;
- if (dbp != NULL)
- (void)__bt_close(dbp);
- if (fname != NULL)
- (void)close(rfd);
- errno = sverrno;
- return (NULL);
-}
-
-int
-__rec_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, R_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_rfd);
-}
diff --git a/db/recno/rec_put.c b/db/recno/rec_put.c
deleted file mode 100644
index 5454c40..0000000
--- a/db/recno/rec_put.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_PUT -- Add a recno item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
- * already in the tree and R_NOOVERWRITE specified.
- */
-int
-__rec_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT fdata, tdata;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If using fixed-length records, and the record is long, return
- * EINVAL. If it's short, pad it out. Use the record data return
- * memory, it's only short-term.
- */
- if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
- if (data->size > t->bt_reclen)
- goto einval;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- memmove(t->bt_rdata.data, data->data, data->size);
- memset((char *)t->bt_rdata.data + data->size,
- t->bt_bval, t->bt_reclen - data->size);
- fdata.data = t->bt_rdata.data;
- fdata.size = t->bt_reclen;
- } else {
- fdata.data = data->data;
- fdata.size = data->size;
- }
-
- switch (flags) {
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- nrec = t->bt_cursor.rcursor;
- break;
- case R_SETCURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_IAFTER:
- if ((nrec = *(recno_t *)key->data) == 0) {
- nrec = 1;
- flags = R_IBEFORE;
- }
- break;
- case 0:
- case R_IBEFORE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NOOVERWRITE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec <= t->bt_nrecs)
- return (RET_SPECIAL);
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * Make sure that records up to and including the put record are
- * already in the database. If skipping records, create empty ones.
- */
- if (nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, nrec) == RET_ERROR)
- return (RET_ERROR);
- if (nrec > t->bt_nrecs + 1) {
- if (F_ISSET(t, R_FIXLEN)) {
- if ((tdata.data =
- (void *)malloc(t->bt_reclen)) == NULL)
- return (RET_ERROR);
- tdata.size = t->bt_reclen;
- memset(tdata.data, t->bt_bval, tdata.size);
- } else {
- tdata.data = NULL;
- tdata.size = 0;
- }
- while (nrec > t->bt_nrecs + 1)
- if (__rec_iput(t,
- t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
- return (RET_ERROR);
- if (F_ISSET(t, R_FIXLEN))
- free(tdata.data);
- }
- }
-
- if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
- return (status);
-
- if (flags == R_SETCURSOR)
- t->bt_cursor.rcursor = nrec;
-
- F_SET(t, R_MODIFIED);
- return (__rec_ret(t, NULL, nrec, key, NULL));
-}
-
-/*
- * __REC_IPUT -- Add a recno item to the tree.
- *
- * Parameters:
- * t: tree
- * nrec: record number
- * data: data
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_iput(t, nrec, data, flags)
- BTREE *t;
- recno_t nrec;
- const DBT *data;
- u_int flags;
-{
- DBT tdata;
- EPG *e;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, status;
- char *dest, db[NOVFLSIZE];
-
- /*
- * If the data won't fit on a page, store it on indirect pages.
- *
- * XXX
- * If the insert fails later on, these pages aren't recovered.
- */
- if (data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- *(pgno_t *)db = pg;
- *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
- dflags = P_BIGDATA;
- data = &tdata;
- } else
- dflags = 0;
-
- /* __rec_search pins the returned page. */
- if ((e = __rec_search(t, nrec,
- nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
- SINSERT : SEARCH)) == NULL)
- return (RET_ERROR);
-
- h = e->page;
- index = e->index;
-
- /*
- * Add the specified key/data pair to the tree. The R_IAFTER and
- * R_IBEFORE flags insert the key after/before the specified key.
- *
- * Pages are split as required.
- */
- switch (flags) {
- case R_IAFTER:
- ++index;
- break;
- case R_IBEFORE:
- break;
- default:
- if (nrec < t->bt_nrecs &&
- __rec_dleaf(t, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, split the page. The split code will insert
- * the key and data and unpin the current page. If inserting into
- * the offset array, shift the pointers up.
- */
- nbytes = NRLEAFDBT(data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t)) {
- status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
- if (status == RET_SUCCESS)
- ++t->bt_nrecs;
- return (status);
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_RLEAF(dest, data, dflags);
-
- ++t->bt_nrecs;
- F_SET(t, B_MODIFIED);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
diff --git a/db/recno/rec_search.c b/db/recno/rec_search.c
deleted file mode 100644
index acc109e..0000000
--- a/db/recno/rec_search.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_SEARCH -- Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * recno: key to find
- * op: search operation
- *
- * Returns:
- * EPG for matching record, if any, or the EPG for the location of the
- * key, if it were inserted into the tree.
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__rec_search(t, recno, op)
- BTREE *t;
- recno_t recno;
- enum SRCHOP op;
-{
- register indx_t index;
- register PAGE *h;
- EPGNO *parent;
- RINTERNAL *r;
- pgno_t pg;
- indx_t top;
- recno_t total;
- int sverrno;
-
- BT_CLR(t);
- for (pg = P_ROOT, total = 0;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- goto err;
- if (h->flags & P_RLEAF) {
- t->bt_cur.page = h;
- t->bt_cur.index = recno - total;
- return (&t->bt_cur);
- }
- for (index = 0, top = NEXTINDEX(h);;) {
- r = GETRINTERNAL(h, index);
- if (++index == top || total + r->nrecs > recno)
- break;
- total += r->nrecs;
- }
-
- BT_PUSH(t, pg, index - 1);
-
- pg = r->pgno;
- switch (op) {
- case SDELETE:
- --GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SINSERT:
- ++GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SEARCH:
- mpool_put(t->bt_mp, h, 0);
- break;
- }
-
- }
- /* Try and recover the tree. */
-err: sverrno = errno;
- if (op != SEARCH)
- while ((parent = BT_POP(t)) != NULL) {
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- break;
- if (op == SINSERT)
- --GETRINTERNAL(h, parent->index)->nrecs;
- else
- ++GETRINTERNAL(h, parent->index)->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- }
- errno = sverrno;
- return (NULL);
-}
diff --git a/db/recno/rec_seq.c b/db/recno/rec_seq.c
deleted file mode 100644
index 2f8c769..0000000
--- a/db/recno/rec_seq.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_SEQ -- Recno sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__rec_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case R_CURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NEXT:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- nrec = t->bt_cursor.rcursor + 1;
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- nrec = 1;
- break;
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- if ((nrec = t->bt_cursor.rcursor - 1) == 0)
- return (RET_SPECIAL);
- break;
- }
- /* FALLTHROUGH */
- case R_LAST:
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
- nrec = t->bt_nrecs;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- }
-
- if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
- return (RET_ERROR);
-
- F_SET(&t->bt_cursor, CURS_INIT);
- t->bt_cursor.rcursor = nrec;
-
- status = __rec_ret(t, e, nrec, key, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
diff --git a/db/recno/rec_utils.c b/db/recno/rec_utils.c
deleted file mode 100644
index c4c0380..0000000
--- a/db/recno/rec_utils.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __rec_ret --
- * Build return data.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * nrec: record number
- * key: user's key structure
- * data: user's data structure
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_ret(t, e, nrec, key, data)
- BTREE *t;
- EPG *e;
- recno_t nrec;
- DBT *key, *data;
-{
- RLEAF *rl;
- void *p;
-
- if (key == NULL)
- goto dataonly;
-
- /* We have to copy the key, it's not on the page. */
- if (sizeof(recno_t) > t->bt_rkey.size) {
- p = (void *)(t->bt_rkey.data == NULL ?
- malloc(sizeof(recno_t)) :
- realloc(t->bt_rkey.data, sizeof(recno_t)));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rkey.data = p;
- t->bt_rkey.size = sizeof(recno_t);
- }
- memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
- key->size = sizeof(recno_t);
- key->data = t->bt_rkey.data;
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- /*
- * We must copy big keys/data to make them contiguous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- rl = GETRLEAF(e->page, e->index);
- if (rl->flags & P_BIGDATA) {
- if (__ovfl_get(t, rl->bytes,
- &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- data->data = t->bt_rdata.data;
- } else if (F_ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (rl->dsize + 1 > t->bt_rdata.size) {
- p = (void *)(t->bt_rdata.data == NULL ?
- malloc(rl->dsize + 1) :
- realloc(t->bt_rdata.data, rl->dsize + 1));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rdata.data = p;
- t->bt_rdata.size = rl->dsize + 1;
- }
- memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
- data->size = rl->dsize;
- data->data = t->bt_rdata.data;
- } else {
- data->size = rl->dsize;
- data->data = rl->bytes;
- }
- return (RET_SUCCESS);
-}
diff --git a/db/recno/recno.h b/db/recno/recno.h
deleted file mode 100644
index bec772c..0000000
--- a/db/recno/recno.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)recno.h 8.1 (Berkeley) 6/4/93
- */
-
-enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
-
-#include "../btree/btree.h"
-#include "extern.h"
diff --git a/db2/LICENSE b/db2/LICENSE
deleted file mode 100644
index 17ee9b9..0000000
--- a/db2/LICENSE
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- * @(#)LICENSE 10.8 (Sleepycat) 5/1/98
- */
-
-The following are the copyrights and redistribution conditions that apply to
-this copy of the Berkeley DB software. For a license to use, redistribute
-or sell Berkeley DB software under conditions other than those described here,
-or to purchase support for this software, please contact Sleepycat Software at
-one of the following addresses:
-
- Sleepycat Software db@sleepycat.com
- 394 E. Riding Dr. +1-617-633-2429
- Carlisle, MA 01741
- USA
-
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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. Redistributions in any form must be accompanied by information on
- * how to obtain complete source code for the DB software and any
- * accompanying software that uses the DB software. The source code
- * must either be included in the distribution or be available for no
- * more than the cost of distribution plus a nominal fee, and must be
- * freely redistributable under reasonable conditions. For an
- * executable file, complete source code means the source code for all
- * modules it contains. It does not mean source code for modules or
- * files that typically accompany the operating system on which the
- * executable file runs, e.g., standard library modules or system
- * header files.
- *
- * THIS SOFTWARE IS PROVIDED BY SLEEPYCAT SOFTWARE ``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 SLEEPYCAT SOFTWARE 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
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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 Harvard University
- * 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 HARVARD AND ITS 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 HARVARD OR ITS 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
- * SUCH DAMAGE.
- */
diff --git a/db2/Makefile b/db2/Makefile
deleted file mode 100644
index 77aa60c..0000000
--- a/db2/Makefile
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-
-# The GNU C Library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-
-# The GNU C Library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-
-# You should have received a copy of the GNU Library General Public
-# License along with the GNU C Library; see the file COPYING.LIB. If not,
-# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-#
-# Sub-makefile for libdb.
-#
-# The code is lifted straight from the db 2.7.5 distribution
-# with minimal changes.
-#
-
-subdir = db2
-
-subdir-dirs = btree common db db185 dbm hash lock log mp mutex os txn \
- progs/db_archive progs/db_checkpoint progs/db_deadlock \
- progs/db_dump progs/db_dump185 progs/db_load progs/db_printlog \
- progs/db_recover progs/db_stat clib xa
-
-headers = db.h db_185.h
-
-distribute = db_int.h config.h compat.h clib/getlong.c btree/btree.src \
- db/db.src db185/db185_int.h hash/hash.src log/log.src \
- txn/txn.src README LICENSE \
- $(addprefix include/,btree.h btree_auto.h btree_ext.h \
- clib_ext.h common_ext.h cxx_int.h \
- db_185.h.src db_am.h db_auto.h db_cxx.h \
- db_dispatch.h db_ext.h db_join.h \
- db_page.h db_shash.h db_swap.h \
- hash.h hash_auto.h hash_ext.h lock.h \
- lock_ext.h log.h log_auto.h log_ext.h \
- mp.h mp_ext.h mutex_ext.h os_ext.h queue.h \
- shqueue.h txn.h txn_auto.h txn_ext.h \
- os.h os_jump.h xa.h xa_ext.h) \
- $(addprefix mutex/,x86.gcc uts4_cc.s sparc.gcc parisc.gcc \
- README 68020.gcc tsl_parisc.s sco.cc) \
- $(addprefix progs/db_printlog/,README commit.awk count.awk \
- pgno.awk range.awk status.awk \
- txn.awk)
-
-vpath %.c $(subdir-dirs)
-
-extra-libs := libdb
-extra-libs-others := $(extra-libs)
-extra-objs = getlong.o
-
-libdb-routines := bt_compare bt_conv bt_curadj bt_cursor bt_delete \
- bt_open bt_page bt_put bt_rec bt_recno bt_rsearch bt_search \
- bt_split bt_stat btree_auto db db_appinit db_apprec \
- db_auto db_iface db_am db_join \
- db_byteorder db_conv db_dispatch db_dup db_err db_log2 os_alloc \
- os_abs os_config os_dir os_fid os_fsync os_map os_oflags \
- os_open os_rpath os_rw os_seek os_sleep os_stat os_unlink \
- os_spin os_tmpdir db_overflow db_pr db_rec db_region db_ret \
- db_salloc db_shash hash hash_auto hash_conv \
- hash_dup hash_func hash_page hash_rec hash_stat lock \
- lock_conflict lock_deadlock lock_region lock_util log log_archive \
- log_auto log_compare log_findckp log_get log_put log_rec \
- log_register mp_bh mp_fget mp_fopen mp_fput mp_fset \
- mp_open mp_pr mp_region mp_sync mutex txn txn_auto \
- txn_rec dbm db185 xa xa_db xa_map
-
-others := makedb db_dump185 db_archive db_checkpoint db_deadlock \
- db_dump db_load db_recover db_stat db_printlog
-install-bin := makedb db_dump185 db_archive db_checkpoint db_deadlock \
- db_dump db_load db_recover db_stat db_printlog
-
-include ../Rules
-
-CPPFLAGS += -I./include -include ./compat.h
-
-$(objpfx)db_checkpoint: $(objpfx)getlong.o
-$(objpfx)db_deadlock: $(objpfx)getlong.o
-$(objpfx)db_load: $(objpfx)getlong.o
-
-ifeq ($(build-shared),yes)
-$(objpfx)makedb: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_dump185: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_archive: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_checkpoint: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_deadlock: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_dump: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_load: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_printlog: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_recover: $(objpfx)libdb.so$(libdb.so-version)
-$(objpfx)db_stat: $(objpfx)libdb.so$(libdb.so-version)
-else
-$(objpfx)makedb: $(objpfx)libdb.a
-$(objpfx)db_dump185: $(objpfx)libdb.a
-$(objpfx)db_archive: $(objpfx)libdb.a
-$(objpfx)db_checkpoint: $(objpfx)libdb.a
-$(objpfx)db_deadlock: $(objpfx)libdb.a
-$(objpfx)db_dump: $(objpfx)libdb.a
-$(objpfx)db_load: $(objpfx)libdb.a
-$(objpfx)db_printlog: $(objpfx)libdb.a
-$(objpfx)db_recover: $(objpfx)libdb.a
-$(objpfx)db_stat: $(objpfx)libdb.a
-endif
-
-# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
-$(objpfx)libdb.so: $(common-objpfx)libc.so
-
-ifeq ($(build-static),yes)
-subdir_install: $(inst_libdir)/libndbm.a
-$(inst_libdir)/libndbm.a: $(inst_libdir)/libdb.a $(+force)
- $(make-link)
-endif
-
-ifeq ($(build-shared),yes)
-subdir_install: $(inst_libdir)/libndbm.so
-$(inst_libdir)/libndbm.so: $(inst_libdir)/libdb.so $(+force)
- $(make-link)
-endif
diff --git a/db2/README b/db2/README
deleted file mode 100644
index 2671e7f..0000000
--- a/db2/README
+++ /dev/null
@@ -1,13 +0,0 @@
-As a special exception, when Berkeley DB is distributed along with the
-GNU C Library, in any program which uses the GNU C Library in accord
-with that library's distribution terms, it is also permitted for
-Berkeley DB to be loaded dynamically by the GNU C Library to implement
-standard ISO/IEC 9945 and Unix interface functionality.
-
-Sleepycat Software, Inc.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The LICENSE file, mentioned in the beginning of the source files, can
-be found in this directory and also with all the other relevant
-license texts in the manual.
diff --git a/db2/Versions b/db2/Versions
deleted file mode 100644
index a32945a..0000000
--- a/db2/Versions
+++ /dev/null
@@ -1,58 +0,0 @@
-libdb {
- GLIBC_2.0 {
- # db 1.85 interface
- dbopen; __dbopen;
-
- # The compatibility functions.
- dbm_clearerr; dbm_close; dbm_delete; dbm_dirfno; dbm_error;
- dbm_fetch; dbm_firstkey; dbminit; dbm_nextkey; dbm_open;
- dbm_pagfno; dbm_store;
- }
- GLIBC_2.1 {
- # db.2.x interface
- # Internal functions used by db maintenance programs
- __bam_init_print; __bam_pgin; __bam_pgout;
- __db_dispatch;__db_dump; __db_err; __db_init_print;__db_jump;
- __db_omode;__db_prdbt;
- __ham_init_print; __ham_pgin; __ham_pgout;
- __lock_dump_region;
- __log_init_print;
- __memp_dump_region;
- __txn_init_print;
-
- # Functions used by other libraries.
- __nss_db_open;
-
- # Constants
- db_rw_conflicts; db_riw_conflicts;
-
- # Functions
- db_appexit; db_appinit; db_jump_set; db_open; db_value_set;
- db_version;
- lock_close; lock_detect; lock_get; lock_id; lock_open; lock_put;
- lock_stat; lock_unlink; lock_vec; log_archive; log_close;
- log_compare; log_file; log_flush; log_get; log_open; log_put;
- log_register; log_stat; log_unlink; log_unregister;
-
- memp_close; memp_fclose; memp_fget; memp_fopen; memp_fput;
- memp_fset; memp_fsync; memp_open; memp_register; memp_stat;
- memp_sync; memp_trickle; memp_unlink;
-
- txn_abort; txn_begin; txn_checkpoint; txn_close; txn_commit;
- txn_id; txn_open; txn_prepare; txn_stat; txn_unlink;
-
- # compatibility interface for ndbm
- __db_ndbm_clearerr; __db_ndbm_close; __db_ndbm_delete;
- __db_ndbm_dirfno; __db_ndbm_error; __db_ndbm_fetch;
- __db_ndbm_firstkey; __db_ndbm_nextkey; __db_ndbm_open;
- __db_ndbm_pagfno; __db_ndbm_rdonly; __db_ndbm_store;
-
- # compatibility interface for dbm
- __db_dbm_delete; __db_dbm_fetch; __db_dbm_firstkey; __db_dbm_init;
- __db_dbm_nextkey; __db_dbm_store;
- }
- GLIBC_2.2 {
- # Internal functions.
- __ham_get_page; __ham_put_page;
- }
-}
diff --git a/db2/btree/bt_compare.c b/db2/btree/bt_compare.c
deleted file mode 100644
index c60f920..0000000
--- a/db2/btree/bt_compare.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_compare.c 10.14 (Sleepycat) 10/9/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_cmp --
- * Compare a key to a given record.
- *
- * PUBLIC: int __bam_cmp __P((DB *, const DBT *,
- * PUBLIC: PAGE *, u_int32_t, int (*)(const DBT *, const DBT *)));
- */
-int
-__bam_cmp(dbp, dbt, h, indx, func)
- DB *dbp;
- const DBT *dbt;
- PAGE *h;
- u_int32_t indx;
- int (*func)__P((const DBT *, const DBT *));
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- BOVERFLOW *bo;
- DBT pg_dbt;
- int ret;
-
- /*
- * Returns:
- * < 0 if dbt is < page record
- * = 0 if dbt is = page record
- * > 0 if dbt is > page record
- *
- * !!!
- * We do not clear the pg_dbt DBT even though it's likely to contain
- * random bits. That should be okay, because the app's comparison
- * routine had better not be looking at fields other than data/size.
- * We don't clear it because we go through this path a lot and it's
- * expensive.
- */
- if (TYPE(h) == P_LBTREE || TYPE(h) == P_DUPLICATE) {
- bk = GET_BKEYDATA(h, indx);
- if (B_TYPE(bk->type) == B_OVERFLOW)
- bo = (BOVERFLOW *)bk;
- else {
- pg_dbt.data = bk->data;
- pg_dbt.size = bk->len;
- return (func(dbt, &pg_dbt));
- }
- } else {
- /*
- * The following code guarantees that the left-most key on an
- * internal page at any level of the btree is less than any
- * user specified key. This saves us from having to update the
- * leftmost key on an internal page when the user inserts a new
- * key in the tree smaller than anything we've seen before.
- */
- if (indx == 0 && h->prev_pgno == PGNO_INVALID)
- return (1);
-
- bi = GET_BINTERNAL(h, indx);
- if (B_TYPE(bi->type) == B_OVERFLOW)
- bo = (BOVERFLOW *)(bi->data);
- else {
- pg_dbt.data = bi->data;
- pg_dbt.size = bi->len;
- return (func(dbt, &pg_dbt));
- }
- }
-
- /*
- * Overflow.
- *
- * XXX
- * We ignore __db_moff() errors, because we have no way of returning
- * them.
- */
- (void) __db_moff(dbp,
- dbt, bo->pgno, bo->tlen, func == __bam_defcmp ? NULL : func, &ret);
- return (ret);
-}
-
-/*
- * __bam_defcmp --
- * Default comparison routine.
- *
- * PUBLIC: int __bam_defcmp __P((const DBT *, const DBT *));
- */
-int
-__bam_defcmp(a, b)
- const DBT *a, *b;
-{
- size_t len;
- u_int8_t *p1, *p2;
-
- /*
- * Returns:
- * < 0 if a is < b
- * = 0 if a is = b
- * > 0 if a is > b
- *
- * XXX
- * If a size_t doesn't fit into a long, or if the difference between
- * any two characters doesn't fit into an int, this routine can lose.
- * What we need is a signed integral type that's guaranteed to be at
- * least as large as a size_t, and there is no such thing.
- */
- len = a->size > b->size ? b->size : a->size;
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
- if (*p1 != *p2)
- return ((long)*p1 - (long)*p2);
- return ((long)a->size - (long)b->size);
-}
-
-/*
- * __bam_defpfx --
- * Default prefix routine.
- *
- * PUBLIC: size_t __bam_defpfx __P((const DBT *, const DBT *));
- */
-size_t
-__bam_defpfx(a, b)
- const DBT *a, *b;
-{
- size_t cnt, len;
- u_int8_t *p1, *p2;
-
- cnt = 1;
- len = a->size > b->size ? b->size : a->size;
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
- if (*p1 != *p2)
- return (cnt);
-
- /*
- * We know that a->size must be <= b->size, or they wouldn't be
- * in this order.
- */
- return (a->size < b->size ? a->size + 1 : a->size);
-}
diff --git a/db2/btree/bt_conv.c b/db2/btree/bt_conv.c
deleted file mode 100644
index a306908..0000000
--- a/db2/btree/bt_conv.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_conv.c 10.7 (Sleepycat) 9/20/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_swap.h"
-#include "btree.h"
-
-/*
- * __bam_pgin --
- * Convert host-specific page layout from the host-independent format
- * stored on disk.
- *
- * PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *));
- */
-int
-__bam_pgin(pg, pp, cookie)
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB_PGINFO *pginfo;
-
- pginfo = (DB_PGINFO *)cookie->data;
- if (!pginfo->needswap)
- return (0);
- return (pg == PGNO_METADATA ?
- __bam_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
-}
-
-/*
- * __bam_pgout --
- * Convert host-specific page layout to the host-independent format
- * stored on disk.
- *
- * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
- */
-int
-__bam_pgout(pg, pp, cookie)
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB_PGINFO *pginfo;
-
- pginfo = (DB_PGINFO *)cookie->data;
- if (!pginfo->needswap)
- return (0);
- return (pg == PGNO_METADATA ?
- __bam_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
-}
-
-/*
- * __bam_mswap --
- * Swap the bytes on the btree metadata page.
- *
- * PUBLIC: int __bam_mswap __P((PAGE *));
- */
-int
-__bam_mswap(pg)
- PAGE *pg;
-{
- u_int8_t *p;
-
- p = (u_int8_t *)pg;
-
- /* Swap the meta-data information. */
- SWAP32(p); /* lsn.file */
- SWAP32(p); /* lsn.offset */
- SWAP32(p); /* pgno */
- SWAP32(p); /* magic */
- SWAP32(p); /* version */
- SWAP32(p); /* pagesize */
- SWAP32(p); /* maxkey */
- SWAP32(p); /* minkey */
- SWAP32(p); /* free */
- SWAP32(p); /* flags */
-
- return (0);
-}
diff --git a/db2/btree/bt_curadj.c b/db2/btree/bt_curadj.c
deleted file mode 100644
index 9b86fbb..0000000
--- a/db2/btree/bt_curadj.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_curadj.c 10.69 (Sleepycat) 12/2/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-#ifdef DEBUG
-/*
- * __bam_cprint --
- * Display the current cursor list.
- *
- * PUBLIC: int __bam_cprint __P((DB *));
- */
-int
-__bam_cprint(dbp)
- DB *dbp;
-{
- CURSOR *cp;
- DBC *dbc;
-
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
- fprintf(stderr,
- "%#0x->%#0x: page: %lu index: %lu dpage %lu dindex: %lu recno: %lu",
- (u_int)dbc, (u_int)cp, (u_long)cp->pgno, (u_long)cp->indx,
- (u_long)cp->dpgno, (u_long)cp->dindx, (u_long)cp->recno);
- if (F_ISSET(cp, C_DELETED))
- fprintf(stderr, " (deleted)");
- fprintf(stderr, "\n");
- }
- DB_THREAD_UNLOCK(dbp);
-
- return (0);
-}
-#endif /* DEBUG */
-
-/*
- * __bam_ca_delete --
- * Update the cursors when items are deleted and when already deleted
- * items are overwritten. Return the number of relevant cursors found.
- *
- * PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
- */
-int
-__bam_ca_delete(dbp, pgno, indx, delete)
- DB *dbp;
- db_pgno_t pgno;
- u_int32_t indx;
- int delete;
-{
- DBC *dbc;
- CURSOR *cp;
- int count; /* !!!: Has to contain max number of cursors. */
-
- /* Recno is responsible for its own adjustments. */
- if (dbp->type == DB_RECNO)
- return (0);
-
- /*
- * Adjust the cursors. We don't have to review the cursors for any
- * thread of control other than the current one, because we have the
- * page write locked at this point, and any other thread of control
- * had better be using a different locker ID, meaning only cursors in
- * our thread of control can be on the page.
- *
- * It's possible for multiple cursors within the thread to have write
- * locks on the same page, but, cursors within a thread must be single
- * threaded, so all we're locking here is the cursor linked list.
- */
- DB_THREAD_LOCK(dbp);
- for (count = 0, dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
-
- if ((cp->pgno == pgno && cp->indx == indx) ||
- (cp->dpgno == pgno && cp->dindx == indx)) {
- if (delete)
- F_SET(cp, C_DELETED);
- else
- F_CLR(cp, C_DELETED);
- ++count;
- }
- }
- DB_THREAD_UNLOCK(dbp);
-
- return (count);
-}
-
-/*
- * __bam_ca_di --
- * Adjust the cursors during a delete or insert.
- *
- * PUBLIC: void __bam_ca_di __P((DB *, db_pgno_t, u_int32_t, int));
- */
-void
-__bam_ca_di(dbp, pgno, indx, adjust)
- DB *dbp;
- db_pgno_t pgno;
- u_int32_t indx;
- int adjust;
-{
- CURSOR *cp;
- DBC *dbc;
-
- /* Recno is responsible for its own adjustments. */
- if (dbp->type == DB_RECNO)
- return;
-
- /*
- * Adjust the cursors. See the comment in __bam_ca_delete().
- */
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
- if (cp->pgno == pgno && cp->indx >= indx)
- cp->indx += adjust;
- if (cp->dpgno == pgno && cp->dindx >= indx)
- cp->dindx += adjust;
- }
- DB_THREAD_UNLOCK(dbp);
-}
-
-/*
- * __bam_ca_dup --
- * Adjust the cursors when moving items from a leaf page to a duplicates
- * page.
- *
- * PUBLIC: void __bam_ca_dup __P((DB *,
- * PUBLIC: db_pgno_t, u_int32_t, u_int32_t, db_pgno_t, u_int32_t));
- */
-void
-__bam_ca_dup(dbp, fpgno, first, fi, tpgno, ti)
- DB *dbp;
- db_pgno_t fpgno, tpgno;
- u_int32_t first, fi, ti;
-{
- CURSOR *cp;
- DBC *dbc;
-
- /* Recno is responsible for its own adjustments. */
- if (dbp->type == DB_RECNO)
- return;
-
- /*
- * Adjust the cursors. See the comment in __bam_ca_delete().
- */
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
- /*
- * Ignore matching entries that have already been moved,
- * we move from the same location on the leaf page more
- * than once.
- */
- if (cp->dpgno == PGNO_INVALID &&
- cp->pgno == fpgno && cp->indx == fi) {
- cp->indx = first;
- cp->dpgno = tpgno;
- cp->dindx = ti;
- }
- }
- DB_THREAD_UNLOCK(dbp);
-}
-
-/*
- * __bam_ca_rsplit --
- * Adjust the cursors when doing reverse splits.
- *
- * PUBLIC: void __bam_ca_rsplit __P((DB *, db_pgno_t, db_pgno_t));
- */
-void
-__bam_ca_rsplit(dbp, fpgno, tpgno)
- DB *dbp;
- db_pgno_t fpgno, tpgno;
-{
- CURSOR *cp;
- DBC *dbc;
-
- /* Recno is responsible for its own adjustments. */
- if (dbp->type == DB_RECNO)
- return;
-
- /*
- * Adjust the cursors. See the comment in __bam_ca_delete().
- */
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
- if (cp->pgno == fpgno)
- cp->pgno = tpgno;
- }
- DB_THREAD_UNLOCK(dbp);
-}
-
-/*
- * __bam_ca_split --
- * Adjust the cursors when splitting a page.
- *
- * PUBLIC: void __bam_ca_split __P((DB *,
- * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
- */
-void
-__bam_ca_split(dbp, ppgno, lpgno, rpgno, split_indx, cleft)
- DB *dbp;
- db_pgno_t ppgno, lpgno, rpgno;
- u_int32_t split_indx;
- int cleft;
-{
- DBC *dbc;
- CURSOR *cp;
-
- /* Recno is responsible for its own adjustments. */
- if (dbp->type == DB_RECNO)
- return;
-
- /*
- * Adjust the cursors. See the comment in __bam_ca_delete().
- *
- * If splitting the page that a cursor was on, the cursor has to be
- * adjusted to point to the same record as before the split. Most
- * of the time we don't adjust pointers to the left page, because
- * we're going to copy its contents back over the original page. If
- * the cursor is on the right page, it is decremented by the number of
- * records split to the left page.
- */
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = (CURSOR *)dbc->internal;
- if (cp->pgno == ppgno) {
- if (cp->indx < split_indx) {
- if (cleft)
- cp->pgno = lpgno;
- } else {
- cp->pgno = rpgno;
- cp->indx -= split_indx;
- }
- }
- if (cp->dpgno == ppgno) {
- if (cp->dindx < split_indx) {
- if (cleft)
- cp->dpgno = lpgno;
- } else {
- cp->dpgno = rpgno;
- cp->dindx -= split_indx;
- }
- }
- }
- DB_THREAD_UNLOCK(dbp);
-}
diff --git a/db2/btree/bt_cursor.c b/db2/btree/bt_cursor.c
deleted file mode 100644
index 10bc095..0000000
--- a/db2/btree/bt_cursor.c
+++ /dev/null
@@ -1,1913 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_cursor.c 10.81 (Sleepycat) 12/16/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "lock_ext.h"
-
-static int __bam_c_close __P((DBC *));
-static int __bam_c_del __P((DBC *, u_int32_t));
-static int __bam_c_destroy __P((DBC *));
-static int __bam_c_first __P((DBC *, CURSOR *));
-static int __bam_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __bam_c_getstack __P((DBC *, CURSOR *));
-static int __bam_c_last __P((DBC *, CURSOR *));
-static int __bam_c_next __P((DBC *, CURSOR *, int));
-static int __bam_c_physdel __P((DBC *, CURSOR *, PAGE *));
-static int __bam_c_prev __P((DBC *, CURSOR *));
-static int __bam_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
-static void __bam_c_reset __P((CURSOR *));
-static int __bam_c_rget __P((DBC *, DBT *, u_int32_t));
-static int __bam_c_search __P((DBC *, CURSOR *, const DBT *, u_int32_t, int *));
-static int __bam_dsearch __P((DBC *, CURSOR *, DBT *, u_int32_t *));
-
-/* Discard the current page/lock held by a cursor. */
-#undef DISCARD
-#define DISCARD(dbc, cp) { \
- if ((cp)->page != NULL) { \
- (void)memp_fput((dbc)->dbp->mpf, (cp)->page, 0); \
- (cp)->page = NULL; \
- } \
- if ((cp)->lock != LOCK_INVALID) { \
- (void)__BT_TLPUT((dbc), (cp)->lock); \
- (cp)->lock = LOCK_INVALID; \
- } \
-}
-
-/* If the cursor references a deleted record. */
-#undef IS_CUR_DELETED
-#define IS_CUR_DELETED(cp) \
- (((cp)->dpgno == PGNO_INVALID && \
- B_DISSET(GET_BKEYDATA((cp)->page, \
- (cp)->indx + O_INDX)->type)) || \
- ((cp)->dpgno != PGNO_INVALID && \
- B_DISSET(GET_BKEYDATA((cp)->page, (cp)->dindx)->type)))
-
-/* If the cursor and index combination references a deleted record. */
-#undef IS_DELETED
-#define IS_DELETED(cp, indx) \
- (((cp)->dpgno == PGNO_INVALID && \
- B_DISSET(GET_BKEYDATA((cp)->page, (indx) + O_INDX)->type)) || \
- ((cp)->dpgno != PGNO_INVALID && \
- B_DISSET(GET_BKEYDATA((cp)->page, (indx))->type)))
-
-/*
- * Test to see if two cursors could point to duplicates of the same key,
- * whether on-page or off-page. The leaf page numbers must be the same
- * in both cases. In the case of off-page duplicates, the key indices
- * on the leaf page will be the same. In the case of on-page duplicates,
- * the duplicate page number must not be set, and the key index offsets
- * must be the same. For the last test, as the saved copy of the cursor
- * will not have a valid page pointer, we use the cursor's.
- */
-#undef POSSIBLE_DUPLICATE
-#define POSSIBLE_DUPLICATE(cursor, saved_copy) \
- ((cursor)->pgno == (saved_copy).pgno && \
- ((cursor)->indx == (saved_copy).indx || \
- ((cursor)->dpgno == PGNO_INVALID && \
- (saved_copy).dpgno == PGNO_INVALID && \
- (cursor)->page->inp[(cursor)->indx] == \
- (cursor)->page->inp[(saved_copy).indx])))
-
-/*
- * __bam_c_reset --
- * Initialize internal cursor structure.
- */
-static void
-__bam_c_reset(cp)
- CURSOR *cp;
-{
- cp->sp = cp->csp = cp->stack;
- cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
- cp->page = NULL;
- cp->pgno = PGNO_INVALID;
- cp->indx = 0;
- cp->dpgno = PGNO_INVALID;
- cp->dindx = 0;
- cp->lock = LOCK_INVALID;
- cp->mode = DB_LOCK_NG;
- cp->recno = RECNO_OOB;
- cp->flags = 0;
-}
-
-/*
- * __bam_c_init --
- * Initialize the access private portion of a cursor
- *
- * PUBLIC: int __bam_c_init __P((DBC *));
- */
-int
-__bam_c_init(dbc)
- DBC *dbc;
-{
- DB *dbp;
- CURSOR *cp;
- int ret;
-
- if ((ret = __os_calloc(1, sizeof(CURSOR), &cp)) != 0)
- return (ret);
-
- dbp = dbc->dbp;
- cp->dbc = dbc;
-
- /*
- * Logical record numbers are always the same size, and we don't want
- * to have to check for space every time we return one. Allocate it
- * in advance.
- */
- if (dbp->type == DB_RECNO || F_ISSET(dbp, DB_BT_RECNUM)) {
- if ((ret = __os_malloc(sizeof(db_recno_t),
- NULL, &dbc->rkey.data)) != 0) {
- __os_free(cp, sizeof(CURSOR));
- return (ret);
- }
- dbc->rkey.ulen = sizeof(db_recno_t);
- }
-
- /* Initialize methods. */
- dbc->internal = cp;
- if (dbp->type == DB_BTREE) {
- dbc->c_am_close = __bam_c_close;
- dbc->c_am_destroy = __bam_c_destroy;
- dbc->c_del = __bam_c_del;
- dbc->c_get = __bam_c_get;
- dbc->c_put = __bam_c_put;
- } else {
- dbc->c_am_close = __bam_c_close;
- dbc->c_am_destroy = __bam_c_destroy;
- dbc->c_del = __ram_c_del;
- dbc->c_get = __ram_c_get;
- dbc->c_put = __ram_c_put;
- }
-
- /* Initialize dynamic information. */
- __bam_c_reset(cp);
-
- return (0);
-}
-
-/*
- * __bam_c_close --
- * Close down the cursor from a single use.
- */
-static int
-__bam_c_close(dbc)
- DBC *dbc;
-{
- CURSOR *cp;
- DB *dbp;
- int ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- ret = 0;
-
- /*
- * If a cursor deleted a btree key, perform the actual deletion.
- * (Recno keys are either deleted immediately or never deleted.)
- */
- if (dbp->type == DB_BTREE && F_ISSET(cp, C_DELETED))
- ret = __bam_c_physdel(dbc, cp, NULL);
-
- /* Discard any locks not acquired inside of a transaction. */
- if (cp->lock != LOCK_INVALID) {
- (void)__BT_TLPUT(dbc, cp->lock);
- cp->lock = LOCK_INVALID;
- }
-
- /* Sanity checks. */
-#ifdef DIAGNOSTIC
- if (cp->csp != cp->stack)
- __db_err(dbp->dbenv, "btree cursor close: stack not empty");
-#endif
-
- /* Initialize dynamic information. */
- __bam_c_reset(cp);
-
- return (ret);
-}
-
-/*
- * __bam_c_destroy --
- * Close a single cursor -- internal version.
- */
-static int
-__bam_c_destroy(dbc)
- DBC *dbc;
-{
- /* Discard the structures. */
- __os_free(dbc->internal, sizeof(CURSOR));
-
- return (0);
-}
-
-/*
- * __bam_c_del --
- * Delete using a cursor.
- */
-static int
-__bam_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- CURSOR *cp;
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- db_pgno_t pgno;
- db_indx_t indx;
- int ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- h = NULL;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_cdelchk(dbp, flags,
- F_ISSET(dbp, DB_AM_RDONLY), cp->pgno != PGNO_INVALID)) != 0)
- return (ret);
-
- /*
- * If we are running CDB, this had better be either a write
- * cursor or an immediate writer.
- */
- if (F_ISSET(dbp, DB_AM_CDB))
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- DEBUG_LWRITE(dbc, dbc->txn, "bam_c_del", NULL, NULL, flags);
-
- /* If already deleted, return failure. */
- if (F_ISSET(cp, C_DELETED))
- return (DB_KEYEMPTY);
-
- /*
- * We don't physically delete the record until the cursor moves,
- * so we have to have a long-lived write lock on the page instead
- * of a long-lived read lock. Note, we have to have a read lock
- * to even get here, so we simply discard it.
- */
- if (F_ISSET(dbp, DB_AM_LOCKING) && cp->mode != DB_LOCK_WRITE) {
- if ((ret = __bam_lget(dbc,
- 0, cp->pgno, DB_LOCK_WRITE, &lock)) != 0)
- goto err;
- (void)__BT_TLPUT(dbc, cp->lock);
- cp->lock = lock;
- cp->mode = DB_LOCK_WRITE;
- }
-
- /*
- * Acquire the underlying page (which may be different from the above
- * page because it may be a duplicate page), and set the on-page and
- * in-cursor delete flags. We don't need to lock it as we've already
- * write-locked the page leading to it.
- */
- if (cp->dpgno == PGNO_INVALID) {
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
-
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- goto err;
-
- /* Log the change. */
- if (DB_LOGGING(dbc) &&
- (ret = __bam_cdel_log(dbp->dbenv->lg_info, dbc->txn, &LSN(h),
- 0, dbp->log_fileid, PGNO(h), &LSN(h), indx)) != 0) {
- (void)memp_fput(dbp->mpf, h, 0);
- goto err;
- }
-
- /*
- * Set the intent-to-delete flag on the page and update all cursors. */
- if (cp->dpgno == PGNO_INVALID)
- B_DSET(GET_BKEYDATA(h, indx + O_INDX)->type);
- else
- B_DSET(GET_BKEYDATA(h, indx)->type);
- (void)__bam_ca_delete(dbp, pgno, indx, 1);
-
- ret = memp_fput(dbp->mpf, h, DB_MPOOL_DIRTY);
- h = NULL;
-
- /*
- * If the tree has record numbers, we have to adjust the counts.
- *
- * !!!
- * This test is right -- we don't yet support duplicates and record
- * numbers in the same tree, so ignore duplicates if DB_BT_RECNUM
- * set.
- */
- if (F_ISSET(dbp, DB_BT_RECNUM)) {
- if ((ret = __bam_c_getstack(dbc, cp)) != 0)
- goto err;
- if ((ret = __bam_adjust(dbc, -1)) != 0)
- goto err;
- (void)__bam_stkrel(dbc, 0);
- }
-
-err: if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- return (ret);
-}
-
-/*
- * __bam_c_get --
- * Get using a cursor (btree).
- */
-static int
-__bam_c_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- CURSOR *cp, copy, start;
- DB *dbp;
- PAGE *h;
- int exact, ret, tmp_rmw;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_cgetchk(dbp,
- key, data, flags, cp->pgno != PGNO_INVALID)) != 0)
- return (ret);
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- tmp_rmw = 0;
- if (LF_ISSET(DB_RMW)) {
- if (!F_ISSET(dbp, DB_AM_CDB)) {
- tmp_rmw = 1;
- F_SET(dbc, DBC_RMW);
- }
- LF_CLR(DB_RMW);
- }
-
- DEBUG_LREAD(dbc, dbc->txn, "bam_c_get",
- flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
-
- /*
- * Return a cursor's record number. It has nothing to do with the
- * cursor get code except that it's been rammed into the interface.
- */
- if (flags == DB_GET_RECNO) {
- ret = __bam_c_rget(dbc, data, flags);
- if (tmp_rmw)
- F_CLR(dbc, DBC_RMW);
- return (ret);
- }
-
- /*
- * Initialize the cursor for a new retrieval. Clear the cursor's
- * page pointer, it was set before this operation, and no longer
- * has any meaning.
- */
- cp->page = NULL;
- copy = *cp;
- cp->lock = LOCK_INVALID;
-
- switch (flags) {
- case DB_CURRENT:
- /* It's not possible to return a deleted record. */
- if (F_ISSET(cp, C_DELETED)) {
- ret = DB_KEYEMPTY;
- goto err;
- }
-
- /* Acquire the current page. */
- if ((ret = __bam_lget(dbc,
- 0, cp->pgno, DB_LOCK_READ, &cp->lock)) == 0)
- ret = memp_fget(dbp->mpf,
- cp->dpgno == PGNO_INVALID ? &cp->pgno : &cp->dpgno,
- 0, &cp->page);
- if (ret != 0)
- goto err;
- break;
- case DB_NEXT_DUP:
- if (cp->pgno == PGNO_INVALID) {
- ret = EINVAL;
- goto err;
- }
- if ((ret = __bam_c_next(dbc, cp, 1)) != 0)
- goto err;
-
- /* Make sure we didn't go past the end of the duplicates. */
- if (!POSSIBLE_DUPLICATE(cp, copy)) {
- ret = DB_NOTFOUND;
- goto err;
- }
- break;
- case DB_NEXT:
- if (cp->pgno != PGNO_INVALID) {
- if ((ret = __bam_c_next(dbc, cp, 1)) != 0)
- goto err;
- break;
- }
- /* FALLTHROUGH */
- case DB_FIRST:
- if ((ret = __bam_c_first(dbc, cp)) != 0)
- goto err;
- break;
- case DB_PREV:
- if (cp->pgno != PGNO_INVALID) {
- if ((ret = __bam_c_prev(dbc, cp)) != 0)
- goto err;
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST:
- if ((ret = __bam_c_last(dbc, cp)) != 0)
- goto err;
- break;
- case DB_SET:
- if ((ret = __bam_c_search(dbc, cp, key, flags, &exact)) != 0)
- goto err;
-
- /*
- * We cannot currently be referencing a deleted record, but we
- * may be referencing off-page duplicates.
- *
- * If we're referencing off-page duplicates, move off-page.
- * If we moved off-page, move to the next non-deleted record.
- * If we moved to the next non-deleted record, check to make
- * sure we didn't switch records because our current record
- * had no non-deleted data items.
- */
- start = *cp;
- if ((ret = __bam_dup(dbc, cp, cp->indx, 0)) != 0)
- goto err;
- if (cp->dpgno != PGNO_INVALID && IS_CUR_DELETED(cp)) {
- if ((ret = __bam_c_next(dbc, cp, 0)) != 0)
- goto err;
- if (!POSSIBLE_DUPLICATE(cp, start)) {
- ret = DB_NOTFOUND;
- goto err;
- }
- }
- break;
- case DB_SET_RECNO:
- if ((ret = __bam_c_search(dbc, cp, key, flags, &exact)) != 0)
- goto err;
- break;
- case DB_GET_BOTH:
- if (F_ISSET(dbc, DBC_CONTINUE | DBC_KEYSET)) {
- /* Acquire the current page. */
- if ((ret = memp_fget(dbp->mpf,
- cp->dpgno == PGNO_INVALID ? &cp->pgno : &cp->dpgno,
- 0, &cp->page)) != 0)
- goto err;
-
- /* If DBC_CONTINUE, move to the next item. */
- if (F_ISSET(dbc, DBC_CONTINUE) &&
- (ret = __bam_c_next(dbc, cp, 1)) != 0)
- goto err;
- } else {
- if ((ret =
- __bam_c_search(dbc, cp, key, flags, &exact)) != 0)
- goto err;
-
- /*
- * We may be referencing a duplicates page. Move to
- * the first duplicate.
- */
- if ((ret = __bam_dup(dbc, cp, cp->indx, 0)) != 0)
- goto err;
- }
-
- /* Search for a matching entry. */
- if ((ret = __bam_dsearch(dbc, cp, data, NULL)) != 0)
- goto err;
-
- /* Ignore deleted entries. */
- if (IS_CUR_DELETED(cp)) {
- ret = DB_NOTFOUND;
- goto err;
- }
- break;
- case DB_SET_RANGE:
- if ((ret = __bam_c_search(dbc, cp, key, flags, &exact)) != 0)
- goto err;
-
- /*
- * As we didn't require an exact match, the search function
- * may have returned an entry past the end of the page. If
- * so, move to the next entry.
- */
- if (cp->indx == NUM_ENT(cp->page) &&
- (ret = __bam_c_next(dbc, cp, 0)) != 0)
- goto err;
-
- /*
- * We may be referencing off-page duplicates, if so, move
- * off-page.
- */
- if ((ret = __bam_dup(dbc, cp, cp->indx, 0)) != 0)
- goto err;
-
- /*
- * We may be referencing a deleted record, if so, move to
- * the next non-deleted record.
- */
- if (IS_CUR_DELETED(cp) && (ret = __bam_c_next(dbc, cp, 0)) != 0)
- goto err;
- break;
- }
-
- /*
- * Return the key if the user didn't give us one. If we've moved to
- * a duplicate page, we may no longer have a pointer to the main page,
- * so we have to go get it. We know that it's already read-locked,
- * however, so we don't have to acquire a new lock.
- */
- if (flags != DB_SET) {
- if (cp->dpgno != PGNO_INVALID) {
- if ((ret = memp_fget(dbp->mpf, &cp->pgno, 0, &h)) != 0)
- goto err;
- } else
- h = cp->page;
- ret = __db_ret(dbp,
- h, cp->indx, key, &dbc->rkey.data, &dbc->rkey.ulen);
- if (cp->dpgno != PGNO_INVALID)
- (void)memp_fput(dbp->mpf, h, 0);
- if (ret)
- goto err;
- }
-
- /* Return the data. */
- if ((ret = __db_ret(dbp, cp->page,
- cp->dpgno == PGNO_INVALID ? cp->indx + O_INDX : cp->dindx,
- data, &dbc->rdata.data, &dbc->rdata.ulen)) != 0)
- goto err;
-
- /*
- * If the previous cursor record has been deleted, physically delete
- * the entry from the page. We clear the deleted flag before we call
- * the underlying delete routine so that, if an error occurs, and we
- * restore the cursor, the deleted flag is cleared. This is because,
- * if we manage to physically modify the page, and then restore the
- * cursor, we might try to repeat the page modification when closing
- * the cursor.
- */
- if (F_ISSET(&copy, C_DELETED)) {
- F_CLR(&copy, C_DELETED);
- if ((ret = __bam_c_physdel(dbc, &copy, cp->page)) != 0)
- goto err;
- }
- F_CLR(cp, C_DELETED);
-
- /* Release the previous lock, if any; the current lock is retained. */
- if (copy.lock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, copy.lock);
-
- /* Release the current page. */
- if ((ret = memp_fput(dbp->mpf, cp->page, 0)) != 0)
- goto err;
-
- if (0) {
-err: if (cp->page != NULL)
- (void)memp_fput(dbp->mpf, cp->page, 0);
- if (cp->lock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, cp->lock);
- *cp = copy;
- }
-
- /* Release temporary lock upgrade. */
- if (tmp_rmw)
- F_CLR(dbc, DBC_RMW);
-
- return (ret);
-}
-
-/*
- * __bam_dsearch --
- * Search for a matching data item (or the first data item that's
- * equal to or greater than the one we're searching for).
- */
-static int
-__bam_dsearch(dbc, cp, data, iflagp)
- DBC *dbc;
- CURSOR *cp;
- DBT *data;
- u_int32_t *iflagp;
-{
- DB *dbp;
- CURSOR copy, last;
- int cmp, ret;
-
- dbp = dbc->dbp;
-
- /*
- * If iflagp is non-NULL, we're doing an insert.
- *
- * If the duplicates are off-page, use the duplicate search routine.
- */
- if (cp->dpgno != PGNO_INVALID) {
- if ((ret = __db_dsearch(dbc, iflagp != NULL,
- data, cp->dpgno, &cp->dindx, &cp->page, &cmp)) != 0)
- return (ret);
- cp->dpgno = cp->page->pgno;
-
- if (iflagp == NULL) {
- if (cmp != 0)
- return (DB_NOTFOUND);
- return (0);
- }
- *iflagp = DB_BEFORE;
- return (0);
- }
-
- /* Otherwise, do the search ourselves. */
- copy = *cp;
- for (;;) {
- /* Save the last interesting cursor position. */
- last = *cp;
-
- /* See if the data item matches the one we're looking for. */
- if ((cmp = __bam_cmp(dbp, data, cp->page, cp->indx + O_INDX,
- dbp->dup_compare == NULL ?
- __bam_defcmp : dbp->dup_compare)) == 0) {
- if (iflagp != NULL)
- *iflagp = DB_AFTER;
- return (0);
- }
-
- /*
- * If duplicate entries are sorted, we're done if we find a
- * page entry that sorts greater than the application item.
- * If doing an insert, return success, otherwise DB_NOTFOUND.
- */
- if (dbp->dup_compare != NULL && cmp < 0) {
- if (iflagp == NULL)
- return (DB_NOTFOUND);
- *iflagp = DB_BEFORE;
- return (0);
- }
-
- /*
- * Move to the next item. If we reach the end of the page and
- * we're doing an insert, set the cursor to the last item and
- * set the referenced memory location so callers know to insert
- * after the item, instead of before it. If not inserting, we
- * return DB_NOTFOUND.
- */
- if ((cp->indx += P_INDX) >= NUM_ENT(cp->page)) {
- if (iflagp == NULL)
- return (DB_NOTFOUND);
- goto use_last;
- }
-
- /*
- * Make sure we didn't go past the end of the duplicates. The
- * error conditions are the same as above.
- */
- if (!POSSIBLE_DUPLICATE(cp, copy)) {
- if (iflagp == NULL)
- return (DB_NOTFOUND);
-use_last: *cp = last;
- *iflagp = DB_AFTER;
- return (0);
- }
- }
- /* NOTREACHED */
-}
-
-/*
- * __bam_c_rget --
- * Return the record number for a cursor.
- */
-static int
-__bam_c_rget(dbc, data, flags)
- DBC *dbc;
- DBT *data;
- u_int32_t flags;
-{
- CURSOR *cp;
- DB *dbp;
- DBT dbt;
- db_recno_t recno;
- int exact, ret;
-
- COMPQUIET(flags, 0);
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- /* Get the page with the current item on it. */
- if ((ret = memp_fget(dbp->mpf, &cp->pgno, 0, &cp->page)) != 0)
- return (ret);
-
- /* Get a copy of the key. */
- memset(&dbt, 0, sizeof(DBT));
- dbt.flags = DB_DBT_MALLOC | DB_DBT_INTERNAL;
- if ((ret = __db_ret(dbp, cp->page, cp->indx, &dbt, NULL, NULL)) != 0)
- goto err;
-
- exact = 1;
- if ((ret = __bam_search(dbc, &dbt,
- F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND,
- 1, &recno, &exact)) != 0)
- goto err;
-
- ret = __db_retcopy(data, &recno, sizeof(recno),
- &dbc->rdata.data, &dbc->rdata.ulen, dbp->db_malloc);
-
- /* Release the stack. */
- __bam_stkrel(dbc, 0);
-
-err: (void)memp_fput(dbp->mpf, cp->page, 0);
- __os_free(dbt.data, dbt.size);
- return (ret);
-}
-
-/*
- * __bam_c_put --
- * Put using a cursor.
- */
-static int
-__bam_c_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- CURSOR *cp, copy;
- DB *dbp;
- DBT dbt;
- db_indx_t indx;
- db_pgno_t pgno;
- u_int32_t iiflags, iiop;
- int exact, needkey, ret, stack;
- void *arg;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- DB_PANIC_CHECK(dbp);
-
- DEBUG_LWRITE(dbc, dbc->txn, "bam_c_put",
- flags == DB_KEYFIRST || flags == DB_KEYLAST ? key : NULL,
- data, flags);
-
- if ((ret = __db_cputchk(dbp, key, data, flags,
- F_ISSET(dbp, DB_AM_RDONLY), cp->pgno != PGNO_INVALID)) != 0)
- return (ret);
-
- /*
- * If we are running CDB, this had better be either a write
- * cursor or an immediate writer. If it's a regular writer,
- * that means we have an IWRITE lock and we need to upgrade
- * it to a write lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- if (0) {
-split: /*
- * To split, we need a valid key for the page. Since it's a
- * cursor, we have to build one.
- *
- * Acquire a copy of a key from the page.
- */
- if (needkey) {
- memset(&dbt, 0, sizeof(DBT));
- if ((ret = __db_ret(dbp, cp->page, indx,
- &dbt, &dbc->rkey.data, &dbc->rkey.ulen)) != 0)
- goto err;
- arg = &dbt;
- } else
- arg = key;
-
- /*
- * Discard any locks and pinned pages (the locks are discarded
- * even if we're running with transactions, as they lock pages
- * that we're sorry we ever acquired). If stack is set and the
- * cursor entries are valid, they point to the same entries as
- * the stack, don't free them twice.
- */
- if (stack) {
- (void)__bam_stkrel(dbc, 1);
- stack = 0;
- } else
- DISCARD(dbc, cp);
-
- /*
- * Restore the cursor to its original value. This is necessary
- * for two reasons. First, we are about to copy it in case of
- * error, again. Second, we adjust cursors during the split,
- * and we have to ensure this cursor is adjusted appropriately,
- * along with all the other cursors.
- */
- *cp = copy;
-
- if ((ret = __bam_split(dbc, arg)) != 0)
- goto err;
- }
-
- /*
- * Initialize the cursor for a new retrieval. Clear the cursor's
- * page pointer, it was set before this operation, and no longer
- * has any meaning.
- */
- cp->page = NULL;
- copy = *cp;
- cp->lock = LOCK_INVALID;
-
- iiflags = needkey = ret = stack = 0;
- switch (flags) {
- case DB_AFTER:
- case DB_BEFORE:
- case DB_CURRENT:
- needkey = 1;
- if (cp->dpgno == PGNO_INVALID) {
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
-
- /*
- * !!!
- * This test is right -- we don't yet support duplicates and
- * record numbers in the same tree, so ignore duplicates if
- * DB_BT_RECNUM set.
- */
- if (F_ISSET(dbp, DB_BT_RECNUM) &&
- (flags != DB_CURRENT || F_ISSET(cp, C_DELETED))) {
- /* Acquire a complete stack. */
- if ((ret = __bam_c_getstack(dbc, cp)) != 0)
- goto err;
- cp->page = cp->csp->page;
-
- stack = 1;
- iiflags = BI_DOINCR;
- } else {
- /* Acquire the current page. */
- if ((ret = __bam_lget(dbc,
- 0, cp->pgno, DB_LOCK_WRITE, &cp->lock)) == 0)
- ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page);
- if (ret != 0)
- goto err;
-
- iiflags = 0;
- }
-
- /*
- * If the user has specified a duplicate comparison function,
- * we return an error if DB_CURRENT was specified and the
- * replacement data doesn't compare equal to the current data.
- * This stops apps from screwing up the duplicate sort order.
- */
- if (flags == DB_CURRENT && dbp->dup_compare != NULL)
- if (__bam_cmp(dbp, data,
- cp->page, indx, dbp->dup_compare) != 0) {
- ret = EINVAL;
- goto err;
- }
-
- iiop = flags;
- break;
- case DB_KEYFIRST:
- case DB_KEYLAST:
- /*
- * If we have a duplicate comparison function, we position to
- * the first of any on-page duplicates, and use __bam_dsearch
- * to search for the right slot. Otherwise, we position to
- * the first/last of any on-page duplicates based on the flag
- * value.
- */
- if ((ret = __bam_c_search(dbc, cp, key,
- flags == DB_KEYFIRST || dbp->dup_compare != NULL ?
- DB_KEYFIRST : DB_KEYLAST, &exact)) != 0)
- goto err;
- stack = 1;
-
- /*
- * If an exact match:
- * If duplicates aren't supported, replace the current
- * item. (When implementing the DB->put function, our
- * caller has already checked the DB_NOOVERWRITE flag.)
- *
- * If there's a duplicate comparison function, find the
- * correct slot for this duplicate item.
- *
- * If there's no duplicate comparison function, set the
- * insert flag based on the argument flags.
- *
- * If there's no match, the search function returned the
- * smallest slot greater than the key, use it.
- */
- if (exact) {
- if (F_ISSET(dbp, DB_AM_DUP)) {
- /*
- * If at off-page duplicate page, move to the
- * first or last entry -- if a comparison
- * function was specified, start searching at
- * the first entry. Otherwise, move based on
- * the DB_KEYFIRST/DB_KEYLAST flags.
- */
- if ((ret = __bam_dup(dbc, cp, cp->indx,
- dbp->dup_compare == NULL &&
- flags != DB_KEYFIRST)) != 0)
- goto err;
-
- /*
- * If there's a comparison function, search for
- * the correct slot. Otherwise, set the insert
- * flag based on the argment flag.
- */
- if (dbp->dup_compare == NULL)
- iiop = flags == DB_KEYFIRST ?
- DB_BEFORE : DB_AFTER;
- else
- if ((ret = __bam_dsearch(dbc,
- cp, data, &iiop)) != 0)
- goto err;
- } else
- iiop = DB_CURRENT;
- iiflags = 0;
- } else {
- iiop = DB_BEFORE;
- iiflags = BI_NEWKEY;
- }
-
- if (cp->dpgno == PGNO_INVALID) {
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
- break;
- }
-
- ret = __bam_iitem(dbc, &cp->page, &indx, key, data, iiop, iiflags);
-
- if (ret == DB_NEEDSPLIT)
- goto split;
- if (ret != 0)
- goto err;
-
- /*
- * Reset any cursors referencing this item that might have the item
- * marked for deletion.
- */
- if (iiop == DB_CURRENT) {
- (void)__bam_ca_delete(dbp, pgno, indx, 0);
-
- /*
- * It's also possible that we are the cursor that had the
- * item marked for deletion, in which case we want to make
- * sure that we don't delete it because we had the delete
- * flag set already.
- */
- if (cp->pgno == copy.pgno && cp->indx == copy.indx &&
- cp->dpgno == copy.dpgno && cp->dindx == copy.dindx)
- F_CLR(&copy, C_DELETED);
- }
-
- /*
- * Update the cursor to point to the new entry. The new entry was
- * stored on the current page, because we split pages until it was
- * possible.
- */
- if (cp->dpgno == PGNO_INVALID)
- cp->indx = indx;
- else
- cp->dindx = indx;
-
- /*
- * If the previous cursor record has been deleted, physically delete
- * the entry from the page. We clear the deleted flag before we call
- * the underlying delete routine so that, if an error occurs, and we
- * restore the cursor, the deleted flag is cleared. This is because,
- * if we manage to physically modify the page, and then restore the
- * cursor, we might try to repeat the page modification when closing
- * the cursor.
- */
- if (F_ISSET(&copy, C_DELETED)) {
- F_CLR(&copy, C_DELETED);
- if ((ret = __bam_c_physdel(dbc, &copy, cp->page)) != 0)
- goto err;
- }
- F_CLR(cp, C_DELETED);
-
- /* Release the previous lock, if any; the current lock is retained. */
- if (copy.lock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, copy.lock);
-
- /*
- * Discard any pages pinned in the tree and their locks, except for
- * the leaf page, for which we only discard the pin, not the lock.
- *
- * Note, the leaf page participated in the stack we acquired, and so
- * we have to adjust the stack as necessary. If there was only a
- * single page on the stack, we don't have to free further stack pages.
- */
- if (stack && BT_STK_POP(cp) != NULL)
- (void)__bam_stkrel(dbc, 0);
-
- /* Release the current page. */
- if ((ret = memp_fput(dbp->mpf, cp->page, 0)) != 0)
- goto err;
-
- if (0) {
-err: /* Discard any pinned pages. */
- if (stack)
- (void)__bam_stkrel(dbc, 0);
- else
- DISCARD(dbc, cp);
- *cp = copy;
- }
-
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
-
- return (ret);
-}
-
-/*
- * __bam_c_first --
- * Return the first record.
- */
-static int
-__bam_c_first(dbc, cp)
- DBC *dbc;
- CURSOR *cp;
-{
- DB *dbp;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Walk down the left-hand side of the tree. */
- for (pgno = PGNO_ROOT;;) {
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
-
- /* If we find a leaf page, we're done. */
- if (ISLEAF(cp->page))
- break;
-
- pgno = GET_BINTERNAL(cp->page, 0)->pgno;
- DISCARD(dbc, cp);
- }
-
- cp->pgno = cp->page->pgno;
- cp->indx = 0;
- cp->dpgno = PGNO_INVALID;
-
- /* Check for duplicates. */
- if ((ret = __bam_dup(dbc, cp, cp->indx, 0)) != 0)
- return (ret);
-
- /* If on an empty page or a deleted record, move to the next one. */
- if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(cp))
- if ((ret = __bam_c_next(dbc, cp, 0)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __bam_c_last --
- * Return the last record.
- */
-static int
-__bam_c_last(dbc, cp)
- DBC *dbc;
- CURSOR *cp;
-{
- DB *dbp;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Walk down the right-hand side of the tree. */
- for (pgno = PGNO_ROOT;;) {
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
-
- /* If we find a leaf page, we're done. */
- if (ISLEAF(cp->page))
- break;
-
- pgno =
- GET_BINTERNAL(cp->page, NUM_ENT(cp->page) - O_INDX)->pgno;
- DISCARD(dbc, cp);
- }
-
- cp->pgno = cp->page->pgno;
- cp->indx = NUM_ENT(cp->page) == 0 ? 0 : NUM_ENT(cp->page) - P_INDX;
- cp->dpgno = PGNO_INVALID;
-
- /* Check for duplicates. */
- if ((ret = __bam_dup(dbc, cp, cp->indx, 1)) != 0)
- return (ret);
-
- /* If on an empty page or a deleted record, move to the next one. */
- if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(cp))
- if ((ret = __bam_c_prev(dbc, cp)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __bam_c_next --
- * Move to the next record.
- */
-static int
-__bam_c_next(dbc, cp, initial_move)
- DBC *dbc;
- CURSOR *cp;
- int initial_move;
-{
- DB *dbp;
- db_indx_t adjust, indx;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- /*
- * We're either moving through a page of duplicates or a btree leaf
- * page.
- */
- if (cp->dpgno == PGNO_INVALID) {
- adjust = dbp->type == DB_BTREE ? P_INDX : O_INDX;
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- adjust = O_INDX;
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
- if (cp->page == NULL) {
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
- }
-
- /*
- * If at the end of the page, move to a subsequent page.
- *
- * !!!
- * Check for >= NUM_ENT. If we're here as the result of a search that
- * landed us on NUM_ENT, we'll increment indx before we test.
- *
- * !!!
- * This code handles empty pages and pages with only deleted entries.
- */
- if (initial_move)
- indx += adjust;
- for (;;) {
- if (indx >= NUM_ENT(cp->page)) {
- /*
- * If we're in a btree leaf page, we've reached the end
- * of the tree. If we've reached the end of a page of
- * duplicates, continue from the btree leaf page where
- * we found this page of duplicates.
- */
- pgno = cp->page->next_pgno;
- if (pgno == PGNO_INVALID) {
- /* If in a btree leaf page, it's EOF. */
- if (cp->dpgno == PGNO_INVALID)
- return (DB_NOTFOUND);
-
- /* Continue from the last btree leaf page. */
- cp->dpgno = PGNO_INVALID;
-
- adjust = P_INDX;
- pgno = cp->pgno;
- indx = cp->indx + P_INDX;
- } else
- indx = 0;
-
- DISCARD(dbc, cp);
- if ((ret = __bam_lget(dbc,
- 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret =
- memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
- continue;
- }
-
- /* Ignore deleted records. */
- if (IS_DELETED(cp, indx)) {
- indx += adjust;
- continue;
- }
-
- /*
- * If we're not in a duplicates page, check to see if we've
- * found a page of duplicates, in which case we move to the
- * first entry.
- */
- if (cp->dpgno == PGNO_INVALID) {
- cp->pgno = cp->page->pgno;
- cp->indx = indx;
-
- if ((ret = __bam_dup(dbc, cp, indx, 0)) != 0)
- return (ret);
- if (cp->dpgno != PGNO_INVALID) {
- indx = cp->dindx;
- adjust = O_INDX;
- continue;
- }
- } else {
- cp->dpgno = cp->page->pgno;
- cp->dindx = indx;
- }
- break;
- }
- return (0);
-}
-
-/*
- * __bam_c_prev --
- * Move to the previous record.
- */
-static int
-__bam_c_prev(dbc, cp)
- DBC *dbc;
- CURSOR *cp;
-{
- DB *dbp;
- db_indx_t indx, adjust;
- db_pgno_t pgno;
- int ret, set_indx;
-
- dbp = dbc->dbp;
-
- /*
- * We're either moving through a page of duplicates or a btree leaf
- * page.
- */
- if (cp->dpgno == PGNO_INVALID) {
- adjust = dbp->type == DB_BTREE ? P_INDX : O_INDX;
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- adjust = O_INDX;
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
- if (cp->page == NULL) {
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
- }
-
- /*
- * If at the beginning of the page, move to any previous one.
- *
- * !!!
- * This code handles empty pages and pages with only deleted entries.
- */
- for (;;) {
- if (indx == 0) {
- /*
- * If we're in a btree leaf page, we've reached the
- * beginning of the tree. If we've reached the first
- * of a page of duplicates, continue from the btree
- * leaf page where we found this page of duplicates.
- */
- pgno = cp->page->prev_pgno;
- if (pgno == PGNO_INVALID) {
- /* If in a btree leaf page, it's SOF. */
- if (cp->dpgno == PGNO_INVALID)
- return (DB_NOTFOUND);
-
- /* Continue from the last btree leaf page. */
- cp->dpgno = PGNO_INVALID;
-
- adjust = P_INDX;
- pgno = cp->pgno;
- indx = cp->indx;
- set_indx = 0;
- } else
- set_indx = 1;
-
- DISCARD(dbc, cp);
- if ((ret = __bam_lget(dbc,
- 0, pgno, DB_LOCK_READ, &cp->lock)) != 0)
- return (ret);
- if ((ret =
- memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
-
- if (set_indx)
- indx = NUM_ENT(cp->page);
- if (indx == 0)
- continue;
- }
-
- /* Ignore deleted records. */
- indx -= adjust;
- if (IS_DELETED(cp, indx))
- continue;
-
- /*
- * If we're not in a duplicates page, check to see if we've
- * found a page of duplicates, in which case we move to the
- * last entry.
- */
- if (cp->dpgno == PGNO_INVALID) {
- cp->pgno = cp->page->pgno;
- cp->indx = indx;
-
- if ((ret = __bam_dup(dbc, cp, indx, 1)) != 0)
- return (ret);
- if (cp->dpgno != PGNO_INVALID) {
- indx = cp->dindx + O_INDX;
- adjust = O_INDX;
- continue;
- }
- } else {
- cp->dpgno = cp->page->pgno;
- cp->dindx = indx;
- }
- break;
- }
- return (0);
-}
-
-/*
- * __bam_c_search --
- * Move to a specified record.
- */
-static int
-__bam_c_search(dbc, cp, key, flags, exactp)
- DBC *dbc;
- CURSOR *cp;
- const DBT *key;
- u_int32_t flags;
- int *exactp;
-{
- BTREE *t;
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- db_recno_t recno;
- db_indx_t indx;
- u_int32_t sflags;
- int cmp, needexact, ret;
-
- dbp = dbc->dbp;
- t = dbp->internal;
-
- /* Find an entry in the database. */
- switch (flags) {
- case DB_SET_RECNO:
- if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
- return (ret);
- sflags = F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND;
- needexact = *exactp = 1;
- ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp);
- break;
- case DB_SET:
- case DB_GET_BOTH:
- sflags = F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND;
- needexact = *exactp = 1;
- goto search;
- case DB_SET_RANGE:
- sflags = F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND;
- needexact = *exactp = 0;
- goto search;
- case DB_KEYFIRST:
- sflags = S_KEYFIRST;
- goto fast_search;
- case DB_KEYLAST:
- sflags = S_KEYLAST;
-fast_search: needexact = *exactp = 0;
- /*
- * If the application has a history of inserting into the first
- * or last pages of the database, we check those pages first to
- * avoid doing a full search.
- *
- * Record numbers can't be fast-tracked, the entire tree has to
- * be locked.
- */
- h = NULL;
- lock = LOCK_INVALID;
- if (F_ISSET(dbp, DB_BT_RECNUM))
- goto search;
-
- /* Check if the application has a history of sorted input. */
- if (t->bt_lpgno == PGNO_INVALID)
- goto search;
-
- /*
- * Lock and retrieve the page on which we did the last insert.
- * It's okay if it doesn't exist, or if it's not the page type
- * we expected, it just means that the world changed.
- */
- if (__bam_lget(dbc, 0, t->bt_lpgno, DB_LOCK_WRITE, &lock))
- goto fast_miss;
- if (memp_fget(dbp->mpf, &t->bt_lpgno, 0, &h))
- goto fast_miss;
- if (TYPE(h) != P_LBTREE)
- goto fast_miss;
- if (NUM_ENT(h) == 0)
- goto fast_miss;
-
- /*
- * What we do here is test to see if we're at the beginning or
- * end of the tree and if the new item sorts before/after the
- * first/last page entry. We don't try and catch inserts into
- * the middle of the tree (although we could, as long as there
- * were two keys on the page and we saved both the index and
- * the page number of the last insert).
- */
- if (h->next_pgno == PGNO_INVALID) {
- indx = NUM_ENT(h) - P_INDX;
- if ((cmp =
- __bam_cmp(dbp, key, h, indx, t->bt_compare)) < 0)
- goto try_begin;
- if (cmp > 0) {
- indx += P_INDX;
- goto fast_hit;
- }
-
- /*
- * Found a duplicate. If doing DB_KEYLAST, we're at
- * the correct position, otherwise, move to the first
- * of the duplicates.
- */
- if (flags == DB_KEYLAST)
- goto fast_hit;
- for (;
- indx > 0 && h->inp[indx - P_INDX] == h->inp[indx];
- indx -= P_INDX)
- ;
- goto fast_hit;
- }
-try_begin: if (h->prev_pgno == PGNO_INVALID) {
- indx = 0;
- if ((cmp =
- __bam_cmp(dbp, key, h, indx, t->bt_compare)) > 0)
- goto fast_miss;
- if (cmp < 0)
- goto fast_hit;
- /*
- * Found a duplicate. If doing DB_KEYFIRST, we're at
- * the correct position, otherwise, move to the last
- * of the duplicates.
- */
- if (flags == DB_KEYFIRST)
- goto fast_hit;
- for (;
- indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
- h->inp[indx] == h->inp[indx + P_INDX];
- indx += P_INDX)
- ;
- goto fast_hit;
- }
- goto fast_miss;
-
-fast_hit: /* Set the exact match flag, we may have found a duplicate. */
- *exactp = cmp == 0;
-
- /* Enter the entry in the stack. */
- BT_STK_CLR(cp);
- BT_STK_ENTER(cp, h, indx, lock, ret);
- break;
-
-fast_miss: if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- if (lock != LOCK_INVALID)
- (void)__BT_LPUT(dbc, lock);
-
-search: ret = __bam_search(dbc, key, sflags, 1, NULL, exactp);
- break;
- default: /* XXX: Impossible. */
- abort();
- /* NOTREACHED */
- }
- if (ret != 0)
- return (ret);
-
- /*
- * Initialize the cursor to reference it. This has to be done
- * before we return (even with DB_NOTFOUND) because we have to
- * free the page(s) we locked in __bam_search.
- */
- cp->page = cp->csp->page;
- cp->pgno = cp->csp->page->pgno;
- cp->indx = cp->csp->indx;
- cp->lock = cp->csp->lock;
- cp->dpgno = PGNO_INVALID;
-
- /*
- * If we inserted a key into the first or last slot of the tree,
- * remember where it was so we can do it more quickly next time.
- */
- if (flags == DB_KEYFIRST || flags == DB_KEYLAST)
- t->bt_lpgno =
- ((cp->page->next_pgno == PGNO_INVALID &&
- cp->indx >= NUM_ENT(cp->page)) ||
- (cp->page->prev_pgno == PGNO_INVALID && cp->indx == 0)) ?
- cp->pgno : PGNO_INVALID;
-
- /* If we need an exact match and didn't find one, we're done. */
- if (needexact && *exactp == 0)
- return (DB_NOTFOUND);
-
- return (0);
-}
-
-/*
- * __bam_dup --
- * Check for an off-page duplicates entry, and if found, move to the
- * first or last entry.
- *
- * PUBLIC: int __bam_dup __P((DBC *, CURSOR *, u_int32_t, int));
- */
-int
-__bam_dup(dbc, cp, indx, last_dup)
- DBC *dbc;
- CURSOR *cp;
- u_int32_t indx;
- int last_dup;
-{
- BOVERFLOW *bo;
- DB *dbp;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- /*
- * Check for an overflow entry. If we find one, move to the
- * duplicates page, and optionally move to the last record on
- * that page.
- *
- * !!!
- * We don't lock duplicates pages, we've already got the correct
- * lock on the main page.
- */
- bo = GET_BOVERFLOW(cp->page, indx + O_INDX);
- if (B_TYPE(bo->type) != B_DUPLICATE)
- return (0);
-
- pgno = bo->pgno;
- if ((ret = memp_fput(dbp->mpf, cp->page, 0)) != 0)
- return (ret);
- cp->page = NULL;
- if (last_dup) {
- if ((ret = __db_dend(dbc, pgno, &cp->page)) != 0)
- return (ret);
- indx = NUM_ENT(cp->page) - O_INDX;
- } else {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &cp->page)) != 0)
- return (ret);
- indx = 0;
- }
-
- /* Update the cursor's duplicate information. */
- cp->dpgno = cp->page->pgno;
- cp->dindx = indx;
-
- return (0);
-}
-
-/*
- * __bam_c_physdel --
- * Actually do the cursor deletion.
- */
-static int
-__bam_c_physdel(dbc, cp, h)
- DBC *dbc;
- CURSOR *cp;
- PAGE *h;
-{
- enum { DELETE_ITEM, DELETE_PAGE, NOTHING_FURTHER } cmd;
- BOVERFLOW bo;
- DB *dbp;
- DBT dbt;
- DB_LOCK lock;
- db_indx_t indx;
- db_pgno_t pgno, next_pgno, prev_pgno;
- int delete_page, local_page, ret;
-
- dbp = dbc->dbp;
-
- delete_page = ret = 0;
-
- /* Figure out what we're deleting. */
- if (cp->dpgno == PGNO_INVALID) {
- pgno = cp->pgno;
- indx = cp->indx;
- } else {
- pgno = cp->dpgno;
- indx = cp->dindx;
- }
-
- /*
- * If the item is referenced by another cursor, set that cursor's
- * delete flag and leave it up to it to do the delete.
- *
- * !!!
- * This test for > 0 is a tricky. There are two ways that we can
- * be called here. Either we are closing the cursor or we've moved
- * off the page with the deleted entry. In the first case, we've
- * already removed the cursor from the active queue, so we won't see
- * it in __bam_ca_delete. In the second case, it will be on a different
- * item, so we won't bother with it in __bam_ca_delete.
- */
- if (__bam_ca_delete(dbp, pgno, indx, 1) > 0)
- return (0);
-
- /*
- * If this is concurrent DB, upgrade the lock if necessary.
- */
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info,
- dbc->locker, DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
-
- /*
- * If we don't already have the page locked, get it and delete the
- * items.
- */
- if ((h == NULL || h->pgno != pgno)) {
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- return (ret);
- local_page = 1;
- } else
- local_page = 0;
-
- /*
- * If we're deleting a duplicate entry and there are other duplicate
- * entries remaining, call the common code to do the work and fix up
- * the parent page as necessary. Otherwise, do a normal btree delete.
- *
- * There are 5 possible cases:
- *
- * 1. It's not a duplicate item: do a normal btree delete.
- * 2. It's a duplicate item:
- * 2a: We delete an item from a page of duplicates, but there are
- * more items on the page.
- * 2b: We delete the last item from a page of duplicates, deleting
- * the last duplicate.
- * 2c: We delete the last item from a page of duplicates, but there
- * is a previous page of duplicates.
- * 2d: We delete the last item from a page of duplicates, but there
- * is a following page of duplicates.
- *
- * In the case of:
- *
- * 1: There's nothing further to do.
- * 2a: There's nothing further to do.
- * 2b: Do the normal btree delete instead of a duplicate delete, as
- * that deletes both the duplicate chain and the parent page's
- * entry.
- * 2c: There's nothing further to do.
- * 2d: Delete the duplicate, and update the parent page's entry.
- */
- if (TYPE(h) == P_DUPLICATE) {
- pgno = PGNO(h);
- prev_pgno = PREV_PGNO(h);
- next_pgno = NEXT_PGNO(h);
-
- if (NUM_ENT(h) == 1 &&
- prev_pgno == PGNO_INVALID && next_pgno == PGNO_INVALID)
- cmd = DELETE_PAGE;
- else {
- cmd = DELETE_ITEM;
-
- /* Delete the duplicate. */
- if ((ret = __db_drem(dbc, &h, indx, __bam_free)) != 0)
- goto err;
-
- /*
- * 2a: h != NULL, h->pgno == pgno
- * 2b: We don't reach this clause, as the above test
- * was true.
- * 2c: h == NULL, prev_pgno != PGNO_INVALID
- * 2d: h != NULL, next_pgno != PGNO_INVALID
- *
- * Test for 2a and 2c: if we didn't empty the current
- * page or there was a previous page of duplicates, we
- * don't need to touch the parent page.
- */
- if ((h != NULL && pgno == h->pgno) ||
- prev_pgno != PGNO_INVALID)
- cmd = NOTHING_FURTHER;
- }
-
- /*
- * Release any page we're holding and its lock.
- *
- * !!!
- * If there is no subsequent page in the duplicate chain, then
- * __db_drem will have put page "h" and set it to NULL.
- */
- if (local_page) {
- if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_TLPUT(dbc, lock);
- local_page = 0;
- }
-
- if (cmd == NOTHING_FURTHER)
- goto done;
-
- /* Acquire the parent page and switch the index to its entry. */
- if ((ret =
- __bam_lget(dbc, 0, cp->pgno, DB_LOCK_WRITE, &lock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &cp->pgno, 0, &h)) != 0) {
- (void)__BT_TLPUT(dbc, lock);
- goto err;
- }
- local_page = 1;
- indx = cp->indx;
-
- if (cmd == DELETE_PAGE)
- goto btd;
-
- /*
- * Copy, delete, update, add-back the parent page's data entry.
- *
- * XXX
- * This may be a performance/logging problem. We should add a
- * log message which simply logs/updates a random set of bytes
- * on a page, and use it instead of doing a delete/add pair.
- */
- indx += O_INDX;
- bo = *GET_BOVERFLOW(h, indx);
- (void)__db_ditem(dbc, h, indx, BOVERFLOW_SIZE);
- bo.pgno = next_pgno;
- memset(&dbt, 0, sizeof(dbt));
- dbt.data = &bo;
- dbt.size = BOVERFLOW_SIZE;
- (void)__db_pitem(dbc, h, indx, BOVERFLOW_SIZE, &dbt, NULL);
- (void)memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY);
- goto done;
- }
-
-btd: /*
- * If the page is going to be emptied, delete it. To delete a leaf
- * page we need a copy of a key from the page. We use the 0th page
- * index since it's the last key that the page held.
- *
- * We malloc the page information instead of using the return key/data
- * memory because we've already set them -- the reason we've already
- * set them is because we're (potentially) about to do a reverse split,
- * which would make our saved page information useless.
- *
- * !!!
- * The following operations to delete a page might deadlock. I think
- * that's OK. The problem is if we're deleting an item because we're
- * closing cursors because we've already deadlocked and want to call
- * txn_abort(). If we fail due to deadlock, we leave a locked empty
- * page in the tree, which won't be empty long because we're going to
- * undo the delete.
- */
- if (NUM_ENT(h) == 2 && h->pgno != PGNO_ROOT) {
- memset(&dbt, 0, sizeof(DBT));
- dbt.flags = DB_DBT_MALLOC | DB_DBT_INTERNAL;
- if ((ret = __db_ret(dbp, h, 0, &dbt, NULL, NULL)) != 0)
- goto err;
- delete_page = 1;
- }
-
- /*
- * Do a normal btree delete.
- *
- * !!!
- * Delete the key item first, otherwise the duplicate checks in
- * __bam_ditem() won't work!
- */
- if ((ret = __bam_ditem(dbc, h, indx)) != 0)
- goto err;
- if ((ret = __bam_ditem(dbc, h, indx)) != 0)
- goto err;
-
- /* Discard any remaining locks/pages. */
- if (local_page) {
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_TLPUT(dbc, lock);
- local_page = 0;
- }
-
- /* Delete the page if it was emptied. */
- if (delete_page)
- ret = __bam_dpage(dbc, &dbt);
-
-err:
-done: if (delete_page)
- __os_free(dbt.data, dbt.size);
-
- if (local_page) {
- /*
- * It's possible for h to be NULL, as __db_drem may have
- * been relinking pages by the time that it deadlocked.
- */
- if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_TLPUT(dbc, lock);
- }
-
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
-
- return (ret);
-}
-
-/*
- * __bam_c_getstack --
- * Acquire a full stack for a cursor.
- */
-static int
-__bam_c_getstack(dbc, cp)
- DBC *dbc;
- CURSOR *cp;
-{
- DB *dbp;
- DBT dbt;
- PAGE *h;
- db_pgno_t pgno;
- int exact, ret;
-
- dbp = dbc->dbp;
- h = NULL;
- memset(&dbt, 0, sizeof(DBT));
- ret = 0;
-
- /* Get the page with the current item on it. */
- pgno = cp->pgno;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- /* Get a copy of a key from the page. */
- dbt.flags = DB_DBT_MALLOC | DB_DBT_INTERNAL;
- if ((ret = __db_ret(dbp, h, 0, &dbt, NULL, NULL)) != 0)
- goto err;
-
- /* Get a write-locked stack for that page. */
- exact = 0;
- ret = __bam_search(dbc, &dbt, S_KEYFIRST, 1, NULL, &exact);
-
- /* We no longer need the key or the page. */
-err: if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- if (dbt.data != NULL)
- __os_free(dbt.data, dbt.size);
- return (ret);
-}
diff --git a/db2/btree/bt_delete.c b/db2/btree/bt_delete.c
deleted file mode 100644
index d623bd8..0000000
--- a/db2/btree/bt_delete.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_delete.c 10.43 (Sleepycat) 12/7/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_delete --
- * Delete the items referenced by a key.
- *
- * PUBLIC: int __bam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
- */
-int
-__bam_delete(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DBC *dbc;
- DBT data;
- u_int32_t f_init, f_next;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret =
- __db_delchk(dbp, key, flags, F_ISSET(dbp, DB_AM_RDONLY))) != 0)
- return (ret);
-
- /* Allocate a cursor. */
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "bam_delete", key, NULL, flags);
-
- /*
- * Walk a cursor through the key/data pairs, deleting as we go. Set
- * the DB_DBT_USERMEM flag, as this might be a threaded application
- * and the flags checking will catch us. We don't actually want the
- * keys or data, so request a partial of length 0.
- */
- memset(&data, 0, sizeof(data));
- F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- /* If locking, set read-modify-write flag. */
- f_init = DB_SET;
- f_next = DB_NEXT_DUP;
- if (dbp->dbenv != NULL && dbp->dbenv->lk_info != NULL) {
- f_init |= DB_RMW;
- f_next |= DB_RMW;
- }
-
- /* Walk through the set of key/data pairs, deleting as we go. */
- if ((ret = dbc->c_get(dbc, key, &data, f_init)) != 0)
- goto err;
- for (;;) {
- if ((ret = dbc->c_del(dbc, 0)) != 0)
- goto err;
- if ((ret = dbc->c_get(dbc, key, &data, f_next)) != 0) {
- if (ret == DB_NOTFOUND) {
- ret = 0;
- break;
- }
- goto err;
- }
- }
-
-err: /* Discard the cursor. */
- if ((t_ret = dbc->c_close(dbc)) != 0 &&
- (ret == 0 || ret == DB_NOTFOUND))
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __bam_ditem --
- * Delete one or more entries from a page.
- *
- * PUBLIC: int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
- */
-int
-__bam_ditem(dbc, h, indx)
- DBC *dbc;
- PAGE *h;
- u_int32_t indx;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- BOVERFLOW *bo;
- DB *dbp;
- u_int32_t nbytes;
- int ret;
-
- dbp = dbc->dbp;
-
- switch (TYPE(h)) {
- case P_IBTREE:
- bi = GET_BINTERNAL(h, indx);
- switch (B_TYPE(bi->type)) {
- case B_DUPLICATE:
- case B_OVERFLOW:
- nbytes = BINTERNAL_SIZE(bi->len);
- bo = (BOVERFLOW *)bi->data;
- goto offpage;
- case B_KEYDATA:
- nbytes = BINTERNAL_SIZE(bi->len);
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
- break;
- case P_IRECNO:
- nbytes = RINTERNAL_SIZE;
- break;
- case P_LBTREE:
- /*
- * If it's a duplicate key, discard the index and don't touch
- * the actual page item.
- *
- * XXX
- * This works because no data item can have an index matching
- * any other index so even if the data item is in a key "slot",
- * it won't match any other index.
- */
- if ((indx % 2) == 0) {
- /*
- * Check for a duplicate after us on the page. NOTE:
- * we have to delete the key item before deleting the
- * data item, otherwise the "indx + P_INDX" calculation
- * won't work!
- */
- if (indx + P_INDX < (u_int32_t)NUM_ENT(h) &&
- h->inp[indx] == h->inp[indx + P_INDX])
- return (__bam_adjindx(dbc,
- h, indx, indx + O_INDX, 0));
- /*
- * Check for a duplicate before us on the page. It
- * doesn't matter if we delete the key item before or
- * after the data item for the purposes of this one.
- */
- if (indx > 0 && h->inp[indx] == h->inp[indx - P_INDX])
- return (__bam_adjindx(dbc,
- h, indx, indx - P_INDX, 0));
- }
- /* FALLTHROUGH */
- case P_LRECNO:
- bk = GET_BKEYDATA(h, indx);
- switch (B_TYPE(bk->type)) {
- case B_DUPLICATE:
- case B_OVERFLOW:
- nbytes = BOVERFLOW_SIZE;
- bo = GET_BOVERFLOW(h, indx);
-
-offpage: /* Delete duplicate/offpage chains. */
- if (B_TYPE(bo->type) == B_DUPLICATE) {
- if ((ret =
- __db_ddup(dbc, bo->pgno, __bam_free)) != 0)
- return (ret);
- } else
- if ((ret =
- __db_doff(dbc, bo->pgno, __bam_free)) != 0)
- return (ret);
- break;
- case B_KEYDATA:
- nbytes = BKEYDATA_SIZE(bk->len);
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
-
- /* Delete the item. */
- if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0)
- return (ret);
-
- /* Mark the page dirty. */
- return (memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY));
-}
-
-/*
- * __bam_adjindx --
- * Adjust an index on the page.
- *
- * PUBLIC: int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
- */
-int
-__bam_adjindx(dbc, h, indx, indx_copy, is_insert)
- DBC *dbc;
- PAGE *h;
- u_int32_t indx, indx_copy;
- int is_insert;
-{
- DB *dbp;
- db_indx_t copy;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Log the change. */
- if (DB_LOGGING(dbc) &&
- (ret = __bam_adj_log(dbp->dbenv->lg_info, dbc->txn, &LSN(h),
- 0, dbp->log_fileid, PGNO(h), &LSN(h), indx, indx_copy,
- (u_int32_t)is_insert)) != 0)
- return (ret);
-
- if (is_insert) {
- copy = h->inp[indx_copy];
- if (indx != NUM_ENT(h))
- memmove(&h->inp[indx + O_INDX], &h->inp[indx],
- sizeof(db_indx_t) * (NUM_ENT(h) - indx));
- h->inp[indx] = copy;
- ++NUM_ENT(h);
- } else {
- --NUM_ENT(h);
- if (indx != NUM_ENT(h))
- memmove(&h->inp[indx], &h->inp[indx + O_INDX],
- sizeof(db_indx_t) * (NUM_ENT(h) - indx));
- }
-
- /* Mark the page dirty. */
- ret = memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY);
-
- /* Adjust the cursors. */
- __bam_ca_di(dbp, h->pgno, indx, is_insert ? 1 : -1);
- return (0);
-}
-
-/*
- * __bam_dpage --
- * Delete a page from the tree.
- *
- * PUBLIC: int __bam_dpage __P((DBC *, const DBT *));
- */
-int
-__bam_dpage(dbc, key)
- DBC *dbc;
- const DBT *key;
-{
- CURSOR *cp;
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- db_pgno_t pgno;
- int level; /* !!!: has to hold number of tree levels. */
- int exact, ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- ret = 0;
-
- /*
- * The locking protocol is that we acquire locks by walking down the
- * tree, to avoid the obvious deadlocks.
- *
- * Call __bam_search to reacquire the empty leaf page, but this time
- * get both the leaf page and it's parent, locked. Walk back up the
- * tree, until we have the top pair of pages that we want to delete.
- * Once we have the top page that we want to delete locked, lock the
- * underlying pages and check to make sure they're still empty. If
- * they are, delete them.
- */
- for (level = LEAFLEVEL;; ++level) {
- /* Acquire a page and its parent, locked. */
- if ((ret =
- __bam_search(dbc, key, S_WRPAIR, level, NULL, &exact)) != 0)
- return (ret);
-
- /*
- * If we reach the root or the page isn't going to be empty
- * when we delete one record, quit.
- */
- h = cp->csp[-1].page;
- if (h->pgno == PGNO_ROOT || NUM_ENT(h) != 1)
- break;
-
- /* Release the two locked pages. */
- (void)memp_fput(dbp->mpf, cp->csp[-1].page, 0);
- (void)__BT_TLPUT(dbc, cp->csp[-1].lock);
- (void)memp_fput(dbp->mpf, cp->csp[0].page, 0);
- (void)__BT_TLPUT(dbc, cp->csp[0].lock);
- }
-
- /*
- * Leave the stack pointer one after the last entry, we may be about
- * to push more items on the stack.
- */
- ++cp->csp;
-
- /*
- * cp->csp[-2].page is the top page, which we're not going to delete,
- * and cp->csp[-1].page is the first page we are going to delete.
- *
- * Walk down the chain, acquiring the rest of the pages until we've
- * retrieved the leaf page. If we find any pages that aren't going
- * to be emptied by the delete, someone else added something while we
- * were walking the tree, and we discontinue the delete.
- */
- for (h = cp->csp[-1].page;;) {
- if (ISLEAF(h)) {
- if (NUM_ENT(h) != 0)
- goto release;
- break;
- } else
- if (NUM_ENT(h) != 1)
- goto release;
-
- /*
- * Get the next page, write lock it and push it onto the stack.
- * We know it's index 0, because it can only have one element.
- */
- pgno = TYPE(h) == P_IBTREE ?
- GET_BINTERNAL(h, 0)->pgno : GET_RINTERNAL(h, 0)->pgno;
-
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &lock)) != 0)
- goto release;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- goto release;
- BT_STK_PUSH(cp, h, 0, lock, ret);
- }
-
- /* Adjust back to reference the last page on the stack. */
- BT_STK_POP(cp);
-
- /* Delete the pages. */
- return (__bam_dpages(dbc));
-
-release:
- /* Adjust back to reference the last page on the stack. */
- BT_STK_POP(cp);
-
- /* Discard any locked pages and return. */
- __bam_stkrel(dbc, 0);
-
- return (ret);
-}
-
-/*
- * __bam_dpages --
- * Delete a set of locked pages.
- *
- * PUBLIC: int __bam_dpages __P((DBC *));
- */
-int
-__bam_dpages(dbc)
- DBC *dbc;
-{
- CURSOR *cp;
- DB *dbp;
- DBT a, b;
- DB_LOCK c_lock, p_lock;
- EPG *epg;
- PAGE *child, *parent;
- db_indx_t nitems;
- db_pgno_t pgno;
- db_recno_t rcnt;
- int done, ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- epg = cp->sp;
-
- /*
- * !!!
- * There is an interesting deadlock situation here. We have to relink
- * the leaf page chain around the leaf page being deleted. Consider
- * a cursor walking through the leaf pages, that has the previous page
- * read-locked and is waiting on a lock for the page we're deleting.
- * It will deadlock here. This is a problem, because if our process is
- * selected to resolve the deadlock, we'll leave an empty leaf page
- * that we can never again access by walking down the tree. So, before
- * we unlink the subtree, we relink the leaf page chain.
- */
- if ((ret = __db_relink(dbc, DB_REM_PAGE, cp->csp->page, NULL, 1)) != 0)
- goto release;
-
- /*
- * We have the entire stack of deletable pages locked.
- *
- * Delete the highest page in the tree's reference to the underlying
- * stack of pages. Then, release that page, letting the rest of the
- * tree get back to business.
- */
- if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) {
-release: (void)__bam_stkrel(dbc, 0);
- return (ret);
- }
-
- pgno = epg->page->pgno;
- nitems = NUM_ENT(epg->page);
-
- (void)memp_fput(dbp->mpf, epg->page, 0);
- (void)__BT_TLPUT(dbc, epg->lock);
-
- /*
- * Free the rest of the stack of pages.
- *
- * !!!
- * Don't bother checking for errors. We've unlinked the subtree from
- * the tree, and there's no possibility of recovery outside of doing
- * TXN rollback.
- */
- while (++epg <= cp->csp) {
- /*
- * Delete page entries so they will be restored as part of
- * recovery.
- */
- if (NUM_ENT(epg->page) != 0)
- (void)__bam_ditem(dbc, epg->page, epg->indx);
-
- (void)__bam_free(dbc, epg->page);
- (void)__BT_TLPUT(dbc, epg->lock);
- }
- BT_STK_CLR(cp);
-
- /*
- * Try and collapse the tree a level -- this is only applicable
- * if we've deleted the next-to-last element from the root page.
- *
- * There are two cases when collapsing a tree.
- *
- * If we've just deleted the last item from the root page, there is no
- * further work to be done. The code above has emptied the root page
- * and freed all pages below it.
- */
- if (pgno != PGNO_ROOT || nitems != 1)
- return (0);
-
- /*
- * If we just deleted the next-to-last item from the root page, the
- * tree can collapse one or more levels. While there remains only a
- * single item on the root page, write lock the last page referenced
- * by the root page and copy it over the root page. If we can't get a
- * write lock, that's okay, the tree just stays deeper than we'd like.
- */
- for (done = 0; !done;) {
- /* Initialize. */
- parent = child = NULL;
- p_lock = c_lock = LOCK_INVALID;
-
- /* Lock the root. */
- pgno = PGNO_ROOT;
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &p_lock)) != 0)
- goto stop;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &parent)) != 0)
- goto stop;
-
- if (NUM_ENT(parent) != 1 ||
- (TYPE(parent) != P_IBTREE && TYPE(parent) != P_IRECNO))
- goto stop;
-
- pgno = TYPE(parent) == P_IBTREE ?
- GET_BINTERNAL(parent, 0)->pgno :
- GET_RINTERNAL(parent, 0)->pgno;
-
- /* Lock the child page. */
- if ((ret =
- __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &c_lock)) != 0)
- goto stop;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &child)) != 0)
- goto stop;
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- memset(&a, 0, sizeof(a));
- a.data = child;
- a.size = dbp->pgsize;
- memset(&b, 0, sizeof(b));
- b.data = P_ENTRY(parent, 0);
- b.size = BINTERNAL_SIZE(((BINTERNAL *)b.data)->len);
- __bam_rsplit_log(dbp->dbenv->lg_info, dbc->txn,
- &child->lsn, 0, dbp->log_fileid, child->pgno, &a,
- RE_NREC(parent), &b, &parent->lsn);
- }
-
- /*
- * Make the switch.
- *
- * One fixup -- if the tree has record numbers and we're not
- * converting to a leaf page, we have to preserve the total
- * record count. Note that we are about to overwrite everything
- * on the parent, including its LSN. This is actually OK,
- * because the above log message, which describes this update,
- * stores its LSN on the child page. When the child is copied
- * to the parent, the correct LSN is going to copied into
- * place in the parent.
- */
- COMPQUIET(rcnt, 0);
- if (TYPE(child) == P_IRECNO ||
- (TYPE(child) == P_IBTREE && F_ISSET(dbp, DB_BT_RECNUM)))
- rcnt = RE_NREC(parent);
- memcpy(parent, child, dbp->pgsize);
- parent->pgno = PGNO_ROOT;
- if (TYPE(child) == P_IRECNO ||
- (TYPE(child) == P_IBTREE && F_ISSET(dbp, DB_BT_RECNUM)))
- RE_NREC_SET(parent, rcnt);
-
- /* Mark the pages dirty. */
- memp_fset(dbp->mpf, parent, DB_MPOOL_DIRTY);
- memp_fset(dbp->mpf, child, DB_MPOOL_DIRTY);
-
- /* Adjust the cursors. */
- __bam_ca_rsplit(dbp, child->pgno, PGNO_ROOT);
-
- /*
- * Free the page copied onto the root page and discard its
- * lock. (The call to __bam_free() discards our reference
- * to the page.)
- */
- (void)__bam_free(dbc, child);
- child = NULL;
-
- if (0) {
-stop: done = 1;
- }
- if (p_lock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, p_lock);
- if (parent != NULL)
- memp_fput(dbp->mpf, parent, 0);
- if (c_lock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, c_lock);
- if (child != NULL)
- memp_fput(dbp->mpf, child, 0);
- }
-
- return (0);
-}
diff --git a/db2/btree/bt_open.c b/db2/btree/bt_open.c
deleted file mode 100644
index a89cfcc..0000000
--- a/db2/btree/bt_open.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_open.c 10.39 (Sleepycat) 11/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_open --
- * Open a btree.
- *
- * PUBLIC: int __bam_open __P((DB *, DB_INFO *));
- */
-int
-__bam_open(dbp, dbinfo)
- DB *dbp;
- DB_INFO *dbinfo;
-{
- BTREE *t;
- int ret;
-
- /* Allocate and initialize the private btree structure. */
- if ((ret = __os_calloc(1, sizeof(BTREE), &t)) != 0)
- return (ret);
- dbp->internal = t;
-
- /*
- * Intention is to make sure all of the user's selections are okay
- * here and then use them without checking.
- */
- if (dbinfo == NULL) {
- t->bt_minkey = DEFMINKEYPAGE;
- t->bt_compare = __bam_defcmp;
- t->bt_prefix = __bam_defpfx;
- } else {
- /* Minimum number of keys per page. */
- if (dbinfo->bt_minkey == 0)
- t->bt_minkey = DEFMINKEYPAGE;
- else {
- if (dbinfo->bt_minkey < 2)
- goto einval;
- t->bt_minkey = dbinfo->bt_minkey;
- }
-
- /* Maximum number of keys per page. */
- if (dbinfo->bt_maxkey == 0)
- t->bt_maxkey = 0;
- else {
- if (dbinfo->bt_maxkey < 1)
- goto einval;
- t->bt_maxkey = dbinfo->bt_maxkey;
- }
-
- /*
- * If no comparison, use default comparison. If no comparison
- * and no prefix, use default prefix. (We can't default the
- * prefix if the user supplies a comparison routine; shortening
- * the keys may break their comparison algorithm. We don't
- * permit the user to specify a prefix routine if they didn't
- * also specify a comparison routine, they can't know enough
- * about our comparison routine to get it right.)
- */
- if ((t->bt_compare = dbinfo->bt_compare) == NULL) {
- if (dbinfo->bt_prefix != NULL)
- goto einval;
- t->bt_compare = __bam_defcmp;
- t->bt_prefix = __bam_defpfx;
- } else
- t->bt_prefix = dbinfo->bt_prefix;
- }
-
- /* Initialize the remaining fields/methods of the DB. */
- dbp->am_close = __bam_close;
- dbp->del = __bam_delete;
- dbp->stat = __bam_stat;
-
- /* Start up the tree. */
- if ((ret = __bam_read_root(dbp)) != 0)
- goto err;
-
- /* Set the overflow page size. */
- __bam_setovflsize(dbp);
-
- return (0);
-
-einval: ret = EINVAL;
-
-err: __os_free(t, sizeof(BTREE));
- return (ret);
-}
-
-/*
- * __bam_close --
- * Close a btree.
- *
- * PUBLIC: int __bam_close __P((DB *));
- */
-int
-__bam_close(dbp)
- DB *dbp;
-{
- __os_free(dbp->internal, sizeof(BTREE));
- dbp->internal = NULL;
-
- return (0);
-}
-
-/*
- * __bam_setovflsize --
- *
- * PUBLIC: void __bam_setovflsize __P((DB *));
- */
-void
-__bam_setovflsize(dbp)
- DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /*
- * !!!
- * Correction for recno, which doesn't know anything about minimum
- * keys per page.
- */
- if (t->bt_minkey == 0)
- t->bt_minkey = DEFMINKEYPAGE;
-
- /*
- * The btree data structure requires that at least two key/data pairs
- * can fit on a page, but other than that there's no fixed requirement.
- * Translate the minimum number of items into the bytes a key/data pair
- * can use before being placed on an overflow page. We calculate for
- * the worst possible alignment by assuming every item requires the
- * maximum alignment for padding.
- *
- * Recno uses the btree bt_ovflsize value -- it's close enough.
- */
- t->bt_ovflsize = (dbp->pgsize - P_OVERHEAD) / (t->bt_minkey * P_INDX)
- - (BKEYDATA_PSIZE(0) + ALIGN(1, 4));
-}
-
-/*
- * __bam_read_root --
- * Check (and optionally create) a tree.
- *
- * PUBLIC: int __bam_read_root __P((DB *));
- */
-int
-__bam_read_root(dbp)
- DB *dbp;
-{
- BTMETA *meta;
- BTREE *t;
- DBC *dbc;
- DB_LOCK metalock, rootlock;
- PAGE *root;
- db_pgno_t pgno;
- int ret, t_ret;
-
- ret = 0;
- t = dbp->internal;
-
- /* Get a cursor. */
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
-
- /* Get, and optionally create the metadata page. */
- pgno = PGNO_METADATA;
- if ((ret =
- __bam_lget(dbc, 0, PGNO_METADATA, DB_LOCK_WRITE, &metalock)) != 0)
- goto err;
- if ((ret =
- memp_fget(dbp->mpf, &pgno, DB_MPOOL_CREATE, (PAGE **)&meta)) != 0) {
- (void)__BT_LPUT(dbc, metalock);
- goto err;
- }
-
- /*
- * If the magic number is correct, we're not creating the tree.
- * Correct any fields that may not be right. Note, all of the
- * local flags were set by db_open(3).
- */
- if (meta->magic != 0) {
- t->bt_maxkey = meta->maxkey;
- t->bt_minkey = meta->minkey;
-
- (void)memp_fput(dbp->mpf, (PAGE *)meta, 0);
- (void)__BT_LPUT(dbc, metalock);
- goto done;
- }
-
- /* Initialize the tree structure metadata information. */
- memset(meta, 0, sizeof(BTMETA));
- ZERO_LSN(meta->lsn);
- meta->pgno = PGNO_METADATA;
- meta->magic = DB_BTREEMAGIC;
- meta->version = DB_BTREEVERSION;
- meta->pagesize = dbp->pgsize;
- meta->maxkey = t->bt_maxkey;
- meta->minkey = t->bt_minkey;
- meta->free = PGNO_INVALID;
- if (dbp->type == DB_RECNO)
- F_SET(meta, BTM_RECNO);
- if (F_ISSET(dbp, DB_AM_DUP))
- F_SET(meta, BTM_DUP);
- if (F_ISSET(dbp, DB_RE_FIXEDLEN))
- F_SET(meta, BTM_FIXEDLEN);
- if (F_ISSET(dbp, DB_BT_RECNUM))
- F_SET(meta, BTM_RECNUM);
- if (F_ISSET(dbp, DB_RE_RENUMBER))
- F_SET(meta, BTM_RENUMBER);
- memcpy(meta->uid, dbp->fileid, DB_FILE_ID_LEN);
-
- /* Create and initialize a root page. */
- pgno = PGNO_ROOT;
- if ((ret =
- __bam_lget(dbc, 0, PGNO_ROOT, DB_LOCK_WRITE, &rootlock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0) {
- (void)__BT_LPUT(dbc, rootlock);
- goto err;
- }
- P_INIT(root, dbp->pgsize, PGNO_ROOT, PGNO_INVALID,
- PGNO_INVALID, 1, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
- ZERO_LSN(root->lsn);
-
- /* Release the metadata and root pages. */
- if ((ret = memp_fput(dbp->mpf, (PAGE *)meta, DB_MPOOL_DIRTY)) != 0)
- goto err;
- if ((ret = memp_fput(dbp->mpf, root, DB_MPOOL_DIRTY)) != 0)
- goto err;
-
- /*
- * Flush the metadata and root pages to disk -- since the user can't
- * transaction protect open, the pages have to exist during recovery.
- *
- * XXX
- * It's not useful to return not-yet-flushed here -- convert it to
- * an error.
- */
- if ((ret = memp_fsync(dbp->mpf)) == DB_INCOMPLETE)
- ret = EINVAL;
-
- /* Release the locks. */
- (void)__BT_LPUT(dbc, metalock);
- (void)__BT_LPUT(dbc, rootlock);
-
-err:
-done: if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
diff --git a/db2/btree/bt_page.c b/db2/btree/bt_page.c
deleted file mode 100644
index 6ccd68a..0000000
--- a/db2/btree/bt_page.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_page.c 10.17 (Sleepycat) 1/3/99";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_new --
- * Get a new page, preferably from the freelist.
- *
- * PUBLIC: int __bam_new __P((DBC *, u_int32_t, PAGE **));
- */
-int
-__bam_new(dbc, type, pagepp)
- DBC *dbc;
- u_int32_t type;
- PAGE **pagepp;
-{
- BTMETA *meta;
- DB *dbp;
- DB_LOCK metalock;
- PAGE *h;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
- meta = NULL;
- h = NULL;
- metalock = LOCK_INVALID;
-
- pgno = PGNO_METADATA;
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &metalock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, (PAGE **)&meta)) != 0)
- goto err;
-
- if (meta->free == PGNO_INVALID) {
- if ((ret = memp_fget(dbp->mpf, &pgno, DB_MPOOL_NEW, &h)) != 0)
- goto err;
- ZERO_LSN(h->lsn);
- h->pgno = pgno;
- } else {
- pgno = meta->free;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- goto err;
- meta->free = h->next_pgno;
- }
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- if ((ret = __bam_pg_alloc_log(dbp->dbenv->lg_info, dbc->txn,
- &meta->lsn, 0, dbp->log_fileid, &meta->lsn, &h->lsn,
- h->pgno, (u_int32_t)type, meta->free)) != 0)
- goto err;
- LSN(h) = LSN(meta);
- }
-
- (void)memp_fput(dbp->mpf, (PAGE *)meta, DB_MPOOL_DIRTY);
- (void)__BT_TLPUT(dbc, metalock);
-
- P_INIT(h, dbp->pgsize, h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type);
- *pagepp = h;
- return (0);
-
-err: if (h != NULL)
- (void)memp_fput(dbp->mpf, h, 0);
- if (meta != NULL)
- (void)memp_fput(dbp->mpf, meta, 0);
- if (metalock != LOCK_INVALID)
- (void)__BT_TLPUT(dbc, metalock);
- return (ret);
-}
-
-/*
- * __bam_lput --
- * The standard lock put call.
- *
- * PUBLIC: int __bam_lput __P((DBC *, DB_LOCK));
- */
-int
-__bam_lput(dbc, lock)
- DBC *dbc;
- DB_LOCK lock;
-{
- return (__BT_LPUT(dbc, lock));
-}
-
-/*
- * __bam_free --
- * Add a page to the head of the freelist.
- *
- * PUBLIC: int __bam_free __P((DBC *, PAGE *));
- */
-int
-__bam_free(dbc, h)
- DBC *dbc;
- PAGE *h;
-{
- BTMETA *meta;
- DB *dbp;
- DBT ldbt;
- DB_LOCK metalock;
- db_pgno_t pgno;
- u_int32_t dirty_flag;
- int ret, t_ret;
-
- dbp = dbc->dbp;
-
- /*
- * Retrieve the metadata page and insert the page at the head of
- * the free list. If either the lock get or page get routines
- * fail, then we need to put the page with which we were called
- * back because our caller assumes we take care of it.
- */
- dirty_flag = 0;
- pgno = PGNO_METADATA;
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_WRITE, &metalock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, (PAGE **)&meta)) != 0) {
- (void)__BT_TLPUT(dbc, metalock);
- goto err;
- }
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- memset(&ldbt, 0, sizeof(ldbt));
- ldbt.data = h;
- ldbt.size = P_OVERHEAD;
- if ((ret = __bam_pg_free_log(dbp->dbenv->lg_info,
- dbc->txn, &meta->lsn, 0, dbp->log_fileid, h->pgno,
- &meta->lsn, &ldbt, meta->free)) != 0) {
- (void)memp_fput(dbp->mpf, (PAGE *)meta, 0);
- (void)__BT_TLPUT(dbc, metalock);
- return (ret);
- }
- LSN(h) = LSN(meta);
- }
-
- /*
- * The page should have nothing interesting on it, re-initialize it,
- * leaving only the page number and the LSN.
- */
-#ifdef DIAGNOSTIC
- { db_pgno_t __pgno; DB_LSN __lsn;
- __pgno = h->pgno;
- __lsn = h->lsn;
- memset(h, 0xdb, dbp->pgsize);
- h->pgno = __pgno;
- h->lsn = __lsn;
- }
-#endif
- P_INIT(h, dbp->pgsize, h->pgno, PGNO_INVALID, meta->free, 0, P_INVALID);
-
- /* Link the page on the metadata free list. */
- meta->free = h->pgno;
-
- /* Discard the metadata page. */
- ret = memp_fput(dbp->mpf, (PAGE *)meta, DB_MPOOL_DIRTY);
- if ((t_ret = __BT_TLPUT(dbc, metalock)) != 0)
- ret = t_ret;
-
- /* Discard the caller's page reference. */
- dirty_flag = DB_MPOOL_DIRTY;
-err: if ((t_ret = memp_fput(dbp->mpf, h, dirty_flag)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * XXX
- * We have to unlock the caller's page in the caller!
- */
- return (ret);
-}
-
-#ifdef DEBUG
-/*
- * __bam_lt --
- * Print out the list of locks currently held by a cursor.
- *
- * PUBLIC: int __bam_lt __P((DBC *));
- */
-int
-__bam_lt(dbc)
- DBC *dbc;
-{
- DB *dbp;
- DB_LOCKREQ req;
-
- dbp = dbc->dbp;
- if (F_ISSET(dbp, DB_AM_LOCKING)) {
- req.op = DB_LOCK_DUMP;
- lock_vec(dbp->dbenv->lk_info, dbc->locker, 0, &req, 1, NULL);
- }
- return (0);
-}
-#endif
-
-/*
- * __bam_lget --
- * The standard lock get call.
- *
- * PUBLIC: int __bam_lget
- * PUBLIC: __P((DBC *, int, db_pgno_t, db_lockmode_t, DB_LOCK *));
- */
-int
-__bam_lget(dbc, do_couple, pgno, mode, lockp)
- DBC *dbc;
- int do_couple;
- db_pgno_t pgno;
- db_lockmode_t mode;
- DB_LOCK *lockp;
-{
- DB *dbp;
- DB_LOCKREQ couple[2];
- int ret;
-
- dbp = dbc->dbp;
-
- if (!F_ISSET(dbp, DB_AM_LOCKING)) {
- *lockp = LOCK_INVALID;
- return (0);
- }
-
- dbc->lock.pgno = pgno;
-
- /*
- * If the object not currently locked, acquire the lock and return,
- * otherwise, lock couple. If we fail and it's not a system error,
- * convert to EAGAIN.
- */
- if (do_couple) {
- couple[0].op = DB_LOCK_GET;
- couple[0].obj = &dbc->lock_dbt;
- couple[0].mode = mode;
- couple[1].op = DB_LOCK_PUT;
- couple[1].lock = *lockp;
-
- if (dbc->txn == NULL)
- ret = lock_vec(dbp->dbenv->lk_info,
- dbc->locker, 0, couple, 2, NULL);
- else
- ret = lock_tvec(dbp->dbenv->lk_info,
- dbc->txn, 0, couple, 2, NULL);
- if (ret != 0) {
- /* If we fail, discard the lock we held. */
- __BT_LPUT(dbc, *lockp);
-
- return (ret < 0 ? EAGAIN : ret);
- }
- *lockp = couple[0].lock;
- } else {
- if (dbc->txn == NULL)
- ret = lock_get(dbp->dbenv->lk_info,
- dbc->locker, 0, &dbc->lock_dbt, mode, lockp);
- else
- ret = lock_tget(dbp->dbenv->lk_info,
- dbc->txn, 0, &dbc->lock_dbt, mode, lockp);
- return (ret < 0 ? EAGAIN : ret);
- }
- return (0);
-}
diff --git a/db2/btree/bt_put.c b/db2/btree/bt_put.c
deleted file mode 100644
index 0d7a698..0000000
--- a/db2/btree/bt_put.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_put.c 10.54 (Sleepycat) 12/6/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-static int __bam_fixed __P((DBC *, DBT *));
-static int __bam_ndup __P((DBC *, PAGE *, u_int32_t));
-static int __bam_ovput __P((DBC *, PAGE *, u_int32_t, DBT *));
-static int __bam_partial __P((DBC *,
- DBT *, PAGE *, u_int32_t, u_int32_t, u_int32_t));
-static u_int32_t __bam_partsize __P((DBT *, PAGE *, u_int32_t));
-
-/*
- * __bam_iitem --
- * Insert an item into the tree.
- *
- * PUBLIC: int __bam_iitem __P((DBC *,
- * PUBLIC: PAGE **, db_indx_t *, DBT *, DBT *, u_int32_t, u_int32_t));
- */
-int
-__bam_iitem(dbc, hp, indxp, key, data, op, flags)
- DBC *dbc;
- PAGE **hp;
- db_indx_t *indxp;
- DBT *key, *data;
- u_int32_t op, flags;
-{
- BTREE *t;
- BKEYDATA *bk;
- DB *dbp;
- DBT tdbt;
- PAGE *h;
- db_indx_t indx, nbytes;
- u_int32_t data_size, have_bytes, need_bytes, needed;
- int bigkey, bigdata, dupadjust, replace, ret;
-
- COMPQUIET(bk, NULL);
-
- dbp = dbc->dbp;
- t = dbp->internal;
- h = *hp;
- indx = *indxp;
- dupadjust = replace = 0;
-
- /*
- * If it's a page of duplicates, call the common code to do the work.
- *
- * !!!
- * Here's where the hp and indxp are important. The duplicate code
- * may decide to rework/rearrange the pages and indices we're using,
- * so the caller must understand that the page stack may change.
- */
- if (TYPE(h) == P_DUPLICATE) {
- /* Adjust the index for the new item if it's a DB_AFTER op. */
- if (op == DB_AFTER)
- ++*indxp;
-
- /* Remove the current item if it's a DB_CURRENT op. */
- if (op == DB_CURRENT) {
- bk = GET_BKEYDATA(*hp, *indxp);
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- nbytes = BKEYDATA_SIZE(bk->len);
- break;
- case B_OVERFLOW:
- nbytes = BOVERFLOW_SIZE;
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
- if ((ret = __db_ditem(dbc, *hp, *indxp, nbytes)) != 0)
- return (ret);
- }
-
- /* Put the new/replacement item onto the page. */
- if ((ret = __db_dput(dbc, data, hp, indxp, __bam_new)) != 0)
- return (ret);
-
- goto done;
- }
-
- /* Handle fixed-length records: build the real record. */
- if (F_ISSET(dbp, DB_RE_FIXEDLEN) && data->size != t->recno->re_len) {
- tdbt = *data;
- if ((ret = __bam_fixed(dbc, &tdbt)) != 0)
- return (ret);
- data = &tdbt;
- }
-
- /*
- * Figure out how much space the data will take, including if it's a
- * partial record. If either of the key or data items won't fit on
- * a page, we'll have to store them on overflow pages.
- */
- bigkey = LF_ISSET(BI_NEWKEY) && key->size > t->bt_ovflsize;
- data_size = F_ISSET(data, DB_DBT_PARTIAL) ?
- __bam_partsize(data, h, indx) : data->size;
- bigdata = data_size > t->bt_ovflsize;
-
- needed = 0;
- if (LF_ISSET(BI_NEWKEY)) {
- /* If BI_NEWKEY is set we're adding a new key and data pair. */
- if (bigkey)
- needed += BOVERFLOW_PSIZE;
- else
- needed += BKEYDATA_PSIZE(key->size);
- if (bigdata)
- needed += BOVERFLOW_PSIZE;
- else
- needed += BKEYDATA_PSIZE(data_size);
- } else {
- /*
- * We're either overwriting the data item of a key/data pair
- * or we're adding the data item only, i.e. a new duplicate.
- */
- if (op == DB_CURRENT) {
- bk = GET_BKEYDATA(h,
- indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
- if (B_TYPE(bk->type) == B_KEYDATA)
- have_bytes = BKEYDATA_PSIZE(bk->len);
- else
- have_bytes = BOVERFLOW_PSIZE;
- need_bytes = 0;
- } else {
- have_bytes = 0;
- need_bytes = sizeof(db_indx_t);
- }
- if (bigdata)
- need_bytes += BOVERFLOW_PSIZE;
- else
- need_bytes += BKEYDATA_PSIZE(data_size);
-
- if (have_bytes < need_bytes)
- needed += need_bytes - have_bytes;
- }
-
- /*
- * If there's not enough room, or the user has put a ceiling on the
- * number of keys permitted in the page, split the page.
- *
- * XXX
- * The t->bt_maxkey test here may be insufficient -- do we have to
- * check in the btree split code, so we don't undo it there!?!?
- */
- if (P_FREESPACE(h) < needed ||
- (t->bt_maxkey != 0 && NUM_ENT(h) > t->bt_maxkey))
- return (DB_NEEDSPLIT);
-
- /* Handle partial puts: build the real record. */
- if (F_ISSET(data, DB_DBT_PARTIAL)) {
- tdbt = *data;
- if ((ret = __bam_partial(dbc,
- &tdbt, h, indx, data_size, flags)) != 0)
- return (ret);
- data = &tdbt;
- }
-
- /*
- * The code breaks it up into six cases:
- *
- * 1. Append a new key/data pair.
- * 2. Insert a new key/data pair.
- * 3. Append a new data item (a new duplicate).
- * 4. Insert a new data item (a new duplicate).
- * 5. Overflow item: delete and re-add the data item.
- * 6. Replace the data item.
- */
- if (LF_ISSET(BI_NEWKEY)) {
- switch (op) {
- case DB_AFTER: /* 1. Append a new key/data pair. */
- indx += 2;
- *indxp += 2;
- break;
- case DB_BEFORE: /* 2. Insert a new key/data pair. */
- break;
- default:
- return (EINVAL);
- }
-
- /* Add the key. */
- if (bigkey) {
- if ((ret = __bam_ovput(dbc, h, indx, key)) != 0)
- return (ret);
- } else
- if ((ret = __db_pitem(dbc, h, indx,
- BKEYDATA_SIZE(key->size), NULL, key)) != 0)
- return (ret);
- ++indx;
- } else {
- switch (op) {
- case DB_AFTER: /* 3. Append a new data item. */
- if (TYPE(h) == P_LBTREE) {
- /*
- * Adjust the cursor and copy in the key for
- * the duplicate.
- */
- if ((ret = __bam_adjindx(dbc,
- h, indx + P_INDX, indx, 1)) != 0)
- return (ret);
-
- indx += 3;
- dupadjust = 1;
-
- *indxp += 2;
- } else {
- ++indx;
- __bam_ca_di(dbp, h->pgno, indx, 1);
-
- *indxp += 1;
- }
- break;
- case DB_BEFORE: /* 4. Insert a new data item. */
- if (TYPE(h) == P_LBTREE) {
- /*
- * Adjust the cursor and copy in the key for
- * the duplicate.
- */
- if ((ret =
- __bam_adjindx(dbc, h, indx, indx, 1)) != 0)
- return (ret);
-
- ++indx;
- dupadjust = 1;
- } else
- __bam_ca_di(dbp, h->pgno, indx, 1);
- break;
- case DB_CURRENT:
- if (TYPE(h) == P_LBTREE)
- ++indx;
-
- /*
- * 5. Delete/re-add the data item.
- *
- * If we're dealing with offpage items, we have to
- * delete and then re-add the item.
- */
- if (bigdata || B_TYPE(bk->type) != B_KEYDATA) {
- if ((ret = __bam_ditem(dbc, h, indx)) != 0)
- return (ret);
- break;
- }
-
- /* 6. Replace the data item. */
- replace = 1;
- break;
- default:
- return (EINVAL);
- }
- }
-
- /* Add the data. */
- if (bigdata) {
- if ((ret = __bam_ovput(dbc, h, indx, data)) != 0)
- return (ret);
- } else {
- BKEYDATA __bk;
- DBT __hdr;
-
- if (LF_ISSET(BI_DELETED)) {
- B_TSET(__bk.type, B_KEYDATA, 1);
- __bk.len = data->size;
- __hdr.data = &__bk;
- __hdr.size = SSZA(BKEYDATA, data);
- ret = __db_pitem(dbc, h, indx,
- BKEYDATA_SIZE(data->size), &__hdr, data);
- } else if (replace)
- ret = __bam_ritem(dbc, h, indx, data);
- else
- ret = __db_pitem(dbc, h, indx,
- BKEYDATA_SIZE(data->size), NULL, data);
- if (ret != 0)
- return (ret);
- }
-
- if ((ret = memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY)) != 0)
- return (ret);
-
- /*
- * If the page is at least 50% full, and we added a duplicate, see if
- * that set of duplicates takes up at least 25% of the space. If it
- * does, move it off onto its own page.
- */
- if (dupadjust && P_FREESPACE(h) <= dbp->pgsize / 2) {
- --indx;
- if ((ret = __bam_ndup(dbc, h, indx)) != 0)
- return (ret);
- }
-
- /*
- * If we've changed the record count, update the tree. Record counts
- * need to be updated in recno databases and in btree databases where
- * we are supporting records. In both cases, adjust the count if the
- * operation wasn't performed on the current record or when the caller
- * overrides and wants the adjustment made regardless.
- */
-done: if (LF_ISSET(BI_DOINCR) ||
- (op != DB_CURRENT &&
- (F_ISSET(dbp, DB_BT_RECNUM) || dbp->type == DB_RECNO)))
- if ((ret = __bam_adjust(dbc, 1)) != 0)
- return (ret);
-
- /* If we've modified a recno file, set the flag */
- if (t->recno != NULL)
- F_SET(t->recno, RECNO_MODIFIED);
-
- return (ret);
-}
-
-/*
- * __bam_partsize --
- * Figure out how much space a partial data item is in total.
- */
-static u_int32_t
-__bam_partsize(data, h, indx)
- DBT *data;
- PAGE *h;
- u_int32_t indx;
-{
- BKEYDATA *bk;
- u_int32_t nbytes;
-
- /*
- * Figure out how much total space we'll need. If the record doesn't
- * already exist, it's simply the data we're provided.
- */
- if (indx >= NUM_ENT(h))
- return (data->doff + data->size);
-
- /*
- * Otherwise, it's the data provided plus any already existing data
- * that we're not replacing.
- */
- bk = GET_BKEYDATA(h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
- nbytes =
- B_TYPE(bk->type) == B_OVERFLOW ? ((BOVERFLOW *)bk)->tlen : bk->len;
-
- /*
- * There are really two cases here:
- *
- * Case 1: We are replacing some bytes that do not exist (i.e., they
- * are past the end of the record). In this case the number of bytes
- * we are replacing is irrelevant and all we care about is how many
- * bytes we are going to add from offset. So, the new record length
- * is going to be the size of the new bytes (size) plus wherever those
- * new bytes begin (doff).
- *
- * Case 2: All the bytes we are replacing exist. Therefore, the new
- * size is the oldsize (nbytes) minus the bytes we are replacing (dlen)
- * plus the bytes we are adding (size).
- */
- if (nbytes < data->doff + data->dlen) /* Case 1 */
- return (data->doff + data->size);
-
- return (nbytes + data->size - data->dlen); /* Case 2 */
-}
-
-/*
- * OVPUT --
- * Copy an overflow item onto a page.
- */
-#undef OVPUT
-#define OVPUT(h, indx, bo) do { \
- DBT __hdr; \
- memset(&__hdr, 0, sizeof(__hdr)); \
- __hdr.data = &bo; \
- __hdr.size = BOVERFLOW_SIZE; \
- if ((ret = __db_pitem(dbc, \
- h, indx, BOVERFLOW_SIZE, &__hdr, NULL)) != 0) \
- return (ret); \
-} while (0)
-
-/*
- * __bam_ovput --
- * Build an overflow item and put it on the page.
- */
-static int
-__bam_ovput(dbc, h, indx, item)
- DBC *dbc;
- PAGE *h;
- u_int32_t indx;
- DBT *item;
-{
- BOVERFLOW bo;
- int ret;
-
- UMRW(bo.unused1);
- B_TSET(bo.type, B_OVERFLOW, 0);
- UMRW(bo.unused2);
- if ((ret = __db_poff(dbc, item, &bo.pgno, __bam_new)) != 0)
- return (ret);
- bo.tlen = item->size;
-
- OVPUT(h, indx, bo);
-
- return (0);
-}
-
-/*
- * __bam_ritem --
- * Replace an item on a page.
- *
- * PUBLIC: int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *));
- */
-int
-__bam_ritem(dbc, h, indx, data)
- DBC *dbc;
- PAGE *h;
- u_int32_t indx;
- DBT *data;
-{
- BKEYDATA *bk;
- DB *dbp;
- DBT orig, repl;
- db_indx_t cnt, lo, ln, min, off, prefix, suffix;
- int32_t nbytes;
- int ret;
- u_int8_t *p, *t;
-
- dbp = dbc->dbp;
-
- /*
- * Replace a single item onto a page. The logic figuring out where
- * to insert and whether it fits is handled in the caller. All we do
- * here is manage the page shuffling.
- */
- bk = GET_BKEYDATA(h, indx);
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- /*
- * We might as well check to see if the two data items share
- * a common prefix and suffix -- it can save us a lot of log
- * message if they're large.
- */
- min = data->size < bk->len ? data->size : bk->len;
- for (prefix = 0,
- p = bk->data, t = data->data;
- prefix < min && *p == *t; ++prefix, ++p, ++t)
- ;
-
- min -= prefix;
- for (suffix = 0,
- p = (u_int8_t *)bk->data + bk->len - 1,
- t = (u_int8_t *)data->data + data->size - 1;
- suffix < min && *p == *t; ++suffix, --p, --t)
- ;
-
- /* We only log the parts of the keys that have changed. */
- orig.data = (u_int8_t *)bk->data + prefix;
- orig.size = bk->len - (prefix + suffix);
- repl.data = (u_int8_t *)data->data + prefix;
- repl.size = data->size - (prefix + suffix);
- if ((ret = __bam_repl_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(h), 0, dbp->log_fileid, PGNO(h), &LSN(h),
- (u_int32_t)indx, (u_int32_t)B_DISSET(bk->type),
- &orig, &repl, (u_int32_t)prefix, (u_int32_t)suffix)) != 0)
- return (ret);
- }
-
- /*
- * Set references to the first in-use byte on the page and the
- * first byte of the item being replaced.
- */
- p = (u_int8_t *)h + HOFFSET(h);
- t = (u_int8_t *)bk;
-
- /*
- * If the entry is growing in size, shift the beginning of the data
- * part of the page down. If the entry is shrinking in size, shift
- * the beginning of the data part of the page up. Use memmove(3),
- * the regions overlap.
- */
- lo = BKEYDATA_SIZE(bk->len);
- ln = BKEYDATA_SIZE(data->size);
- if (lo != ln) {
- nbytes = lo - ln; /* Signed difference. */
- if (p == t) /* First index is fast. */
- h->inp[indx] += nbytes;
- else { /* Else, shift the page. */
- memmove(p + nbytes, p, t - p);
-
- /* Adjust the indices' offsets. */
- off = h->inp[indx];
- for (cnt = 0; cnt < NUM_ENT(h); ++cnt)
- if (h->inp[cnt] <= off)
- h->inp[cnt] += nbytes;
- }
-
- /* Clean up the page and adjust the item's reference. */
- HOFFSET(h) += nbytes;
- t += nbytes;
- }
-
- /* Copy the new item onto the page. */
- bk = (BKEYDATA *)t;
- B_TSET(bk->type, B_KEYDATA, 0);
- bk->len = data->size;
- memcpy(bk->data, data->data, data->size);
-
- return (0);
-}
-
-/*
- * __bam_ndup --
- * Check to see if the duplicate set at indx should have its own page.
- * If it should, create it.
- */
-static int
-__bam_ndup(dbc, h, indx)
- DBC *dbc;
- PAGE *h;
- u_int32_t indx;
-{
- BKEYDATA *bk;
- BOVERFLOW bo;
- DB *dbp;
- DBT hdr;
- PAGE *cp;
- db_indx_t cnt, cpindx, first, sz;
- int ret;
-
- dbp = dbc->dbp;
-
- while (indx > 0 && h->inp[indx] == h->inp[indx - P_INDX])
- indx -= P_INDX;
- for (cnt = 0, sz = 0, first = indx;; ++cnt, indx += P_INDX) {
- if (indx >= NUM_ENT(h) || h->inp[first] != h->inp[indx])
- break;
- bk = GET_BKEYDATA(h, indx);
- sz += B_TYPE(bk->type) == B_KEYDATA ?
- BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
- bk = GET_BKEYDATA(h, indx + O_INDX);
- sz += B_TYPE(bk->type) == B_KEYDATA ?
- BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
- }
-
- /*
- * If this set of duplicates is using more than 25% of the page, move
- * them off. The choice of 25% is a WAG, but it has to be small enough
- * that we can always split regardless of the presence of duplicates.
- */
- if (sz < dbp->pgsize / 4)
- return (0);
-
- /* Get a new page. */
- if ((ret = __bam_new(dbc, P_DUPLICATE, &cp)) != 0)
- return (ret);
-
- /*
- * Move this set of duplicates off the page. First points to the first
- * key of the first duplicate key/data pair, cnt is the number of pairs
- * we're dealing with.
- */
- memset(&hdr, 0, sizeof(hdr));
- for (indx = first + O_INDX, cpindx = 0;; ++cpindx) {
- /* Copy the entry to the new page. */
- bk = GET_BKEYDATA(h, indx);
- hdr.data = bk;
- hdr.size = B_TYPE(bk->type) == B_KEYDATA ?
- BKEYDATA_SIZE(bk->len) : BOVERFLOW_SIZE;
- if ((ret =
- __db_pitem(dbc, cp, cpindx, hdr.size, &hdr, NULL)) != 0)
- goto err;
-
- /*
- * Move cursors referencing the old entry to the new entry.
- * Done after the page put because __db_pitem() adjusts
- * cursors on the new page, and before the delete because
- * __db_ditem adjusts cursors on the old page.
- */
- __bam_ca_dup(dbp,
- PGNO(h), first, indx - O_INDX, PGNO(cp), cpindx);
-
- /* Delete the data item. */
- if ((ret = __db_ditem(dbc, h, indx, hdr.size)) != 0)
- goto err;
-
- /* Delete all but the first reference to the key. */
- if (--cnt == 0)
- break;
- if ((ret = __bam_adjindx(dbc, h, indx, first, 0)) != 0)
- goto err;
- }
-
- /* Put in a new data item that points to the duplicates page. */
- UMRW(bo.unused1);
- B_TSET(bo.type, B_DUPLICATE, 0);
- UMRW(bo.unused2);
- bo.pgno = cp->pgno;
- bo.tlen = 0;
-
- OVPUT(h, indx, bo);
-
- return (memp_fput(dbp->mpf, cp, DB_MPOOL_DIRTY));
-
-err: (void)__bam_free(dbc, cp);
- return (ret);
-}
-
-/*
- * __bam_fixed --
- * Build the real record for a fixed length put.
- */
-static int
-__bam_fixed(dbc, dbt)
- DBC *dbc;
- DBT *dbt;
-{
- DB *dbp;
- RECNO *rp;
- int ret;
-
- dbp = dbc->dbp;
- rp = ((BTREE *)dbp->internal)->recno;
-
- /*
- * If database contains fixed-length records, and the record is long,
- * return EINVAL.
- */
- if (dbt->size > rp->re_len)
- return (EINVAL);
-
- /*
- * The caller checked to see if it was just right, so we know it's
- * short. Pad it out. We use the record data return memory, it's
- * only a short-term use.
- */
- if (dbc->rdata.ulen < rp->re_len) {
- if ((ret = __os_realloc(&dbc->rdata.data, rp->re_len)) != 0) {
- dbc->rdata.ulen = 0;
- dbc->rdata.data = NULL;
- return (ret);
- }
- dbc->rdata.ulen = rp->re_len;
- }
- memcpy(dbc->rdata.data, dbt->data, dbt->size);
- memset((u_int8_t *)dbc->rdata.data + dbt->size,
- rp->re_pad, rp->re_len - dbt->size);
-
- /*
- * Clean up our flags and other information just in case, and
- * change the caller's DBT to reference our created record.
- */
- dbc->rdata.size = rp->re_len;
- dbc->rdata.dlen = 0;
- dbc->rdata.doff = 0;
- dbc->rdata.flags = 0;
- *dbt = dbc->rdata;
-
- return (0);
-}
-
-/*
- * __bam_partial --
- * Build the real record for a partial put.
- */
-static int
-__bam_partial(dbc, dbt, h, indx, nbytes, flags)
- DBC *dbc;
- DBT *dbt;
- PAGE *h;
- u_int32_t indx, nbytes, flags;
-{
- BKEYDATA *bk, tbk;
- BOVERFLOW *bo;
- DB *dbp;
- DBT copy;
- u_int32_t len, tlen;
- u_int8_t *p;
- int ret;
-
- COMPQUIET(bo, NULL);
-
- dbp = dbc->dbp;
-
- /* We use the record data return memory, it's only a short-term use. */
- if (dbc->rdata.ulen < nbytes) {
- if ((ret = __os_realloc(&dbc->rdata.data, nbytes)) != 0) {
- dbc->rdata.ulen = 0;
- dbc->rdata.data = NULL;
- return (ret);
- }
- dbc->rdata.ulen = nbytes;
- }
-
- /*
- * We use nul bytes for any part of the record that isn't specified;
- * get it over with.
- */
- memset(dbc->rdata.data, 0, nbytes);
-
- /*
- * In the next clauses, we need to do three things: a) set p to point
- * to the place at which to copy the user's data, b) set tlen to the
- * total length of the record, not including the bytes contributed by
- * the user, and c) copy any valid data from an existing record.
- */
- if (LF_ISSET(BI_NEWKEY)) {
- tlen = dbt->doff;
- p = (u_int8_t *)dbc->rdata.data + dbt->doff;
- goto ucopy;
- }
-
- /* Find the current record. */
- if (indx < NUM_ENT(h)) {
- bk = GET_BKEYDATA(h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
- bo = (BOVERFLOW *)bk;
- } else {
- bk = &tbk;
- B_TSET(bk->type, B_KEYDATA, 0);
- bk->len = 0;
- }
- if (B_TYPE(bk->type) == B_OVERFLOW) {
- /*
- * In the case of an overflow record, we shift things around
- * in the current record rather than allocate a separate copy.
- */
- memset(&copy, 0, sizeof(copy));
- if ((ret = __db_goff(dbp, &copy, bo->tlen,
- bo->pgno, &dbc->rdata.data, &dbc->rdata.ulen)) != 0)
- return (ret);
-
- /* Skip any leading data from the original record. */
- tlen = dbt->doff;
- p = (u_int8_t *)dbc->rdata.data + dbt->doff;
-
- /*
- * Copy in any trailing data from the original record.
- *
- * If the original record was larger than the original offset
- * plus the bytes being deleted, there is trailing data in the
- * original record we need to preserve. If we aren't deleting
- * the same number of bytes as we're inserting, copy it up or
- * down, into place.
- *
- * Use memmove(), the regions may overlap.
- */
- if (bo->tlen > dbt->doff + dbt->dlen) {
- len = bo->tlen - (dbt->doff + dbt->dlen);
- if (dbt->dlen != dbt->size)
- memmove(p + dbt->size, p + dbt->dlen, len);
- tlen += len;
- }
- } else {
- /* Copy in any leading data from the original record. */
- memcpy(dbc->rdata.data,
- bk->data, dbt->doff > bk->len ? bk->len : dbt->doff);
- tlen = dbt->doff;
- p = (u_int8_t *)dbc->rdata.data + dbt->doff;
-
- /* Copy in any trailing data from the original record. */
- len = dbt->doff + dbt->dlen;
- if (bk->len > len) {
- memcpy(p + dbt->size, bk->data + len, bk->len - len);
- tlen += bk->len - len;
- }
- }
-
-ucopy: /*
- * Copy in the application provided data -- p and tlen must have been
- * initialized above.
- */
- memcpy(p, dbt->data, dbt->size);
- tlen += dbt->size;
-
- /* Set the DBT to reference our new record. */
- dbc->rdata.size = tlen;
- dbc->rdata.dlen = 0;
- dbc->rdata.doff = 0;
- dbc->rdata.flags = 0;
- *dbt = dbc->rdata;
- return (0);
-}
diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c
deleted file mode 100644
index de6b3b7..0000000
--- a/db2/btree/bt_rec.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_rec.c 10.28 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "shqueue.h"
-#include "hash.h"
-#include "btree.h"
-#include "log.h"
-#include "common_ext.h"
-
-/*
- * __bam_pg_alloc_recover --
- * Recovery function for pg_alloc.
- *
- * PUBLIC: int __bam_pg_alloc_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_pg_alloc_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_pg_alloc_args *argp;
- BTMETA *meta;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- DB *file_dbp;
- DBC *dbc;
- db_pgno_t pgno;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_pg_alloc_print);
- REC_INTRO(__bam_pg_alloc_read);
-
- /*
- * Fix up the allocated page. If we're redoing the operation, we have
- * to get the page (creating it if it doesn't exist), and update its
- * LSN. If we're undoing the operation, we have to reset the page's
- * LSN and put it on the free list.
- *
- * Fix up the metadata page. If we're redoing the operation, we have
- * to get the metadata page and update its LSN and its free pointer.
- * If we're undoing the operation and the page was ever created, we put
- * it on the freelist.
- */
- pgno = PGNO_METADATA;
- if ((ret = memp_fget(mpf, &pgno, 0, &meta)) != 0) {
- /* The metadata page must always exist. */
- (void)__db_pgerr(file_dbp, pgno);
- goto out;
- }
- if ((ret = memp_fget(mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
- /*
- * We specify creation and check for it later, because this
- * operation was supposed to create the page, and even in
- * the undo case it's going to get linked onto the freelist
- * which we're also fixing up.
- */
- (void)__db_pgerr(file_dbp, argp->pgno);
- (void)memp_fput(mpf, meta, 0);
- goto out;
- }
-
- /* Fix up the allocated page. */
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->page_lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, PGNO_INVALID, 0, argp->ptype);
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, meta->free, 0, P_INVALID);
-
- pagep->lsn = argp->page_lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) {
- (void)memp_fput(mpf, meta, 0);
- goto out;
- }
-
- /* Fix up the metadata page. */
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(meta));
- cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- meta->lsn = *lsnp;
- meta->free = argp->next;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- meta->lsn = argp->meta_lsn;
- meta->free = argp->pgno;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __bam_pg_free_recover --
- * Recovery function for pg_free.
- *
- * PUBLIC: int __bam_pg_free_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_pg_free_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_pg_free_args *argp;
- BTMETA *meta;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_pg_free_print);
- REC_INTRO(__bam_pg_free_read);
-
- /*
- * Fix up the freed page. If we're redoing the operation we get the
- * page and explicitly discard its contents, then update its LSN. If
- * we're undoing the operation, we get the page and restore its header.
- */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- /*
- * We don't automatically create the page. The only way the
- * page might not exist is if the alloc never happened, and
- * the only way the alloc might never have happened is if we
- * are undoing, in which case there's no reason to create the
- * page.
- */
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &LSN(argp->header.data));
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- P_INIT(pagep, file_dbp->pgsize,
- pagep->pgno, PGNO_INVALID, argp->next, 0, P_INVALID);
- pagep->lsn = *lsnp;
-
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- memcpy(pagep, argp->header.data, argp->header.size);
-
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
- /*
- * Fix up the metadata page. If we're redoing or undoing the operation
- * we get the page and update its LSN and free pointer.
- */
- pgno = PGNO_METADATA;
- if ((ret = memp_fget(mpf, &pgno, 0, &meta)) != 0) {
- /* The metadata page must always exist. */
- (void)__db_pgerr(file_dbp, pgno);
- goto out;
- }
-
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(meta));
- cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- meta->free = argp->pgno;
-
- meta->lsn = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- meta->free = argp->next;
-
- meta->lsn = argp->meta_lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __bam_split_recover --
- * Recovery function for split.
- *
- * PUBLIC: int __bam_split_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_split_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_split_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp;
- db_pgno_t pgno;
- int l_update, p_update, r_update, ret, rootsplit, t_ret;
-
- REC_PRINT(__bam_split_print);
-
- mpf = NULL;
- _lp = lp = np = pp = _rp = rp = NULL;
-
- REC_INTRO(__bam_split_read);
-
- /*
- * There are two kinds of splits that we have to recover from. The
- * first is a root-page split, where the root page is split from a
- * leaf page into an internal page and two new leaf pages are created.
- * The second is where a page is split into two pages, and a new key
- * is inserted into the parent page.
- */
- sp = argp->pg.data;
- pgno = PGNO(sp);
- rootsplit = pgno == PGNO_ROOT;
- if (memp_fget(mpf, &argp->left, 0, &lp) != 0)
- lp = NULL;
- if (memp_fget(mpf, &argp->right, 0, &rp) != 0)
- rp = NULL;
-
- if (redo) {
- l_update = r_update = p_update = 0;
- /*
- * Decide if we need to resplit the page.
- *
- * If this is a root split, then the root has to exist, it's
- * the page we're splitting and it gets modified. If this is
- * not a root split, then the left page has to exist, for the
- * same reason.
- */
- if (rootsplit) {
- if ((ret = memp_fget(mpf, &pgno, 0, &pp)) != 0) {
- (void)__db_pgerr(file_dbp, pgno);
- pp = NULL;
- goto out;
- }
- p_update =
- log_compare(&LSN(pp), &LSN(argp->pg.data)) == 0;
- } else
- if (lp == NULL) {
- (void)__db_pgerr(file_dbp, argp->left);
- goto out;
- }
- if (lp == NULL || log_compare(&LSN(lp), &argp->llsn) == 0)
- l_update = 1;
- if (rp == NULL || log_compare(&LSN(rp), &argp->rlsn) == 0)
- r_update = 1;
- if (!p_update && !l_update && !r_update)
- goto done;
-
- /* Allocate and initialize new left/right child pages. */
- if ((ret = __os_malloc(file_dbp->pgsize, NULL, &_lp)) != 0 ||
- (ret = __os_malloc(file_dbp->pgsize, NULL, &_rp)) != 0)
- goto out;
- if (rootsplit) {
- P_INIT(_lp, file_dbp->pgsize, argp->left,
- PGNO_INVALID,
- ISINTERNAL(sp) ? PGNO_INVALID : argp->right,
- LEVEL(sp), TYPE(sp));
- P_INIT(_rp, file_dbp->pgsize, argp->right,
- ISINTERNAL(sp) ? PGNO_INVALID : argp->left,
- PGNO_INVALID, LEVEL(sp), TYPE(sp));
- } else {
- P_INIT(_lp, file_dbp->pgsize, PGNO(sp),
- ISINTERNAL(sp) ? PGNO_INVALID : PREV_PGNO(sp),
- ISINTERNAL(sp) ? PGNO_INVALID : argp->right,
- LEVEL(sp), TYPE(sp));
- P_INIT(_rp, file_dbp->pgsize, argp->right,
- ISINTERNAL(sp) ? PGNO_INVALID : sp->pgno,
- ISINTERNAL(sp) ? PGNO_INVALID : NEXT_PGNO(sp),
- LEVEL(sp), TYPE(sp));
- }
-
- /* Split the page. */
- if ((ret = __bam_copy(file_dbp, sp, _lp, 0, argp->indx)) != 0 ||
- (ret = __bam_copy(file_dbp, sp, _rp, argp->indx,
- NUM_ENT(sp))) != 0)
- goto out;
-
- /* If the left child is wrong, update it. */
- if (lp == NULL && (ret =
- memp_fget(mpf, &argp->left, DB_MPOOL_CREATE, &lp)) != 0) {
- (void)__db_pgerr(file_dbp, argp->left);
- lp = NULL;
- goto out;
- }
- if (l_update) {
- memcpy(lp, _lp, file_dbp->pgsize);
- lp->lsn = *lsnp;
- if ((ret = memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- lp = NULL;
- }
-
- /* If the right child is wrong, update it. */
- if (rp == NULL && (ret = memp_fget(mpf,
- &argp->right, DB_MPOOL_CREATE, &rp)) != 0) {
- (void)__db_pgerr(file_dbp, argp->right);
- rp = NULL;
- goto out;
- }
- if (r_update) {
- memcpy(rp, _rp, file_dbp->pgsize);
- rp->lsn = *lsnp;
- if ((ret = memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- rp = NULL;
- }
-
- /*
- * If the parent page is wrong, update it. This is of interest
- * only if it was a root split, since root splits create parent
- * pages. All other splits modify a parent page, but those are
- * separately logged and recovered.
- */
- if (rootsplit && p_update) {
- if (file_dbp->type == DB_BTREE)
- P_INIT(pp, file_dbp->pgsize,
- PGNO_ROOT, PGNO_INVALID, PGNO_INVALID,
- _lp->level + 1, P_IBTREE);
- else
- P_INIT(pp, file_dbp->pgsize,
- PGNO_ROOT, PGNO_INVALID, PGNO_INVALID,
- _lp->level + 1, P_IRECNO);
- RE_NREC_SET(pp,
- file_dbp->type == DB_RECNO ||
- F_ISSET(file_dbp, DB_BT_RECNUM) ?
- __bam_total(_lp) + __bam_total(_rp) : 0);
- pp->lsn = *lsnp;
- if ((ret = memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- pp = NULL;
- }
-
- /*
- * Finally, redo the next-page link if necessary. This is of
- * interest only if it wasn't a root split -- inserting a new
- * page in the tree requires that any following page have its
- * previous-page pointer updated to our new page. The next
- * page must exist because we're redoing the operation.
- */
- if (!rootsplit && !IS_ZERO_LSN(argp->nlsn)) {
- if ((ret = memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
- (void)__db_pgerr(file_dbp, argp->npgno);
- np = NULL;
- goto out;
- }
- if (log_compare(&LSN(np), &argp->nlsn) == 0) {
- PREV_PGNO(np) = argp->right;
- np->lsn = *lsnp;
- if ((ret =
- memp_fput(mpf, np, DB_MPOOL_DIRTY)) != 0)
- goto out;
- np = NULL;
- }
- }
- } else {
- /*
- * If the split page is wrong, replace its contents with the
- * logged page contents. If the page doesn't exist, it means
- * that the create of the page never happened, nor did any of
- * the adds onto the page that caused the split, and there's
- * really no undo-ing to be done.
- */
- if ((ret = memp_fget(mpf, &pgno, 0, &pp)) != 0) {
- pp = NULL;
- goto lrundo;
- }
- if (log_compare(lsnp, &LSN(pp)) == 0) {
- memcpy(pp, argp->pg.data, argp->pg.size);
- if ((ret = memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- pp = NULL;
- }
-
- /*
- * If it's a root split and the left child ever existed, update
- * its LSN. (If it's not a root split, we've updated the left
- * page already -- it's the same as the split page.) If the
- * right child ever existed, root split or not, update its LSN.
- * The undo of the page allocation(s) will restore them to the
- * free list.
- */
-lrundo: if ((rootsplit && lp != NULL) || rp != NULL) {
- if (rootsplit && lp != NULL &&
- log_compare(lsnp, &LSN(lp)) == 0) {
- lp->lsn = argp->llsn;
- if ((ret =
- memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- lp = NULL;
- }
- if (rp != NULL &&
- log_compare(lsnp, &LSN(rp)) == 0) {
- rp->lsn = argp->rlsn;
- if ((ret =
- memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0)
- goto out;
- rp = NULL;
- }
- }
-
- /*
- * Finally, undo the next-page link if necessary. This is of
- * interest only if it wasn't a root split -- inserting a new
- * page in the tree requires that any following page have its
- * previous-page pointer updated to our new page. Since it's
- * possible that the next-page never existed, we ignore it as
- * if there's nothing to undo.
- */
- if (!rootsplit && !IS_ZERO_LSN(argp->nlsn)) {
- if ((ret = memp_fget(mpf, &argp->npgno, 0, &np)) != 0) {
- np = NULL;
- goto done;
- }
- if (log_compare(lsnp, &LSN(np)) == 0) {
- PREV_PGNO(np) = argp->left;
- np->lsn = argp->nlsn;
- if (memp_fput(mpf, np, DB_MPOOL_DIRTY))
- goto out;
- np = NULL;
- }
- }
- }
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: /* Free any pages that weren't dirtied. */
- if (pp != NULL && (t_ret = memp_fput(mpf, pp, 0)) != 0 && ret == 0)
- ret = t_ret;
- if (lp != NULL && (t_ret = memp_fput(mpf, lp, 0)) != 0 && ret == 0)
- ret = t_ret;
- if (np != NULL && (t_ret = memp_fput(mpf, np, 0)) != 0 && ret == 0)
- ret = t_ret;
- if (rp != NULL && (t_ret = memp_fput(mpf, rp, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Free any allocated space. */
- if (_lp != NULL)
- __os_free(_lp, file_dbp->pgsize);
- if (_rp != NULL)
- __os_free(_rp, file_dbp->pgsize);
-
- REC_CLOSE;
-}
-
-/*
- * __bam_rsplit_recover --
- * Recovery function for a reverse split.
- *
- * PUBLIC: int __bam_rsplit_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_rsplit_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_rsplit_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_rsplit_print);
- REC_INTRO(__bam_rsplit_read);
-
- /* Fix the root page. */
- pgno = PGNO_ROOT;
- if ((ret = memp_fget(mpf, &pgno, 0, &pagep)) != 0) {
- /* The root page must always exist. */
- __db_pgerr(file_dbp, pgno);
- goto out;
- }
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->rootlsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
- pagep->pgno = PGNO_ROOT;
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- P_INIT(pagep, file_dbp->pgsize, PGNO_ROOT,
- argp->nrec, PGNO_INVALID, pagep->level + 1,
- file_dbp->type == DB_BTREE ? P_IBTREE : P_IRECNO);
- if ((ret = __db_pitem(dbc, pagep, 0,
- argp->rootent.size, &argp->rootent, NULL)) != 0)
- goto out;
- pagep->lsn = argp->rootlsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
- /*
- * Fix the page copied over the root page. It's possible that the
- * page never made it to disk, so if we're undo-ing and the page
- * doesn't exist, it's okay and there's nothing further to do.
- */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &LSN(argp->pgdbt.data));
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __bam_adj_recover --
- * Recovery function for adj.
- *
- * PUBLIC: int __bam_adj_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_adj_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_adj_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_adj_print);
- REC_INTRO(__bam_adj_read);
-
- /* Get the page; if it never existed and we're undoing, we're done. */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
-
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- if ((ret = __bam_adjindx(dbc,
- pagep, argp->indx, argp->indx_copy, argp->is_insert)) != 0)
- goto err;
-
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- if ((ret = __bam_adjindx(dbc,
- pagep, argp->indx, argp->indx_copy, !argp->is_insert)) != 0)
- goto err;
-
- LSN(pagep) = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
- if (0) {
-err: (void)memp_fput(mpf, pagep, 0);
- }
-out: REC_CLOSE;
-}
-
-/*
- * __bam_cadjust_recover --
- * Recovery function for the adjust of a count change in an internal
- * page.
- *
- * PUBLIC: int __bam_cadjust_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_cadjust_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_cadjust_print);
- REC_INTRO(__bam_cadjust_read);
-
- /* Get the page; if it never existed and we're undoing, we're done. */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
-
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- if (file_dbp->type == DB_BTREE &&
- F_ISSET(file_dbp, DB_BT_RECNUM)) {
- GET_BINTERNAL(pagep, argp->indx)->nrecs += argp->adjust;
- if (argp->total && PGNO(pagep) == PGNO_ROOT)
- RE_NREC_ADJ(pagep, argp->adjust);
- }
- if (file_dbp->type == DB_RECNO) {
- GET_RINTERNAL(pagep, argp->indx)->nrecs += argp->adjust;
- if (argp->total && PGNO(pagep) == PGNO_ROOT)
- RE_NREC_ADJ(pagep, argp->adjust);
- }
-
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- if (file_dbp->type == DB_BTREE &&
- F_ISSET(file_dbp, DB_BT_RECNUM)) {
- GET_BINTERNAL(pagep, argp->indx)->nrecs -= argp->adjust;
- if (argp->total && PGNO(pagep) == PGNO_ROOT)
- RE_NREC_ADJ(pagep, argp->adjust);
- }
- if (file_dbp->type == DB_RECNO) {
- GET_RINTERNAL(pagep, argp->indx)->nrecs -= argp->adjust;
- if (argp->total && PGNO(pagep) == PGNO_ROOT)
- RE_NREC_ADJ(pagep, -(argp->adjust));
- }
- LSN(pagep) = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __bam_cdel_recover --
- * Recovery function for the intent-to-delete of a cursor record.
- *
- * PUBLIC: int __bam_cdel_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_cdel_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_cdel_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__bam_cdel_print);
- REC_INTRO(__bam_cdel_read);
-
- /* Get the page; if it never existed and we're undoing, we're done. */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
-
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- if (pagep->type == P_DUPLICATE)
- B_DSET(GET_BKEYDATA(pagep, argp->indx)->type);
- else
- B_DSET(GET_BKEYDATA(pagep, argp->indx + O_INDX)->type);
-
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- if (pagep->type == P_DUPLICATE)
- B_DCLR(GET_BKEYDATA(pagep, argp->indx)->type);
- else
- B_DCLR(GET_BKEYDATA(pagep, argp->indx + O_INDX)->type);
-
- LSN(pagep) = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __bam_repl_recover --
- * Recovery function for page item replacement.
- *
- * PUBLIC: int __bam_repl_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_repl_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __bam_repl_args *argp;
- BKEYDATA *bk;
- DB *file_dbp;
- DBC *dbc;
- DBT dbt;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret;
- u_int8_t *p;
-
- REC_PRINT(__bam_repl_print);
- REC_INTRO(__bam_repl_read);
-
- /* Get the page; if it never existed and we're undoing, we're done. */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo)
- goto done;
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
- bk = GET_BKEYDATA(pagep, argp->indx);
-
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- if (cmp_p == 0 && redo) {
- /*
- * Need to redo update described.
- *
- * Re-build the replacement item.
- */
- memset(&dbt, 0, sizeof(dbt));
- dbt.size = argp->prefix + argp->suffix + argp->repl.size;
- if ((ret = __os_malloc(dbt.size, NULL, &dbt.data)) != 0)
- goto err;
- p = dbt.data;
- memcpy(p, bk->data, argp->prefix);
- p += argp->prefix;
- memcpy(p, argp->repl.data, argp->repl.size);
- p += argp->repl.size;
- memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix);
-
- ret = __bam_ritem(dbc, pagep, argp->indx, &dbt);
- __os_free(dbt.data, dbt.size);
- if (ret != 0)
- goto err;
-
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /*
- * Need to undo update described.
- *
- * Re-build the original item.
- */
- memset(&dbt, 0, sizeof(dbt));
- dbt.size = argp->prefix + argp->suffix + argp->orig.size;
- if ((ret = __os_malloc(dbt.size, NULL, &dbt.data)) != 0)
- goto err;
- p = dbt.data;
- memcpy(p, bk->data, argp->prefix);
- p += argp->prefix;
- memcpy(p, argp->orig.data, argp->orig.size);
- p += argp->orig.size;
- memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix);
-
- ret = __bam_ritem(dbc, pagep, argp->indx, &dbt);
- __os_free(dbt.data, dbt.size);
- if (ret != 0)
- goto err;
-
- /* Reset the deleted flag, if necessary. */
- if (argp->isdeleted)
- B_DSET(GET_BKEYDATA(pagep, argp->indx)->type);
-
- LSN(pagep) = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
- if (0) {
-err: (void)memp_fput(mpf, pagep, 0);
- }
-out: REC_CLOSE;
-}
diff --git a/db2/btree/bt_recno.c b/db2/btree/bt_recno.c
deleted file mode 100644
index c69877f..0000000
--- a/db2/btree/bt_recno.c
+++ /dev/null
@@ -1,1356 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_recno.c 10.53 (Sleepycat) 12/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "db_ext.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "lock_ext.h"
-
-static int __ram_add __P((DBC *, db_recno_t *, DBT *, u_int32_t, u_int32_t));
-static int __ram_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-static int __ram_fmap __P((DBC *, db_recno_t));
-static int __ram_i_delete __P((DBC *));
-static int __ram_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-static int __ram_source __P((DB *, RECNO *, const char *));
-static int __ram_sync __P((DB *, u_int32_t));
-static int __ram_update __P((DBC *, db_recno_t, int));
-static int __ram_vmap __P((DBC *, db_recno_t));
-static int __ram_writeback __P((DBC *));
-
-/*
- * In recno, there are two meanings to the on-page "deleted" flag. If we're
- * re-numbering records, it means the record was implicitly created. We skip
- * over implicitly created records if doing a cursor "next" or "prev", and
- * return DB_KEYEMPTY if they're explicitly requested.. If not re-numbering
- * records, it means that the record was implicitly created, or was deleted.
- * We skip over implicitly created or deleted records if doing a cursor "next"
- * or "prev", and return DB_KEYEMPTY if they're explicitly requested.
- *
- * If we're re-numbering records, then we have to detect in the cursor that
- * a record was deleted, and adjust the cursor as necessary on the next get.
- * If we're not re-numbering records, then we can detect that a record has
- * been deleted by looking at the actual on-page record, so we completely
- * ignore the cursor's delete flag. This is different from the B+tree code.
- * It also maintains whether the cursor references a deleted record in the
- * cursor, and it doesn't always check the on-page value.
- */
-#define CD_SET(dbp, cp) { \
- if (F_ISSET(dbp, DB_RE_RENUMBER)) \
- F_SET(cp, C_DELETED); \
-}
-#define CD_CLR(dbp, cp) { \
- if (F_ISSET(dbp, DB_RE_RENUMBER)) \
- F_CLR(cp, C_DELETED); \
-}
-#define CD_ISSET(dbp, cp) \
- (F_ISSET(dbp, DB_RE_RENUMBER) && F_ISSET(cp, C_DELETED))
-
-/*
- * __ram_open --
- * Recno open function.
- *
- * PUBLIC: int __ram_open __P((DB *, DB_INFO *));
- */
-int
-__ram_open(dbp, dbinfo)
- DB *dbp;
- DB_INFO *dbinfo;
-{
- BTREE *t;
- DBC *dbc;
- RECNO *rp;
- int ret, t_ret;
-
- /* Allocate and initialize the private btree structure. */
- if ((ret = __os_calloc(1, sizeof(BTREE), &t)) != 0)
- return (ret);
- dbp->internal = t;
- __bam_setovflsize(dbp);
-
- /* Allocate and initialize the private recno structure. */
- if ((ret = __os_calloc(1, sizeof(*rp), &rp)) != 0)
- return (ret);
- /* Link in the private recno structure. */
- t->recno = rp;
-
- /*
- * Intention is to make sure all of the user's selections are okay
- * here and then use them without checking.
- */
- if (dbinfo == NULL) {
- rp->re_delim = '\n';
- rp->re_pad = ' ';
- rp->re_fd = -1;
- F_SET(rp, RECNO_EOF);
- } else {
- /*
- * If the user specified a source tree, open it and map it in.
- *
- * !!!
- * We don't complain if the user specified transactions or
- * threads. It's possible to make it work, but you'd better
- * know what you're doing!
- */
- if (dbinfo->re_source == NULL) {
- rp->re_fd = -1;
- F_SET(rp, RECNO_EOF);
- } else {
- if ((ret =
- __ram_source(dbp, rp, dbinfo->re_source)) != 0)
- goto err;
- }
-
- /* Copy delimiter, length and padding values. */
- rp->re_delim =
- F_ISSET(dbp, DB_RE_DELIMITER) ? dbinfo->re_delim : '\n';
- rp->re_pad = F_ISSET(dbp, DB_RE_PAD) ? dbinfo->re_pad : ' ';
-
- if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
- if ((rp->re_len = dbinfo->re_len) == 0) {
- __db_err(dbp->dbenv,
- "record length must be greater than 0");
- ret = EINVAL;
- goto err;
- }
- } else
- rp->re_len = 0;
- }
-
- /* Initialize the remaining fields/methods of the DB. */
- dbp->am_close = __ram_close;
- dbp->del = __ram_delete;
- dbp->put = __ram_put;
- dbp->stat = __bam_stat;
- dbp->sync = __ram_sync;
-
- /* Start up the tree. */
- if ((ret = __bam_read_root(dbp)) != 0)
- goto err;
-
- /* Set the overflow page size. */
- __bam_setovflsize(dbp);
-
- /* If we're snapshotting an underlying source file, do it now. */
- if (dbinfo != NULL && F_ISSET(dbinfo, DB_SNAPSHOT)) {
- /* Allocate a cursor. */
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- goto err;
-
- /* Do the snapshot. */
- if ((ret = __ram_update(dbc,
- DB_MAX_RECORDS, 0)) != 0 && ret == DB_NOTFOUND)
- ret = 0;
-
- /* Discard the cursor. */
- if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- if (ret != 0)
- goto err;
- }
-
- return (0);
-
-err: /* If we mmap'd a source file, discard it. */
- if (rp->re_smap != NULL)
- (void)__db_unmapfile(rp->re_smap, rp->re_msize);
-
- /* If we opened a source file, discard it. */
- if (rp->re_fd != -1)
- (void)__os_close(rp->re_fd);
- if (rp->re_source != NULL)
- __os_freestr(rp->re_source);
-
- __os_free(rp, sizeof(*rp));
-
- return (ret);
-}
-
-/*
- * __ram_delete --
- * Recno db->del function.
- */
-static int
-__ram_delete(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- CURSOR *cp;
- DBC *dbc;
- db_recno_t recno;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_delchk(dbp,
- key, flags, F_ISSET(dbp, DB_AM_RDONLY))) != 0)
- return (ret);
-
- /* Acquire a cursor. */
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "ram_delete", key, NULL, flags);
-
- /* Check the user's record number and fill in as necessary. */
- if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
- goto err;
-
- /* Do the delete. */
- cp = dbc->internal;
- cp->recno = recno;
- ret = __ram_i_delete(dbc);
-
- /* Release the cursor. */
-err: if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __ram_i_delete --
- * Internal version of recno delete, called by __ram_delete and
- * __ram_c_del.
- */
-static int
-__ram_i_delete(dbc)
- DBC *dbc;
-{
- BKEYDATA bk;
- BTREE *t;
- CURSOR *cp;
- DB *dbp;
- DBT hdr, data;
- PAGE *h;
- db_indx_t indx;
- int exact, ret, stack;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- t = dbp->internal;
- stack = 0;
-
- /*
- * If this is CDB and this isn't a write cursor, then it's an error.
- * If it is a write cursor, but we don't yet hold the write lock, then
- * we need to upgrade to the write lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- /* Make sure it's a valid update cursor. */
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- /* Search the tree for the key; delete only deletes exact matches. */
- if ((ret = __bam_rsearch(dbc, &cp->recno, S_DELETE, 1, &exact)) != 0)
- goto err;
- if (!exact) {
- ret = DB_NOTFOUND;
- goto err;
- }
- stack = 1;
-
- h = cp->csp->page;
- indx = cp->csp->indx;
-
- /*
- * If re-numbering records, the on-page deleted flag can only mean
- * that this record was implicitly created. Applications aren't
- * permitted to delete records they never created, return an error.
- *
- * If not re-numbering records, the on-page deleted flag means that
- * this record was implicitly created, or, was deleted at some time.
- * The former is an error because applications aren't permitted to
- * delete records they never created, the latter is an error because
- * if the record was "deleted", we could never have found it.
- */
- if (B_DISSET(GET_BKEYDATA(h, indx)->type)) {
- ret = DB_KEYEMPTY;
- goto err;
- }
-
- if (F_ISSET(dbp, DB_RE_RENUMBER)) {
- /* Delete the item, adjust the counts, adjust the cursors. */
- if ((ret = __bam_ditem(dbc, h, indx)) != 0)
- goto err;
- __bam_adjust(dbc, -1);
- __ram_ca(dbp, cp->recno, CA_DELETE);
-
- /*
- * If the page is empty, delete it. The whole tree is locked
- * so there are no preparations to make.
- */
- if (NUM_ENT(h) == 0 && h->pgno != PGNO_ROOT) {
- stack = 0;
- ret = __bam_dpages(dbc);
- }
- } else {
- /* Use a delete/put pair to replace the record with a marker. */
- if ((ret = __bam_ditem(dbc, h, indx)) != 0)
- goto err;
-
- B_TSET(bk.type, B_KEYDATA, 1);
- bk.len = 0;
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &bk;
- hdr.size = SSZA(BKEYDATA, data);
- memset(&data, 0, sizeof(data));
- data.data = (char *)"";
- data.size = 0;
- if ((ret = __db_pitem(dbc,
- h, indx, BKEYDATA_SIZE(0), &hdr, &data)) != 0)
- goto err;
- }
- F_SET(t->recno, RECNO_MODIFIED);
-
-err: if (stack)
- __bam_stkrel(dbc, 0);
-
- /* If we upgraded the CDB lock upon entry; downgrade it now. */
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
- return (ret);
-}
-
-/*
- * __ram_put --
- * Recno db->put function.
- */
-static int
-__ram_put(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- db_recno_t recno;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_putchk(dbp,
- key, data, flags, F_ISSET(dbp, DB_AM_RDONLY), 0)) != 0)
- return (ret);
-
- /* Allocate a cursor. */
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "ram_put", key, data, flags);
-
- /*
- * If we're appending to the tree, make sure we've read in all of
- * the backing source file. Otherwise, check the user's record
- * number and fill in as necessary.
- */
- ret = flags == DB_APPEND ?
- __ram_update(dbc, DB_MAX_RECORDS, 0) :
- __ram_getno(dbc, key, &recno, 1);
-
- /* Add the record. */
- if (ret == 0)
- ret = __ram_add(dbc, &recno, data, flags, 0);
-
- /* Discard the cursor. */
- if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Return the record number if we're appending to the tree. */
- if (ret == 0 && flags == DB_APPEND)
- *(db_recno_t *)key->data = recno;
-
- return (ret);
-}
-
-/*
- * __ram_sync --
- * Recno db->sync function.
- */
-static int
-__ram_sync(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DBC *dbc;
- int ret, t_ret;
-
- /*
- * Sync the underlying btree.
- *
- * !!!
- * We don't need to do a panic check or flags check, the "real"
- * sync function does all that for us.
- */
- if ((ret = __db_sync(dbp, flags)) != 0)
- return (ret);
-
- /* Allocate a cursor. */
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, NULL, "ram_sync", NULL, NULL, flags);
-
- /* Copy back the backing source file. */
- ret = __ram_writeback(dbc);
-
- /* Discard the cursor. */
- if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __ram_close --
- * Recno db->close function.
- *
- * PUBLIC: int __ram_close __P((DB *));
- */
-int
-__ram_close(dbp)
- DB *dbp;
-{
- RECNO *rp;
-
- rp = ((BTREE *)dbp->internal)->recno;
-
- /* Close any underlying mmap region. */
- if (rp->re_smap != NULL)
- (void)__db_unmapfile(rp->re_smap, rp->re_msize);
-
- /* Close any backing source file descriptor. */
- if (rp->re_fd != -1)
- (void)__os_close(rp->re_fd);
-
- /* Free any backing source file name. */
- if (rp->re_source != NULL)
- __os_freestr(rp->re_source);
-
- /* Free allocated memory. */
- __os_free(rp, sizeof(RECNO));
- ((BTREE *)dbp->internal)->recno = NULL;
-
- /* Close the underlying btree. */
- return (__bam_close(dbp));
-}
-
-/*
- * __ram_c_del --
- * Recno cursor->c_del function.
- *
- * PUBLIC: int __ram_c_del __P((DBC *, u_int32_t));
- */
-int
-__ram_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- CURSOR *cp;
- DB *dbp;
- int ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_cdelchk(dbp, flags,
- F_ISSET(dbp, DB_AM_RDONLY), cp->recno != RECNO_OOB)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, dbc->txn, "ram_c_del", NULL, NULL, flags);
-
- /*
- * If we are running CDB, this had better be either a write
- * cursor or an immediate writer.
- */
- if (F_ISSET(dbp, DB_AM_CDB))
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- /*
- * The semantics of cursors during delete are as follows: if record
- * numbers are mutable (DB_RE_RENUMBER is set), deleting a record
- * causes the cursor to automatically point to the record immediately
- * following. In this case it is possible to use a single cursor for
- * repeated delete operations, without intervening operations.
- *
- * If record numbers are not mutable, then records are replaced with
- * a marker containing a delete flag. If the record referenced by
- * this cursor has already been deleted, we will detect that as part
- * of the delete operation, and fail.
- */
- return (__ram_i_delete(dbc));
-}
-
-/*
- * __ram_c_get --
- * Recno cursor->c_get function.
- *
- * PUBLIC: int __ram_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__ram_c_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- CURSOR *cp, copy;
- DB *dbp;
- PAGE *h;
- db_indx_t indx;
- int exact, ret, stack, tmp_rmw;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_cgetchk(dbc->dbp,
- key, data, flags, cp->recno != RECNO_OOB)) != 0)
- return (ret);
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- tmp_rmw = 0;
- if (LF_ISSET(DB_RMW)) {
- if (!F_ISSET(dbp, DB_AM_CDB)) {
- tmp_rmw = 1;
- F_SET(dbc, DBC_RMW);
- }
- LF_CLR(DB_RMW);
- }
-
- DEBUG_LREAD(dbc, dbc->txn, "ram_c_get",
- flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
-
- /* Initialize the cursor for a new retrieval. */
- copy = *cp;
-
-retry: /* Update the record number. */
- stack = 0;
- switch (flags) {
- case DB_CURRENT:
- /*
- * If record numbers are mutable: if we just deleted a record,
- * there is no action necessary, we return the record following
- * the deleted item by virtue of renumbering the tree.
- */
- break;
- case DB_NEXT:
- /*
- * If record numbers are mutable: if we just deleted a record,
- * we have to avoid incrementing the record number so that we
- * return the right record by virtue of renumbering the tree.
- */
- if (CD_ISSET(dbp, cp))
- break;
-
- if (cp->recno != RECNO_OOB) {
- ++cp->recno;
- break;
- }
- /* FALLTHROUGH */
- case DB_FIRST:
- flags = DB_NEXT;
- cp->recno = 1;
- break;
- case DB_PREV:
- if (cp->recno != RECNO_OOB) {
- if (cp->recno == 1) {
- ret = DB_NOTFOUND;
- goto err;
- }
- --cp->recno;
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST:
- flags = DB_PREV;
- if (((ret = __ram_update(dbc,
- DB_MAX_RECORDS, 0)) != 0) && ret != DB_NOTFOUND)
- goto err;
- if ((ret = __bam_nrecs(dbc, &cp->recno)) != 0)
- goto err;
- if (cp->recno == 0) {
- ret = DB_NOTFOUND;
- goto err;
- }
- break;
- case DB_SET:
- case DB_SET_RANGE:
- if ((ret = __ram_getno(dbc, key, &cp->recno, 0)) != 0)
- goto err;
- break;
- }
-
- /* Return the key if the user didn't give us one. */
- if (flags != DB_SET && flags != DB_SET_RANGE &&
- (ret = __db_retcopy(key, &cp->recno, sizeof(cp->recno),
- &dbc->rkey.data, &dbc->rkey.ulen, dbp->db_malloc)) != 0)
- goto err;
-
- /* Search the tree for the record. */
- if ((ret = __bam_rsearch(dbc, &cp->recno,
- F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND, 1, &exact)) != 0)
- goto err;
- stack = 1;
- if (!exact) {
- ret = DB_NOTFOUND;
- goto err;
- }
- h = cp->csp->page;
- indx = cp->csp->indx;
-
- /*
- * If re-numbering records, the on-page deleted flag means this record
- * was implicitly created. If not re-numbering records, the on-page
- * deleted flag means this record was implicitly created, or, it was
- * deleted at some time. Regardless, we skip such records if doing
- * cursor next/prev operations, and fail if the application requested
- * them explicitly.
- */
- if (B_DISSET(GET_BKEYDATA(h, indx)->type)) {
- if (flags == DB_NEXT || flags == DB_PREV) {
- (void)__bam_stkrel(dbc, 0);
- goto retry;
- }
- ret = DB_KEYEMPTY;
- goto err;
- }
-
- /* Return the data item. */
- if ((ret = __db_ret(dbp,
- h, indx, data, &dbc->rdata.data, &dbc->rdata.ulen)) != 0)
- goto err;
-
- /* The cursor was reset, no further delete adjustment is necessary. */
- CD_CLR(dbp, cp);
-
-err: if (stack)
- (void)__bam_stkrel(dbc, 0);
-
- /* Release temporary lock upgrade. */
- if (tmp_rmw)
- F_CLR(dbc, DBC_RMW);
-
- if (ret != 0)
- *cp = copy;
-
- return (ret);
-}
-
-/*
- * __ram_c_put --
- * Recno cursor->c_put function.
- *
- * PUBLIC: int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__ram_c_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- CURSOR *cp, copy;
- DB *dbp;
- int exact, ret;
- void *arg;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret = __db_cputchk(dbc->dbp, key, data, flags,
- F_ISSET(dbc->dbp, DB_AM_RDONLY), cp->recno != RECNO_OOB)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, dbc->txn, "ram_c_put", NULL, data, flags);
-
- /*
- * If we are running CDB, this had better be either a write
- * cursor or an immediate writer. If it's a regular writer,
- * that means we have an IWRITE lock and we need to upgrade
- * it to a write lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- /* Initialize the cursor for a new retrieval. */
- copy = *cp;
-
- /*
- * To split, we need a valid key for the page. Since it's a cursor,
- * we have to build one.
- *
- * The split code discards all short-term locks and stack pages.
- */
- if (0) {
-split: arg = &cp->recno;
- if ((ret = __bam_split(dbc, arg)) != 0)
- goto err;
- }
-
- if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0)
- goto err;
- if (!exact) {
- ret = DB_NOTFOUND;
- goto err;
- }
- if ((ret = __bam_iitem(dbc, &cp->csp->page,
- &cp->csp->indx, key, data, flags, 0)) == DB_NEEDSPLIT) {
- if ((ret = __bam_stkrel(dbc, 0)) != 0)
- goto err;
- goto split;
- }
- if ((ret = __bam_stkrel(dbc, 0)) != 0)
- goto err;
-
- switch (flags) {
- case DB_AFTER:
- /* Adjust the cursors. */
- __ram_ca(dbp, cp->recno, CA_IAFTER);
-
- /* Set this cursor to reference the new record. */
- cp->recno = copy.recno + 1;
- break;
- case DB_BEFORE:
- /* Adjust the cursors. */
- __ram_ca(dbp, cp->recno, CA_IBEFORE);
-
- /* Set this cursor to reference the new record. */
- cp->recno = copy.recno;
- break;
- }
-
- /* The cursor was reset, no further delete adjustment is necessary. */
- CD_CLR(dbp, cp);
-
-err: if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
-
- if (ret != 0)
- *cp = copy;
-
- return (ret);
-}
-
-/*
- * __ram_ca --
- * Adjust cursors.
- *
- * PUBLIC: void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
- */
-void
-__ram_ca(dbp, recno, op)
- DB *dbp;
- db_recno_t recno;
- ca_recno_arg op;
-{
- CURSOR *cp;
- DBC *dbc;
-
- /*
- * Adjust the cursors. See the comment in __bam_ca_delete().
- */
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- cp = dbc->internal;
- switch (op) {
- case CA_DELETE:
- if (recno > cp->recno)
- --cp->recno;
- if (recno == cp->recno)
- CD_SET(dbp, cp);
- break;
- case CA_IAFTER:
- if (recno > cp->recno)
- ++cp->recno;
- break;
- case CA_IBEFORE:
- if (recno >= cp->recno)
- ++cp->recno;
- break;
- }
- }
- DB_THREAD_UNLOCK(dbp);
-}
-
-/*
- * __ram_getno --
- * Check the user's record number, and make sure we've seen it.
- *
- * PUBLIC: int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
- */
-int
-__ram_getno(dbc, key, rep, can_create)
- DBC *dbc;
- const DBT *key;
- db_recno_t *rep;
- int can_create;
-{
- DB *dbp;
- db_recno_t recno;
-
- dbp = dbc->dbp;
-
- /* Check the user's record number. */
- if ((recno = *(db_recno_t *)key->data) == 0) {
- __db_err(dbp->dbenv, "illegal record number of 0");
- return (EINVAL);
- }
- if (rep != NULL)
- *rep = recno;
-
- /*
- * Btree can neither create records nor read them in. Recno can
- * do both, see if we can find the record.
- */
- return (dbp->type == DB_RECNO ?
- __ram_update(dbc, recno, can_create) : 0);
-}
-
-/*
- * __ram_update --
- * Ensure the tree has records up to and including the specified one.
- */
-static int
-__ram_update(dbc, recno, can_create)
- DBC *dbc;
- db_recno_t recno;
- int can_create;
-{
- BTREE *t;
- DB *dbp;
- RECNO *rp;
- db_recno_t nrecs;
- int ret;
-
- dbp = dbc->dbp;
- t = dbp->internal;
- rp = t->recno;
-
- /*
- * If we can't create records and we've read the entire backing input
- * file, we're done.
- */
- if (!can_create && F_ISSET(rp, RECNO_EOF))
- return (0);
-
- /*
- * If we haven't seen this record yet, try to get it from the original
- * file.
- */
- if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)
- return (ret);
- if (!F_ISSET(rp, RECNO_EOF) && recno > nrecs) {
- if ((ret = rp->re_irec(dbc, recno)) != 0)
- return (ret);
- if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)
- return (ret);
- }
-
- /*
- * If we can create records, create empty ones up to the requested
- * record.
- */
- if (!can_create || recno <= nrecs + 1)
- return (0);
-
- dbc->rdata.dlen = 0;
- dbc->rdata.doff = 0;
- dbc->rdata.flags = 0;
- if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
- if (dbc->rdata.ulen < rp->re_len) {
- if ((ret =
- __os_realloc(&dbc->rdata.data, rp->re_len)) != 0) {
- dbc->rdata.ulen = 0;
- dbc->rdata.data = NULL;
- return (ret);
- }
- dbc->rdata.ulen = rp->re_len;
- }
- dbc->rdata.size = rp->re_len;
- memset(dbc->rdata.data, rp->re_pad, rp->re_len);
- } else
- dbc->rdata.size = 0;
-
- while (recno > ++nrecs)
- if ((ret = __ram_add(dbc,
- &nrecs, &dbc->rdata, 0, BI_DELETED)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * __ram_source --
- * Load information about the backing file.
- */
-static int
-__ram_source(dbp, rp, fname)
- DB *dbp;
- RECNO *rp;
- const char *fname;
-{
- size_t size;
- u_int32_t bytes, mbytes, oflags;
- int ret;
-
- /*
- * !!!
- * The caller has full responsibility for cleaning up on error --
- * (it has to anyway, in case it fails after this routine succeeds).
- */
- if ((ret = __db_appname(dbp->dbenv,
- DB_APP_DATA, NULL, fname, 0, NULL, &rp->re_source)) != 0)
- return (ret);
-
- oflags = F_ISSET(dbp, DB_AM_RDONLY) ? DB_RDONLY : 0;
- if ((ret =
- __db_open(rp->re_source, oflags, oflags, 0, &rp->re_fd)) != 0) {
- __db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
- return (ret);
- }
-
- /*
- * XXX
- * We'd like to test to see if the file is too big to mmap. Since we
- * don't know what size or type off_t's or size_t's are, or the largest
- * unsigned integral type is, or what random insanity the local C
- * compiler will perpetrate, doing the comparison in a portable way is
- * flatly impossible. Hope that mmap fails if the file is too large.
- */
- if ((ret = __os_ioinfo(rp->re_source,
- rp->re_fd, &mbytes, &bytes, NULL)) != 0) {
- __db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
- return (ret);
- }
- if (mbytes == 0 && bytes == 0) {
- F_SET(rp, RECNO_EOF);
- return (0);
- }
-
- size = mbytes * MEGABYTE + bytes;
- if ((ret = __db_mapfile(rp->re_source,
- rp->re_fd, (size_t)size, 1, &rp->re_smap)) != 0)
- return (ret);
- rp->re_cmap = rp->re_smap;
- rp->re_emap = (u_int8_t *)rp->re_smap + (rp->re_msize = size);
- rp->re_irec = F_ISSET(dbp, DB_RE_FIXEDLEN) ? __ram_fmap : __ram_vmap;
- return (0);
-}
-
-/*
- * __ram_writeback --
- * Rewrite the backing file.
- */
-static int
-__ram_writeback(dbc)
- DBC *dbc;
-{
- DB *dbp;
- DBT key, data;
- RECNO *rp;
- db_recno_t keyno;
- ssize_t nw;
- int fd, ret, t_ret;
- u_int8_t delim, *pad;
-
- dbp = dbc->dbp;
- rp = ((BTREE *)dbp->internal)->recno;
-
- /* If the file wasn't modified, we're done. */
- if (!F_ISSET(rp, RECNO_MODIFIED))
- return (0);
-
- /* If there's no backing source file, we're done. */
- if (rp->re_source == NULL) {
- F_CLR(rp, RECNO_MODIFIED);
- return (0);
- }
-
- /*
- * Read any remaining records into the tree.
- *
- * !!!
- * This is why we can't support transactions when applications specify
- * backing (re_source) files. At this point we have to read in the
- * rest of the records from the file so that we can write all of the
- * records back out again, which could modify a page for which we'd
- * have to log changes and which we don't have locked. This could be
- * partially fixed by taking a snapshot of the entire file during the
- * db_open(), or, since db_open() isn't transaction protected, as part
- * of the first DB operation. But, if a checkpoint occurs then, the
- * part of the log holding the copy of the file could be discarded, and
- * that would make it impossible to recover in the face of disaster.
- * This could all probably be fixed, but it would require transaction
- * protecting the backing source file, i.e. mpool would have to know
- * about it, and we don't want to go there.
- */
- if ((ret =
- __ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND)
- return (ret);
-
- /*
- * !!!
- * Close any underlying mmap region. This is required for Windows NT
- * (4.0, Service Pack 2) -- if the file is still mapped, the following
- * open will fail.
- */
- if (rp->re_smap != NULL) {
- (void)__db_unmapfile(rp->re_smap, rp->re_msize);
- rp->re_smap = NULL;
- }
-
- /* Get rid of any backing file descriptor, just on GP's. */
- if (rp->re_fd != -1) {
- (void)__os_close(rp->re_fd);
- rp->re_fd = -1;
- }
-
- /* Open the file, truncating it. */
- if ((ret = __db_open(rp->re_source,
- DB_SEQUENTIAL | DB_TRUNCATE,
- DB_SEQUENTIAL | DB_TRUNCATE, 0, &fd)) != 0) {
- __db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
- return (ret);
- }
-
- /*
- * We step through the records, writing each one out. Use the record
- * number and the dbp->get() function, instead of a cursor, so we find
- * and write out "deleted" or non-existent records.
- */
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- key.size = sizeof(db_recno_t);
- key.data = &keyno;
-
- /*
- * We'll need the delimiter if we're doing variable-length records,
- * and the pad character if we're doing fixed-length records.
- */
- delim = rp->re_delim;
- if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
- if ((ret = __os_malloc(rp->re_len, NULL, &pad)) != 0)
- goto err;
- memset(pad, rp->re_pad, rp->re_len);
- } else
- COMPQUIET(pad, NULL);
- for (keyno = 1;; ++keyno) {
- switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) {
- case 0:
- if ((ret =
- __os_write(fd, data.data, data.size, &nw)) != 0)
- goto err;
- if (nw != (ssize_t)data.size) {
- ret = EIO;
- goto err;
- }
- break;
- case DB_KEYEMPTY:
- if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
- if ((ret =
- __os_write(fd, pad, rp->re_len, &nw)) != 0)
- goto err;
- if (nw != (ssize_t)rp->re_len) {
- ret = EIO;
- goto err;
- }
- }
- break;
- case DB_NOTFOUND:
- ret = 0;
- goto done;
- }
- if (!F_ISSET(dbp, DB_RE_FIXEDLEN)) {
- if ((ret = __os_write(fd, &delim, 1, &nw)) != 0)
- goto err;
- if (nw != 1) {
- ret = EIO;
- goto err;
- }
- }
- }
-
-err:
-done: /* Close the file descriptor. */
- if ((t_ret = __os_close(fd)) != 0 || ret == 0)
- ret = t_ret;
-
- if (ret == 0)
- F_CLR(rp, RECNO_MODIFIED);
- return (ret);
-}
-
-/*
- * __ram_fmap --
- * Get fixed length records from a file.
- */
-static int
-__ram_fmap(dbc, top)
- DBC *dbc;
- db_recno_t top;
-{
- DB *dbp;
- DBT data;
- RECNO *rp;
- db_recno_t recno;
- u_int32_t len;
- u_int8_t *sp, *ep, *p;
- int ret;
-
- if ((ret = __bam_nrecs(dbc, &recno)) != 0)
- return (ret);
-
- dbp = dbc->dbp;
- rp = ((BTREE *)(dbp->internal))->recno;
-
- if (dbc->rdata.ulen < rp->re_len) {
- if ((ret = __os_realloc(&dbc->rdata.data, rp->re_len)) != 0) {
- dbc->rdata.ulen = 0;
- dbc->rdata.data = NULL;
- return (ret);
- }
- dbc->rdata.ulen = rp->re_len;
- }
-
- memset(&data, 0, sizeof(data));
- data.data = dbc->rdata.data;
- data.size = rp->re_len;
-
- sp = (u_int8_t *)rp->re_cmap;
- ep = (u_int8_t *)rp->re_emap;
- while (recno < top) {
- if (sp >= ep) {
- F_SET(rp, RECNO_EOF);
- return (DB_NOTFOUND);
- }
- len = rp->re_len;
- for (p = dbc->rdata.data;
- sp < ep && len > 0; *p++ = *sp++, --len)
- ;
-
- /*
- * Another process may have read this record from the input
- * file and stored it into the database already, in which
- * case we don't need to repeat that operation. We detect
- * this by checking if the last record we've read is greater
- * or equal to the number of records in the database.
- *
- * XXX
- * We should just do a seek, since the records are fixed
- * length.
- */
- if (rp->re_last >= recno) {
- if (len != 0)
- memset(p, rp->re_pad, len);
-
- ++recno;
- if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0)
- return (ret);
- }
- ++rp->re_last;
- }
- rp->re_cmap = sp;
- return (0);
-}
-
-/*
- * __ram_vmap --
- * Get variable length records from a file.
- */
-static int
-__ram_vmap(dbc, top)
- DBC *dbc;
- db_recno_t top;
-{
- DBT data;
- RECNO *rp;
- db_recno_t recno;
- u_int8_t *sp, *ep;
- int delim, ret;
-
- rp = ((BTREE *)(dbc->dbp->internal))->recno;
-
- if ((ret = __bam_nrecs(dbc, &recno)) != 0)
- return (ret);
-
- memset(&data, 0, sizeof(data));
-
- delim = rp->re_delim;
-
- sp = (u_int8_t *)rp->re_cmap;
- ep = (u_int8_t *)rp->re_emap;
- while (recno < top) {
- if (sp >= ep) {
- F_SET(rp, RECNO_EOF);
- return (DB_NOTFOUND);
- }
- for (data.data = sp; sp < ep && *sp != delim; ++sp)
- ;
-
- /*
- * Another process may have read this record from the input
- * file and stored it into the database already, in which
- * case we don't need to repeat that operation. We detect
- * this by checking if the last record we've read is greater
- * or equal to the number of records in the database.
- */
- if (rp->re_last >= recno) {
- data.size = sp - (u_int8_t *)data.data;
- ++recno;
- if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0)
- return (ret);
- }
- ++rp->re_last;
- ++sp;
- }
- rp->re_cmap = sp;
- return (0);
-}
-
-/*
- * __ram_add --
- * Add records into the tree.
- */
-static int
-__ram_add(dbc, recnop, data, flags, bi_flags)
- DBC *dbc;
- db_recno_t *recnop;
- DBT *data;
- u_int32_t flags, bi_flags;
-{
- BKEYDATA *bk;
- CURSOR *cp;
- DB *dbp;
- PAGE *h;
- db_indx_t indx;
- int exact, isdeleted, ret, stack;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
-retry: /* Find the slot for insertion. */
- if ((ret = __bam_rsearch(dbc, recnop,
- S_INSERT | (flags == DB_APPEND ? S_APPEND : 0), 1, &exact)) != 0)
- return (ret);
- h = cp->csp->page;
- indx = cp->csp->indx;
- stack = 1;
-
- /*
- * If re-numbering records, the on-page deleted flag means this record
- * was implicitly created. If not re-numbering records, the on-page
- * deleted flag means this record was implicitly created, or, it was
- * deleted at some time.
- *
- * If DB_NOOVERWRITE is set and the item already exists in the tree,
- * return an error unless the item was either marked for deletion or
- * only implicitly created.
- */
- isdeleted = 0;
- if (exact) {
- bk = GET_BKEYDATA(h, indx);
- if (B_DISSET(bk->type))
- isdeleted = 1;
- else
- if (flags == DB_NOOVERWRITE) {
- ret = DB_KEYEXIST;
- goto err;
- }
- }
-
- /*
- * Select the arguments for __bam_iitem() and do the insert. If the
- * key is an exact match, or we're replacing the data item with a
- * new data item, replace the current item. If the key isn't an exact
- * match, we're inserting a new key/data pair, before the search
- * location.
- */
- switch (ret = __bam_iitem(dbc,
- &h, &indx, NULL, data, exact ? DB_CURRENT : DB_BEFORE, bi_flags)) {
- case 0:
- /*
- * Don't adjust anything.
- *
- * If we inserted a record, no cursors need adjusting because
- * the only new record it's possible to insert is at the very
- * end of the tree. The necessary adjustments to the internal
- * page counts were made by __bam_iitem().
- *
- * If we overwrote a record, no cursors need adjusting because
- * future DBcursor->get calls will simply return the underlying
- * record (there's no adjustment made for the DB_CURRENT flag
- * when a cursor get operation immediately follows a cursor
- * delete operation, and the normal adjustment for the DB_NEXT
- * flag is still correct).
- */
- break;
- case DB_NEEDSPLIT:
- /* Discard the stack of pages and split the page. */
- (void)__bam_stkrel(dbc, 0);
- stack = 0;
-
- if ((ret = __bam_split(dbc, recnop)) != 0)
- goto err;
-
- goto retry;
- /* NOTREACHED */
- default:
- goto err;
- }
-
-
-err: if (stack)
- __bam_stkrel(dbc, 0);
-
- return (ret);
-}
diff --git a/db2/btree/bt_rsearch.c b/db2/btree/bt_rsearch.c
deleted file mode 100644
index 8efe405..0000000
--- a/db2/btree/bt_rsearch.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_rsearch.c 10.21 (Sleepycat) 12/2/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_rsearch --
- * Search a btree for a record number.
- *
- * PUBLIC: int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
- */
-int
-__bam_rsearch(dbc, recnop, flags, stop, exactp)
- DBC *dbc;
- db_recno_t *recnop;
- u_int32_t flags;
- int stop, *exactp;
-{
- BINTERNAL *bi;
- CURSOR *cp;
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- RINTERNAL *ri;
- db_indx_t indx, top;
- db_pgno_t pg;
- db_recno_t i, recno, total;
- int ret, stack;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- BT_STK_CLR(cp);
-
- /*
- * There are several ways we search a btree tree. The flags argument
- * specifies if we're acquiring read or write locks and if we are
- * locking pairs of pages. In addition, if we're adding or deleting
- * an item, we have to lock the entire tree, regardless. See btree.h
- * for more details.
- *
- * If write-locking pages, we need to know whether or not to acquire a
- * write lock on a page before getting it. This depends on how deep it
- * is in tree, which we don't know until we acquire the root page. So,
- * if we need to lock the root page we may have to upgrade it later,
- * because we won't get the correct lock initially.
- *
- * Retrieve the root page.
- */
- pg = PGNO_ROOT;
- stack = LF_ISSET(S_STACK);
- if ((ret = __bam_lget(dbc,
- 0, pg, stack ? DB_LOCK_WRITE : DB_LOCK_READ, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
- (void)__BT_LPUT(dbc, lock);
- return (ret);
- }
-
- /*
- * Decide if we need to save this page; if we do, write lock it.
- * We deliberately don't lock-couple on this call. If the tree
- * is tiny, i.e., one page, and two threads are busily updating
- * the root page, we're almost guaranteed deadlocks galore, as
- * each one gets a read lock and then blocks the other's attempt
- * for a write lock.
- */
- if (!stack &&
- ((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
- (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- if ((ret = __bam_lget(dbc, 0, pg, DB_LOCK_WRITE, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
- (void)__BT_LPUT(dbc, lock);
- return (ret);
- }
- stack = 1;
- }
-
- /*
- * If appending to the tree, set the record number now -- we have the
- * root page locked.
- *
- * Delete only deletes exact matches, read only returns exact matches.
- * Note, this is different from __bam_search(), which returns non-exact
- * matches for read.
- *
- * The record may not exist. We can only return the correct location
- * for the record immediately after the last record in the tree, so do
- * a fast check now.
- */
- total = RE_NREC(h);
- if (LF_ISSET(S_APPEND)) {
- *exactp = 0;
- *recnop = recno = total + 1;
- } else {
- recno = *recnop;
- if (recno <= total)
- *exactp = 1;
- else {
- *exactp = 0;
- if (!LF_ISSET(S_PAST_EOF) || recno > total + 1) {
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- return (DB_NOTFOUND);
- }
- }
- }
-
- /*
- * !!!
- * Record numbers in the tree are 0-based, but the recno is
- * 1-based. All of the calculations below have to take this
- * into account.
- */
- for (total = 0;;) {
- switch (TYPE(h)) {
- case P_LBTREE:
- recno -= total;
-
- /*
- * There may be logically deleted records on the page,
- * walk the page correcting for them. The record may
- * not exist if there are enough deleted records in the
- * page.
- */
- if (recno <= (db_recno_t)NUM_ENT(h) / P_INDX)
- for (i = recno - 1;; --i) {
- if (B_DISSET(GET_BKEYDATA(h,
- i * P_INDX + O_INDX)->type))
- ++recno;
- if (i == 0)
- break;
- }
- if (recno > (db_recno_t)NUM_ENT(h) / P_INDX) {
- *exactp = 0;
- if (!LF_ISSET(S_PAST_EOF) || recno >
- (db_recno_t)(NUM_ENT(h) / P_INDX + 1)) {
- ret = DB_NOTFOUND;
- goto err;
- }
-
- }
-
- /* Correct from 1-based to 0-based for a page offset. */
- --recno;
- BT_STK_ENTER(cp, h, recno * P_INDX, lock, ret);
- return (ret);
- case P_IBTREE:
- for (indx = 0, top = NUM_ENT(h);;) {
- bi = GET_BINTERNAL(h, indx);
- if (++indx == top || total + bi->nrecs >= recno)
- break;
- total += bi->nrecs;
- }
- pg = bi->pgno;
- break;
- case P_LRECNO:
- recno -= total;
-
- /* Correct from 1-based to 0-based for a page offset. */
- --recno;
- BT_STK_ENTER(cp, h, recno, lock, ret);
- return (ret);
- case P_IRECNO:
- for (indx = 0, top = NUM_ENT(h);;) {
- ri = GET_RINTERNAL(h, indx);
- if (++indx == top || total + ri->nrecs >= recno)
- break;
- total += ri->nrecs;
- }
- pg = ri->pgno;
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
- --indx;
-
- if (stack) {
- /* Return if this is the lowest page wanted. */
- if (LF_ISSET(S_PARENT) && stop == h->level) {
- BT_STK_ENTER(cp, h, indx, lock, ret);
- return (ret);
- }
- BT_STK_PUSH(cp, h, indx, lock, ret);
- if (ret != 0)
- goto err;
-
- if ((ret =
- __bam_lget(dbc, 0, pg, DB_LOCK_WRITE, &lock)) != 0)
- goto err;
- } else {
- /*
- * Decide if we want to return a pointer to the next
- * page in the stack. If we do, write lock it and
- * never unlock it.
- */
- if ((LF_ISSET(S_PARENT) &&
- (u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
- (h->level - 1) == LEAFLEVEL)
- stack = 1;
-
- (void)memp_fput(dbp->mpf, h, 0);
-
- if ((ret =
- __bam_lget(dbc, 1, pg, stack && LF_ISSET(S_WRITE) ?
- DB_LOCK_WRITE : DB_LOCK_READ, &lock)) != 0)
- goto err;
- }
-
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0)
- goto err;
- }
- /* NOTREACHED */
-
-err: BT_STK_POP(cp);
- __bam_stkrel(dbc, 0);
- return (ret);
-}
-
-/*
- * __bam_adjust --
- * Adjust the tree after adding or deleting a record.
- *
- * PUBLIC: int __bam_adjust __P((DBC *, int32_t));
- */
-int
-__bam_adjust(dbc, adjust)
- DBC *dbc;
- int32_t adjust;
-{
- CURSOR *cp;
- DB *dbp;
- EPG *epg;
- PAGE *h;
- int ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- /* Update the record counts for the tree. */
- for (epg = cp->sp; epg <= cp->csp; ++epg) {
- h = epg->page;
- if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO) {
- if (DB_LOGGING(dbc) &&
- (ret = __bam_cadjust_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(h), 0, dbp->log_fileid,
- PGNO(h), &LSN(h), (u_int32_t)epg->indx,
- adjust, 1)) != 0)
- return (ret);
-
- if (TYPE(h) == P_IBTREE)
- GET_BINTERNAL(h, epg->indx)->nrecs += adjust;
- else
- GET_RINTERNAL(h, epg->indx)->nrecs += adjust;
-
- if (PGNO(h) == PGNO_ROOT)
- RE_NREC_ADJ(h, adjust);
-
- if ((ret = memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY)) != 0)
- return (ret);
- }
- }
- return (0);
-}
-
-/*
- * __bam_nrecs --
- * Return the number of records in the tree.
- *
- * PUBLIC: int __bam_nrecs __P((DBC *, db_recno_t *));
- */
-int
-__bam_nrecs(dbc, rep)
- DBC *dbc;
- db_recno_t *rep;
-{
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- db_pgno_t pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- pgno = PGNO_ROOT;
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- *rep = RE_NREC(h);
-
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_TLPUT(dbc, lock);
-
- return (0);
-}
-
-/*
- * __bam_total --
- * Return the number of records below a page.
- *
- * PUBLIC: db_recno_t __bam_total __P((PAGE *));
- */
-db_recno_t
-__bam_total(h)
- PAGE *h;
-{
- db_recno_t nrecs;
- db_indx_t indx, top;
-
- nrecs = 0;
- top = NUM_ENT(h);
-
- switch (TYPE(h)) {
- case P_LBTREE:
- /* Check for logically deleted records. */
- for (indx = 0; indx < top; indx += P_INDX)
- if (!B_DISSET(GET_BKEYDATA(h, indx + O_INDX)->type))
- ++nrecs;
- break;
- case P_IBTREE:
- for (indx = 0; indx < top; indx += O_INDX)
- nrecs += GET_BINTERNAL(h, indx)->nrecs;
- break;
- case P_LRECNO:
- nrecs = NUM_ENT(h);
- break;
- case P_IRECNO:
- for (indx = 0; indx < top; indx += O_INDX)
- nrecs += GET_RINTERNAL(h, indx)->nrecs;
- break;
- }
-
- return (nrecs);
-}
diff --git a/db2/btree/bt_search.c b/db2/btree/bt_search.c
deleted file mode 100644
index 1f439a4..0000000
--- a/db2/btree/bt_search.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_search.c 10.25 (Sleepycat) 12/16/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_search --
- * Search a btree for a key.
- *
- * PUBLIC: int __bam_search __P((DBC *,
- * PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *));
- */
-int
-__bam_search(dbc, key, flags, stop, recnop, exactp)
- DBC *dbc;
- const DBT *key;
- u_int32_t flags;
- int stop, *exactp;
- db_recno_t *recnop;
-{
- BTREE *t;
- CURSOR *cp;
- DB *dbp;
- DB_LOCK lock;
- PAGE *h;
- db_indx_t base, i, indx, lim;
- db_pgno_t pg;
- db_recno_t recno;
- int cmp, jump, ret, stack;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
- t = dbp->internal;
- recno = 0;
-
- BT_STK_CLR(cp);
-
- /*
- * There are several ways we search a btree tree. The flags argument
- * specifies if we're acquiring read or write locks, if we position
- * to the first or last item in a set of duplicates, if we return
- * deleted items, and if we are locking pairs of pages. In addition,
- * if we're modifying record numbers, we have to lock the entire tree
- * regardless. See btree.h for more details.
- *
- * If write-locking pages, we need to know whether or not to acquire a
- * write lock on a page before getting it. This depends on how deep it
- * is in tree, which we don't know until we acquire the root page. So,
- * if we need to lock the root page we may have to upgrade it later,
- * because we won't get the correct lock initially.
- *
- * Retrieve the root page.
- */
- pg = PGNO_ROOT;
- stack = F_ISSET(dbp, DB_BT_RECNUM) && LF_ISSET(S_STACK);
- if ((ret = __bam_lget(dbc,
- 0, pg, stack ? DB_LOCK_WRITE : DB_LOCK_READ, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
- (void)__BT_LPUT(dbc, lock);
- return (ret);
- }
-
- /*
- * Decide if we need to save this page; if we do, write lock it.
- * We deliberately don't lock-couple on this call. If the tree
- * is tiny, i.e., one page, and two threads are busily updating
- * the root page, we're almost guaranteed deadlocks galore, as
- * each one gets a read lock and then blocks the other's attempt
- * for a write lock.
- */
- if (!stack &&
- ((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
- (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- if ((ret = __bam_lget(dbc, 0, pg, DB_LOCK_WRITE, &lock)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
- (void)__BT_LPUT(dbc, lock);
- return (ret);
- }
- stack = 1;
- }
-
- for (;;) {
- /*
- * Do a binary search on the current page. If we're searching
- * a leaf page, we have to manipulate the indices in groups of
- * two. If we're searching an internal page, they're an index
- * per page item. If we find an exact match on a leaf page,
- * we're done.
- */
- jump = TYPE(h) == P_LBTREE ? P_INDX : O_INDX;
- for (base = 0,
- lim = NUM_ENT(h) / (db_indx_t)jump; lim != 0; lim >>= 1) {
- indx = base + ((lim >> 1) * jump);
- if ((cmp =
- __bam_cmp(dbp, key, h, indx, t->bt_compare)) == 0) {
- if (TYPE(h) == P_LBTREE)
- goto match;
- goto next;
- }
- if (cmp > 0) {
- base = indx + jump;
- --lim;
- }
- }
-
- /*
- * No match found. Base is the smallest index greater than
- * key and may be zero or a last + O_INDX index.
- *
- * If it's a leaf page, return base as the "found" value.
- * Delete only deletes exact matches.
- */
- if (TYPE(h) == P_LBTREE) {
- *exactp = 0;
-
- if (LF_ISSET(S_EXACT))
- goto notfound;
-
- /*
- * !!!
- * Possibly returning a deleted record -- DB_SET_RANGE,
- * DB_KEYFIRST and DB_KEYLAST don't require an exact
- * match, and we don't want to walk multiple pages here
- * to find an undeleted record. This is handled in the
- * __bam_c_search() routine.
- */
- BT_STK_ENTER(cp, h, base, lock, ret);
- return (ret);
- }
-
- /*
- * If it's not a leaf page, record the internal page (which is
- * a parent page for the key). Decrement the base by 1 if it's
- * non-zero so that if a split later occurs, the inserted page
- * will be to the right of the saved page.
- */
- indx = base > 0 ? base - O_INDX : base;
-
- /*
- * If we're trying to calculate the record number, sum up
- * all the record numbers on this page up to the indx point.
- */
- if (recnop != NULL)
- for (i = 0; i < indx; ++i)
- recno += GET_BINTERNAL(h, i)->nrecs;
-
-next: pg = GET_BINTERNAL(h, indx)->pgno;
- if (stack) {
- /* Return if this is the lowest page wanted. */
- if (LF_ISSET(S_PARENT) && stop == h->level) {
- BT_STK_ENTER(cp, h, indx, lock, ret);
- return (ret);
- }
- BT_STK_PUSH(cp, h, indx, lock, ret);
- if (ret != 0)
- goto err;
-
- if ((ret =
- __bam_lget(dbc, 0, pg, DB_LOCK_WRITE, &lock)) != 0)
- goto err;
- } else {
- /*
- * Decide if we want to return a reference to the next
- * page in the return stack. If so, lock it and never
- * unlock it.
- */
- if ((LF_ISSET(S_PARENT) &&
- (u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
- (h->level - 1) == LEAFLEVEL)
- stack = 1;
-
- (void)memp_fput(dbp->mpf, h, 0);
-
- if ((ret =
- __bam_lget(dbc, 1, pg, stack && LF_ISSET(S_WRITE) ?
- DB_LOCK_WRITE : DB_LOCK_READ, &lock)) != 0)
- goto err;
- }
- if ((ret = memp_fget(dbp->mpf, &pg, 0, &h)) != 0)
- goto err;
- }
- /* NOTREACHED */
-
-match: *exactp = 1;
-
- /*
- * If we're trying to calculate the record number, add in the
- * offset on this page and correct for the fact that records
- * in the tree are 0-based.
- */
- if (recnop != NULL)
- *recnop = recno + (indx / P_INDX) + 1;
-
- /*
- * If we got here, we know that we have a btree leaf page.
- *
- * If there are duplicates, go to the first/last one. This is
- * safe because we know that we're not going to leave the page,
- * all duplicate sets that are not on overflow pages exist on a
- * single leaf page.
- */
- if (LF_ISSET(S_DUPLAST))
- while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
- h->inp[indx] == h->inp[indx + P_INDX])
- indx += P_INDX;
- else
- while (indx > 0 &&
- h->inp[indx] == h->inp[indx - P_INDX])
- indx -= P_INDX;
-
- /*
- * Now check if we are allowed to return deleted items; if not
- * find the next (or previous) non-deleted item.
- */
- if (LF_ISSET(S_DELNO)) {
- if (LF_ISSET(S_DUPLAST))
- while (B_DISSET(GET_BKEYDATA(h, indx + O_INDX)->type) &&
- indx > 0 &&
- h->inp[indx] == h->inp[indx - P_INDX])
- indx -= P_INDX;
- else
- while (B_DISSET(GET_BKEYDATA(h, indx + O_INDX)->type) &&
- indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
- h->inp[indx] == h->inp[indx + P_INDX])
- indx += P_INDX;
-
- if (B_DISSET(GET_BKEYDATA(h, indx + O_INDX)->type))
- goto notfound;
- }
-
- BT_STK_ENTER(cp, h, indx, lock, ret);
- return (ret);
-
-notfound:
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- ret = DB_NOTFOUND;
-
-err: if (cp->csp > cp->sp) {
- BT_STK_POP(cp);
- __bam_stkrel(dbc, 0);
- }
- return (ret);
-}
-
-/*
- * __bam_stkrel --
- * Release all pages currently held in the stack.
- *
- * PUBLIC: int __bam_stkrel __P((DBC *, int));
- */
-int
-__bam_stkrel(dbc, nolocks)
- DBC *dbc;
- int nolocks;
-{
- CURSOR *cp;
- DB *dbp;
- EPG *epg;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- /* Release inner pages first. */
- for (epg = cp->sp; epg <= cp->csp; ++epg) {
- if (epg->page != NULL)
- (void)memp_fput(dbp->mpf, epg->page, 0);
- if (epg->lock != LOCK_INVALID) {
- if (nolocks)
- (void)__BT_LPUT(dbc, epg->lock);
- else
- (void)__BT_TLPUT(dbc, epg->lock);
- }
- }
-
- /* Clear the stack, all pages have been released. */
- BT_STK_CLR(cp);
-
- return (0);
-}
-
-/*
- * __bam_stkgrow --
- * Grow the stack.
- *
- * PUBLIC: int __bam_stkgrow __P((CURSOR *));
- */
-int
-__bam_stkgrow(cp)
- CURSOR *cp;
-{
- EPG *p;
- size_t entries;
- int ret;
-
- entries = cp->esp - cp->sp;
-
- if ((ret = __os_calloc(entries * 2, sizeof(EPG), &p)) != 0)
- return (ret);
- memcpy(p, cp->sp, entries * sizeof(EPG));
- if (cp->sp != cp->stack)
- __os_free(cp->sp, entries * sizeof(EPG));
- cp->sp = p;
- cp->csp = p + entries;
- cp->esp = p + entries * 2;
- return (0);
-}
diff --git a/db2/btree/bt_split.c b/db2/btree/bt_split.c
deleted file mode 100644
index 1d8e926..0000000
--- a/db2/btree/bt_split.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_split.c 10.33 (Sleepycat) 10/13/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *));
-static int __bam_page __P((DBC *, EPG *, EPG *));
-static int __bam_pinsert __P((DBC *, EPG *, PAGE *, PAGE *));
-static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *));
-static int __bam_root __P((DBC *, EPG *));
-static int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *));
-
-/*
- * __bam_split --
- * Split a page.
- *
- * PUBLIC: int __bam_split __P((DBC *, void *));
- */
-int
-__bam_split(dbc, arg)
- DBC *dbc;
- void *arg;
-{
- CURSOR *cp;
- DB *dbp;
- enum { UP, DOWN } dir;
- int exact, level, ret;
-
- dbp = dbc->dbp;
- cp = dbc->internal;
-
- /*
- * The locking protocol we use to avoid deadlock to acquire locks by
- * walking down the tree, but we do it as lazily as possible, locking
- * the root only as a last resort. We expect all stack pages to have
- * been discarded before we're called; we discard all short-term locks.
- *
- * When __bam_split is first called, we know that a leaf page was too
- * full for an insert. We don't know what leaf page it was, but we
- * have the key/recno that caused the problem. We call XX_search to
- * reacquire the leaf page, but this time get both the leaf page and
- * its parent, locked. We then split the leaf page and see if the new
- * internal key will fit into the parent page. If it will, we're done.
- *
- * If it won't, we discard our current locks and repeat the process,
- * only this time acquiring the parent page and its parent, locked.
- * This process repeats until we succeed in the split, splitting the
- * root page as the final resort. The entire process then repeats,
- * as necessary, until we split a leaf page.
- *
- * XXX
- * A traditional method of speeding this up is to maintain a stack of
- * the pages traversed in the original search. You can detect if the
- * stack is correct by storing the page's LSN when it was searched and
- * comparing that LSN with the current one when it's locked during the
- * split. This would be an easy change for this code, but I have no
- * numbers that indicate it's worthwhile.
- */
- for (dir = UP, level = LEAFLEVEL;; dir == UP ? ++level : --level) {
- /*
- * Acquire a page and its parent, locked.
- */
- if ((ret = (dbp->type == DB_BTREE ?
- __bam_search(dbc, arg, S_WRPAIR, level, NULL, &exact) :
- __bam_rsearch(dbc,
- (db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0)
- return (ret);
-
- /* Split the page. */
- ret = cp->csp[0].page->pgno == PGNO_ROOT ?
- __bam_root(dbc, &cp->csp[0]) :
- __bam_page(dbc, &cp->csp[-1], &cp->csp[0]);
- BT_STK_CLR(cp);
-
- switch (ret) {
- case 0:
- /* Once we've split the leaf page, we're done. */
- if (level == LEAFLEVEL)
- return (0);
-
- /* Switch directions. */
- if (dir == UP)
- dir = DOWN;
- break;
- case DB_NEEDSPLIT:
- /*
- * It's possible to fail to split repeatedly, as other
- * threads may be modifying the tree, or the page usage
- * is sufficiently bad that we don't get enough space
- * the first time.
- */
- if (dir == DOWN)
- dir = UP;
- break;
- default:
- return (ret);
- }
- }
- /* NOTREACHED */
-}
-
-/*
- * __bam_root --
- * Split the root page of a btree.
- */
-static int
-__bam_root(dbc, cp)
- DBC *dbc;
- EPG *cp;
-{
- DB *dbp;
- PAGE *lp, *rp;
- db_indx_t split;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Yeah, right. */
- if (cp->page->level >= MAXBTREELEVEL) {
- ret = ENOSPC;
- goto err;
- }
-
- /* Create new left and right pages for the split. */
- lp = rp = NULL;
- if ((ret = __bam_new(dbc, TYPE(cp->page), &lp)) != 0 ||
- (ret = __bam_new(dbc, TYPE(cp->page), &rp)) != 0)
- goto err;
- P_INIT(lp, dbp->pgsize, lp->pgno,
- PGNO_INVALID, ISINTERNAL(cp->page) ? PGNO_INVALID : rp->pgno,
- cp->page->level, TYPE(cp->page));
- P_INIT(rp, dbp->pgsize, rp->pgno,
- ISINTERNAL(cp->page) ? PGNO_INVALID : lp->pgno, PGNO_INVALID,
- cp->page->level, TYPE(cp->page));
-
- /* Split the page. */
- if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0)
- goto err;
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- DBT __a;
- DB_LSN __lsn;
- memset(&__a, 0, sizeof(__a));
- __a.data = cp->page;
- __a.size = dbp->pgsize;
- ZERO_LSN(__lsn);
- if ((ret = __bam_split_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(cp->page), 0, dbp->log_fileid, PGNO(lp), &LSN(lp),
- PGNO(rp), &LSN(rp), (u_int32_t)NUM_ENT(lp), 0, &__lsn,
- &__a)) != 0)
- goto err;
- LSN(lp) = LSN(rp) = LSN(cp->page);
- }
-
- /* Clean up the new root page. */
- if ((ret = (dbp->type == DB_RECNO ?
- __ram_root(dbc, cp->page, lp, rp) :
- __bam_broot(dbc, cp->page, lp, rp))) != 0)
- goto err;
-
- /* Adjust any cursors. Do it last so we don't have to undo it. */
- __bam_ca_split(dbp, cp->page->pgno, lp->pgno, rp->pgno, split, 1);
-
- /* Success -- write the real pages back to the store. */
- (void)memp_fput(dbp->mpf, cp->page, DB_MPOOL_DIRTY);
- (void)__BT_TLPUT(dbc, cp->lock);
- (void)memp_fput(dbp->mpf, lp, DB_MPOOL_DIRTY);
- (void)memp_fput(dbp->mpf, rp, DB_MPOOL_DIRTY);
-
- return (0);
-
-err: if (lp != NULL)
- (void)__bam_free(dbc, lp);
- if (rp != NULL)
- (void)__bam_free(dbc, rp);
- (void)memp_fput(dbp->mpf, cp->page, 0);
- (void)__BT_TLPUT(dbc, cp->lock);
- return (ret);
-}
-
-/*
- * __bam_page --
- * Split the non-root page of a btree.
- */
-static int
-__bam_page(dbc, pp, cp)
- DBC *dbc;
- EPG *pp, *cp;
-{
- DB *dbp;
- DB_LOCK tplock;
- PAGE *lp, *rp, *tp;
- db_indx_t split;
- int ret;
-
- dbp = dbc->dbp;
- lp = rp = tp = NULL;
- ret = -1;
-
- /* Create new right page for the split. */
- if ((ret = __bam_new(dbc, TYPE(cp->page), &rp)) != 0)
- goto err;
- P_INIT(rp, dbp->pgsize, rp->pgno,
- ISINTERNAL(cp->page) ? PGNO_INVALID : cp->page->pgno,
- ISINTERNAL(cp->page) ? PGNO_INVALID : cp->page->next_pgno,
- cp->page->level, TYPE(cp->page));
-
- /* Create new left page for the split. */
- if ((ret = __os_malloc(dbp->pgsize, NULL, &lp)) != 0)
- goto err;
- P_INIT(lp, dbp->pgsize, cp->page->pgno,
- ISINTERNAL(cp->page) ? PGNO_INVALID : cp->page->prev_pgno,
- ISINTERNAL(cp->page) ? PGNO_INVALID : rp->pgno,
- cp->page->level, TYPE(cp->page));
- ZERO_LSN(lp->lsn);
-
- /*
- * Split right.
- *
- * Only the indices are sorted on the page, i.e., the key/data pairs
- * aren't, so it's simpler to copy the data from the split page onto
- * two new pages instead of copying half the data to the right page
- * and compacting the left page in place. Since the left page can't
- * change, we swap the original and the allocated left page after the
- * split.
- */
- if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0)
- goto err;
-
- /*
- * Fix up the previous pointer of any leaf page following the split
- * page.
- *
- * !!!
- * There are interesting deadlock situations here as we write-lock a
- * page that's not in our direct ancestry. Consider a cursor walking
- * through the leaf pages, that has the previous page read-locked and
- * is waiting on a lock for the page we just split. It will deadlock
- * here. If this is a problem, we can fail in the split; it's not a
- * problem as the split will succeed after the cursor passes through
- * the page we're splitting.
- */
- if (TYPE(cp->page) == P_LBTREE && rp->next_pgno != PGNO_INVALID) {
- if ((ret = __bam_lget(dbc,
- 0, rp->next_pgno, DB_LOCK_WRITE, &tplock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &rp->next_pgno, 0, &tp)) != 0)
- goto err;
- }
-
- /* Insert the new pages into the parent page. */
- if ((ret = __bam_pinsert(dbc, pp, lp, rp)) != 0)
- goto err;
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- DBT __a;
- DB_LSN __lsn;
- memset(&__a, 0, sizeof(__a));
- __a.data = cp->page;
- __a.size = dbp->pgsize;
- if (tp == NULL)
- ZERO_LSN(__lsn);
- if ((ret = __bam_split_log(dbp->dbenv->lg_info, dbc->txn,
- &cp->page->lsn, 0, dbp->log_fileid, PGNO(cp->page),
- &LSN(cp->page), PGNO(rp), &LSN(rp), (u_int32_t)NUM_ENT(lp),
- tp == NULL ? 0 : PGNO(tp),
- tp == NULL ? &__lsn : &LSN(tp), &__a)) != 0)
- goto err;
-
- LSN(lp) = LSN(rp) = LSN(cp->page);
- if (tp != NULL)
- LSN(tp) = LSN(cp->page);
- }
-
- /* Copy the allocated page into place. */
- memcpy(cp->page, lp, LOFFSET(lp));
- memcpy((u_int8_t *)cp->page + HOFFSET(lp),
- (u_int8_t *)lp + HOFFSET(lp), dbp->pgsize - HOFFSET(lp));
- __os_free(lp, dbp->pgsize);
- lp = NULL;
-
- /* Finish the next-page link. */
- if (tp != NULL)
- tp->prev_pgno = rp->pgno;
-
- /* Adjust any cursors. Do so last so we don't have to undo it. */
- __bam_ca_split(dbp, cp->page->pgno, cp->page->pgno, rp->pgno, split, 0);
-
- /* Success -- write the real pages back to the store. */
- (void)memp_fput(dbp->mpf, pp->page, DB_MPOOL_DIRTY);
- (void)__BT_TLPUT(dbc, pp->lock);
- (void)memp_fput(dbp->mpf, cp->page, DB_MPOOL_DIRTY);
- (void)__BT_TLPUT(dbc, cp->lock);
- (void)memp_fput(dbp->mpf, rp, DB_MPOOL_DIRTY);
- if (tp != NULL) {
- (void)memp_fput(dbp->mpf, tp, DB_MPOOL_DIRTY);
- (void)__BT_TLPUT(dbc, tplock);
- }
- return (0);
-
-err: if (lp != NULL)
- __os_free(lp, dbp->pgsize);
- if (rp != NULL)
- (void)__bam_free(dbc, rp);
- if (tp != NULL) {
- (void)memp_fput(dbp->mpf, tp, 0);
- if (ret == DB_NEEDSPLIT)
- (void)__BT_LPUT(dbc, tplock);
- else
- (void)__BT_TLPUT(dbc, tplock);
- }
- (void)memp_fput(dbp->mpf, pp->page, 0);
- if (ret == DB_NEEDSPLIT)
- (void)__BT_LPUT(dbc, pp->lock);
- else
- (void)__BT_TLPUT(dbc, pp->lock);
- (void)memp_fput(dbp->mpf, cp->page, 0);
- if (ret == DB_NEEDSPLIT)
- (void)__BT_LPUT(dbc, cp->lock);
- else
- (void)__BT_TLPUT(dbc, cp->lock);
- return (ret);
-}
-
-/*
- * __bam_broot --
- * Fix up the btree root page after it has been split.
- */
-static int
-__bam_broot(dbc, rootp, lp, rp)
- DBC *dbc;
- PAGE *rootp, *lp, *rp;
-{
- BINTERNAL bi, *child_bi;
- BKEYDATA *child_bk;
- DB *dbp;
- DBT hdr, data;
- int ret;
-
- dbp = dbc->dbp;
-
- /*
- * If the root page was a leaf page, change it into an internal page.
- * We copy the key we split on (but not the key's data, in the case of
- * a leaf page) to the new root page.
- */
- P_INIT(rootp, dbp->pgsize,
- PGNO_ROOT, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IBTREE);
-
- memset(&data, 0, sizeof(data));
- memset(&hdr, 0, sizeof(hdr));
-
- /*
- * The btree comparison code guarantees that the left-most key on any
- * level of the tree is never used, so it doesn't need to be filled in.
- */
- memset(&bi, 0, sizeof(bi));
- bi.len = 0;
- B_TSET(bi.type, B_KEYDATA, 0);
- bi.pgno = lp->pgno;
- if (F_ISSET(dbp, DB_BT_RECNUM)) {
- bi.nrecs = __bam_total(lp);
- RE_NREC_SET(rootp, bi.nrecs);
- }
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- if ((ret =
- __db_pitem(dbc, rootp, 0, BINTERNAL_SIZE(0), &hdr, NULL)) != 0)
- return (ret);
-
- switch (TYPE(rp)) {
- case P_IBTREE:
- /* Copy the first key of the child page onto the root page. */
- child_bi = GET_BINTERNAL(rp, 0);
-
- bi.len = child_bi->len;
- B_TSET(bi.type, child_bi->type, 0);
- bi.pgno = rp->pgno;
- if (F_ISSET(dbp, DB_BT_RECNUM)) {
- bi.nrecs = __bam_total(rp);
- RE_NREC_ADJ(rootp, bi.nrecs);
- }
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- data.data = child_bi->data;
- data.size = child_bi->len;
- if ((ret = __db_pitem(dbc, rootp, 1,
- BINTERNAL_SIZE(child_bi->len), &hdr, &data)) != 0)
- return (ret);
-
- /* Increment the overflow ref count. */
- if (B_TYPE(child_bi->type) == B_OVERFLOW)
- if ((ret = __db_ovref(dbc,
- ((BOVERFLOW *)(child_bi->data))->pgno, 1)) != 0)
- return (ret);
- break;
- case P_LBTREE:
- /* Copy the first key of the child page onto the root page. */
- child_bk = GET_BKEYDATA(rp, 0);
- switch (B_TYPE(child_bk->type)) {
- case B_KEYDATA:
- bi.len = child_bk->len;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = rp->pgno;
- if (F_ISSET(dbp, DB_BT_RECNUM)) {
- bi.nrecs = __bam_total(rp);
- RE_NREC_ADJ(rootp, bi.nrecs);
- }
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- data.data = child_bk->data;
- data.size = child_bk->len;
- if ((ret = __db_pitem(dbc, rootp, 1,
- BINTERNAL_SIZE(child_bk->len), &hdr, &data)) != 0)
- return (ret);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- bi.len = BOVERFLOW_SIZE;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = rp->pgno;
- if (F_ISSET(dbp, DB_BT_RECNUM)) {
- bi.nrecs = __bam_total(rp);
- RE_NREC_ADJ(rootp, bi.nrecs);
- }
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- data.data = child_bk;
- data.size = BOVERFLOW_SIZE;
- if ((ret = __db_pitem(dbc, rootp, 1,
- BINTERNAL_SIZE(BOVERFLOW_SIZE), &hdr, &data)) != 0)
- return (ret);
-
- /* Increment the overflow ref count. */
- if (B_TYPE(child_bk->type) == B_OVERFLOW)
- if ((ret = __db_ovref(dbc,
- ((BOVERFLOW *)child_bk)->pgno, 1)) != 0)
- return (ret);
- break;
- default:
- return (__db_pgfmt(dbp, rp->pgno));
- }
- break;
- default:
- return (__db_pgfmt(dbp, rp->pgno));
- }
- return (0);
-}
-
-/*
- * __ram_root --
- * Fix up the recno root page after it has been split.
- */
-static int
-__ram_root(dbc, rootp, lp, rp)
- DBC *dbc;
- PAGE *rootp, *lp, *rp;
-{
- DB *dbp;
- DBT hdr;
- RINTERNAL ri;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Initialize the page. */
- P_INIT(rootp, dbp->pgsize,
- PGNO_ROOT, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IRECNO);
-
- /* Initialize the header. */
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &ri;
- hdr.size = RINTERNAL_SIZE;
-
- /* Insert the left and right keys, set the header information. */
- ri.pgno = lp->pgno;
- ri.nrecs = __bam_total(lp);
- if ((ret = __db_pitem(dbc, rootp, 0, RINTERNAL_SIZE, &hdr, NULL)) != 0)
- return (ret);
- RE_NREC_SET(rootp, ri.nrecs);
- ri.pgno = rp->pgno;
- ri.nrecs = __bam_total(rp);
- if ((ret = __db_pitem(dbc, rootp, 1, RINTERNAL_SIZE, &hdr, NULL)) != 0)
- return (ret);
- RE_NREC_ADJ(rootp, ri.nrecs);
- return (0);
-}
-
-/*
- * __bam_pinsert --
- * Insert a new key into a parent page, completing the split.
- */
-static int
-__bam_pinsert(dbc, parent, lchild, rchild)
- DBC *dbc;
- EPG *parent;
- PAGE *lchild, *rchild;
-{
- BINTERNAL bi, *child_bi;
- BKEYDATA *child_bk, *tmp_bk;
- BTREE *t;
- DB *dbp;
- DBT a, b, hdr, data;
- PAGE *ppage;
- RINTERNAL ri;
- db_indx_t off;
- db_recno_t nrecs;
- u_int32_t n, nbytes, nksize;
- int ret;
-
- dbp = dbc->dbp;
- t = dbp->internal;
- ppage = parent->page;
-
- /* If handling record numbers, count records split to the right page. */
- nrecs = dbp->type == DB_RECNO || F_ISSET(dbp, DB_BT_RECNUM) ?
- __bam_total(rchild) : 0;
-
- /*
- * Now we insert the new page's first key into the parent page, which
- * completes the split. The parent points to a PAGE and a page index
- * offset, where the new key goes ONE AFTER the index, because we split
- * to the right.
- *
- * XXX
- * Some btree algorithms replace the key for the old page as well as
- * the new page. We don't, as there's no reason to believe that the
- * first key on the old page is any better than the key we have, and,
- * in the case of a key being placed at index 0 causing the split, the
- * key is unavailable.
- */
- off = parent->indx + O_INDX;
-
- /*
- * Calculate the space needed on the parent page.
- *
- * Prefix trees: space hack used when inserting into BINTERNAL pages.
- * Retain only what's needed to distinguish between the new entry and
- * the LAST entry on the page to its left. If the keys compare equal,
- * retain the entire key. We ignore overflow keys, and the entire key
- * must be retained for the next-to-leftmost key on the leftmost page
- * of each level, or the search will fail. Applicable ONLY to internal
- * pages that have leaf pages as children. Further reduction of the
- * key between pairs of internal pages loses too much information.
- */
- switch (TYPE(rchild)) {
- case P_IBTREE:
- child_bi = GET_BINTERNAL(rchild, 0);
- nbytes = BINTERNAL_PSIZE(child_bi->len);
-
- if (P_FREESPACE(ppage) < nbytes)
- return (DB_NEEDSPLIT);
-
- /* Add a new record for the right page. */
- memset(&bi, 0, sizeof(bi));
- bi.len = child_bi->len;
- B_TSET(bi.type, child_bi->type, 0);
- bi.pgno = rchild->pgno;
- bi.nrecs = nrecs;
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- memset(&data, 0, sizeof(data));
- data.data = child_bi->data;
- data.size = child_bi->len;
- if ((ret = __db_pitem(dbc, ppage, off,
- BINTERNAL_SIZE(child_bi->len), &hdr, &data)) != 0)
- return (ret);
-
- /* Increment the overflow ref count. */
- if (B_TYPE(child_bi->type) == B_OVERFLOW)
- if ((ret = __db_ovref(dbc,
- ((BOVERFLOW *)(child_bi->data))->pgno, 1)) != 0)
- return (ret);
- break;
- case P_LBTREE:
- child_bk = GET_BKEYDATA(rchild, 0);
- switch (B_TYPE(child_bk->type)) {
- case B_KEYDATA:
- nbytes = BINTERNAL_PSIZE(child_bk->len);
- nksize = child_bk->len;
- if (t->bt_prefix == NULL)
- goto noprefix;
- if (ppage->prev_pgno == PGNO_INVALID && off <= 1)
- goto noprefix;
- tmp_bk = GET_BKEYDATA(lchild, NUM_ENT(lchild) - P_INDX);
- if (B_TYPE(tmp_bk->type) != B_KEYDATA)
- goto noprefix;
- memset(&a, 0, sizeof(a));
- a.size = tmp_bk->len;
- a.data = tmp_bk->data;
- memset(&b, 0, sizeof(b));
- b.size = child_bk->len;
- b.data = child_bk->data;
- nksize = t->bt_prefix(&a, &b);
- if ((n = BINTERNAL_PSIZE(nksize)) < nbytes)
- nbytes = n;
- else
-noprefix: nksize = child_bk->len;
-
- if (P_FREESPACE(ppage) < nbytes)
- return (DB_NEEDSPLIT);
-
- memset(&bi, 0, sizeof(bi));
- bi.len = nksize;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = rchild->pgno;
- bi.nrecs = nrecs;
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- memset(&data, 0, sizeof(data));
- data.data = child_bk->data;
- data.size = nksize;
- if ((ret = __db_pitem(dbc, ppage, off,
- BINTERNAL_SIZE(nksize), &hdr, &data)) != 0)
- return (ret);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- nbytes = BINTERNAL_PSIZE(BOVERFLOW_SIZE);
-
- if (P_FREESPACE(ppage) < nbytes)
- return (DB_NEEDSPLIT);
-
- memset(&bi, 0, sizeof(bi));
- bi.len = BOVERFLOW_SIZE;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = rchild->pgno;
- bi.nrecs = nrecs;
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &bi;
- hdr.size = SSZA(BINTERNAL, data);
- memset(&data, 0, sizeof(data));
- data.data = child_bk;
- data.size = BOVERFLOW_SIZE;
- if ((ret = __db_pitem(dbc, ppage, off,
- BINTERNAL_SIZE(BOVERFLOW_SIZE), &hdr, &data)) != 0)
- return (ret);
-
- /* Increment the overflow ref count. */
- if (B_TYPE(child_bk->type) == B_OVERFLOW)
- if ((ret = __db_ovref(dbc,
- ((BOVERFLOW *)child_bk)->pgno, 1)) != 0)
- return (ret);
- break;
- default:
- return (__db_pgfmt(dbp, rchild->pgno));
- }
- break;
- case P_IRECNO:
- case P_LRECNO:
- nbytes = RINTERNAL_PSIZE;
-
- if (P_FREESPACE(ppage) < nbytes)
- return (DB_NEEDSPLIT);
-
- /* Add a new record for the right page. */
- memset(&hdr, 0, sizeof(hdr));
- hdr.data = &ri;
- hdr.size = RINTERNAL_SIZE;
- ri.pgno = rchild->pgno;
- ri.nrecs = nrecs;
- if ((ret = __db_pitem(dbc,
- ppage, off, RINTERNAL_SIZE, &hdr, NULL)) != 0)
- return (ret);
- break;
- default:
- return (__db_pgfmt(dbp, rchild->pgno));
- }
-
- /* Adjust the parent page's left page record count. */
- if (dbp->type == DB_RECNO || F_ISSET(dbp, DB_BT_RECNUM)) {
- /* Log the change. */
- if (DB_LOGGING(dbc) &&
- (ret = __bam_cadjust_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(ppage), 0, dbp->log_fileid,
- PGNO(ppage), &LSN(ppage), (u_int32_t)parent->indx,
- -(int32_t)nrecs, (int32_t)0)) != 0)
- return (ret);
-
- /* Update the left page count. */
- if (dbp->type == DB_RECNO)
- GET_RINTERNAL(ppage, parent->indx)->nrecs -= nrecs;
- else
- GET_BINTERNAL(ppage, parent->indx)->nrecs -= nrecs;
- }
-
- return (0);
-}
-
-/*
- * __bam_psplit --
- * Do the real work of splitting the page.
- */
-static int
-__bam_psplit(dbc, cp, lp, rp, splitret)
- DBC *dbc;
- EPG *cp;
- PAGE *lp, *rp;
- db_indx_t *splitret;
-{
- DB *dbp;
- PAGE *pp;
- db_indx_t half, nbytes, off, splitp, top;
- int adjust, cnt, isbigkey, ret;
-
- dbp = dbc->dbp;
- pp = cp->page;
- adjust = TYPE(pp) == P_LBTREE ? P_INDX : O_INDX;
-
- /*
- * If we're splitting the first (last) page on a level because we're
- * inserting (appending) a key to it, it's likely that the data is
- * sorted. Moving a single item to the new page is less work and can
- * push the fill factor higher than normal. If we're wrong it's not
- * a big deal, we'll just do the split the right way next time.
- */
- off = 0;
- if (NEXT_PGNO(pp) == PGNO_INVALID &&
- ((ISINTERNAL(pp) && cp->indx == NUM_ENT(cp->page) - 1) ||
- (!ISINTERNAL(pp) && cp->indx == NUM_ENT(cp->page))))
- off = NUM_ENT(cp->page) - adjust;
- else if (PREV_PGNO(pp) == PGNO_INVALID && cp->indx == 0)
- off = adjust;
-
- if (off != 0)
- goto sort;
-
- /*
- * Split the data to the left and right pages. Try not to split on
- * an overflow key. (Overflow keys on internal pages will slow down
- * searches.) Refuse to split in the middle of a set of duplicates.
- *
- * First, find the optimum place to split.
- *
- * It's possible to try and split past the last record on the page if
- * there's a very large record at the end of the page. Make sure this
- * doesn't happen by bounding the check at the next-to-last entry on
- * the page.
- *
- * Note, we try and split half the data present on the page. This is
- * because another process may have already split the page and left
- * it half empty. We don't try and skip the split -- we don't know
- * how much space we're going to need on the page, and we may need up
- * to half the page for a big item, so there's no easy test to decide
- * if we need to split or not. Besides, if two threads are inserting
- * data into the same place in the database, we're probably going to
- * need more space soon anyway.
- */
- top = NUM_ENT(pp) - adjust;
- half = (dbp->pgsize - HOFFSET(pp)) / 2;
- for (nbytes = 0, off = 0; off < top && nbytes < half; ++off)
- switch (TYPE(pp)) {
- case P_IBTREE:
- if (B_TYPE(GET_BINTERNAL(pp, off)->type) == B_KEYDATA)
- nbytes +=
- BINTERNAL_SIZE(GET_BINTERNAL(pp, off)->len);
- else
- nbytes += BINTERNAL_SIZE(BOVERFLOW_SIZE);
- break;
- case P_LBTREE:
- if (B_TYPE(GET_BKEYDATA(pp, off)->type) == B_KEYDATA)
- nbytes +=
- BKEYDATA_SIZE(GET_BKEYDATA(pp, off)->len);
- else
- nbytes += BOVERFLOW_SIZE;
-
- ++off;
- if (B_TYPE(GET_BKEYDATA(pp, off)->type) == B_KEYDATA)
- nbytes +=
- BKEYDATA_SIZE(GET_BKEYDATA(pp, off)->len);
- else
- nbytes += BOVERFLOW_SIZE;
- break;
- case P_IRECNO:
- nbytes += RINTERNAL_SIZE;
- break;
- case P_LRECNO:
- nbytes += BKEYDATA_SIZE(GET_BKEYDATA(pp, off)->len);
- break;
- default:
- return (__db_pgfmt(dbp, pp->pgno));
- }
-sort: splitp = off;
-
- /*
- * Splitp is either at or just past the optimum split point. If
- * it's a big key, try and find something close by that's not.
- */
- if (TYPE(pp) == P_IBTREE)
- isbigkey = B_TYPE(GET_BINTERNAL(pp, off)->type) != B_KEYDATA;
- else if (TYPE(pp) == P_LBTREE)
- isbigkey = B_TYPE(GET_BKEYDATA(pp, off)->type) != B_KEYDATA;
- else
- isbigkey = 0;
- if (isbigkey)
- for (cnt = 1; cnt <= 3; ++cnt) {
- off = splitp + cnt * adjust;
- if (off < (db_indx_t)NUM_ENT(pp) &&
- ((TYPE(pp) == P_IBTREE &&
- B_TYPE(GET_BINTERNAL(pp,off)->type) == B_KEYDATA) ||
- B_TYPE(GET_BKEYDATA(pp, off)->type) == B_KEYDATA)) {
- splitp = off;
- break;
- }
- if (splitp <= (db_indx_t)(cnt * adjust))
- continue;
- off = splitp - cnt * adjust;
- if (TYPE(pp) == P_IBTREE ?
- B_TYPE(GET_BINTERNAL(pp, off)->type) == B_KEYDATA :
- B_TYPE(GET_BKEYDATA(pp, off)->type) == B_KEYDATA) {
- splitp = off;
- break;
- }
- }
-
- /*
- * We can't split in the middle a set of duplicates. We know that
- * no duplicate set can take up more than about 25% of the page,
- * because that's the point where we push it off onto a duplicate
- * page set. So, this loop can't be unbounded.
- */
- if (F_ISSET(dbp, DB_AM_DUP) && TYPE(pp) == P_LBTREE &&
- pp->inp[splitp] == pp->inp[splitp - adjust])
- for (cnt = 1;; ++cnt) {
- off = splitp + cnt * adjust;
- if (off < NUM_ENT(pp) &&
- pp->inp[splitp] != pp->inp[off]) {
- splitp = off;
- break;
- }
- if (splitp <= (db_indx_t)(cnt * adjust))
- continue;
- off = splitp - cnt * adjust;
- if (pp->inp[splitp] != pp->inp[off]) {
- splitp = off + adjust;
- break;
- }
- }
-
-
- /* We're going to split at splitp. */
- if ((ret = __bam_copy(dbp, pp, lp, 0, splitp)) != 0)
- return (ret);
- if ((ret = __bam_copy(dbp, pp, rp, splitp, NUM_ENT(pp))) != 0)
- return (ret);
-
- *splitret = splitp;
- return (0);
-}
-
-/*
- * __bam_copy --
- * Copy a set of records from one page to another.
- *
- * PUBLIC: int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
- */
-int
-__bam_copy(dbp, pp, cp, nxt, stop)
- DB *dbp;
- PAGE *pp, *cp;
- u_int32_t nxt, stop;
-{
- db_indx_t nbytes, off;
-
- /*
- * Copy the rest of the data to the right page. Nxt is the next
- * offset placed on the target page.
- */
- for (off = 0; nxt < stop; ++nxt, ++NUM_ENT(cp), ++off) {
- switch (TYPE(pp)) {
- case P_IBTREE:
- if (B_TYPE(GET_BINTERNAL(pp, nxt)->type) == B_KEYDATA)
- nbytes =
- BINTERNAL_SIZE(GET_BINTERNAL(pp, nxt)->len);
- else
- nbytes = BINTERNAL_SIZE(BOVERFLOW_SIZE);
- break;
- case P_LBTREE:
- /*
- * If we're on a key and it's a duplicate, just copy
- * the offset.
- */
- if (off != 0 && (nxt % P_INDX) == 0 &&
- pp->inp[nxt] == pp->inp[nxt - P_INDX]) {
- cp->inp[off] = cp->inp[off - P_INDX];
- continue;
- }
- /* FALLTHROUGH */
- case P_LRECNO:
- if (B_TYPE(GET_BKEYDATA(pp, nxt)->type) == B_KEYDATA)
- nbytes =
- BKEYDATA_SIZE(GET_BKEYDATA(pp, nxt)->len);
- else
- nbytes = BOVERFLOW_SIZE;
- break;
- case P_IRECNO:
- nbytes = RINTERNAL_SIZE;
- break;
- default:
- return (__db_pgfmt(dbp, pp->pgno));
- }
- cp->inp[off] = HOFFSET(cp) -= nbytes;
- memcpy(P_ENTRY(cp, off), P_ENTRY(pp, nxt), nbytes);
- }
- return (0);
-}
diff --git a/db2/btree/bt_stat.c b/db2/btree/bt_stat.c
deleted file mode 100644
index 855ef40..0000000
--- a/db2/btree/bt_stat.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)bt_stat.c 10.27 (Sleepycat) 11/25/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-
-/*
- * __bam_stat --
- * Gather/print the btree statistics
- *
- * PUBLIC: int __bam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
- */
-int
-__bam_stat(dbp, spp, db_malloc, flags)
- DB *dbp;
- void *spp;
- void *(*db_malloc) __P((size_t));
- u_int32_t flags;
-{
- BTMETA *meta;
- BTREE *t;
- DBC *dbc;
- DB_BTREE_STAT *sp;
- DB_LOCK lock;
- PAGE *h;
- db_pgno_t lastpgno, pgno;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- /* Check for invalid flags. */
- if ((ret = __db_statchk(dbp, flags)) != 0)
- return (ret);
-
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, NULL, "bam_stat", NULL, NULL, flags);
-
- t = dbp->internal;
-
- if (spp == NULL)
- return (0);
-
- /* Allocate and clear the structure. */
- if ((ret = __os_malloc(sizeof(*sp), db_malloc, &sp)) != 0)
- goto err;
- memset(sp, 0, sizeof(*sp));
-
- /* If the app just wants the record count, make it fast. */
- if (flags == DB_RECORDCOUNT) {
- pgno = PGNO_ROOT;
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &lock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, (PAGE **)&h)) != 0)
- goto err;
-
- sp->bt_nrecs = RE_NREC(h);
-
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- goto done;
- }
-
- /* Get the meta-data page. */
- pgno = PGNO_METADATA;
- if ((ret = __bam_lget(dbc, 0, pgno, DB_LOCK_READ, &lock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, (PAGE **)&meta)) != 0)
- goto err;
-
- /* Translate the metadata flags. */
- if (F_ISSET(meta, BTM_DUP))
- sp->bt_flags |= DB_DUP;
- if (F_ISSET(meta, BTM_FIXEDLEN))
- sp->bt_flags |= DB_FIXEDLEN;
- if (F_ISSET(meta, BTM_RECNUM))
- sp->bt_flags |= DB_RECNUM;
- if (F_ISSET(meta, BTM_RENUMBER))
- sp->bt_flags |= DB_RENUMBER;
-
- /* Get the remaining metadata fields. */
- sp->bt_minkey = meta->minkey;
- sp->bt_maxkey = meta->maxkey;
- sp->bt_re_len = meta->re_len;
- sp->bt_re_pad = meta->re_pad;
- sp->bt_magic = meta->magic;
- sp->bt_version = meta->version;
-
- /* Get the page size from the DB. */
- sp->bt_pagesize = dbp->pgsize;
-
- /* Walk the free list, counting pages. */
- for (sp->bt_free = 0, pgno = meta->free; pgno != PGNO_INVALID;) {
- ++sp->bt_free;
-
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
- (void)memp_fput(dbp->mpf, meta, 0);
- (void)__BT_TLPUT(dbc, lock);
- goto err;
- }
- pgno = h->next_pgno;
- (void)memp_fput(dbp->mpf, h, 0);
- }
-
- /* Discard the meta-data page. */
- (void)memp_fput(dbp->mpf, meta, 0);
- (void)__BT_TLPUT(dbc, lock);
-
- /* Determine the last page of the database. */
- if ((ret = memp_fget(dbp->mpf, &lastpgno, DB_MPOOL_LAST, &h)) != 0)
- goto err;
- (void)memp_fput(dbp->mpf, h, 0);
-
- /* Get the root page. */
- pgno = PGNO_ROOT;
- if ((ret = __bam_lget(dbc, 0, PGNO_ROOT, DB_LOCK_READ, &lock)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
- (void)__BT_LPUT(dbc, lock);
- goto err;
- }
-
- /* Get the levels from the root page. */
- sp->bt_levels = h->level;
-
- /* Walk the page list, counting things. */
- for (;;) {
- switch (TYPE(h)) {
- case P_INVALID:
- break;
- case P_IBTREE:
- case P_IRECNO:
- ++sp->bt_int_pg;
- sp->bt_int_pgfree += HOFFSET(h) - LOFFSET(h);
- break;
- case P_LBTREE:
- ++sp->bt_leaf_pg;
- sp->bt_leaf_pgfree += HOFFSET(h) - LOFFSET(h);
- sp->bt_nrecs += NUM_ENT(h) / P_INDX;
- break;
- case P_LRECNO:
- ++sp->bt_leaf_pg;
- sp->bt_leaf_pgfree += HOFFSET(h) - LOFFSET(h);
- sp->bt_nrecs += NUM_ENT(h);
- break;
- case P_DUPLICATE:
- ++sp->bt_dup_pg;
- /* XXX MARGO: sp->bt_dup_pgfree; */
- break;
- case P_OVERFLOW:
- ++sp->bt_over_pg;
- /* XXX MARGO: sp->bt_over_pgfree; */
- break;
- default:
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
- return (__db_pgfmt(dbp, pgno));
- }
-
- (void)memp_fput(dbp->mpf, h, 0);
- (void)__BT_LPUT(dbc, lock);
-
- if (++pgno > lastpgno)
- break;
- if (__bam_lget(dbc, 0, pgno, DB_LOCK_READ, &lock))
- break;
- if (memp_fget(dbp->mpf, &pgno, 0, &h) != 0) {
- (void)__BT_LPUT(dbc, lock);
- break;
- }
- }
-
-done: *(DB_BTREE_STAT **)spp = sp;
- ret = 0;
-
-err: if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
diff --git a/db2/btree/btree_auto.c b/db2/btree/btree_auto.c
deleted file mode 100644
index 95ea76e..0000000
--- a/db2/btree/btree_auto.c
+++ /dev/null
@@ -1,1508 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "btree.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __bam_pg_alloc_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, DB_LSN *, DB_LSN *, db_pgno_t,
- * PUBLIC: u_int32_t, db_pgno_t));
- */
-int __bam_pg_alloc_log(logp, txnid, ret_lsnp, flags,
- fileid, meta_lsn, page_lsn, pgno, ptype, next)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- DB_LSN * meta_lsn;
- DB_LSN * page_lsn;
- db_pgno_t pgno;
- u_int32_t ptype;
- db_pgno_t next;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_pg_alloc;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(*meta_lsn)
- + sizeof(*page_lsn)
- + sizeof(pgno)
- + sizeof(ptype)
- + sizeof(next);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- if (meta_lsn != NULL)
- memcpy(bp, meta_lsn, sizeof(*meta_lsn));
- else
- memset(bp, 0, sizeof(*meta_lsn));
- bp += sizeof(*meta_lsn);
- if (page_lsn != NULL)
- memcpy(bp, page_lsn, sizeof(*page_lsn));
- else
- memset(bp, 0, sizeof(*page_lsn));
- bp += sizeof(*page_lsn);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &ptype, sizeof(ptype));
- bp += sizeof(ptype);
- memcpy(bp, &next, sizeof(next));
- bp += sizeof(next);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_pg_alloc_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_pg_alloc_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_pg_alloc_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_pg_alloc: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tmeta_lsn: [%lu][%lu]\n",
- (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
- printf("\tpage_lsn: [%lu][%lu]\n",
- (u_long)argp->page_lsn.file, (u_long)argp->page_lsn.offset);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tptype: %lu\n", (u_long)argp->ptype);
- printf("\tnext: %lu\n", (u_long)argp->next);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_pg_alloc_read __P((void *, __bam_pg_alloc_args **));
- */
-int
-__bam_pg_alloc_read(recbuf, argpp)
- void *recbuf;
- __bam_pg_alloc_args **argpp;
-{
- __bam_pg_alloc_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_pg_alloc_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->meta_lsn, bp, sizeof(argp->meta_lsn));
- bp += sizeof(argp->meta_lsn);
- memcpy(&argp->page_lsn, bp, sizeof(argp->page_lsn));
- bp += sizeof(argp->page_lsn);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->ptype, bp, sizeof(argp->ptype));
- bp += sizeof(argp->ptype);
- memcpy(&argp->next, bp, sizeof(argp->next));
- bp += sizeof(argp->next);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_pg_free_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, const DBT *,
- * PUBLIC: db_pgno_t));
- */
-int __bam_pg_free_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, meta_lsn, header, next)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * meta_lsn;
- const DBT *header;
- db_pgno_t next;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_pg_free;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*meta_lsn)
- + sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
- + sizeof(next);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (meta_lsn != NULL)
- memcpy(bp, meta_lsn, sizeof(*meta_lsn));
- else
- memset(bp, 0, sizeof(*meta_lsn));
- bp += sizeof(*meta_lsn);
- if (header == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &header->size, sizeof(header->size));
- bp += sizeof(header->size);
- memcpy(bp, header->data, header->size);
- bp += header->size;
- }
- memcpy(bp, &next, sizeof(next));
- bp += sizeof(next);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_pg_free_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_pg_free_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_pg_free_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_pg_free: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tmeta_lsn: [%lu][%lu]\n",
- (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
- printf("\theader: ");
- for (i = 0; i < argp->header.size; i++) {
- ch = ((u_int8_t *)argp->header.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tnext: %lu\n", (u_long)argp->next);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_pg_free_read __P((void *, __bam_pg_free_args **));
- */
-int
-__bam_pg_free_read(recbuf, argpp)
- void *recbuf;
- __bam_pg_free_args **argpp;
-{
- __bam_pg_free_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_pg_free_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->meta_lsn, bp, sizeof(argp->meta_lsn));
- bp += sizeof(argp->meta_lsn);
- memcpy(&argp->header.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->header.data = bp;
- bp += argp->header.size;
- memcpy(&argp->next, bp, sizeof(argp->next));
- bp += sizeof(argp->next);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_split_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- * PUBLIC: DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *,
- * PUBLIC: const DBT *));
- */
-int __bam_split_log(logp, txnid, ret_lsnp, flags,
- fileid, left, llsn, right, rlsn, indx,
- npgno, nlsn, pg)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t left;
- DB_LSN * llsn;
- db_pgno_t right;
- DB_LSN * rlsn;
- u_int32_t indx;
- db_pgno_t npgno;
- DB_LSN * nlsn;
- const DBT *pg;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_split;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(left)
- + sizeof(*llsn)
- + sizeof(right)
- + sizeof(*rlsn)
- + sizeof(indx)
- + sizeof(npgno)
- + sizeof(*nlsn)
- + sizeof(u_int32_t) + (pg == NULL ? 0 : pg->size);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &left, sizeof(left));
- bp += sizeof(left);
- if (llsn != NULL)
- memcpy(bp, llsn, sizeof(*llsn));
- else
- memset(bp, 0, sizeof(*llsn));
- bp += sizeof(*llsn);
- memcpy(bp, &right, sizeof(right));
- bp += sizeof(right);
- if (rlsn != NULL)
- memcpy(bp, rlsn, sizeof(*rlsn));
- else
- memset(bp, 0, sizeof(*rlsn));
- bp += sizeof(*rlsn);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
- memcpy(bp, &npgno, sizeof(npgno));
- bp += sizeof(npgno);
- if (nlsn != NULL)
- memcpy(bp, nlsn, sizeof(*nlsn));
- else
- memset(bp, 0, sizeof(*nlsn));
- bp += sizeof(*nlsn);
- if (pg == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &pg->size, sizeof(pg->size));
- bp += sizeof(pg->size);
- memcpy(bp, pg->data, pg->size);
- bp += pg->size;
- }
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_split_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_split_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_split_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_split_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tleft: %lu\n", (u_long)argp->left);
- printf("\tllsn: [%lu][%lu]\n",
- (u_long)argp->llsn.file, (u_long)argp->llsn.offset);
- printf("\tright: %lu\n", (u_long)argp->right);
- printf("\trlsn: [%lu][%lu]\n",
- (u_long)argp->rlsn.file, (u_long)argp->rlsn.offset);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\tnpgno: %lu\n", (u_long)argp->npgno);
- printf("\tnlsn: [%lu][%lu]\n",
- (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset);
- printf("\tpg: ");
- for (i = 0; i < argp->pg.size; i++) {
- ch = ((u_int8_t *)argp->pg.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_split_read __P((void *, __bam_split_args **));
- */
-int
-__bam_split_read(recbuf, argpp)
- void *recbuf;
- __bam_split_args **argpp;
-{
- __bam_split_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_split_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->left, bp, sizeof(argp->left));
- bp += sizeof(argp->left);
- memcpy(&argp->llsn, bp, sizeof(argp->llsn));
- bp += sizeof(argp->llsn);
- memcpy(&argp->right, bp, sizeof(argp->right));
- bp += sizeof(argp->right);
- memcpy(&argp->rlsn, bp, sizeof(argp->rlsn));
- bp += sizeof(argp->rlsn);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- memcpy(&argp->npgno, bp, sizeof(argp->npgno));
- bp += sizeof(argp->npgno);
- memcpy(&argp->nlsn, bp, sizeof(argp->nlsn));
- bp += sizeof(argp->nlsn);
- memcpy(&argp->pg.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->pg.data = bp;
- bp += argp->pg.size;
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_rsplit_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, const DBT *, db_pgno_t,
- * PUBLIC: const DBT *, DB_LSN *));
- */
-int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, pgdbt, nrec, rootent, rootlsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- const DBT *pgdbt;
- db_pgno_t nrec;
- const DBT *rootent;
- DB_LSN * rootlsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_rsplit;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(u_int32_t) + (pgdbt == NULL ? 0 : pgdbt->size)
- + sizeof(nrec)
- + sizeof(u_int32_t) + (rootent == NULL ? 0 : rootent->size)
- + sizeof(*rootlsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (pgdbt == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &pgdbt->size, sizeof(pgdbt->size));
- bp += sizeof(pgdbt->size);
- memcpy(bp, pgdbt->data, pgdbt->size);
- bp += pgdbt->size;
- }
- memcpy(bp, &nrec, sizeof(nrec));
- bp += sizeof(nrec);
- if (rootent == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &rootent->size, sizeof(rootent->size));
- bp += sizeof(rootent->size);
- memcpy(bp, rootent->data, rootent->size);
- bp += rootent->size;
- }
- if (rootlsn != NULL)
- memcpy(bp, rootlsn, sizeof(*rootlsn));
- else
- memset(bp, 0, sizeof(*rootlsn));
- bp += sizeof(*rootlsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_rsplit_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_rsplit_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_rsplit_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_rsplit: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tpgdbt: ");
- for (i = 0; i < argp->pgdbt.size; i++) {
- ch = ((u_int8_t *)argp->pgdbt.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tnrec: %lu\n", (u_long)argp->nrec);
- printf("\trootent: ");
- for (i = 0; i < argp->rootent.size; i++) {
- ch = ((u_int8_t *)argp->rootent.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\trootlsn: [%lu][%lu]\n",
- (u_long)argp->rootlsn.file, (u_long)argp->rootlsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_rsplit_read __P((void *, __bam_rsplit_args **));
- */
-int
-__bam_rsplit_read(recbuf, argpp)
- void *recbuf;
- __bam_rsplit_args **argpp;
-{
- __bam_rsplit_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_rsplit_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->pgdbt.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->pgdbt.data = bp;
- bp += argp->pgdbt.size;
- memcpy(&argp->nrec, bp, sizeof(argp->nrec));
- bp += sizeof(argp->nrec);
- memcpy(&argp->rootent.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->rootent.data = bp;
- bp += argp->rootent.size;
- memcpy(&argp->rootlsn, bp, sizeof(argp->rootlsn));
- bp += sizeof(argp->rootlsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_adj_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t));
- */
-int __bam_adj_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, lsn, indx, indx_copy, is_insert)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- u_int32_t indx;
- u_int32_t indx_copy;
- u_int32_t is_insert;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_adj;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(indx)
- + sizeof(indx_copy)
- + sizeof(is_insert);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
- memcpy(bp, &indx_copy, sizeof(indx_copy));
- bp += sizeof(indx_copy);
- memcpy(bp, &is_insert, sizeof(is_insert));
- bp += sizeof(is_insert);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_adj_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_adj_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_adj_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_adj_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_adj: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\tindx_copy: %lu\n", (u_long)argp->indx_copy);
- printf("\tis_insert: %lu\n", (u_long)argp->is_insert);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_adj_read __P((void *, __bam_adj_args **));
- */
-int
-__bam_adj_read(recbuf, argpp)
- void *recbuf;
- __bam_adj_args **argpp;
-{
- __bam_adj_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_adj_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- memcpy(&argp->indx_copy, bp, sizeof(argp->indx_copy));
- bp += sizeof(argp->indx_copy);
- memcpy(&argp->is_insert, bp, sizeof(argp->is_insert));
- bp += sizeof(argp->is_insert);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_cadjust_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- * PUBLIC: int32_t, int32_t));
- */
-int __bam_cadjust_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, lsn, indx, adjust, total)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- u_int32_t indx;
- int32_t adjust;
- int32_t total;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_cadjust;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(indx)
- + sizeof(adjust)
- + sizeof(total);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
- memcpy(bp, &adjust, sizeof(adjust));
- bp += sizeof(adjust);
- memcpy(bp, &total, sizeof(total));
- bp += sizeof(total);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_cadjust_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_cadjust_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_cadjust_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_cadjust: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\tadjust: %ld\n", (long)argp->adjust);
- printf("\ttotal: %ld\n", (long)argp->total);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_cadjust_read __P((void *, __bam_cadjust_args **));
- */
-int
-__bam_cadjust_read(recbuf, argpp)
- void *recbuf;
- __bam_cadjust_args **argpp;
-{
- __bam_cadjust_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_cadjust_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- memcpy(&argp->adjust, bp, sizeof(argp->adjust));
- bp += sizeof(argp->adjust);
- memcpy(&argp->total, bp, sizeof(argp->total));
- bp += sizeof(argp->total);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_cdel_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t));
- */
-int __bam_cdel_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, lsn, indx)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- u_int32_t indx;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_cdel;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(indx);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_cdel_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_cdel_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_cdel_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_cdel_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_cdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_cdel_read __P((void *, __bam_cdel_args **));
- */
-int
-__bam_cdel_read(recbuf, argpp)
- void *recbuf;
- __bam_cdel_args **argpp;
-{
- __bam_cdel_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_cdel_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_repl_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, const DBT *, const DBT *, u_int32_t,
- * PUBLIC: u_int32_t));
- */
-int __bam_repl_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, lsn, indx, isdeleted, orig,
- repl, prefix, suffix)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- u_int32_t indx;
- u_int32_t isdeleted;
- const DBT *orig;
- const DBT *repl;
- u_int32_t prefix;
- u_int32_t suffix;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_bam_repl;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(indx)
- + sizeof(isdeleted)
- + sizeof(u_int32_t) + (orig == NULL ? 0 : orig->size)
- + sizeof(u_int32_t) + (repl == NULL ? 0 : repl->size)
- + sizeof(prefix)
- + sizeof(suffix);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
- memcpy(bp, &isdeleted, sizeof(isdeleted));
- bp += sizeof(isdeleted);
- if (orig == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &orig->size, sizeof(orig->size));
- bp += sizeof(orig->size);
- memcpy(bp, orig->data, orig->size);
- bp += orig->size;
- }
- if (repl == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &repl->size, sizeof(repl->size));
- bp += sizeof(repl->size);
- memcpy(bp, repl->data, repl->size);
- bp += repl->size;
- }
- memcpy(bp, &prefix, sizeof(prefix));
- bp += sizeof(prefix);
- memcpy(bp, &suffix, sizeof(suffix));
- bp += sizeof(suffix);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __bam_repl_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__bam_repl_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __bam_repl_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __bam_repl_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]bam_repl: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\tisdeleted: %lu\n", (u_long)argp->isdeleted);
- printf("\torig: ");
- for (i = 0; i < argp->orig.size; i++) {
- ch = ((u_int8_t *)argp->orig.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\trepl: ");
- for (i = 0; i < argp->repl.size; i++) {
- ch = ((u_int8_t *)argp->repl.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tprefix: %lu\n", (u_long)argp->prefix);
- printf("\tsuffix: %lu\n", (u_long)argp->suffix);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_repl_read __P((void *, __bam_repl_args **));
- */
-int
-__bam_repl_read(recbuf, argpp)
- void *recbuf;
- __bam_repl_args **argpp;
-{
- __bam_repl_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__bam_repl_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- memcpy(&argp->isdeleted, bp, sizeof(argp->isdeleted));
- bp += sizeof(argp->isdeleted);
- memcpy(&argp->orig.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->orig.data = bp;
- bp += argp->orig.size;
- memcpy(&argp->repl.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->repl.data = bp;
- bp += argp->repl.size;
- memcpy(&argp->prefix, bp, sizeof(argp->prefix));
- bp += sizeof(argp->prefix);
- memcpy(&argp->suffix, bp, sizeof(argp->suffix));
- bp += sizeof(argp->suffix);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_init_print __P((DB_ENV *));
- */
-int
-__bam_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __bam_pg_alloc_print, DB_bam_pg_alloc)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_pg_free_print, DB_bam_pg_free)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_split_print, DB_bam_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_rsplit_print, DB_bam_rsplit)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_adj_print, DB_bam_adj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_cadjust_print, DB_bam_cadjust)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_cdel_print, DB_bam_cdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_repl_print, DB_bam_repl)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __bam_init_recover __P((DB_ENV *));
- */
-int
-__bam_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __bam_pg_alloc_recover, DB_bam_pg_alloc)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_pg_free_recover, DB_bam_pg_free)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_split_recover, DB_bam_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_rsplit_recover, DB_bam_rsplit)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_adj_recover, DB_bam_adj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_cadjust_recover, DB_bam_cadjust)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_cdel_recover, DB_bam_cdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __bam_repl_recover, DB_bam_repl)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/clib/getlong.c b/db2/clib/getlong.c
deleted file mode 100644
index 4e144b1..0000000
--- a/db2/clib/getlong.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)getlong.c 10.3 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#endif
-
-#include "db.h"
-#include "clib_ext.h"
-
-/*
- * get_long --
- * Return a long value inside of basic parameters.
- *
- * PUBLIC: void get_long __P((char *, long, long, long *));
- */
-void
-get_long(p, min, max, storep)
- char *p;
- long min, max, *storep;
-{
- long val;
- char *end;
-
- __set_errno(0);
- val = strtol(p, &end, 10);
- if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
- err(1, "%s", p);
- if (p[0] == '\0' || end[0] != '\0')
- errx(1, "%s: Invalid numeric argument", p);
- if (val < min)
- errx(1, "%s: Less than minimum value (%ld)", p, min);
- if (val > max)
- errx(1, "%s: Greater than maximum value (%ld)", p, max);
- *storep = val;
-}
diff --git a/db2/common/db_appinit.c b/db2/common/db_appinit.c
deleted file mode 100644
index e02b1a8..0000000
--- a/db2/common/db_appinit.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_appinit.c 10.66 (Sleepycat) 12/7/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "btree.h"
-#include "hash.h"
-#include "log.h"
-#include "txn.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-static int __db_home __P((DB_ENV *, const char *, u_int32_t));
-static int __db_parse __P((DB_ENV *, char *));
-static int __db_tmp_open __P((DB_ENV *, u_int32_t, char *, int *));
-
-/*
- * This conflict array is used for concurrent db access (cdb). It
- * uses the same locks as the db_rw_conflict array, but adds an IW
- * mode to be used for write cursors.
- */
-static u_int8_t const db_cdb_conflicts[] = {
- /* N R W IW */
- /* N */ 0, 0, 0, 0,
- /* R */ 0, 0, 1, 0,
- /* W */ 0, 1, 1, 1,
- /* IW */ 0, 0, 1, 1
-};
-
-/*
- * db_version --
- * Return version information.
- */
-char *
-db_version(majverp, minverp, patchp)
- int *majverp, *minverp, *patchp;
-{
- if (majverp != NULL)
- *majverp = DB_VERSION_MAJOR;
- if (minverp != NULL)
- *minverp = DB_VERSION_MINOR;
- if (patchp != NULL)
- *patchp = DB_VERSION_PATCH;
- return ((char *)DB_VERSION_STRING);
-}
-
-/*
- * db_appinit --
- * Initialize the application environment.
- */
-int
-db_appinit(db_home, db_config, dbenv, flags)
- const char *db_home;
- char * const *db_config;
- DB_ENV *dbenv;
- u_int32_t flags;
-{
- FILE *fp;
- int mode, ret;
- char * const *p;
- char *lp, buf[MAXPATHLEN * 2];
-
- fp = NULL;
-
- /* Validate arguments. */
- if (dbenv == NULL)
- return (EINVAL);
-
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS \
- (DB_CREATE | DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | \
- DB_INIT_MPOOL | DB_INIT_TXN | DB_MPOOL_PRIVATE | DB_NOMMAP | \
- DB_RECOVER | DB_RECOVER_FATAL | DB_THREAD | DB_TXN_NOSYNC | \
- DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
-#else
-#define OKFLAGS \
- (DB_CREATE | DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | \
- DB_INIT_MPOOL | DB_INIT_TXN | DB_MPOOL_PRIVATE | DB_NOMMAP | \
- DB_RECOVER | DB_RECOVER_FATAL | DB_TXN_NOSYNC | \
- DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
-#endif
- if ((ret = __db_fchk(dbenv, "db_appinit", flags, OKFLAGS)) != 0)
- return (ret);
-
- /* Transactions imply logging. */
- if (LF_ISSET(DB_INIT_TXN))
- LF_SET(DB_INIT_LOG);
-
- /* Convert the db_appinit(3) flags. */
- if (LF_ISSET(DB_THREAD))
- F_SET(dbenv, DB_ENV_THREAD);
-
- /* Set the database home. */
- if ((ret = __db_home(dbenv, db_home, flags)) != 0)
- goto err;
-
- /* Parse the config array. */
- for (p = db_config; p != NULL && *p != NULL; ++p)
- if ((ret = __db_parse(dbenv, *p)) != 0)
- goto err;
-
- /*
- * Parse the config file.
- *
- * XXX
- * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and
- * the latter isn't standard, and we're manipulating strings handed
- * us by the application.
- */
- if (dbenv->db_home != NULL) {
-#define CONFIG_NAME "/DB_CONFIG"
- if (strlen(dbenv->db_home) +
- strlen(CONFIG_NAME) + 1 > sizeof(buf)) {
- ret = ENAMETOOLONG;
- goto err;
- }
- (void)strcpy(buf, dbenv->db_home);
- (void)strcat(buf, CONFIG_NAME);
- if ((fp = fopen(buf, "r")) != NULL) {
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- if ((lp = strchr(buf, '\n')) == NULL) {
- __db_err(dbenv,
- "%s: line too long", CONFIG_NAME);
- ret = EINVAL;
- goto err;
- }
- *lp = '\0';
- if (buf[0] == '\0' ||
- buf[0] == '#' || isspace(buf[0]))
- continue;
-
- if ((ret = __db_parse(dbenv, buf)) != 0)
- goto err;
- }
- (void)fclose(fp);
- fp = NULL;
- }
- }
-
- /* Set up the tmp directory path. */
- if (dbenv->db_tmp_dir == NULL && (ret = __os_tmpdir(dbenv, flags)) != 0)
- goto err;
-
- /*
- * Flag that the structure has been initialized by the application.
- * Note, this must be set before calling into the subsystems as it
- * is used when we're doing file naming.
- */
- F_SET(dbenv, DB_ENV_APPINIT);
-
- /*
- * If we are doing recovery, remove all the old shared memory
- * regions.
- */
- if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) {
- if ((ret = log_unlink(NULL, 1, dbenv)) != 0)
- goto err;
- if ((ret = memp_unlink(NULL, 1, dbenv)) != 0)
- goto err;
- if ((ret = lock_unlink(NULL, 1, dbenv)) != 0)
- goto err;
- if ((ret = txn_unlink(NULL, 1, dbenv)) != 0)
- goto err;
- }
-
- /*
- * Create the new shared regions.
- *
- * Default permissions are read-write for both owner and group.
- */
- mode = __db_omode("rwrw--");
- if (LF_ISSET(DB_INIT_CDB)) {
- if (LF_ISSET(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN)) {
- ret = EINVAL;
- goto err;
- }
- F_SET(dbenv, DB_ENV_CDB);
- dbenv->lk_conflicts = db_cdb_conflicts;
- dbenv->lk_modes = DB_LOCK_RW_N + 1;
- if ((ret = lock_open(NULL, LF_ISSET(DB_CREATE | DB_THREAD),
- mode, dbenv, &dbenv->lk_info)) != 0)
- goto err;
- }
- if (LF_ISSET(DB_INIT_LOCK) && (ret = lock_open(NULL,
- LF_ISSET(DB_CREATE | DB_THREAD),
- mode, dbenv, &dbenv->lk_info)) != 0)
- goto err;
- if (LF_ISSET(DB_INIT_LOG) && (ret = log_open(NULL,
- LF_ISSET(DB_CREATE | DB_THREAD),
- mode, dbenv, &dbenv->lg_info)) != 0)
- goto err;
- if (LF_ISSET(DB_INIT_MPOOL) && (ret = memp_open(NULL,
- LF_ISSET(DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP | DB_THREAD),
- mode, dbenv, &dbenv->mp_info)) != 0)
- goto err;
- if (LF_ISSET(DB_INIT_TXN) && (ret = txn_open(NULL,
- LF_ISSET(DB_CREATE | DB_THREAD | DB_TXN_NOSYNC),
- mode, dbenv, &dbenv->tx_info)) != 0)
- goto err;
-
- /*
- * If the application is running with transactions, initialize the
- * function tables. Once that's done, do recovery for any previous
- * run.
- */
- if (LF_ISSET(DB_INIT_TXN)) {
- if ((ret = __bam_init_recover(dbenv)) != 0)
- goto err;
- if ((ret = __db_init_recover(dbenv)) != 0)
- goto err;
- if ((ret = __ham_init_recover(dbenv)) != 0)
- goto err;
- if ((ret = __log_init_recover(dbenv)) != 0)
- goto err;
- if ((ret = __txn_init_recover(dbenv)) != 0)
- goto err;
-
- if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&
- (ret = __db_apprec(dbenv,
- LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0)
- goto err;
- }
-
- return (ret);
-
-err: if (fp != NULL)
- (void)fclose(fp);
-
- (void)db_appexit(dbenv);
- return (ret);
-}
-
-/*
- * db_appexit --
- * Close down the default application environment.
- */
-int
-db_appexit(dbenv)
- DB_ENV *dbenv;
-{
- int ret, t_ret;
- char **p;
-
- ret = 0;
-
- /* Close subsystems. */
- if (dbenv->tx_info && (t_ret = txn_close(dbenv->tx_info)) != 0)
- if (ret == 0)
- ret = t_ret;
- if (dbenv->lg_info && (t_ret = log_close(dbenv->lg_info)) != 0)
- if (ret == 0)
- ret = t_ret;
- if (dbenv->mp_info && (t_ret = memp_close(dbenv->mp_info)) != 0)
- if (ret == 0)
- ret = t_ret;
- if (dbenv->lk_info && (t_ret = lock_close(dbenv->lk_info)) != 0)
- if (ret == 0)
- ret = t_ret;
-
- /* Clear initialized flag (after subsystems, it affects naming). */
- F_CLR(dbenv, DB_ENV_APPINIT);
-
- /* Free allocated memory. */
- if (dbenv->db_home != NULL)
- __os_freestr(dbenv->db_home);
- if ((p = dbenv->db_data_dir) != NULL) {
- for (; *p != NULL; ++p)
- __os_freestr(*p);
- __os_free(dbenv->db_data_dir,
- dbenv->data_cnt * sizeof(char **));
- }
- if (dbenv->db_log_dir != NULL)
- __os_freestr(dbenv->db_log_dir);
- if (dbenv->db_tmp_dir != NULL)
- __os_freestr(dbenv->db_tmp_dir);
-
- return (ret);
-}
-
-#define DB_ADDSTR(str) { \
- if ((str) != NULL) { \
- /* If leading slash, start over. */ \
- if (__os_abspath(str)) { \
- p = start; \
- slash = 0; \
- } \
- /* Append to the current string. */ \
- len = strlen(str); \
- if (slash) \
- *p++ = PATH_SEPARATOR[0]; \
- memcpy(p, str, len); \
- p += len; \
- slash = strchr(PATH_SEPARATOR, p[-1]) == NULL; \
- } \
-}
-
-/*
- * __db_appname --
- * Given an optional DB environment, directory and file name and type
- * of call, build a path based on the db_appinit(3) rules, and return
- * it in allocated space.
- *
- * PUBLIC: int __db_appname __P((DB_ENV *,
- * PUBLIC: APPNAME, const char *, const char *, u_int32_t, int *, char **));
- */
-int
-__db_appname(dbenv, appname, dir, file, tmp_oflags, fdp, namep)
- DB_ENV *dbenv;
- APPNAME appname;
- const char *dir, *file;
- u_int32_t tmp_oflags;
- int *fdp;
- char **namep;
-{
- DB_ENV etmp;
- size_t len;
- int data_entry, ret, slash, tmp_create, tmp_free;
- const char *a, *b, *c;
- char *p, *start;
-
- a = b = c = NULL;
- data_entry = -1;
- tmp_create = tmp_free = 0;
-
- /*
- * We don't return a name when creating temporary files, just an fd.
- * Default to error now.
- */
- if (fdp != NULL)
- *fdp = -1;
- if (namep != NULL)
- *namep = NULL;
-
- /*
- * Absolute path names are never modified. If the file is an absolute
- * path, we're done. If the directory is, simply append the file and
- * return.
- */
- if (file != NULL && __os_abspath(file))
- return (__os_strdup(file, namep));
- if (dir != NULL && __os_abspath(dir)) {
- a = dir;
- goto done;
- }
-
- /*
- * DB_ENV DIR APPNAME RESULT
- * -------------------------------------------
- * null null none <tmp>/file
- * null set none DIR/file
- * set null none DB_HOME/file
- * set set none DB_HOME/DIR/file
- *
- * DB_ENV FILE APPNAME RESULT
- * -------------------------------------------
- * null null DB_APP_DATA <tmp>/<create>
- * null set DB_APP_DATA ./file
- * set null DB_APP_DATA <tmp>/<create>
- * set set DB_APP_DATA DB_HOME/DB_DATA_DIR/file
- *
- * DB_ENV DIR APPNAME RESULT
- * -------------------------------------------
- * null null DB_APP_LOG <tmp>/file
- * null set DB_APP_LOG DIR/file
- * set null DB_APP_LOG DB_HOME/DB_LOG_DIR/file
- * set set DB_APP_LOG DB_HOME/DB_LOG_DIR/DIR/file
- *
- * DB_ENV APPNAME RESULT
- * -------------------------------------------
- * null DB_APP_TMP* <tmp>/<create>
- * set DB_APP_TMP* DB_HOME/DB_TMP_DIR/<create>
- */
-retry: switch (appname) {
- case DB_APP_NONE:
- if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
- if (dir == NULL)
- goto tmp;
- a = dir;
- } else {
- a = dbenv->db_home;
- b = dir;
- }
- break;
- case DB_APP_DATA:
- if (dir != NULL) {
- __db_err(dbenv,
- "DB_APP_DATA: illegal directory specification");
- return (EINVAL);
- }
-
- if (file == NULL) {
- tmp_create = 1;
- goto tmp;
- }
- if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT))
- a = PATH_DOT;
- else {
- a = dbenv->db_home;
- if (dbenv->db_data_dir != NULL &&
- (b = dbenv->db_data_dir[++data_entry]) == NULL) {
- data_entry = -1;
- b = dbenv->db_data_dir[0];
- }
- }
- break;
- case DB_APP_LOG:
- if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
- if (dir == NULL)
- goto tmp;
- a = dir;
- } else {
- a = dbenv->db_home;
- b = dbenv->db_log_dir;
- c = dir;
- }
- break;
- case DB_APP_TMP:
- if (dir != NULL || file != NULL) {
- __db_err(dbenv,
- "DB_APP_TMP: illegal directory or file specification");
- return (EINVAL);
- }
-
- tmp_create = 1;
- if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT))
- goto tmp;
- else {
- a = dbenv->db_home;
- b = dbenv->db_tmp_dir;
- }
- break;
- }
-
- /* Reference a file from the appropriate temporary directory. */
- if (0) {
-tmp: if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
- memset(&etmp, 0, sizeof(etmp));
- if ((ret = __os_tmpdir(&etmp, DB_USE_ENVIRON)) != 0)
- return (ret);
- tmp_free = 1;
- a = etmp.db_tmp_dir;
- } else
- a = dbenv->db_tmp_dir;
- }
-
-done: len =
- (a == NULL ? 0 : strlen(a) + 1) +
- (b == NULL ? 0 : strlen(b) + 1) +
- (c == NULL ? 0 : strlen(c) + 1) +
- (file == NULL ? 0 : strlen(file) + 1);
-
- /*
- * Allocate space to hold the current path information, as well as any
- * temporary space that we're going to need to create a temporary file
- * name.
- */
-#define DB_TRAIL "XXXXXX"
- if ((ret =
- __os_malloc(len + sizeof(DB_TRAIL) + 10, NULL, &start)) != 0) {
- if (tmp_free)
- __os_freestr(etmp.db_tmp_dir);
- return (ret);
- }
-
- slash = 0;
- p = start;
- DB_ADDSTR(a);
- DB_ADDSTR(b);
- DB_ADDSTR(file);
- *p = '\0';
-
- /* Discard any space allocated to find the temp directory. */
- if (tmp_free) {
- __os_freestr(etmp.db_tmp_dir);
- tmp_free = 0;
- }
-
- /*
- * If we're opening a data file, see if it exists. If it does,
- * return it, otherwise, try and find another one to open.
- */
- if (data_entry != -1 && __os_exists(start, NULL) != 0) {
- __os_freestr(start);
- a = b = c = NULL;
- goto retry;
- }
-
- /* Create the file if so requested. */
- if (tmp_create &&
- (ret = __db_tmp_open(dbenv, tmp_oflags, start, fdp)) != 0) {
- __os_freestr(start);
- return (ret);
- }
-
- if (namep == NULL)
- __os_freestr(start);
- else
- *namep = start;
- return (0);
-}
-
-/*
- * __db_home --
- * Find the database home.
- */
-static int
-__db_home(dbenv, db_home, flags)
- DB_ENV *dbenv;
- const char *db_home;
- u_int32_t flags;
-{
- const char *p;
-
- p = db_home;
-
- /* Use the environment if it's permitted and initialized. */
-#ifdef HAVE_GETUID
- if (LF_ISSET(DB_USE_ENVIRON) ||
- (LF_ISSET(DB_USE_ENVIRON_ROOT) && getuid() == 0)) {
-#else
- if (LF_ISSET(DB_USE_ENVIRON)) {
-#endif
- if ((p = getenv("DB_HOME")) == NULL)
- p = db_home;
- else if (p[0] == '\0') {
- __db_err(dbenv,
- "illegal DB_HOME environment variable");
- return (EINVAL);
- }
- }
-
- if (p == NULL)
- return (0);
-
- return (__os_strdup(p, &dbenv->db_home));
-}
-
-/*
- * __db_parse --
- * Parse a single NAME VALUE pair.
- */
-static int
-__db_parse(dbenv, s)
- DB_ENV *dbenv;
- char *s;
-{
- int ret;
- char *local_s, *name, *value, **p, *tp;
-
- /*
- * We need to strdup the argument in case the caller passed us
- * static data.
- */
- if ((ret = __os_strdup(s, &local_s)) != 0)
- return (ret);
-
- /*
- * Name/value pairs are parsed as two white-space separated strings.
- * Leading and trailing white-space is trimmed from the value, but
- * it may contain embedded white-space. Note: we use the isspace(3)
- * macro because it's more portable, but that means that you can use
- * characters like form-feed to separate the strings.
- */
- name = local_s;
- for (tp = name; *tp != '\0' && !isspace(*tp); ++tp)
- ;
- if (*tp == '\0' || tp == name)
- goto illegal;
- *tp = '\0';
- for (++tp; isspace(*tp); ++tp)
- ;
- if (*tp == '\0')
- goto illegal;
- value = tp;
- for (++tp; *tp != '\0'; ++tp)
- ;
- for (--tp; isspace(*tp); --tp)
- ;
- if (tp == value) {
-illegal: ret = EINVAL;
- __db_err(dbenv, "illegal name-value pair: %s", s);
- goto err;
- }
- *++tp = '\0';
-
-#define DATA_INIT_CNT 20 /* Start with 20 data slots. */
- if (!strcmp(name, "DB_DATA_DIR")) {
- if (dbenv->db_data_dir == NULL) {
- if ((ret = __os_calloc(DATA_INIT_CNT,
- sizeof(char **), &dbenv->db_data_dir)) != 0)
- goto err;
- dbenv->data_cnt = DATA_INIT_CNT;
- } else if (dbenv->data_next == dbenv->data_cnt - 1) {
- dbenv->data_cnt *= 2;
- if ((ret = __os_realloc(&dbenv->db_data_dir,
- dbenv->data_cnt * sizeof(char **))) != 0)
- goto err;
- }
- p = &dbenv->db_data_dir[dbenv->data_next++];
- } else if (!strcmp(name, "DB_LOG_DIR")) {
- if (dbenv->db_log_dir != NULL)
- __os_freestr(dbenv->db_log_dir);
- p = &dbenv->db_log_dir;
- } else if (!strcmp(name, "DB_TMP_DIR")) {
- if (dbenv->db_tmp_dir != NULL)
- __os_freestr(dbenv->db_tmp_dir);
- p = &dbenv->db_tmp_dir;
- } else
- goto err;
-
- ret = __os_strdup(value, p);
-
-err: __os_freestr(local_s);
- return (ret);
-}
-
-/*
- * __db_tmp_open --
- * Create a temporary file.
- */
-static int
-__db_tmp_open(dbenv, flags, path, fdp)
- DB_ENV *dbenv;
- u_int32_t flags;
- char *path;
- int *fdp;
-{
- u_long pid;
- int mode, isdir, ret;
- const char *p;
- char *trv;
-
- /*
- * Check the target directory; if you have six X's and it doesn't
- * exist, this runs for a *very* long time.
- */
- if ((ret = __os_exists(path, &isdir)) != 0) {
- __db_err(dbenv, "%s: %s", path, strerror(ret));
- return (ret);
- }
- if (!isdir) {
- __db_err(dbenv, "%s: %s", path, strerror(EINVAL));
- return (EINVAL);
- }
-
- /* Build the path. */
- for (trv = path; *trv != '\0'; ++trv)
- ;
- *trv = PATH_SEPARATOR[0];
- for (p = DB_TRAIL; (*++trv = *p) != '\0'; ++p)
- ;
-
- /*
- * Replace the X's with the process ID. Pid should be a pid_t,
- * but we use unsigned long for portability.
- */
- for (pid = getpid(); *--trv == 'X'; pid /= 10)
- switch (pid % 10) {
- case 0: *trv = '0'; break;
- case 1: *trv = '1'; break;
- case 2: *trv = '2'; break;
- case 3: *trv = '3'; break;
- case 4: *trv = '4'; break;
- case 5: *trv = '5'; break;
- case 6: *trv = '6'; break;
- case 7: *trv = '7'; break;
- case 8: *trv = '8'; break;
- case 9: *trv = '9'; break;
- }
- ++trv;
-
- /* Set up open flags and mode. */
- LF_SET(DB_CREATE | DB_EXCL);
- mode = __db_omode("rw----");
-
- /* Loop, trying to open a file. */
- for (;;) {
- if ((ret = __db_open(path, flags, flags, mode, fdp)) == 0)
- return (0);
-
- /*
- * XXX:
- * If we don't get an EEXIST error, then there's something
- * seriously wrong. Unfortunately, if the implementation
- * doesn't return EEXIST for O_CREAT and O_EXCL regardless
- * of other possible errors, we've lost.
- */
- if (ret != EEXIST) {
- __db_err(dbenv,
- "tmp_open: %s: %s", path, strerror(ret));
- return (ret);
- }
-
- /*
- * Tricky little algorithm for backward compatibility.
- * Assumes the ASCII ordering of lower-case characters.
- */
- for (;;) {
- if (*trv == '\0')
- return (EINVAL);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit(*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /* NOTREACHED */
-}
diff --git a/db2/common/db_apprec.c b/db2/common/db_apprec.c
deleted file mode 100644
index 5e8fec4..0000000
--- a/db2/common/db_apprec.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_apprec.c 10.33 (Sleepycat) 10/5/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "db_am.h"
-#include "log.h"
-#include "txn.h"
-#include "common_ext.h"
-
-/*
- * __db_apprec --
- * Perform recovery.
- *
- * PUBLIC: int __db_apprec __P((DB_ENV *, u_int32_t));
- */
-int
-__db_apprec(dbenv, flags)
- DB_ENV *dbenv;
- u_int32_t flags;
-{
- DBT data;
- DB_LOG *lp;
- DB_LSN ckp_lsn, first_lsn, lsn, open_lsn;
- __txn_ckp_args *ckp_args;
- time_t now;
- u_int32_t is_thread;
- int ret;
- void *txninfo;
-
- lp = dbenv->lg_info;
-
- /* Initialize the transaction list. */
- if ((ret = __db_txnlist_init(&txninfo)) != 0)
- return (ret);
-
- /*
- * Save the state of the thread flag -- we don't need it on at the
- * moment because we're single-threaded until recovery is complete.
- */
- is_thread = F_ISSET(lp, DB_AM_THREAD);
- F_CLR(lp, DB_AM_THREAD);
-
- /*
- * Recovery is done in three passes:
- * Pass #0:
- * We need to find the position from which we will open files
- * We need to open files beginning with the last to next
- * checkpoint because we might have crashed after writing the
- * last checkpoint record, but before having written out all
- * the open file information.
- * Pass #1:
- * Read forward through the log from the second to last checkpoint
- * opening and closing files so that at the end of the log we have
- * the "current" set of files open.
- * Pass #2:
- * Read backward through the log undoing any uncompleted TXNs.
- * If doing catastrophic recovery, we read to the beginning of
- * the log, otherwise, to the most recent checkpoint that occurs
- * before the most recent checkpoint LSN, which is returned by
- * __log_findckp(). During this pass, checkpoint file information
- * is ignored, and file openings and closings are undone.
- * Pass #3:
- * Read forward through the log from the LSN found in pass #2,
- * redoing any committed TXNs. During this pass, checkpoint
- * file information is ignored, and file openings and closings
- * are redone.
- */
-
- /*
- * Find the second to last checkpoint in the log. This is the point
- * from which we want to begin pass #1 (the TXN_OPENFILES pass).
- */
- memset(&data, 0, sizeof(data));
- ckp_args = NULL;
-
- if ((ret = log_get(lp, &ckp_lsn, &data, DB_CHECKPOINT)) != 0) {
- /*
- * If we don't find a checkpoint, start from the beginning.
- * If that fails, we're done. Note, we do not require that
- * there be log records if we're performing recovery.
- */
-first: if ((ret = log_get(lp, &ckp_lsn, &data, DB_FIRST)) != 0) {
- if (ret == DB_NOTFOUND)
- ret = 0;
- else
- __db_err(dbenv, "First log record not found");
- goto out;
- }
- open_lsn = ckp_lsn;
- } else if ((ret = __txn_ckp_read(data.data, &ckp_args)) != 0) {
- __db_err(dbenv, "Invalid checkpoint record at [%ld][%ld]\n",
- (u_long)ckp_lsn.file, (u_long)ckp_lsn.offset);
- goto out;
- } else if (IS_ZERO_LSN(ckp_args->last_ckp) ||
- (ret = log_get(lp, &ckp_args->last_ckp, &data, DB_SET)) != 0)
- goto first;
- else
- open_lsn = ckp_args->last_ckp;
-
- /*
- * Now, ckp_lsn is either the lsn of the last checkpoint or the lsn
- * of the first record in the log. Open_lsn is the second to last
- * checkpoint or the beinning of the log; begin the TXN_OPENFILES
- * pass from that lsn, and proceed to the end of the log.
- */
- lsn = open_lsn;
- for (;;) {
- if (dbenv->tx_recover != NULL)
- ret = dbenv->tx_recover(lp,
- &data, &lsn, TXN_OPENFILES, txninfo);
- else
- ret = __db_dispatch(lp,
- &data, &lsn, TXN_OPENFILES, txninfo);
- if (ret != 0 && ret != DB_TXN_CKP)
- goto msgerr;
- if ((ret = log_get(lp, &lsn, &data, DB_NEXT)) != 0) {
- if (ret == DB_NOTFOUND)
- break;
- goto out;
- }
- }
-
- /*
- * Pass #2.
- *
- * Before we can begin pass #2, backward roll phase, we determine how
- * far back in the log to recover. If we are doing catastrophic
- * recovery, then we go as far back as we have files. If we are
- * doing normal recovery, we go as back to the most recent checkpoint
- * that occurs before the most recent checkpoint LSN.
- */
- if (LF_ISSET(DB_RECOVER_FATAL)) {
- ZERO_LSN(first_lsn);
- } else
- if ((ret = __log_findckp(lp, &first_lsn)) == DB_NOTFOUND) {
- /*
- * We don't require that log files exist if recovery
- * was specified.
- */
- ret = 0;
- goto out;
- }
-
- if (dbenv->db_verbose)
- __db_err(lp->dbenv, "Recovery starting from [%lu][%lu]",
- (u_long)first_lsn.file, (u_long)first_lsn.offset);
-
- for (ret = log_get(lp, &lsn, &data, DB_LAST);
- ret == 0 && log_compare(&lsn, &first_lsn) > 0;
- ret = log_get(lp, &lsn, &data, DB_PREV)) {
- if (dbenv->tx_recover != NULL)
- ret = dbenv->tx_recover(lp,
- &data, &lsn, TXN_BACKWARD_ROLL, txninfo);
- else
- ret = __db_dispatch(lp,
- &data, &lsn, TXN_BACKWARD_ROLL, txninfo);
- if (ret != 0) {
- if (ret != DB_TXN_CKP)
- goto msgerr;
- else
- ret = 0;
- }
- }
- if (ret != 0 && ret != DB_NOTFOUND)
- goto out;
-
- /*
- * Pass #3.
- */
- for (ret = log_get(lp, &lsn, &data, DB_NEXT);
- ret == 0; ret = log_get(lp, &lsn, &data, DB_NEXT)) {
- if (dbenv->tx_recover != NULL)
- ret = dbenv->tx_recover(lp,
- &data, &lsn, TXN_FORWARD_ROLL, txninfo);
- else
- ret = __db_dispatch(lp,
- &data, &lsn, TXN_FORWARD_ROLL, txninfo);
- if (ret != 0) {
- if (ret != DB_TXN_CKP)
- goto msgerr;
- else
- ret = 0;
- }
- }
- if (ret != DB_NOTFOUND)
- goto out;
-
- /* Now close all the db files that are open. */
- __log_close_files(lp);
-
- /*
- * Now set the last checkpoint lsn and the current time,
- * take a checkpoint, and reset the txnid.
- */
- (void)time(&now);
- dbenv->tx_info->region->last_ckp = ckp_lsn;
- dbenv->tx_info->region->time_ckp = (u_int32_t)now;
- if ((ret = txn_checkpoint(dbenv->tx_info, 0, 0)) != 0)
- goto out;
- dbenv->tx_info->region->last_txnid = TXN_MINIMUM;
-
- if (dbenv->db_verbose) {
- __db_err(lp->dbenv, "Recovery complete at %.24s", ctime(&now));
- __db_err(lp->dbenv, "%s %lx %s [%lu][%lu]",
- "Maximum transaction id",
- ((DB_TXNHEAD *)txninfo)->maxid,
- "Recovery checkpoint",
- (u_long)dbenv->tx_info->region->last_ckp.file,
- (u_long)dbenv->tx_info->region->last_ckp.offset);
- }
-
- if (0) {
-msgerr: __db_err(dbenv, "Recovery function for LSN %lu %lu failed",
- (u_long)lsn.file, (u_long)lsn.offset);
- }
-
-out: F_SET(lp, is_thread);
- __db_txnlist_end(txninfo);
- if (ckp_args != NULL)
- __os_free(ckp_args, sizeof(*ckp_args));
-
- return (ret);
-}
diff --git a/db2/common/db_byteorder.c b/db2/common/db_byteorder.c
deleted file mode 100644
index cadf742..0000000
--- a/db2/common/db_byteorder.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_byteorder.c 10.5 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#if BYTE_ORDER == BIG_ENDIAN
-#define WORDS_BIGENDIAN 1
-#endif
-#endif
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "common_ext.h"
-
-/*
- * __db_byteorder --
- * Return if we need to do byte swapping, checking for illegal
- * values.
- *
- * PUBLIC: int __db_byteorder __P((DB_ENV *, int));
- */
-int
-__db_byteorder(dbenv, lorder)
- DB_ENV *dbenv;
- int lorder;
-{
- switch (lorder) {
- case 0:
- break;
- case 1234:
-#if defined(WORDS_BIGENDIAN)
- return (DB_SWAPBYTES);
-#else
- break;
-#endif
- case 4321:
-#if defined(WORDS_BIGENDIAN)
- break;
-#else
- return (DB_SWAPBYTES);
-#endif
- default:
- __db_err(dbenv,
- "illegal byte order, only big and little-endian supported");
- return (EINVAL);
- }
- return (0);
-}
diff --git a/db2/common/db_err.c b/db2/common/db_err.c
deleted file mode 100644
index e935ddf..0000000
--- a/db2/common/db_err.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_err.c 10.42 (Sleepycat) 11/24/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "lock_ext.h"
-#include "log.h"
-#include "log_ext.h"
-#include "mp.h"
-#include "mp_ext.h"
-#include "txn.h"
-#include "txn_ext.h"
-#include "common_ext.h"
-#include "clib_ext.h"
-
-/*
- * __db_fchk --
- * General flags checking routine.
- *
- * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
- */
-int
-__db_fchk(dbenv, name, flags, ok_flags)
- DB_ENV *dbenv;
- const char *name;
- u_int32_t flags, ok_flags;
-{
- return (flags & ~ok_flags ? __db_ferr(dbenv, name, 0) : 0);
-}
-
-/*
- * __db_fcchk --
- * General combination flags checking routine.
- *
- * PUBLIC: int __db_fcchk
- * PUBLIC: __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
- */
-int
-__db_fcchk(dbenv, name, flags, flag1, flag2)
- DB_ENV *dbenv;
- const char *name;
- u_int32_t flags, flag1, flag2;
-{
- return ((flags & flag1) &&
- (flags & flag2) ? __db_ferr(dbenv, name, 1) : 0);
-}
-
-/*
- * __db_ferr --
- * Common flag errors.
- *
- * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
- */
-int
-__db_ferr(dbenv, name, iscombo)
- const DB_ENV *dbenv;
- const char *name;
- int iscombo;
-{
- __db_err(dbenv, "illegal flag %sspecified to %s",
- iscombo ? "combination " : "", name);
- return (EINVAL);
-}
-
-/*
- * __db_err --
- * Standard DB error routine.
- *
- * PUBLIC: #ifdef __STDC__
- * PUBLIC: void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
- * PUBLIC: #else
- * PUBLIC: void __db_err();
- * PUBLIC: #endif
- */
-void
-#ifdef __STDC__
-__db_err(const DB_ENV *dbenv, const char *fmt, ...)
-#else
-__db_err(dbenv, fmt, va_alist)
- const DB_ENV *dbenv;
- const char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char errbuf[2048]; /* XXX: END OF THE STACK DON'T TRUST SPRINTF. */
-
- if (dbenv == NULL)
- return;
-
- if (dbenv->db_errcall != NULL) {
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
- dbenv->db_errcall(dbenv->db_errpfx, errbuf);
- va_end(ap);
- }
- if (dbenv->db_errfile != NULL) {
- if (dbenv->db_errpfx != NULL)
- (void)fprintf(dbenv->db_errfile, "%s: ",
- dbenv->db_errpfx);
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)vfprintf(dbenv->db_errfile, fmt, ap);
- (void)fprintf(dbenv->db_errfile, "\n");
- (void)fflush(dbenv->db_errfile);
- va_end(ap);
- }
-}
-
-/*
- * __db_pgerr --
- * Error when unable to retrieve a specified page.
- *
- * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t));
- */
-int
-__db_pgerr(dbp, pgno)
- DB *dbp;
- db_pgno_t pgno;
-{
- /*
- * Three things are certain:
- * Death, taxes, and lost data.
- * Guess which has occurred.
- */
- __db_err(dbp->dbenv,
- "unable to create/retrieve page %lu", (u_long)pgno);
- return (__db_panic(dbp->dbenv, EIO));
-}
-
-/*
- * __db_pgfmt --
- * Error when a page has the wrong format.
- *
- * PUBLIC: int __db_pgfmt __P((DB *, db_pgno_t));
- */
-int
-__db_pgfmt(dbp, pgno)
- DB *dbp;
- db_pgno_t pgno;
-{
- __db_err(dbp->dbenv,
- "page %lu: illegal page type or format", (u_long)pgno);
- return (__db_panic(dbp->dbenv, EINVAL));
-}
-
-/*
- * __db_panic --
- * Lock out the tree due to unrecoverable error.
- *
- * PUBLIC: int __db_panic __P((DB_ENV *, int));
- */
-int
-__db_panic(dbenv, errval)
- DB_ENV *dbenv;
- int errval;
-{
- if (dbenv != NULL) {
- dbenv->db_panic = errval;
-
- (void)__log_panic(dbenv);
- (void)__memp_panic(dbenv);
- (void)__lock_panic(dbenv);
- (void)__txn_panic(dbenv);
-
- __db_err(dbenv, "PANIC: %s", strerror(errval));
-
- if (dbenv->db_paniccall != NULL)
- dbenv->db_paniccall(dbenv, errval);
- }
-
- /*
- * Chaos reigns within.
- * Reflect, repent, and reboot.
- * Order shall return.
- */
- return (DB_RUNRECOVERY);
-}
diff --git a/db2/common/db_log2.c b/db2/common/db_log2.c
deleted file mode 100644
index d6b14f5..0000000
--- a/db2/common/db_log2.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_log2.c 10.5 (Sleepycat) 4/26/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "common_ext.h"
-
-/*
- * PUBLIC: u_int32_t __db_log2 __P((u_int32_t));
- */
-u_int32_t
-__db_log2(num)
- u_int32_t num;
-{
- u_int32_t i, limit;
-
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++)
- ;
- return (i);
-}
diff --git a/db2/common/db_region.c b/db2/common/db_region.c
deleted file mode 100644
index 12abfa5..0000000
--- a/db2/common/db_region.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_region.c 10.53 (Sleepycat) 11/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "common_ext.h"
-
-static int __db_growregion __P((REGINFO *, size_t));
-
-/*
- * __db_rattach --
- * Optionally create and attach to a shared memory region.
- *
- * PUBLIC: int __db_rattach __P((REGINFO *));
- */
-int
-__db_rattach(infop)
- REGINFO *infop;
-{
- RLAYOUT *rlp, rl;
- size_t grow_region, size;
- ssize_t nr, nw;
- u_int32_t flags, mbytes, bytes;
- u_int8_t *p;
- int malloc_possible, ret, retry_cnt;
-
- grow_region = 0;
- malloc_possible = 1;
- ret = retry_cnt = 0;
-
- /* Round off the requested size to the next page boundary. */
- DB_ROUNDOFF(infop->size, DB_VMPAGESIZE);
-
- /* Some architectures have hard limits on the maximum region size. */
-#ifdef DB_REGIONSIZE_MAX
- if (infop->size > DB_REGIONSIZE_MAX) {
- __db_err(infop->dbenv, "__db_rattach: cache size too large");
- return (EINVAL);
- }
-#endif
-
- /* Intialize the return information in the REGINFO structure. */
-loop: infop->addr = NULL;
- infop->fd = -1;
- infop->segid = INVALID_SEGID;
- if (infop->name != NULL) {
- __os_freestr(infop->name);
- infop->name = NULL;
- }
- F_CLR(infop, REGION_CANGROW | REGION_CREATED);
-
-#ifndef HAVE_SPINLOCKS
- /*
- * XXX
- * Lacking spinlocks, we must have a file descriptor for fcntl(2)
- * locking, which implies using mmap(2) to map in a regular file.
- * (Theoretically, we could probably get a file descriptor to lock
- * other types of shared regions, but I don't see any reason to
- * bother.)
- *
- * Since we may be using shared memory regions, e.g., shmget(2),
- * and not mmap of regular files, the backing file may be only a
- * few tens of bytes in length. So, this depends on the ability
- * to fcntl lock file offsets much larger than the physical file.
- */
- malloc_possible = 0;
-#endif
-
-#ifdef __hppa
- /*
- * XXX
- * HP-UX won't permit mutexes to live in anything but shared memory.
- * Instantiate a shared region file on that architecture, regardless.
- */
- malloc_possible = 0;
-#endif
- /*
- * If a region is truly private, malloc the memory. That's faster
- * than either anonymous memory or a shared file.
- */
- if (malloc_possible && F_ISSET(infop, REGION_PRIVATE)) {
- if ((ret = __os_malloc(infop->size, NULL, &infop->addr)) != 0)
- return (ret);
-
- /*
- * It's sometimes significantly faster to page-fault in all of
- * the region's pages before we run the application, as we see
- * nasty side-effects when we page-fault while holding various
- * locks, i.e., the lock takes a long time to acquire because
- * of the underlying page fault, and the other threads convoy
- * behind the lock holder.
- */
- if (DB_GLOBAL(db_region_init))
- for (p = infop->addr;
- p < (u_int8_t *)infop->addr + infop->size;
- p += DB_VMPAGESIZE)
- p[0] = '\0';
-
- F_SET(infop, REGION_CREATED | REGION_MALLOC);
- goto region_init;
- }
-
- /*
- * Get the name of the region (creating the file if a temporary file
- * is being used). The dbenv contains the current DB environment,
- * including naming information. The path argument may be a file or
- * a directory. If path is a directory, it must exist and file is the
- * file name to be created inside the directory. If path is a file,
- * then file must be NULL.
- */
- if ((ret = __db_appname(infop->dbenv, infop->appname, infop->path,
- infop->file, infop->dbflags, &infop->fd, &infop->name)) != 0)
- return (ret);
- if (infop->fd != -1)
- F_SET(infop, REGION_CREATED);
-
- /*
- * Try to create the file, if we have authority. We have to make sure
- * that multiple threads/processes attempting to simultaneously create
- * the region are properly ordered, so we open it using DB_CREATE and
- * DB_EXCL, so two attempts to create the region will return failure in
- * one.
- */
- if (infop->fd == -1 && infop->dbflags & DB_CREATE) {
- flags = infop->dbflags;
- LF_SET(DB_EXCL);
- if ((ret = __db_open(infop->name,
- flags, flags, infop->mode, &infop->fd)) == 0)
- F_SET(infop, REGION_CREATED);
- else
- if (ret != EEXIST)
- goto errmsg;
- }
-
- /* If we couldn't create the file, try and open it. */
- if (infop->fd == -1) {
- flags = infop->dbflags;
- LF_CLR(DB_CREATE | DB_EXCL);
- if ((ret = __db_open(infop->name,
- flags, flags, infop->mode, &infop->fd)) != 0)
- goto errmsg;
- }
-
- /*
- * There are three cases we support:
- * 1. Named anonymous memory (shmget(2)).
- * 2. Unnamed anonymous memory (mmap(2): MAP_ANON/MAP_ANONYMOUS).
- * 3. Memory backed by a regular file (mmap(2)).
- *
- * We instantiate a backing file in all cases, which contains at least
- * the RLAYOUT structure, and in case #3, contains the actual region.
- * This is necessary for a couple of reasons:
- *
- * First, the mpool region uses temporary files to name regions, and
- * since you may have multiple regions in the same directory, we need
- * a filesystem name to ensure that they don't collide.
- *
- * Second, applications are allowed to forcibly remove regions, even
- * if they don't know anything about them other than the name. If a
- * region is backed by anonymous memory, there has to be some way for
- * the application to find out that information, and, in some cases,
- * determine ID information for the anonymous memory.
- */
- if (F_ISSET(infop, REGION_CREATED)) {
- /*
- * If we're using anonymous memory to back this region, set
- * the flag.
- */
- if (DB_GLOBAL(db_region_anon))
- F_SET(infop, REGION_ANONYMOUS);
-
- /*
- * If we're using a regular file to back a region we created,
- * grow it to the specified size.
- */
- if (!DB_GLOBAL(db_region_anon) &&
- (ret = __db_growregion(infop, infop->size)) != 0)
- goto err;
- } else {
- /*
- * If we're joining a region, figure out what it looks like.
- *
- * XXX
- * We have to figure out if the file is a regular file backing
- * a region that we want to map into our address space, or a
- * file with the information we need to find a shared anonymous
- * region that we want to map into our address space.
- *
- * All this noise is because some systems don't have a coherent
- * VM and buffer cache, and worse, if you mix operations on the
- * VM and buffer cache, half the time you hang the system.
- *
- * There are two possibilities. If the file is the size of an
- * RLAYOUT structure, then we know that the real region is in
- * shared memory, because otherwise it would be bigger. (As
- * the RLAYOUT structure size is smaller than a disk sector,
- * the only way it can be this size is if deliberately written
- * that way.) In which case, retrieve the information we need
- * from the RLAYOUT structure and use it to acquire the shared
- * memory.
- *
- * If the structure is larger than an RLAYOUT structure, then
- * the file is backing the shared memory region, and we use
- * the current size of the file without reading any information
- * from the file itself so that we don't confuse the VM.
- *
- * And yes, this makes me want to take somebody and kill them,
- * but I can't think of any other solution.
- */
- if ((ret = __os_ioinfo(infop->name,
- infop->fd, &mbytes, &bytes, NULL)) != 0)
- goto errmsg;
- size = mbytes * MEGABYTE + bytes;
-
- if (size <= sizeof(RLAYOUT)) {
- /*
- * If the size is too small, the read fails or the
- * valid flag is incorrect, assume it's because the
- * RLAYOUT information hasn't been written out yet,
- * and retry.
- */
- if (size < sizeof(RLAYOUT))
- goto retry;
- if ((ret =
- __os_read(infop->fd, &rl, sizeof(rl), &nr)) != 0)
- goto retry;
- if (rl.valid != DB_REGIONMAGIC)
- goto retry;
-
- /* Copy the size, memory id and characteristics. */
- size = rl.size;
- infop->segid = rl.segid;
- if (F_ISSET(&rl, REGION_ANONYMOUS))
- F_SET(infop, REGION_ANONYMOUS);
- }
-
- /*
- * If the region is larger than we think, that's okay, use the
- * current size. If it's smaller than we think, and we were
- * just using the default size, that's okay, use the current
- * size. If it's smaller than we think and we really care,
- * save the size and we'll catch that further down -- we can't
- * correct it here because we have to have a lock to grow the
- * region.
- */
- if (infop->size > size && !F_ISSET(infop, REGION_SIZEDEF))
- grow_region = infop->size;
- infop->size = size;
- }
-
- /*
- * Map the region into our address space. If we're creating it, the
- * underlying routines will make it the right size.
- *
- * There are at least two cases where we can "reasonably" fail when
- * we attempt to map in the region. On Windows/95, closing the last
- * reference to a region causes it to be zeroed out. On UNIX, when
- * using the shmget(2) interfaces, the region will no longer exist
- * if the system was rebooted. In these cases, the underlying map call
- * returns EAGAIN, and we *remove* our file and try again. There are
- * obvious races in doing this, but it should eventually settle down
- * to a winner and then things should proceed normally.
- */
- if ((ret = __db_mapregion(infop->name, infop)) != 0) {
- if (ret == EAGAIN) {
- /*
- * Pretend we created the region even if we didn't so
- * that our error processing unlinks it.
- */
- F_SET(infop, REGION_CREATED);
- ret = 0;
- goto retry;
- } else
- goto err;
- }
-
-region_init:
- /*
- * Initialize the common region information.
- *
- * !!!
- * We have to order the region creates so that two processes don't try
- * to simultaneously create the region. This is handled by using the
- * DB_CREATE and DB_EXCL flags when we create the "backing" region file.
- *
- * We also have to order region joins so that processes joining regions
- * never see inconsistent data. We'd like to play permissions games
- * with the backing file, but we can't because WNT filesystems won't
- * open a file mode 0.
- */
- rlp = (RLAYOUT *)infop->addr;
- if (F_ISSET(infop, REGION_CREATED)) {
- /*
- * The process creating the region acquires a lock before it
- * sets the valid flag. Any processes joining the region will
- * check the valid flag before acquiring the lock.
- *
- * Check the return of __db_mutex_init() and __db_mutex_lock(),
- * even though we don't usually check elsewhere. This is the
- * first lock we initialize and acquire, and we have to know if
- * it fails. (It CAN fail, e.g., SunOS, when using fcntl(2)
- * for locking, with an in-memory filesystem specified as the
- * database home.)
- */
- if ((ret = __db_mutex_init(&rlp->lock,
- MUTEX_LOCK_OFFSET(rlp, &rlp->lock))) != 0 ||
- (ret = __db_mutex_lock(&rlp->lock, infop->fd)) != 0)
- goto err;
-
- /* Initialize the remaining region information. */
- rlp->refcnt = 1;
- rlp->size = infop->size;
- db_version(&rlp->majver, &rlp->minver, &rlp->patch);
- rlp->panic = 0;
- rlp->segid = infop->segid;
- rlp->flags = 0;
- if (F_ISSET(infop, REGION_ANONYMOUS))
- F_SET(rlp, REGION_ANONYMOUS);
-
- /*
- * Fill in the valid field last -- use a magic number, memory
- * may not be zero-filled, and we want to minimize the chance
- * for collision.
- */
- rlp->valid = DB_REGIONMAGIC;
-
- /*
- * If the region is anonymous, write the RLAYOUT information
- * into the backing file so that future region join and unlink
- * calls can find it.
- *
- * XXX
- * We MUST do the seek before we do the write. On Win95, while
- * closing the last reference to an anonymous shared region
- * doesn't discard the region, it does zero it out. So, the
- * REGION_CREATED may be set, but the file may have already
- * been written and the file descriptor may be at the end of
- * the file.
- */
- if (F_ISSET(infop, REGION_ANONYMOUS)) {
- if ((ret = __os_seek(infop->fd, 0, 0, 0, 0, 0)) != 0)
- goto err;
- if ((ret =
- __os_write(infop->fd, rlp, sizeof(*rlp), &nw)) != 0)
- goto err;
- }
- } else {
- /* Check to see if the region has had catastrophic failure. */
- if (rlp->panic) {
- ret = DB_RUNRECOVERY;
- goto err;
- }
-
- /*
- * Check the valid flag to ensure the region is initialized.
- * If the valid flag has not been set, the mutex may not have
- * been initialized, and an attempt to get it could lead to
- * random behavior.
- */
- if (rlp->valid != DB_REGIONMAGIC)
- goto retry;
-
- /* Get the region lock. */
- (void)__db_mutex_lock(&rlp->lock, infop->fd);
-
- /*
- * We now own the region. There are a couple of things that
- * may have gone wrong, however.
- *
- * Problem #1: while we were waiting for the lock, the region
- * was deleted. Detected by re-checking the valid flag, since
- * it's cleared by the delete region routines.
- */
- if (rlp->valid != DB_REGIONMAGIC) {
- (void)__db_mutex_unlock(&rlp->lock, infop->fd);
- goto retry;
- }
-
- /*
- * Problem #3: when we checked the size of the file, it was
- * still growing as part of creation. Detected by the fact
- * that infop->size isn't the same size as the region.
- */
- if (infop->size != rlp->size) {
- (void)__db_mutex_unlock(&rlp->lock, infop->fd);
- goto retry;
- }
-
- /* Increment the reference count. */
- ++rlp->refcnt;
- }
-
- /* Return the region in a locked condition. */
-
- if (0) {
-errmsg: __db_err(infop->dbenv, "%s: %s", infop->name, strerror(ret));
-
-err:
-retry: /* Discard the region. */
- if (infop->addr != NULL) {
- (void)__db_unmapregion(infop);
- infop->addr = NULL;
- }
-
- /* Discard the backing file. */
- if (infop->fd != -1) {
- (void)__os_close(infop->fd);
- infop->fd = -1;
-
- if (F_ISSET(infop, REGION_CREATED))
- (void)__os_unlink(infop->name);
- }
-
- /* Discard the name. */
- if (infop->name != NULL) {
- __os_freestr(infop->name);
- infop->name = NULL;
- }
-
- /*
- * If we had a temporary error, wait a few seconds and
- * try again.
- */
- if (ret == 0) {
- if (++retry_cnt <= 3) {
- __os_sleep(retry_cnt * 2, 0);
- goto loop;
- }
- ret = EAGAIN;
- }
- }
-
- /*
- * XXX
- * HP-UX won't permit mutexes to live in anything but shared memory.
- * Instantiate a shared region file on that architecture, regardless.
- *
- * XXX
- * There's a problem in cleaning this up on application exit, or on
- * application failure. If an application opens a database without
- * an environment, we create a temporary backing mpool region for it.
- * That region is marked REGION_PRIVATE, but as HP-UX won't permit
- * mutexes to live in anything but shared memory, we instantiate a
- * real file plus a memory region of some form. If the application
- * crashes, the necessary information to delete the backing file and
- * any system region (e.g., the shmget(2) segment ID) is no longer
- * available. We can't completely fix the problem, but we try.
- *
- * The underlying UNIX __db_mapregion() code preferentially uses the
- * mmap(2) interface with the MAP_ANON/MAP_ANONYMOUS flags for regions
- * that are marked REGION_PRIVATE. This means that we normally aren't
- * holding any system resources when we get here, in which case we can
- * delete the backing file. This results in a short race, from the
- * __db_open() call above to here.
- *
- * If, for some reason, we are holding system resources when we get
- * here, we don't have any choice -- we can't delete the backing file
- * because we may need it to detach from the resources. Set the
- * REGION_LASTDETACH flag, so that we do all necessary cleanup when
- * the application closes the region.
- */
- if (F_ISSET(infop, REGION_PRIVATE) && !F_ISSET(infop, REGION_MALLOC)) {
- if (F_ISSET(infop, REGION_HOLDINGSYS))
- F_SET(infop, REGION_LASTDETACH);
- else {
- F_SET(infop, REGION_REMOVED);
- F_CLR(infop, REGION_CANGROW);
-
- (void)__os_close(infop->fd);
- (void)__os_unlink(infop->name);
- }
- }
-
- return (ret);
-}
-
-/*
- * __db_rdetach --
- * De-attach from a shared memory region.
- *
- * PUBLIC: int __db_rdetach __P((REGINFO *));
- */
-int
-__db_rdetach(infop)
- REGINFO *infop;
-{
- RLAYOUT *rlp;
- int detach, ret, t_ret;
-
- ret = 0;
-
- /*
- * If the region was removed when it was created, no further action
- * is required.
- */
- if (F_ISSET(infop, REGION_REMOVED))
- goto done;
- /*
- * If the region was created in memory returned by malloc, the only
- * action required is freeing the memory.
- */
- if (F_ISSET(infop, REGION_MALLOC)) {
- __os_free(infop->addr, 0);
- goto done;
- }
-
- /* Otherwise, attach to the region and optionally delete it. */
- rlp = infop->addr;
-
- /* Get the lock. */
- (void)__db_mutex_lock(&rlp->lock, infop->fd);
-
- /* Decrement the reference count. */
- if (rlp->refcnt == 0)
- __db_err(infop->dbenv,
- "region rdetach: reference count went to zero!");
- else
- --rlp->refcnt;
-
- /*
- * If we're going to remove the region, clear the valid flag so
- * that any region join that's blocked waiting for us will know
- * what happened.
- */
- detach = 0;
- if (F_ISSET(infop, REGION_LASTDETACH)) {
- if (rlp->refcnt == 0) {
- detach = 1;
- rlp->valid = 0;
- } else
- ret = EBUSY;
- }
-
- /* Release the lock. */
- (void)__db_mutex_unlock(&rlp->lock, infop->fd);
-
- /* Close the backing file descriptor. */
- (void)__os_close(infop->fd);
- infop->fd = -1;
-
- /* Discard our mapping of the region. */
- if ((t_ret = __db_unmapregion(infop)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard the region itself. */
- if (detach) {
- if ((t_ret =
- __db_unlinkregion(infop->name, infop) != 0) && ret == 0)
- ret = t_ret;
- if ((t_ret = __os_unlink(infop->name) != 0) && ret == 0)
- ret = t_ret;
- }
-
-done: /* Discard the name. */
- if (infop->name != NULL) {
- __os_freestr(infop->name);
- infop->name = NULL;
- }
-
- return (ret);
-}
-
-/*
- * __db_runlink --
- * Remove a region.
- *
- * PUBLIC: int __db_runlink __P((REGINFO *, int));
- */
-int
-__db_runlink(infop, force)
- REGINFO *infop;
- int force;
-{
- RLAYOUT rl, *rlp;
- size_t size;
- ssize_t nr;
- u_int32_t mbytes, bytes;
- int fd, ret, t_ret;
- char *name;
-
- /*
- * XXX
- * We assume that we've created a new REGINFO structure for this
- * call, not used one that was already initialized. Regardless,
- * if anyone is planning to use it after we're done, they're going
- * to be sorely disappointed.
- *
- * If force isn't set, we attach to the region, set a flag to delete
- * the region on last close, and let the region delete code do the
- * work.
- */
- if (!force) {
- if ((ret = __db_rattach(infop)) != 0)
- return (ret);
-
- rlp = (RLAYOUT *)infop->addr;
- (void)__db_mutex_unlock(&rlp->lock, infop->fd);
-
- F_SET(infop, REGION_LASTDETACH);
-
- return (__db_rdetach(infop));
- }
-
- /*
- * Otherwise, we don't want to attach to the region. We may have been
- * called to clean up if a process died leaving a region locked and/or
- * corrupted, which could cause the attach to hang.
- */
- if ((ret = __db_appname(infop->dbenv, infop->appname,
- infop->path, infop->file, infop->dbflags, NULL, &name)) != 0)
- return (ret);
-
- /*
- * An underlying file is created for all regions other than private
- * (REGION_PRIVATE) ones, regardless of whether or not it's used to
- * back the region. If that file doesn't exist, we're done.
- */
- if (__os_exists(name, NULL) != 0) {
- __os_freestr(name);
- return (0);
- }
-
- /*
- * See the comments in __db_rattach -- figure out if this is a regular
- * file backing a region or if it's a regular file with information
- * about a region.
- */
- if ((ret = __db_open(name, DB_RDONLY, DB_RDONLY, 0, &fd)) != 0)
- goto errmsg;
- if ((ret = __os_ioinfo(name, fd, &mbytes, &bytes, NULL)) != 0)
- goto errmsg;
- size = mbytes * MEGABYTE + bytes;
-
- if (size <= sizeof(RLAYOUT)) {
- if ((ret = __os_read(fd, &rl, sizeof(rl), &nr)) != 0)
- goto errmsg;
- if (rl.valid != DB_REGIONMAGIC) {
- __db_err(infop->dbenv,
- "%s: illegal region magic number", name);
- ret = EINVAL;
- goto err;
- }
-
- /* Set the size, memory id and characteristics. */
- infop->size = rl.size;
- infop->segid = rl.segid;
- if (F_ISSET(&rl, REGION_ANONYMOUS))
- F_SET(infop, REGION_ANONYMOUS);
- } else {
- infop->size = size;
- infop->segid = INVALID_SEGID;
- }
-
- /* Remove the underlying region. */
- ret = __db_unlinkregion(name, infop);
-
- /*
- * Unlink the backing file. Close the open file descriptor first,
- * because some architectures (e.g., Win32) won't unlink a file if
- * open file descriptors remain.
- */
- (void)__os_close(fd);
- if ((t_ret = __os_unlink(name)) != 0 && ret == 0)
- ret = t_ret;
-
- if (0) {
-errmsg: __db_err(infop->dbenv, "%s: %s", name, strerror(ret));
-err: (void)__os_close(fd);
- }
-
- __os_freestr(name);
- return (ret);
-}
-
-/*
- * __db_rgrow --
- * Extend a region.
- *
- * PUBLIC: int __db_rgrow __P((REGINFO *, size_t));
- */
-int
-__db_rgrow(infop, new_size)
- REGINFO *infop;
- size_t new_size;
-{
- RLAYOUT *rlp;
- size_t increment;
- int ret;
-
- /*
- * !!!
- * This routine MUST be called with the region already locked.
- */
-
- /* The underlying routines have flagged if this region can grow. */
- if (!F_ISSET(infop, REGION_CANGROW))
- return (EINVAL);
-
- /*
- * Round off the requested size to the next page boundary, and
- * determine the additional space required.
- */
- rlp = (RLAYOUT *)infop->addr;
- DB_ROUNDOFF(new_size, DB_VMPAGESIZE);
- increment = new_size - rlp->size;
-
- if ((ret = __db_growregion(infop, increment)) != 0)
- return (ret);
-
- /* Update the on-disk region size. */
- rlp->size = new_size;
-
- /* Detach from and reattach to the region. */
- return (__db_rreattach(infop, new_size));
-}
-
-/*
- * __db_growregion --
- * Grow a shared memory region.
- */
-static int
-__db_growregion(infop, increment)
- REGINFO *infop;
- size_t increment;
-{
- db_pgno_t pages;
- size_t i;
- ssize_t nr, nw;
- u_int32_t relative;
- int ret;
- char buf[DB_VMPAGESIZE];
-
- /* Seek to the end of the region. */
- if ((ret = __os_seek(infop->fd, 0, 0, 0, 0, SEEK_END)) != 0)
- goto err;
-
- /* Write nuls to the new bytes. */
- memset(buf, 0, sizeof(buf));
-
- /*
- * Some systems require that all of the bytes of the region be
- * written before it can be mapped and accessed randomly, and
- * other systems don't zero out the pages.
- */
- if (__db_mapinit())
- /* Extend the region by writing each new page. */
- for (i = 0; i < increment; i += DB_VMPAGESIZE) {
- if ((ret =
- __os_write(infop->fd, buf, sizeof(buf), &nw)) != 0)
- goto err;
- if (nw != sizeof(buf))
- goto eio;
- }
- else {
- /*
- * Extend the region by writing the last page. If the region
- * is >4Gb, increment may be larger than the maximum possible
- * seek "relative" argument, as it's an unsigned 32-bit value.
- * Break the offset into pages of 1MB each so that we don't
- * overflow (2^20 + 2^32 is bigger than any memory I expect
- * to see for awhile).
- */
- pages = (increment - DB_VMPAGESIZE) / MEGABYTE;
- relative = (increment - DB_VMPAGESIZE) % MEGABYTE;
- if ((ret = __os_seek(infop->fd,
- MEGABYTE, pages, relative, 0, SEEK_CUR)) != 0)
- goto err;
- if ((ret = __os_write(infop->fd, buf, sizeof(buf), &nw)) != 0)
- goto err;
- if (nw != sizeof(buf))
- goto eio;
-
- /*
- * It's sometimes significantly faster to page-fault in all of
- * the region's pages before we run the application, as we see
- * nasty side-effects when we page-fault while holding various
- * locks, i.e., the lock takes a long time to acquire because
- * of the underlying page fault, and the other threads convoy
- * behind the lock holder.
- *
- * We also use REGION_INIT to guarantee that there is enough
- * disk space for the region, so we also write a byte to each
- * page. Reading the byte is insufficient as some systems
- * (e.g., Solaris) do not instantiate disk pages to satisfy
- * a read, and so we don't know if there is enough disk space
- * or not.
- */
- if (DB_GLOBAL(db_region_init)) {
- pages = increment / MEGABYTE;
- relative = increment % MEGABYTE;
- if ((ret = __os_seek(infop->fd,
- MEGABYTE, pages, relative, 1, SEEK_END)) != 0)
- goto err;
-
- /* Write a byte to each page. */
- for (i = 0; i < increment; i += DB_VMPAGESIZE) {
- if ((ret =
- __os_write(infop->fd, buf, 1, &nr)) != 0)
- goto err;
- if (nr != 1)
- goto eio;
- if ((ret = __os_seek(infop->fd,
- 0, 0, DB_VMPAGESIZE - 1, 0, SEEK_CUR)) != 0)
- goto err;
- }
- }
- }
- return (0);
-
-eio: ret = EIO;
-err: __db_err(infop->dbenv, "region grow: %s", strerror(ret));
- return (ret);
-}
-
-/*
- * __db_rreattach --
- * Detach from and reattach to a region.
- *
- * PUBLIC: int __db_rreattach __P((REGINFO *, size_t));
- */
-int
-__db_rreattach(infop, new_size)
- REGINFO *infop;
- size_t new_size;
-{
- int ret;
-
-#ifdef DIAGNOSTIC
- if (infop->name == NULL) {
- __db_err(infop->dbenv, "__db_rreattach: name was NULL");
- return (EINVAL);
- }
-#endif
- /*
- * If we're growing an already mapped region, we have to unmap it
- * and get it back. We have it locked, so nobody else can get in,
- * which makes it fairly straight-forward to do, as everybody else
- * is going to block while we do the unmap/remap. NB: if we fail
- * to get it back, the pooch is genuinely screwed, because we can
- * never release the lock we're holding.
- *
- * Detach from the region. We have to do this first so architectures
- * that don't permit a file to be mapped into different places in the
- * address space simultaneously, e.g., HP's PaRisc, will work.
- */
- if ((ret = __db_unmapregion(infop)) != 0)
- return (ret);
-
- /* Update the caller's REGINFO size to the new map size. */
- infop->size = new_size;
-
- /* Attach to the region. */
- ret = __db_mapregion(infop->name, infop);
-
- return (ret);
-}
diff --git a/db2/common/db_salloc.c b/db2/common/db_salloc.c
deleted file mode 100644
index d58b79f..0000000
--- a/db2/common/db_salloc.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_salloc.c 10.14 (Sleepycat) 11/16/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "common_ext.h"
-
-/*
- * Implement shared memory region allocation, using simple first-fit algorithm.
- * The model is that we take a "chunk" of shared memory store and begin carving
- * it up into areas, similarly to how malloc works. We do coalescing on free.
- *
- * The "len" field in the __data struct contains the length of the free region
- * (less the size_t bytes that holds the length). We use the address provided
- * by the caller to find this length, which allows us to free a chunk without
- * requiring that the caller pass in the length of the chunk they're freeing.
- */
-SH_LIST_HEAD(__head);
-struct __data {
- size_t len;
- SH_LIST_ENTRY links;
-};
-
-/*
- * __db_shalloc_init --
- * Initialize the area as one large chunk.
- *
- * PUBLIC: void __db_shalloc_init __P((void *, size_t));
- */
-void
-__db_shalloc_init(area, size)
- void *area;
- size_t size;
-{
- struct __data *elp;
- struct __head *hp;
-
- hp = area;
- SH_LIST_INIT(hp);
-
- elp = (struct __data *)(hp + 1);
- elp->len = size - sizeof(struct __head) - sizeof(elp->len);
- SH_LIST_INSERT_HEAD(hp, elp, links, __data);
-}
-
-/*
- * __db_shalloc --
- * Allocate some space from the shared region.
- *
- * PUBLIC: int __db_shalloc __P((void *, size_t, size_t, void *));
- */
-int
-__db_shalloc(p, len, align, retp)
- void *p, *retp;
- size_t len, align;
-{
- struct __data *elp;
- size_t *sp;
- void *rp;
-
- /*
- * We never allocate less than the size of a struct __data, align
- * to less than a size_t boundary, or align to something that's not
- * a multiple of a size_t.
- */
- if (len < sizeof(struct __data))
- len = sizeof(struct __data);
- align = align <= sizeof(size_t) ?
- sizeof(size_t) : ALIGN(align, sizeof(size_t));
-
- /* Walk the list, looking for a slot. */
- for (elp = SH_LIST_FIRST((struct __head *)p, __data);
- elp != NULL;
- elp = SH_LIST_NEXT(elp, links, __data)) {
- /*
- * Calculate the value of the returned pointer if we were to
- * use this chunk.
- * + Find the end of the chunk.
- * + Subtract the memory the user wants.
- * + Find the closest previous correctly-aligned address.
- */
- rp = (u_int8_t *)elp + sizeof(size_t) + elp->len;
- rp = (u_int8_t *)rp - len;
- rp = (u_int8_t *)((ALIGNTYPE)rp & ~(align - 1));
-
- /*
- * Rp may now point before elp->links, in which case the chunk
- * was too small, and we have to try again.
- */
- if ((u_int8_t *)rp < (u_int8_t *)&elp->links)
- continue;
-
- *(void **)retp = rp;
-
-#define SHALLOC_FRAGMENT 32
- /*
- * If there are at least SHALLOC_FRAGMENT additional bytes of
- * memory, divide the chunk into two chunks.
- */
- if ((u_int8_t *)rp >=
- (u_int8_t *)&elp->links + SHALLOC_FRAGMENT) {
- sp = rp;
- *--sp = elp->len -
- ((u_int8_t *)rp - (u_int8_t *)&elp->links);
- elp->len -= *sp + sizeof(size_t);
- return (0);
- }
-
- /*
- * Otherwise, we return the entire chunk, wasting some amount
- * of space to keep the list compact. However, because the
- * address we're returning to the user may not be the address
- * of the start of the region for alignment reasons, set the
- * size_t length fields back to the "real" length field to a
- * flag value, so that we can find the real length during free.
- */
-#define ILLEGAL_SIZE 1
- SH_LIST_REMOVE(elp, links, __data);
- for (sp = rp; (u_int8_t *)--sp >= (u_int8_t *)&elp->links;)
- *sp = ILLEGAL_SIZE;
- return (0);
- }
-
- /* Nothing found large enough; need to grow the region. */
- return (ENOMEM);
-}
-
-/*
- * __db_shalloc_free --
- * Free a shared memory allocation.
- *
- * PUBLIC: void __db_shalloc_free __P((void *, void *));
- */
-void
-__db_shalloc_free(regionp, ptr)
- void *regionp, *ptr;
-{
- struct __data *elp, *lastp, *newp;
- struct __head *hp;
- size_t free_size, *sp;
- int merged;
-
- /*
- * Step back over flagged length fields to find the beginning of
- * the object and its real size.
- */
- for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp)
- ;
- ptr = sp;
-
- newp = (struct __data *)((u_int8_t *)ptr - sizeof(size_t));
- free_size = newp->len;
-
- /* Trash the returned memory. */
-#ifdef DIAGNOSTIC
- memset(ptr, 0xdb, free_size);
-#endif
-
- /*
- * Walk the list, looking for where this entry goes.
- *
- * We keep the free list sorted by address so that coalescing is
- * trivial.
- *
- * XXX
- * Probably worth profiling this to see how expensive it is.
- */
- hp = (struct __head *)regionp;
- for (elp = SH_LIST_FIRST(hp, __data), lastp = NULL;
- elp != NULL && (void *)elp < (void *)ptr;
- lastp = elp, elp = SH_LIST_NEXT(elp, links, __data))
- ;
-
- /*
- * Elp is either NULL (we reached the end of the list), or the slot
- * after the one that's being returned. Lastp is either NULL (we're
- * returning the first element of the list) or the element before the
- * one being returned.
- *
- * Check for coalescing with the next element.
- */
- merged = 0;
- if ((u_int8_t *)ptr + free_size == (u_int8_t *)elp) {
- newp->len += elp->len + sizeof(size_t);
- SH_LIST_REMOVE(elp, links, __data);
- if (lastp != NULL)
- SH_LIST_INSERT_AFTER(lastp, newp, links, __data);
- else
- SH_LIST_INSERT_HEAD(hp, newp, links, __data);
- merged = 1;
- }
-
- /* Check for coalescing with the previous element. */
- if (lastp != NULL && (u_int8_t *)lastp +
- lastp->len + sizeof(size_t) == (u_int8_t *)newp) {
- lastp->len += newp->len + sizeof(size_t);
-
- /*
- * If we have already put the new element into the list take
- * it back off again because it's just been merged with the
- * previous element.
- */
- if (merged)
- SH_LIST_REMOVE(newp, links, __data);
- merged = 1;
- }
-
- if (!merged) {
- if (lastp == NULL)
- SH_LIST_INSERT_HEAD(hp, newp, links, __data);
- else
- SH_LIST_INSERT_AFTER(lastp, newp, links, __data);
- }
-}
-
-/*
- * __db_shalloc_count --
- * Return the amount of memory on the free list.
- *
- * PUBLIC: size_t __db_shalloc_count __P((void *));
- */
-size_t
-__db_shalloc_count(addr)
- void *addr;
-{
- struct __data *elp;
- size_t count;
-
- count = 0;
- for (elp = SH_LIST_FIRST((struct __head *)addr, __data);
- elp != NULL;
- elp = SH_LIST_NEXT(elp, links, __data))
- count += elp->len;
-
- return (count);
-}
-
-/*
- * __db_shsizeof --
- * Return the size of a shalloc'd piece of memory.
- *
- * PUBLIC: size_t __db_shsizeof __P((void *));
- */
-size_t
-__db_shsizeof(ptr)
- void *ptr;
-{
- struct __data *elp;
- size_t *sp;
-
- /*
- * Step back over flagged length fields to find the beginning of
- * the object and its real size.
- */
- for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp)
- ;
-
- elp = (struct __data *)((u_int8_t *)sp - sizeof(size_t));
- return (elp->len);
-}
-
-/*
- * __db_shalloc_dump --
- *
- * PUBLIC: void __db_shalloc_dump __P((void *, FILE *));
- */
-void
-__db_shalloc_dump(addr, fp)
- void *addr;
- FILE *fp;
-{
- struct __data *elp;
-
- /* Make it easy to call from the debugger. */
- if (fp == NULL)
- fp = stderr;
-
- fprintf(fp, "%s\nMemory free list\n", DB_LINE);
-
- for (elp = SH_LIST_FIRST((struct __head *)addr, __data);
- elp != NULL;
- elp = SH_LIST_NEXT(elp, links, __data))
- fprintf(fp, "%#lx: %lu\t", (u_long)elp, (u_long)elp->len);
- fprintf(fp, "\n");
-}
diff --git a/db2/common/db_shash.c b/db2/common/db_shash.c
deleted file mode 100644
index 3f48a55..0000000
--- a/db2/common/db_shash.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_shash.c 10.9 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "common_ext.h"
-
-/*
- * Table of good hash values. Up to ~250,000 buckets, we use powers of 2.
- * After that, we slow the rate of increase by half. For each choice, we
- * then use a nearby prime number as the hash value.
- *
- * If a terabyte is the maximum cache we'll see, and we assume there are
- * 10 1K buckets on each hash chain, then 107374182 is the maximum number
- * of buckets we'll ever need.
- */
-static const struct {
- u_int32_t power;
- u_int32_t prime;
-} list[] = {
- { 64, 67}, /* 2^6 */
- { 128, 131}, /* 2^7 */
- { 256, 257}, /* 2^8 */
- { 512, 521}, /* 2^9 */
- { 1024, 1031}, /* 2^10 */
- { 2048, 2053}, /* 2^11 */
- { 4096, 4099}, /* 2^12 */
- { 8192, 8191}, /* 2^13 */
- { 16384, 16381}, /* 2^14 */
- { 32768, 32771}, /* 2^15 */
- { 65536, 65537}, /* 2^16 */
- { 131072, 131071}, /* 2^17 */
- { 262144, 262147}, /* 2^18 */
- { 393216, 393209}, /* 2^18 + 2^18/2 */
- { 524288, 524287}, /* 2^19 */
- { 786432, 786431}, /* 2^19 + 2^19/2 */
- { 1048576, 1048573}, /* 2^20 */
- { 1572864, 1572869}, /* 2^20 + 2^20/2 */
- { 2097152, 2097169}, /* 2^21 */
- { 3145728, 3145721}, /* 2^21 + 2^21/2 */
- { 4194304, 4194301}, /* 2^22 */
- { 6291456, 6291449}, /* 2^22 + 2^22/2 */
- { 8388608, 8388617}, /* 2^23 */
- { 12582912, 12582917}, /* 2^23 + 2^23/2 */
- { 16777216, 16777213}, /* 2^24 */
- { 25165824, 25165813}, /* 2^24 + 2^24/2 */
- { 33554432, 33554393}, /* 2^25 */
- { 50331648, 50331653}, /* 2^25 + 2^25/2 */
- { 67108864, 67108859}, /* 2^26 */
- { 100663296, 100663291}, /* 2^26 + 2^26/2 */
- { 134217728, 134217757}, /* 2^27 */
- { 201326592, 201326611}, /* 2^27 + 2^27/2 */
- { 268435456, 268435459}, /* 2^28 */
- { 402653184, 402653189}, /* 2^28 + 2^28/2 */
- { 536870912, 536870909}, /* 2^29 */
- { 805306368, 805306357}, /* 2^29 + 2^29/2 */
- {1073741824, 1073741827}, /* 2^30 */
- {0, 0}
-};
-
-/*
- * __db_tablesize --
- * Choose a size for the hash table.
- *
- * PUBLIC: int __db_tablesize __P((u_int32_t));
- */
-int
-__db_tablesize(n_buckets)
- u_int32_t n_buckets;
-{
- int i;
-
- /*
- * We try to be clever about how big we make the hash tables. Use a
- * prime number close to the "suggested" number of elements that will
- * be in the hash table. Use 64 as the minimum hash table size.
- *
- * Ref: Sedgewick, Algorithms in C, "Hash Functions"
- */
- if (n_buckets < 64)
- n_buckets = 64;
-
- for (i = 0;; ++i) {
- if (list[i].power == 0) {
- --i;
- break;
- }
- if (list[i].power >= n_buckets)
- break;
- }
- return (list[i].prime);
-}
-
-/*
- * __db_hashinit --
- * Initialize a hash table that resides in shared memory.
- *
- * PUBLIC: void __db_hashinit __P((void *, u_int32_t));
- */
-void
-__db_hashinit(begin, nelements)
- void *begin;
- u_int32_t nelements;
-{
- u_int32_t i;
- SH_TAILQ_HEAD(hash_head) *headp;
-
- headp = (struct hash_head *)begin;
-
- for (i = 0; i < nelements; i++, headp++)
- SH_TAILQ_INIT(headp);
-}
diff --git a/db2/compat.h b/db2/compat.h
deleted file mode 100644
index 51008af..0000000
--- a/db2/compat.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Compatibility gunk for the db library. */
-
-#include <sys/types.h>
-#include <errno.h>
-
-#include <sys/stat.h>
-#ifdef _STATBUF_ST_BLKSIZE
-# define HAVE_ST_BLKSIZE
-#endif
-
-
-#ifndef EFTYPE
-# define EFTYPE EINVAL
-#endif
-
-/* Emulate Solaris llseek(). */
-typedef loff_t offset_t;
-
-extern int llseek (int fd, loff_t offset, int whence);
diff --git a/db2/config.h b/db2/config.h
deleted file mode 100644
index 6f09795..0000000
--- a/db2/config.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* config.h. Generated automatically by configure. */
-/* config.h.in. Generated automatically from configure.in by autoheader. */
-
-/* ...but edited by hand to be used in GNU libc. */
-
-/* Define to empty if the keyword does not work. */
-/* #undef const */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef mode_t */
-
-/* Define to `long' if <sys/types.h> doesn't define. */
-/* #undef off_t */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef pid_t */
-
-/* Define to `unsigned' if <sys/types.h> doesn't define. */
-/* #undef size_t */
-
-/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-/* #undef STAT_MACROS_BROKEN */
-
-/* Define if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Say we have endian.h. */
-#define HAVE_ENDIAN_H 1
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef ssize_t */
-
-/* Define if you want a debugging version. */
-/* #undef DEBUG */
-
-/* Define if you want a version with run-time diagnostic checking. */
-/* #undef DIAGNOSTIC */
-
-/* Define if you have sigfillset (and sigprocmask). */
-#define HAVE_SIGFILLSET 1
-
-/* Define if building on AIX, HP, Solaris to get big-file environment. */
-/* #undef HAVE_FILE_OFFSET_BITS */
-#ifdef HAVE_FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64
-#endif
-
-/* Define if you have spinlocks. */
-/* #undef HAVE_SPINLOCKS */
-
-/* Define if you want to use mc68020/gcc assembly spinlocks. */
-/* #undef HAVE_ASSEM_MC68020_GCC */
-
-/* Define if you want to use parisc/gcc assembly spinlocks. */
-/* #undef HAVE_ASSEM_PARISC_GCC */
-
-/* Define if you want to use sco/cc assembly spinlocks. */
-/* #undef HAVE_ASSEM_SCO_CC */
-
-/* Define if you want to use sparc/gcc assembly spinlocks. */
-/* #undef HAVE_ASSEM_SPARC_GCC */
-
-/* Define if you want to use uts4/cc assembly spinlocks. */
-/* #undef HAVE_ASSEM_UTS4_CC */
-
-/* Define if you want to use x86/gcc assembly spinlocks. */
-/* #undef HAVE_ASSEM_X86_GCC */
-
-/* Define if you have the AIX _check_lock spinlocks. */
-/* #undef HAVE_FUNC_AIX */
-
-/* Define if you have the OSF1 or HPPA msemaphore spinlocks. */
-/* #undef HAVE_FUNC_MSEM */
-
-/* Define if you have the SGI abilock_t spinlocks. */
-/* #undef HAVE_FUNC_SGI */
-
-/* Define if you have the ReliantUNIX spinlock_t spinlocks. */
-/* #undef HAVE_FUNC_RELIANT */
-
-/* Define if you have the Solaris mutex_t spinlocks. */
-/* #undef HAVE_FUNC_SOLARIS */
-
-/* Define if your sprintf returns a pointer, not a length. */
-/* #undef SPRINTF_RET_CHARPNT */
-
-/* Define if you have the getcwd function. */
-#define HAVE_GETCWD 1
-
-/* Define if you have the getopt function. */
-#define HAVE_GETOPT 1
-
-/* Define if you have the getuid function. */
-#define HAVE_GETUID 1
-
-/* Define if you have the memcmp function. */
-#define HAVE_MEMCMP 1
-
-/* Define if you have the memcpy function. */
-#define HAVE_MEMCPY 1
-
-/* Define if you have the memmove function. */
-#define HAVE_MEMMOVE 1
-
-/* Define if you have the mmap function. */
-#define HAVE_MMAP 1
-
-/* Define if you have the raise function. */
-#define HAVE_RAISE 1
-
-/* Define if you have the select function. */
-#define HAVE_SELECT 1
-
-/* Define if you have the shmget function. */
-#define HAVE_SHMGET 1
-
-/* Define if you have the snprintf function. */
-#define HAVE_SNPRINTF 1
-
-/* Define if you have the strerror function. */
-#define HAVE_STRERROR 1
-
-/* Define if you have the strsep function. */
-#define HAVE_STRSEP 1
-
-/* Define if you have the sysconf function. */
-#define HAVE_SYSCONF 1
-
-/* Define if you have the vsnprintf function. */
-#define HAVE_VSNPRINTF 1
-
-/* Define if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define if you have the <ndir.h> header file. */
-/* #undef HAVE_NDIR_H */
-
-/* Define if you have the <sys/dir.h> header file. */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define if you have the <sys/ndir.h> header file. */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-#include_next <config.h>
diff --git a/db2/db.h b/db2/db.h
deleted file mode 100644
index 306f2ff..0000000
--- a/db2/db.h
+++ /dev/null
@@ -1,1033 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db.h 10.174 (Sleepycat) 1/3/99
- */
-
-#ifndef _DB_H_
-#define _DB_H_
-
-#ifndef __NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdio.h>
-#endif
-
-/*
- * XXX
- * MacOS: ensure that Metrowerks C makes enumeration types int sized.
- */
-#ifdef __MWERKS__
-#pragma enumsalwaysint on
-#endif
-
-/*
- * XXX
- * Handle function prototypes and the keyword "const". This steps on name
- * space that DB doesn't control, but all of the other solutions are worse.
- *
- * XXX
- * While Microsoft's compiler is ANSI C compliant, it doesn't have _STDC_
- * defined by default, you specify a command line flag or #pragma to turn
- * it on. Don't do that, however, because some of Microsoft's own header
- * files won't compile.
- */
-#undef __P
-#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
-#define __P(protos) protos /* ANSI C prototypes */
-#else
-#define const
-#define __P(protos) () /* K&R C preprocessor */
-#endif
-
-/*
- * !!!
- * DB needs basic information about specifically sized types. If they're
- * not provided by the system, typedef them here.
- *
- * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__,
- * as does BIND and Kerberos, since we don't know for sure what #include
- * files the user is using.
- *
- * !!!
- * We also provide the standard u_int, u_long etc., if they're not provided
- * by the system.
- */
-
-#define DB_VERSION_MAJOR 2
-#define DB_VERSION_MINOR 7
-#define DB_VERSION_PATCH 5
-#define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.5: (04/18/99)"
-
-typedef u_int32_t db_pgno_t; /* Page number type. */
-typedef u_int16_t db_indx_t; /* Page offset type. */
-#define DB_MAX_PAGES 0xffffffff /* >= # of pages in a file */
-
-typedef u_int32_t db_recno_t; /* Record number type. */
-#define DB_MAX_RECORDS 0xffffffff /* >= # of records in a tree */
-
-typedef size_t DB_LOCK; /* Object returned by lock manager. */
-
-/* Forward structure declarations, so applications get type checking. */
-struct __db; typedef struct __db DB;
-#ifdef DB_DBM_HSEARCH
- typedef struct __db DBM;
-#endif
-struct __db_bt_stat; typedef struct __db_bt_stat DB_BTREE_STAT;
-struct __db_dbt; typedef struct __db_dbt DBT;
-struct __db_env; typedef struct __db_env DB_ENV;
-struct __db_ilock; typedef struct __db_ilock DB_LOCK_ILOCK;
-struct __db_info; typedef struct __db_info DB_INFO;
-struct __db_lock_stat; typedef struct __db_lock_stat DB_LOCK_STAT;
-struct __db_lockregion; typedef struct __db_lockregion DB_LOCKREGION;
-struct __db_lockreq; typedef struct __db_lockreq DB_LOCKREQ;
-struct __db_locktab; typedef struct __db_locktab DB_LOCKTAB;
-struct __db_log; typedef struct __db_log DB_LOG;
-struct __db_log_stat; typedef struct __db_log_stat DB_LOG_STAT;
-struct __db_lsn; typedef struct __db_lsn DB_LSN;
-struct __db_mpool; typedef struct __db_mpool DB_MPOOL;
-struct __db_mpool_finfo;typedef struct __db_mpool_finfo DB_MPOOL_FINFO;
-struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT;
-struct __db_mpool_stat; typedef struct __db_mpool_stat DB_MPOOL_STAT;
-struct __db_mpoolfile; typedef struct __db_mpoolfile DB_MPOOLFILE;
-struct __db_txn; typedef struct __db_txn DB_TXN;
-struct __db_txn_active; typedef struct __db_txn_active DB_TXN_ACTIVE;
-struct __db_txn_stat; typedef struct __db_txn_stat DB_TXN_STAT;
-struct __db_txnmgr; typedef struct __db_txnmgr DB_TXNMGR;
-struct __db_txnregion; typedef struct __db_txnregion DB_TXNREGION;
-struct __dbc; typedef struct __dbc DBC;
-
-/* Key/data structure -- a Data-Base Thang. */
-struct __db_dbt {
- void *data; /* key/data */
- u_int32_t size; /* key/data length */
- u_int32_t ulen; /* RO: length of user buffer. */
- u_int32_t dlen; /* RO: get/put record length. */
- u_int32_t doff; /* RO: get/put record offset. */
-
-#define DB_DBT_INTERNAL 0x01 /* Ignore user's malloc (internal). */
-#define DB_DBT_MALLOC 0x02 /* Return in allocated memory. */
-#define DB_DBT_PARTIAL 0x04 /* Partial put/get. */
-#define DB_DBT_USERMEM 0x08 /* Return in user's memory. */
- u_int32_t flags;
-};
-
-/*
- * DB run-time interface configuration.
- *
- * There are a set of functions that the application can replace with its
- * own versions, and some other knobs which can be turned at run-time.
- */
-#define DB_FUNC_CLOSE 1 /* POSIX 1003.1 close. */
-#define DB_FUNC_DIRFREE 2 /* DB: free directory list. */
-#define DB_FUNC_DIRLIST 3 /* DB: create directory list. */
-#define DB_FUNC_EXISTS 4 /* DB: return if file exists. */
-#define DB_FUNC_FREE 5 /* ANSI C free. */
-#define DB_FUNC_FSYNC 6 /* POSIX 1003.1 fsync. */
-#define DB_FUNC_IOINFO 7 /* DB: return file I/O information. */
-#define DB_FUNC_MALLOC 8 /* ANSI C malloc. */
-#define DB_FUNC_MAP 9 /* DB: map file into shared memory. */
-#define DB_FUNC_OPEN 10 /* POSIX 1003.1 open. */
-#define DB_FUNC_READ 11 /* POSIX 1003.1 read. */
-#define DB_FUNC_REALLOC 12 /* ANSI C realloc. */
-#define DB_FUNC_RUNLINK 13 /* DB: remove a shared region. */
-#define DB_FUNC_SEEK 14 /* POSIX 1003.1 lseek. */
-#define DB_FUNC_SLEEP 15 /* DB: sleep secs/usecs. */
-#define DB_FUNC_UNLINK 16 /* POSIX 1003.1 unlink. */
-#define DB_FUNC_UNMAP 17 /* DB: unmap shared memory file. */
-#define DB_FUNC_WRITE 18 /* POSIX 1003.1 write. */
-#define DB_FUNC_YIELD 19 /* DB: yield thread to scheduler. */
-#define DB_MUTEXLOCKS 20 /* DB: turn off all mutex locks. */
-#define DB_PAGEYIELD 21 /* DB: yield the CPU on pool get. */
-#define DB_REGION_ANON 22 /* DB: anonymous, unnamed regions. */
-#define DB_REGION_INIT 23 /* DB: page-fault regions in create. */
-#define DB_REGION_NAME 24 /* DB: anonymous, named regions. */
-#define DB_TSL_SPINS 25 /* DB: initialize spin count. */
-
-/*
- * Database configuration and initialization.
- */
- /*
- * Flags understood by both db_open(3) and db_appinit(3).
- */
-#define DB_CREATE 0x000001 /* O_CREAT: create file as necessary. */
-#define DB_NOMMAP 0x000002 /* Don't mmap underlying file. */
-#define DB_THREAD 0x000004 /* Free-thread DB package handles. */
-
-/*
- * Flags understood by db_appinit(3).
- */
-/* 0x000007 COMMON MASK. */
-#define DB_INIT_CDB 0x000008 /* Concurrent Access Methods. */
-#define DB_INIT_LOCK 0x000010 /* Initialize locking. */
-#define DB_INIT_LOG 0x000020 /* Initialize logging. */
-#define DB_INIT_MPOOL 0x000040 /* Initialize mpool. */
-#define DB_INIT_TXN 0x000080 /* Initialize transactions. */
-#define DB_MPOOL_PRIVATE 0x000100 /* Mpool: private memory pool. */
-#define DB_RECOVER 0x000200 /* Run normal recovery. */
-#define DB_RECOVER_FATAL 0x000400 /* Run catastrophic recovery. */
-#define DB_TXN_NOSYNC 0x000800 /* Do not sync log on commit. */
-#define DB_USE_ENVIRON 0x001000 /* Use the environment. */
-#define DB_USE_ENVIRON_ROOT 0x002000 /* Use the environment if root. */
-
-/*
- * Flags understood by db_open(3).
- *
- * DB_EXCL and DB_TEMPORARY are internal only, and are not documented.
- * DB_SEQUENTIAL is currently internal, but may be exported some day.
- */
-/* 0x000007 COMMON MASK. */
-/* 0x001fff ALREADY USED. */
-#define DB_EXCL 0x002000 /* O_EXCL: exclusive open (internal). */
-#define DB_RDONLY 0x004000 /* O_RDONLY: read-only. */
-#define DB_SEQUENTIAL 0x008000 /* Sequential access (internal). */
-#define DB_TEMPORARY 0x010000 /* Remove on last close (internal). */
-#define DB_TRUNCATE 0x020000 /* O_TRUNCATE: replace existing DB. */
-
-/*
- * Deadlock detector modes; used in the DBENV structure to configure the
- * locking subsystem.
- */
-#define DB_LOCK_NORUN 0
-#define DB_LOCK_DEFAULT 1 /* Default policy. */
-#define DB_LOCK_OLDEST 2 /* Abort oldest transaction. */
-#define DB_LOCK_RANDOM 3 /* Abort random transaction. */
-#define DB_LOCK_YOUNGEST 4 /* Abort youngest transaction. */
-
-struct __db_env {
- int db_lorder; /* Byte order. */
-
- /* Error message callback. */
- void (*db_errcall) (const char *, char *);
- FILE *db_errfile; /* Error message file stream. */
- const char *db_errpfx; /* Error message prefix. */
- int db_verbose; /* Generate debugging messages. */
- int db_panic; /* Panic flag, callback function. */
- void (*db_paniccall) (DB_ENV *, int);
-
- /* User paths. */
- char *db_home; /* Database home. */
- char *db_log_dir; /* Database log file directory. */
- char *db_tmp_dir; /* Database tmp file directory. */
-
- char **db_data_dir; /* Database data file directories. */
- int data_cnt; /* Database data file slots. */
- int data_next; /* Next Database data file slot. */
-
- /* Locking. */
- DB_LOCKTAB *lk_info; /* Return from lock_open(). */
- const u_int8_t *lk_conflicts; /* Two dimensional conflict matrix. */
- u_int32_t lk_modes; /* Number of lock modes in table. */
- u_int32_t lk_max; /* Maximum number of locks. */
- u_int32_t lk_detect; /* Deadlock detect on all conflicts. */
-
- /* Logging. */
- DB_LOG *lg_info; /* Return from log_open(). */
- u_int32_t lg_max; /* Maximum file size. */
-
- /* Memory pool. */
- DB_MPOOL *mp_info; /* Return from memp_open(). */
- size_t mp_mmapsize; /* Maximum file size for mmap. */
- size_t mp_size; /* Bytes in the mpool cache. */
-
- /* Transactions. */
- DB_TXNMGR *tx_info; /* Return from txn_open(). */
- u_int32_t tx_max; /* Maximum number of transactions. */
- int (*tx_recover) /* Dispatch function for recovery. */
- (DB_LOG *, DBT *, DB_LSN *, int, void *);
-
- /*
- * XA support.
- *
- * !!!
- * Explicit representations of structures in queue.h.
- *
- * TAILQ_ENTRY(__db_env);
- */
- struct {
- struct __db_env *tqe_next;
- struct __db_env **tqe_prev;
- } links;
- int xa_rmid; /* XA Resource Manager ID. */
- DB_TXN *xa_txn; /* XA Current transaction. */
-
-#define DB_ENV_APPINIT 0x01 /* Paths initialized by db_appinit(). */
-#define DB_ENV_CDB 0x02 /* Concurrent DB product. */
-#define DB_ENV_STANDALONE 0x04 /* Test: freestanding environment. */
-#define DB_ENV_THREAD 0x08 /* DB_ENV is multi-threaded. */
- u_int32_t flags; /* Flags. */
-};
-
-/*******************************************************
- * Access methods.
- *******************************************************/
-/*
- * !!!
- * Changes here must be reflected in java/src/com/sleepycat/db/Db.java.
- */
-typedef enum {
- DB_BTREE=1, /* B+tree. */
- DB_HASH, /* Extended Linear Hashing. */
- DB_RECNO, /* Fixed and variable-length records. */
- DB_UNKNOWN /* Figure it out on open. */
-} DBTYPE;
-
-#define DB_BTREEVERSION 6 /* Current btree version. */
-#define DB_BTREEOLDVER 6 /* Oldest btree version supported. */
-#define DB_BTREEMAGIC 0x053162
-
-#define DB_HASHVERSION 5 /* Current hash version. */
-#define DB_HASHOLDVER 4 /* Oldest hash version supported. */
-#define DB_HASHMAGIC 0x061561
-
-#define DB_LOGVERSION 2 /* Current log version. */
-#define DB_LOGOLDVER 2 /* Oldest log version supported. */
-#define DB_LOGMAGIC 0x040988
-
-struct __db_info {
- int db_lorder; /* Byte order. */
- size_t db_cachesize; /* Underlying cache size. */
- size_t db_pagesize; /* Underlying page size. */
-
- /* Local heap allocation. */
- void *(*db_malloc) (size_t);
- int (*dup_compare) /* Duplicate compare function. */
- (const DBT *, const DBT *);
-
- /* Btree access method. */
- u_int32_t bt_maxkey; /* Maximum keys per page. */
- u_int32_t bt_minkey; /* Minimum keys per page. */
- int (*bt_compare) /* Comparison function. */
- (const DBT *, const DBT *);
- size_t (*bt_prefix) /* Prefix function. */
- (const DBT *, const DBT *);
-
- /* Hash access method. */
- u_int32_t h_ffactor; /* Fill factor. */
- u_int32_t h_nelem; /* Number of elements. */
- u_int32_t (*h_hash) /* Hash function. */
- (const void *, u_int32_t);
-
- /* Recno access method. */
- int re_pad; /* Fixed-length padding byte. */
- int re_delim; /* Variable-length delimiting byte. */
- u_int32_t re_len; /* Length for fixed-length records. */
- char *re_source; /* Source file name. */
-
-#define DB_DELIMITER 0x0001 /* Recno: re_delim set. */
-#define DB_DUP 0x0002 /* Btree, Hash: duplicate keys. */
-#define DB_DUPSORT 0x0004 /* Btree, Hash: duplicate keys. */
-#define DB_FIXEDLEN 0x0008 /* Recno: fixed-length records. */
-#define DB_PAD 0x0010 /* Recno: re_pad set. */
-#define DB_RECNUM 0x0020 /* Btree: record numbers. */
-#define DB_RENUMBER 0x0040 /* Recno: renumber on insert/delete. */
-#define DB_SNAPSHOT 0x0080 /* Recno: snapshot the input. */
- u_int32_t flags;
-};
-
-/*
- * DB access method and cursor operation values. Each value is an operation
- * code to which additional bit flags are added.
- */
-#define DB_AFTER 1 /* c_put() */
-#define DB_APPEND 2 /* put() */
-#define DB_BEFORE 3 /* c_put() */
-#define DB_CHECKPOINT 4 /* log_put(), log_get() */
-#define DB_CURLSN 5 /* log_put() */
-#define DB_CURRENT 6 /* c_get(), c_put(), log_get() */
-#define DB_FIRST 7 /* c_get(), log_get() */
-#define DB_FLUSH 8 /* log_put() */
-#define DB_GET_BOTH 9 /* get(), c_get() */
-#define DB_GET_RECNO 10 /* c_get() */
-#define DB_JOIN_ITEM 11 /* c_get(); do not do primary lookup */
-#define DB_KEYFIRST 12 /* c_put() */
-#define DB_KEYLAST 13 /* c_put() */
-#define DB_LAST 14 /* c_get(), log_get() */
-#define DB_NEXT 15 /* c_get(), log_get() */
-#define DB_NEXT_DUP 16 /* c_get() */
-#define DB_NOOVERWRITE 17 /* put() */
-#define DB_NOSYNC 18 /* close() */
-#define DB_PREV 19 /* c_get(), log_get() */
-#define DB_RECORDCOUNT 20 /* stat() */
-#define DB_SET 21 /* c_get(), log_get() */
-#define DB_SET_RANGE 22 /* c_get() */
-#define DB_SET_RECNO 23 /* get(), c_get() */
-#define DB_WRITELOCK 24 /* cursor() (internal) */
-
-#define DB_OPFLAGS_MASK 0x1f /* Mask for operations flags. */
-#define DB_RMW 0x80000000 /* Acquire write flag immediately. */
-
-/*
- * DB (user visible) error return codes.
- *
- * !!!
- * Changes to any of the user visible error return codes must be reflected
- * in java/src/com/sleepycat/db/Db.java.
- */
-#define DB_INCOMPLETE ( -1) /* Sync didn't finish. */
-#define DB_KEYEMPTY ( -2) /* The key/data pair was deleted or
- was never created by the user. */
-#define DB_KEYEXIST ( -3) /* The key/data pair already exists. */
-#define DB_LOCK_DEADLOCK ( -4) /* Locker killed to resolve deadlock. */
-#define DB_LOCK_NOTGRANTED ( -5) /* Lock unavailable, no-wait set. */
-#define DB_LOCK_NOTHELD ( -6) /* Lock not held by locker. */
-#define DB_NOTFOUND ( -7) /* Key/data pair not found (EOF). */
-#define DB_RUNRECOVERY ( -8) /* Panic return. */
-
-/* DB (private) error return codes. */
-#define DB_DELETED ( -9) /* Recovery file marked deleted. */
-#define DB_NEEDSPLIT (-10) /* Page needs to be split. */
-#define DB_SWAPBYTES (-11) /* Database needs byte swapping. */
-#define DB_TXN_CKP (-12) /* Encountered ckp record in log. */
-
-#define DB_FILE_ID_LEN 20 /* DB file ID length. */
-
-/* DB access method description structure. */
-struct __db {
- void *mutexp; /* Synchronization for free threading */
-
- /* Documented, returned information. */
- DBTYPE type; /* DB access method. */
- int byteswapped; /* Database byte order is swapped. */
-
- DB_ENV *dbenv; /* DB_ENV structure. */
- DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
-
- void *internal; /* Access method private. */
-
- DB_MPOOL *mp; /* The access method's mpool. */
- DB_MPOOLFILE *mpf; /* The access method's mpool file. */
-
- /*
- * !!!
- * Explicit representations of structures in queue.h.
- *
- * TAILQ_HEAD(free_queue, __dbc);
- * TAILQ_HEAD(active_queue, __dbc);
- */
- struct {
- struct __dbc *tqh_first;
- struct __dbc **tqh_last;
- } free_queue;
- struct {
- struct __dbc *tqh_first;
- struct __dbc **tqh_last;
- } active_queue;
-
- u_int8_t fileid[DB_FILE_ID_LEN]; /* Uniquely identify this file for
- locking. */
- u_int32_t log_fileid; /* Logging file id. */
- size_t pgsize; /* Logical page size of file. */
-
- /* Local heap allocation. */
- void *(*db_malloc) (size_t);
- int (*dup_compare) /* Duplicate compare function. */
- (const DBT *, const DBT *);
- u_int32_t (*h_hash) /* Hash function. */
- (const void *, u_int32_t);
-
- /* Functions. */
- int (*am_close) (DB *);
- int (*close) (DB *, u_int32_t);
- int (*cursor) (DB *, DB_TXN *, DBC **, u_int32_t);
- int (*del) (DB *, DB_TXN *, DBT *, u_int32_t);
- int (*fd) (DB *, int *);
- int (*get) (DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
- int (*join) (DB *, DBC **, u_int32_t, DBC **);
- int (*put) (DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
- int (*stat) (DB *, void *, void *(*)(size_t), u_int32_t);
- int (*sync) (DB *, u_int32_t);
-
-#define DB_AM_CDB 0x000001 /* Concurrent Access Methods. */
-#define DB_AM_DUP 0x000002 /* DB_DUP (internal). */
-#define DB_AM_INMEM 0x000004 /* In-memory; no sync on close. */
-#define DB_AM_LOCKING 0x000008 /* Perform locking. */
-#define DB_AM_LOGGING 0x000010 /* Perform logging. */
-#define DB_AM_MLOCAL 0x000020 /* Database memory pool is local. */
-#define DB_AM_PGDEF 0x000040 /* Page size was defaulted. */
-#define DB_AM_RDONLY 0x000080 /* Database is readonly. */
-#define DB_AM_SWAP 0x000100 /* Pages need to be byte-swapped. */
-#define DB_AM_THREAD 0x000200 /* DB is multi-threaded. */
-#define DB_BT_RECNUM 0x000400 /* DB_RECNUM (internal). */
-#define DB_DBM_ERROR 0x000800 /* Error in DBM/NDBM database. */
-#define DB_RE_DELIMITER 0x001000 /* DB_DELIMITER (internal). */
-#define DB_RE_FIXEDLEN 0x002000 /* DB_FIXEDLEN (internal). */
-#define DB_RE_PAD 0x004000 /* DB_PAD (internal). */
-#define DB_RE_RENUMBER 0x008000 /* DB_RENUMBER (internal). */
-#define DB_RE_SNAPSHOT 0x010000 /* DB_SNAPSHOT (internal). */
- u_int32_t flags;
-};
-
-struct __db_ilock { /* Internal DB access method lock. */
- db_pgno_t pgno; /* Page being locked. */
- u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */
-};
-
-/* Cursor description structure. */
-struct __dbc {
- DB *dbp; /* Related DB access method. */
- DB_TXN *txn; /* Associated transaction. */
-
- /*
- * !!!
- * Explicit representations of structures in queue.h.
- *
- * TAILQ_ENTRY(__dbc);
- */
- struct {
- struct __dbc *tqe_next;
- struct __dbc **tqe_prev;
- } links;
-
- u_int32_t lid; /* Default process' locker id. */
- u_int32_t locker; /* Locker for this operation. */
- DBT lock_dbt; /* DBT referencing lock. */
- DB_LOCK_ILOCK lock; /* Object to be locked. */
- DB_LOCK mylock; /* Lock held on this cursor. */
-
- DBT rkey; /* Returned key. */
- DBT rdata; /* Returned data. */
-
- int (*c_am_close) (DBC *);
- int (*c_am_destroy) (DBC *);
- int (*c_close) (DBC *);
- int (*c_del) (DBC *, u_int32_t);
- int (*c_get) (DBC *, DBT *, DBT *, u_int32_t);
- int (*c_put) (DBC *, DBT *, DBT *, u_int32_t);
-
- void *internal; /* Access method private. */
-
-#define DBC_CONTINUE 0x001 /* Continue dup search: next item. */
-#define DBC_KEYSET 0x002 /* Continue dup search: current item. */
-#define DBC_RECOVER 0x004 /* In recovery (do not log or lock). */
-#define DBC_RMW 0x008 /* Acquire write flag in read op. */
-#define DBC_WRITER 0x010 /* Cursor immediately writing (CDB). */
- u_int32_t flags;
-};
-
-/* Btree/recno statistics structure. */
-struct __db_bt_stat {
- u_int32_t bt_flags; /* Open flags. */
- u_int32_t bt_maxkey; /* Maxkey value. */
- u_int32_t bt_minkey; /* Minkey value. */
- u_int32_t bt_re_len; /* Fixed-length record length. */
- u_int32_t bt_re_pad; /* Fixed-length record pad. */
- u_int32_t bt_pagesize; /* Page size. */
- u_int32_t bt_levels; /* Tree levels. */
- u_int32_t bt_nrecs; /* Number of records. */
- u_int32_t bt_int_pg; /* Internal pages. */
- u_int32_t bt_leaf_pg; /* Leaf pages. */
- u_int32_t bt_dup_pg; /* Duplicate pages. */
- u_int32_t bt_over_pg; /* Overflow pages. */
- u_int32_t bt_free; /* Pages on the free list. */
- u_int32_t bt_int_pgfree; /* Bytes free in internal pages. */
- u_int32_t bt_leaf_pgfree; /* Bytes free in leaf pages. */
- u_int32_t bt_dup_pgfree; /* Bytes free in duplicate pages. */
- u_int32_t bt_over_pgfree; /* Bytes free in overflow pages. */
- u_int32_t bt_magic; /* Magic number. */
- u_int32_t bt_version; /* Version number. */
-};
-
-/* Hash statistics structure. */
-struct __db_h_stat {
- u_int32_t hash_accesses; /* Number of accesses to this table. */
- u_int32_t hash_collisions; /* Number of collisions on search. */
- u_int32_t hash_expansions; /* Number of times we added a bucket. */
- u_int32_t hash_overflows; /* Number of overflow pages. */
- u_int32_t hash_bigpages; /* Number of big key/data pages. */
- u_int32_t hash_dup; /* Number of dup pages. */
- u_int32_t hash_free; /* Pages on the free list. */
- u_int32_t hash_bfree; /* Bytes free on bucket pages. */
- u_int32_t hash_dup_free; /* Bytes free on duplicate pages. */
- u_int32_t hash_big_bfree; /* Bytes free on big item pages. */
- u_int32_t hash_buckets; /* Number of hash buckets. */
- u_int32_t hash_put; /* Number of puts. */
- u_int32_t hash_deleted; /* Number of deletes. */
- u_int32_t hash_get; /* Number of gets. */
- u_int32_t hash_magic; /* Magic number. */
- u_int32_t hash_version; /* Version number. */
- u_int32_t hash_pagesize; /* Page size. */
- u_int32_t hash_nrecs; /* Number of records. */
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int db_appinit (const char *, char * const *, DB_ENV *, u_int32_t);
-int db_appexit (DB_ENV *);
-int db_jump_set (void *, int);
-int db_open (const char *,
- DBTYPE, u_int32_t, int, DB_ENV *, DB_INFO *, DB **);
-int db_value_set (int, int);
-char *db_version (int *, int *, int *);
-int db_xa_open (const char *, DBTYPE, u_int32_t, int, DB_INFO *, DB **);
-#if defined(__cplusplus)
-}
-#endif
-
-/*******************************************************
- * Locking
- *******************************************************/
-#define DB_LOCKVERSION 1
-#define DB_LOCKMAGIC 0x090193
-
-/* Flag values for lock_vec(), lock_get(). */
-#define DB_LOCK_NOWAIT 0x01 /* Don't wait on unavailable lock. */
-#define DB_LOCK_UPGRADE 0x02 /* Upgrade an existing lock instead
- of granting a new one (internal). */
-
-/* Flag values for lock_detect(). */
-#define DB_LOCK_CONFLICT 0x01 /* Run on any conflict. */
-
-/*
- * Request types.
- *
- * !!!
- * Changes here must be reflected in java/src/com/sleepycat/db/Db.java.
- */
-typedef enum {
- DB_LOCK_DUMP=0, /* Display held locks. */
- DB_LOCK_GET, /* Get the lock. */
- DB_LOCK_INHERIT, /* Pass locks to parent. */
- DB_LOCK_PUT, /* Release the lock. */
- DB_LOCK_PUT_ALL, /* Release locker's locks. */
- DB_LOCK_PUT_OBJ /* Release locker's locks on obj. */
-} db_lockop_t;
-
-/*
- * Simple R/W lock modes and for multi-granularity intention locking.
- *
- * !!!
- * These values are NOT random, as they are used as an index into the lock
- * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD
- * must be == 4.
- *
- * !!!
- * Changes here must be reflected in java/src/com/sleepycat/db/Db.java.
- */
-typedef enum {
- DB_LOCK_NG=0, /* Not granted. */
- DB_LOCK_READ, /* Shared/read. */
- DB_LOCK_WRITE, /* Exclusive/write. */
- DB_LOCK_IWRITE, /* Intent exclusive/write. */
- DB_LOCK_IREAD, /* Intent to share/read. */
- DB_LOCK_IWR /* Intent to read and write. */
-} db_lockmode_t;
-
-/*
- * Status of a lock.
- */
-typedef enum {
- DB_LSTAT_ABORTED, /* Lock belongs to an aborted txn. */
- DB_LSTAT_ERR, /* Lock is bad. */
- DB_LSTAT_FREE, /* Lock is unallocated. */
- DB_LSTAT_HELD, /* Lock is currently held. */
- DB_LSTAT_NOGRANT, /* Lock was not granted. */
- DB_LSTAT_PENDING, /* Lock was waiting and has been
- * promoted; waiting for the owner
- * to run and upgrade it to held. */
- DB_LSTAT_WAITING /* Lock is on the wait queue. */
-} db_status_t;
-
-/* Lock request structure. */
-struct __db_lockreq {
- db_lockop_t op; /* Operation. */
- db_lockmode_t mode; /* Requested mode. */
- u_int32_t locker; /* Locker identity. */
- DBT *obj; /* Object being locked. */
- DB_LOCK lock; /* Lock returned. */
-};
-
-/*
- * Commonly used conflict matrices.
- *
- * Standard Read/Write (or exclusive/shared) locks.
- */
-#define DB_LOCK_RW_N 3
-extern const u_int8_t db_rw_conflicts[];
-
-/* Multi-granularity locking. */
-#define DB_LOCK_RIW_N 6
-extern const u_int8_t db_riw_conflicts[];
-
-struct __db_lock_stat {
- u_int32_t st_magic; /* Lock file magic number. */
- u_int32_t st_version; /* Lock file version number. */
- u_int32_t st_maxlocks; /* Maximum number of locks in table. */
- u_int32_t st_nmodes; /* Number of lock modes. */
- u_int32_t st_numobjs; /* Number of objects. */
- u_int32_t st_nlockers; /* Number of lockers. */
- u_int32_t st_nconflicts; /* Number of lock conflicts. */
- u_int32_t st_nrequests; /* Number of lock gets. */
- u_int32_t st_nreleases; /* Number of lock puts. */
- u_int32_t st_ndeadlocks; /* Number of lock deadlocks. */
- u_int32_t st_region_wait; /* Region lock granted after wait. */
- u_int32_t st_region_nowait; /* Region lock granted without wait. */
- u_int32_t st_refcnt; /* Region reference count. */
- u_int32_t st_regsize; /* Region size. */
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int lock_close (DB_LOCKTAB *);
-int lock_detect (DB_LOCKTAB *, u_int32_t, u_int32_t);
-int lock_get (DB_LOCKTAB *,
- u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *);
-int lock_id (DB_LOCKTAB *, u_int32_t *);
-int lock_open (const char *, u_int32_t, int, DB_ENV *, DB_LOCKTAB **);
-int lock_put (DB_LOCKTAB *, DB_LOCK);
-int lock_tget (DB_LOCKTAB *,
- DB_TXN *, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *);
-int lock_stat (DB_LOCKTAB *, DB_LOCK_STAT **, void *(*)(size_t));
-int lock_unlink (const char *, int, DB_ENV *);
-int lock_vec (DB_LOCKTAB *,
- u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **);
-int lock_tvec (DB_LOCKTAB *,
- DB_TXN *, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **);
-#if defined(__cplusplus)
-}
-#endif
-
-/*******************************************************
- * Logging.
- *******************************************************/
-/* Flag values for log_archive(). */
-#define DB_ARCH_ABS 0x001 /* Absolute pathnames. */
-#define DB_ARCH_DATA 0x002 /* Data files. */
-#define DB_ARCH_LOG 0x004 /* Log files. */
-
-/*
- * A DB_LSN has two parts, a fileid which identifies a specific file, and an
- * offset within that file. The fileid is an unsigned 4-byte quantity that
- * uniquely identifies a file within the log directory -- currently a simple
- * counter inside the log. The offset is also an unsigned 4-byte value. The
- * log manager guarantees the offset is never more than 4 bytes by switching
- * to a new log file before the maximum length imposed by an unsigned 4-byte
- * offset is reached.
- */
-struct __db_lsn {
- u_int32_t file; /* File ID. */
- u_int32_t offset; /* File offset. */
-};
-
-/* Log statistics structure. */
-struct __db_log_stat {
- u_int32_t st_magic; /* Log file magic number. */
- u_int32_t st_version; /* Log file version number. */
- int st_mode; /* Log file mode. */
- u_int32_t st_lg_max; /* Maximum log file size. */
- u_int32_t st_w_bytes; /* Bytes to log. */
- u_int32_t st_w_mbytes; /* Megabytes to log. */
- u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */
- u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */
- u_int32_t st_wcount; /* Total syncs to the log. */
- u_int32_t st_scount; /* Total writes to the log. */
- u_int32_t st_region_wait; /* Region lock granted after wait. */
- u_int32_t st_region_nowait; /* Region lock granted without wait. */
- u_int32_t st_cur_file; /* Current log file number. */
- u_int32_t st_cur_offset; /* Current log file offset. */
- u_int32_t st_refcnt; /* Region reference count. */
- u_int32_t st_regsize; /* Region size. */
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int log_archive (DB_LOG *, char **[], u_int32_t, void *(*)(size_t));
-int log_close (DB_LOG *);
-int log_compare (const DB_LSN *, const DB_LSN *);
-int log_file (DB_LOG *, const DB_LSN *, char *, size_t);
-int log_flush (DB_LOG *, const DB_LSN *);
-int log_get (DB_LOG *, DB_LSN *, DBT *, u_int32_t);
-int log_open (const char *, u_int32_t, int, DB_ENV *, DB_LOG **);
-int log_put (DB_LOG *, DB_LSN *, const DBT *, u_int32_t);
-int log_register (DB_LOG *, DB *, const char *, DBTYPE, u_int32_t *);
-int log_stat (DB_LOG *, DB_LOG_STAT **, void *(*)(size_t));
-int log_unlink (const char *, int, DB_ENV *);
-int log_unregister (DB_LOG *, u_int32_t);
-#if defined(__cplusplus)
-}
-#endif
-
-/*******************************************************
- * Mpool
- *******************************************************/
-/* Flag values for memp_fget(). */
-#define DB_MPOOL_CREATE 0x001 /* Create a page. */
-#define DB_MPOOL_LAST 0x002 /* Return the last page. */
-#define DB_MPOOL_NEW 0x004 /* Create a new page. */
-
-/* Flag values for memp_fput(), memp_fset(). */
-#define DB_MPOOL_CLEAN 0x001 /* Clear modified bit. */
-#define DB_MPOOL_DIRTY 0x002 /* Page is modified. */
-#define DB_MPOOL_DISCARD 0x004 /* Don't cache the page. */
-
-/* Mpool statistics structure. */
-struct __db_mpool_stat {
- size_t st_cachesize; /* Cache size. */
- u_int32_t st_cache_hit; /* Pages found in the cache. */
- u_int32_t st_cache_miss; /* Pages not found in the cache. */
- u_int32_t st_map; /* Pages from mapped files. */
- u_int32_t st_page_create; /* Pages created in the cache. */
- u_int32_t st_page_in; /* Pages read in. */
- u_int32_t st_page_out; /* Pages written out. */
- u_int32_t st_ro_evict; /* Clean pages forced from the cache. */
- u_int32_t st_rw_evict; /* Dirty pages forced from the cache. */
- u_int32_t st_hash_buckets; /* Number of hash buckets. */
- u_int32_t st_hash_searches; /* Total hash chain searches. */
- u_int32_t st_hash_longest; /* Longest hash chain searched. */
- u_int32_t st_hash_examined; /* Total hash entries searched. */
- u_int32_t st_page_clean; /* Clean pages. */
- u_int32_t st_page_dirty; /* Dirty pages. */
- u_int32_t st_page_trickle; /* Pages written by memp_trickle. */
- u_int32_t st_region_wait; /* Region lock granted after wait. */
- u_int32_t st_region_nowait; /* Region lock granted without wait. */
- u_int32_t st_refcnt; /* Region reference count. */
- u_int32_t st_regsize; /* Region size. */
-};
-
-/* Mpool file open information structure. */
-struct __db_mpool_finfo {
- int ftype; /* File type. */
- DBT *pgcookie; /* Byte-string passed to pgin/pgout. */
- u_int8_t *fileid; /* Unique file ID. */
- int32_t lsn_offset; /* LSN offset in page. */
- u_int32_t clear_len; /* Cleared length on created pages. */
-};
-
-/* Mpool file statistics structure. */
-struct __db_mpool_fstat {
- char *file_name; /* File name. */
- size_t st_pagesize; /* Page size. */
- u_int32_t st_cache_hit; /* Pages found in the cache. */
- u_int32_t st_cache_miss; /* Pages not found in the cache. */
- u_int32_t st_map; /* Pages from mapped files. */
- u_int32_t st_page_create; /* Pages created in the cache. */
- u_int32_t st_page_in; /* Pages read in. */
- u_int32_t st_page_out; /* Pages written out. */
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int memp_close (DB_MPOOL *);
-int memp_fclose (DB_MPOOLFILE *);
-int memp_fget (DB_MPOOLFILE *, db_pgno_t *, u_int32_t, void *);
-int memp_fopen (DB_MPOOL *, const char *,
- u_int32_t, int, size_t, DB_MPOOL_FINFO *, DB_MPOOLFILE **);
-int memp_fput (DB_MPOOLFILE *, void *, u_int32_t);
-int memp_fset (DB_MPOOLFILE *, void *, u_int32_t);
-int memp_fsync (DB_MPOOLFILE *);
-int memp_open (const char *, u_int32_t, int, DB_ENV *, DB_MPOOL **);
-int memp_register (DB_MPOOL *, int,
- int (*)(db_pgno_t, void *, DBT *),
- int (*)(db_pgno_t, void *, DBT *));
-int memp_stat (DB_MPOOL *,
- DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, void *(*)(size_t));
-int memp_sync (DB_MPOOL *, DB_LSN *);
-int memp_trickle (DB_MPOOL *, int, int *);
-int memp_unlink (const char *, int, DB_ENV *);
-#if defined(__cplusplus)
-}
-#endif
-
-/*******************************************************
- * Transactions.
- *******************************************************/
-#define DB_TXNVERSION 1
-#define DB_TXNMAGIC 0x041593
-
-/* Operations values to the tx_recover() function. */
-#define DB_TXN_BACKWARD_ROLL 1 /* Read the log backwards. */
-#define DB_TXN_FORWARD_ROLL 2 /* Read the log forwards. */
-#define DB_TXN_OPENFILES 3 /* Read for open files. */
-#define DB_TXN_REDO 4 /* Redo the operation. */
-#define DB_TXN_UNDO 5 /* Undo the operation. */
-
-/* Internal transaction status values. */
-
-/* Transaction statistics structure. */
-struct __db_txn_active {
- u_int32_t txnid; /* Transaction ID */
- DB_LSN lsn; /* Lsn of the begin record */
-};
-
-struct __db_txn_stat {
- DB_LSN st_last_ckp; /* lsn of the last checkpoint */
- DB_LSN st_pending_ckp; /* last checkpoint did not finish */
- time_t st_time_ckp; /* time of last checkpoint */
- u_int32_t st_last_txnid; /* last transaction id given out */
- u_int32_t st_maxtxns; /* maximum number of active txns */
- u_int32_t st_naborts; /* number of aborted transactions */
- u_int32_t st_nbegins; /* number of begun transactions */
- u_int32_t st_ncommits; /* number of committed transactions */
- u_int32_t st_nactive; /* number of active transactions */
- DB_TXN_ACTIVE
- *st_txnarray; /* array of active transactions */
- u_int32_t st_region_wait; /* Region lock granted after wait. */
- u_int32_t st_region_nowait; /* Region lock granted without wait. */
- u_int32_t st_refcnt; /* Region reference count. */
- u_int32_t st_regsize; /* Region size. */
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int txn_abort (DB_TXN *);
-int txn_begin (DB_TXNMGR *, DB_TXN *, DB_TXN **);
-int txn_checkpoint (const DB_TXNMGR *, u_int32_t, u_int32_t);
-int txn_commit (DB_TXN *);
-int txn_close (DB_TXNMGR *);
-u_int32_t txn_id (DB_TXN *);
-int txn_open (const char *, u_int32_t, int, DB_ENV *, DB_TXNMGR **);
-int txn_prepare (DB_TXN *);
-int txn_stat (DB_TXNMGR *, DB_TXN_STAT **, void *(*)(size_t));
-int txn_unlink (const char *, int, DB_ENV *);
-#if defined(__cplusplus)
-}
-#endif
-
-#ifndef DB_DBM_HSEARCH
-#define DB_DBM_HSEARCH 0 /* No historic interfaces by default. */
-#endif
-#if DB_DBM_HSEARCH != 0
-/*******************************************************
- * Dbm/Ndbm historic interfaces.
- *******************************************************/
-#define DBM_INSERT 0 /* Flags to dbm_store(). */
-#define DBM_REPLACE 1
-
-/*
- * The db(3) support for ndbm(3) always appends this suffix to the
- * file name to avoid overwriting the user's original database.
- */
-#define DBM_SUFFIX ".db"
-
-#if defined(_XPG4_2)
-typedef struct {
- char *dptr;
- size_t dsize;
-} datum;
-#else
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-#endif
-
-/*
- * Translate DBM calls into DB calls so that DB doesn't step on the
- * application's name space.
- *
- * The global variables dbrdonly, dirf and pagf were not retained when
- * 4BSD replaced the dbm interface with ndbm, and are not support here.
- */
-#define dbminit(a) __db_dbm_init(a)
-#define dbmclose __db_dbm_close
-#if !defined(__cplusplus)
-#define delete(a) __db_dbm_delete(a)
-#endif
-#define fetch(a) __db_dbm_fetch(a)
-#define firstkey __db_dbm_firstkey
-#define nextkey(a) __db_dbm_nextkey(a)
-#define store(a, b) __db_dbm_store(a, b)
-
-/* Prototype the DB calls. */
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_dbm_close (void);
-int __db_dbm_dbrdonly (void);
-int __db_dbm_delete (datum);
-int __db_dbm_dirf (void);
-datum __db_dbm_fetch (datum);
-datum __db_dbm_firstkey (void);
-int __db_dbm_init (char *);
-datum __db_dbm_nextkey (datum);
-int __db_dbm_pagf (void);
-int __db_dbm_store (datum, datum);
-#if defined(__cplusplus)
-}
-#endif
-
-/*
- * Translate NDBM calls into DB calls so that DB doesn't step on the
- * application's name space.
- */
-#define dbm_clearerr(a) __db_ndbm_clearerr(a)
-#define dbm_close(a) __db_ndbm_close(a)
-#define dbm_delete(a, b) __db_ndbm_delete(a, b)
-#define dbm_dirfno(a) __db_ndbm_dirfno(a)
-#define dbm_error(a) __db_ndbm_error(a)
-#define dbm_fetch(a, b) __db_ndbm_fetch(a, b)
-#define dbm_firstkey(a) __db_ndbm_firstkey(a)
-#define dbm_nextkey(a) __db_ndbm_nextkey(a)
-#define dbm_open(a, b, c) __db_ndbm_open(a, b, c)
-#define dbm_pagfno(a) __db_ndbm_pagfno(a)
-#define dbm_rdonly(a) __db_ndbm_rdonly(a)
-#define dbm_store(a, b, c, d) __db_ndbm_store(a, b, c, d)
-
-/* Prototype the DB calls. */
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_ndbm_clearerr (DBM *);
-void __db_ndbm_close (DBM *);
-int __db_ndbm_delete (DBM *, datum);
-int __db_ndbm_dirfno (DBM *);
-int __db_ndbm_error (DBM *);
-datum __db_ndbm_fetch (DBM *, datum);
-datum __db_ndbm_firstkey (DBM *);
-datum __db_ndbm_nextkey (DBM *);
-DBM *__db_ndbm_open (const char *, int, int);
-int __db_ndbm_pagfno (DBM *);
-int __db_ndbm_rdonly (DBM *);
-int __db_ndbm_store (DBM *, datum, datum, int);
-#if defined(__cplusplus)
-}
-#endif
-
-/*******************************************************
- * Hsearch historic interface.
- *******************************************************/
-typedef enum {
- FIND, ENTER
-} ACTION;
-
-typedef struct entry {
- char *key;
- char *data;
-} ENTRY;
-
-/*
- * Translate HSEARCH calls into DB calls so that DB doesn't step on the
- * application's name space.
- */
-#define hcreate(a) __db_hcreate(a)
-#define hdestroy __db_hdestroy
-#define hsearch(a, b) __db_hsearch(a, b)
-
-/* Prototype the DB calls. */
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_hcreate (size_t);
-void __db_hdestroy (void);
-ENTRY *__db_hsearch (ENTRY, ACTION);
-#if defined(__cplusplus)
-}
-#endif
-#endif /* DB_DBM_HSEARCH */
-
-/*
- * XXX
- * MacOS: Reset Metrowerks C enum sizes.
- */
-#ifdef __MWERKS__
-#pragma enumsalwaysint reset
-#endif
-#endif /* !_DB_H_ */
diff --git a/db2/db/db.c b/db2/db/db.c
deleted file mode 100644
index 9f79fd6..0000000
--- a/db2/db/db.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db.c 10.75 (Sleepycat) 12/3/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_shash.h"
-#include "db_swap.h"
-#include "btree.h"
-#include "hash.h"
-#include "mp.h"
-#include "db_am.h"
-#include "common_ext.h"
-
-/*
- * If the metadata page has the flag set, set the local flag. If the page
- * does NOT have the flag set, return EINVAL if the user's dbinfo argument
- * caused us to already set the local flag.
- */
-#define DBINFO_FCHK(dbp, fn, meta_flags, m_name, dbp_name) { \
- if ((meta_flags) & (m_name)) \
- F_SET(dbp, dbp_name); \
- else \
- if (F_ISSET(dbp, dbp_name)) { \
- __db_err(dbenv, \
- "%s: %s specified in dbinfo argument but not set in file", \
- fname, fn); \
- goto einval; \
- } \
-}
-
-#ifdef _LIBC
-#define db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp) \
- __nss_db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
-#endif
-
-/*
- * db_open --
- * Main library interface to the DB access methods.
- */
-int
-db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
- const char *fname;
- DBTYPE type;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_INFO *dbinfo;
- DB **dbpp;
-{
- BTMETA *btm;
- DB *dbp;
- DBT pgcookie;
- DB_ENV *envp, t_dbenv;
- DB_MPOOL_FINFO finfo;
- DB_PGINFO pginfo;
- HASHHDR *hashm;
- size_t cachesize;
- ssize_t nr;
- u_int32_t iopsize;
- int fd, ftype, need_fileid, restore, ret, retry_cnt, swapped;
- char *real_name, mbuf[512];
-
- /* Validate arguments. */
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_NOMMAP | DB_RDONLY | DB_THREAD | DB_TRUNCATE)
-#else
-#define OKFLAGS (DB_CREATE | DB_NOMMAP | DB_RDONLY | DB_TRUNCATE)
-#endif
- if ((ret = __db_fchk(dbenv, "db_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- if (dbenv != NULL) {
- /*
- * You can't specify threads during the db_open() if the
- * environment wasn't configured with them.
- */
- if (LF_ISSET(DB_THREAD) && !F_ISSET(dbenv, DB_ENV_THREAD)) {
- __db_err(dbenv,
- "environment not created using DB_THREAD");
- return (EINVAL);
- }
-
- /*
- * Specifying a cachesize to db_open(3), after creating an
- * environment with DB_INIT_MPOOL, is a common mistake.
- */
- if (dbenv->mp_info != NULL &&
- dbinfo != NULL && dbinfo->db_cachesize != 0) {
- __db_err(dbenv,
- "cachesize will be ignored if environment exists");
- return (EINVAL);
- }
- }
-
- /* Initialize for error return. */
- fd = -1;
- need_fileid = 1;
- real_name = NULL;
-
- /* Allocate the DB structure, reference the DB_ENV structure. */
- if ((ret = __os_calloc(1, sizeof(DB), &dbp)) != 0)
- return (ret);
- dbp->dbenv = dbenv;
-
- /* Random initialization. */
- TAILQ_INIT(&dbp->free_queue);
- TAILQ_INIT(&dbp->active_queue);
- if ((ret = __db_init_wrapper(dbp)) != 0)
- goto err;
-
- /* Convert the db_open(3) flags. */
- if (LF_ISSET(DB_RDONLY))
- F_SET(dbp, DB_AM_RDONLY);
- if (LF_ISSET(DB_THREAD))
- F_SET(dbp, DB_AM_THREAD);
-
- /* Convert the dbinfo structure flags. */
- if (dbinfo != NULL) {
- /*
- * !!!
- * We can't check for illegal flags until we know what type
- * of open we're doing.
- */
- if (F_ISSET(dbinfo, DB_DELIMITER))
- F_SET(dbp, DB_RE_DELIMITER);
- if (F_ISSET(dbinfo, DB_DUP))
- F_SET(dbp, DB_AM_DUP);
- if (F_ISSET(dbinfo, DB_FIXEDLEN))
- F_SET(dbp, DB_RE_FIXEDLEN);
- if (F_ISSET(dbinfo, DB_PAD))
- F_SET(dbp, DB_RE_PAD);
- if (F_ISSET(dbinfo, DB_RECNUM))
- F_SET(dbp, DB_BT_RECNUM);
- if (F_ISSET(dbinfo, DB_RENUMBER))
- F_SET(dbp, DB_RE_RENUMBER);
- if (F_ISSET(dbinfo, DB_SNAPSHOT))
- F_SET(dbp, DB_RE_SNAPSHOT);
- }
-
- /*
- * Set based on the dbenv fields, although no logging or transactions
- * are possible for temporary files.
- */
- if (dbenv != NULL) {
- if (dbenv->lk_info != NULL) {
- if (F_ISSET(dbenv, DB_ENV_CDB))
- F_SET(dbp, DB_AM_CDB);
- else
- F_SET(dbp, DB_AM_LOCKING);
- }
- if (fname != NULL && dbenv->lg_info != NULL)
- F_SET(dbp, DB_AM_LOGGING);
- }
-
- /* Set the common fields. */
- if (dbinfo == NULL) {
- dbp->pgsize = 0;
- dbp->db_malloc = NULL;
- dbp->dup_compare = NULL;
- } else {
- /*
- * We don't want anything that's not a power-of-2, as we rely
- * on that for alignment of various types on the pages.
- */
- if ((dbp->pgsize = dbinfo->db_pagesize) != 0 &&
- (u_int32_t)1 << __db_log2(dbp->pgsize) != dbp->pgsize) {
- __db_err(dbenv, "page sizes must be a power-of-2");
- goto einval;
- }
- dbp->pgsize = dbinfo->db_pagesize;
- dbp->db_malloc = dbinfo->db_malloc;
- if (F_ISSET(dbinfo, DB_DUPSORT)) {
- if (F_ISSET(dbinfo, DB_DUP))
- dbp->dup_compare = dbinfo->dup_compare == NULL ?
- __bam_defcmp : dbinfo->dup_compare;
- else {
- __db_err(dbenv, "DB_DUPSORT requires DB_DUP");
- goto einval;
- }
- F_CLR(dbinfo, DB_DUPSORT);
- }
- }
-
- /* Fill in the default file mode. */
- if (mode == 0)
- mode = __db_omode("rwrw--");
-
- /* Check if the user wants us to swap byte order. */
- if (dbinfo != NULL)
- switch (ret = __db_byteorder(dbenv, dbinfo->db_lorder)) {
- case 0:
- break;
- case DB_SWAPBYTES:
- F_SET(dbp, DB_AM_SWAP);
- break;
- default:
- goto err;
- }
- dbp->byteswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0;
-
- /*
- * If we have a file name, try and read the first page, figure out
- * what type of file it is, and initialize everything we can based
- * on that file's meta-data page.
- *
- * XXX
- * We don't actually expect zero-length strings as arguments. We
- * do the check, permitting them, because scripting languages, e.g.,
- * the Tcl test suite, doesn't know anything about passing NULL's.
- */
- if (fname != NULL && fname[0] != '\0') {
- /* Get the real file name. */
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, NULL, fname, 0, NULL, &real_name)) != 0)
- goto err;
-
- /*
- * Open the backing file. We need to make sure that multiple
- * processes attempting to create the file at the same time
- * are properly ordered so that only one of them creates the
- * "unique" file id, so we open it O_EXCL and O_CREAT so two
- * simultaneous attempts to create the region will return
- * failure in one of the attempts. If we're one of the ones
- * that fail, we simply retry without the O_CREAT flag, which
- * will require that the meta-data page exist.
- */
- retry_cnt = 0;
-open_retry: if (LF_ISSET(DB_CREATE)) {
- if ((ret = __db_open(real_name, flags | DB_EXCL,
- OKFLAGS | DB_EXCL, mode, &fd)) != 0) {
- if (ret == EEXIST) {
- LF_CLR(DB_CREATE);
- goto open_retry;
- } else {
- __db_err(dbenv,
- "%s: %s", fname, strerror(ret));
- goto err;
- }
- }
- } else
- if ((ret = __db_open(real_name,
- flags, OKFLAGS, mode, &fd)) != 0) {
- __db_err(dbenv, "%s: %s", fname, strerror(ret));
- goto err;
- }
-
- /*
- * Use the optimum I/O size as the pagesize if a pagesize not
- * specified. Some filesystems have 64K as their optimum I/O
- * size, but as that results in impossibly large default cache
- * sizes, we limit the default pagesize to 16K.
- */
- if (dbp->pgsize == 0) {
- if ((ret = __os_ioinfo(real_name,
- fd, NULL, NULL, &iopsize)) != 0) {
- __db_err(dbenv,
- "%s: %s", real_name, strerror(ret));
- goto err;
- }
- if (iopsize < 512)
- iopsize = 512;
- if (iopsize > 16 * 1024)
- iopsize = 16 * 1024;
-
- /*
- * Sheer paranoia, but we don't want anything that's
- * not a power-of-2, as we rely on that for alignment
- * of various types on the pages.
- */
- DB_ROUNDOFF(iopsize, 512);
-
- dbp->pgsize = iopsize;
- F_SET(dbp, DB_AM_PGDEF);
- }
-
- /*
- * Try and read the first disk sector -- this code assumes
- * that the meta-data for all access methods fits in 512
- * bytes, and that no database will be smaller than that.
- */
- if ((ret = __os_read(fd, mbuf, sizeof(mbuf), &nr)) != 0)
- goto err;
-
- /* The fd is no longer needed. */
- (void)__os_close(fd);
- fd = -1;
-
- if (nr != sizeof(mbuf)) {
- if (nr != 0) {
- __db_err(dbenv,
- "%s: unexpected file format", fname);
- goto einval;
- }
- /*
- * The only way we can reach here with the DB_CREATE
- * flag set is if we created the file. If that's not
- * the case, then a) someone else created the file
- * but has not yet written out the meta-data page, or
- * b) we truncated the file (DB_TRUNCATE) leaving it
- * zero-length. In the case of a), we want to sleep
- * and give the file creator some time to write the
- * metadata page. In the case of b), charge forward.
- * Note, there is a race in the case of two processes
- * opening the file with the DB_TRUNCATE flag set at
- * roughly the same time, and they could theoretically
- * hurt each other, although it's pretty unlikely.
- */
- if (retry_cnt++ < 3 &&
- !LF_ISSET(DB_CREATE | DB_TRUNCATE)) {
- __os_sleep(1, 0);
- goto open_retry;
- }
- if (type == DB_UNKNOWN) {
- __db_err(dbenv,
- "%s: DBTYPE of unknown with empty file",
- fname);
- goto einval;
- }
- goto empty;
- }
-
- /*
- * A found file overrides some user information. We'll check
- * for possible error conditions based on conflicts between
- * the file and the user's arguments below.
- */
- swapped = 0;
- F_CLR(dbp, DB_AM_SWAP);
-
-retry: switch (((BTMETA *)mbuf)->magic) {
- case DB_BTREEMAGIC:
- if (type != DB_BTREE &&
- type != DB_RECNO && type != DB_UNKNOWN)
- goto einval;
-
- btm = (BTMETA *)mbuf;
- if (swapped && (ret = __bam_mswap((PAGE *)btm)) != 0)
- goto err;
-
- if (btm->version < DB_BTREEOLDVER ||
- btm->version > DB_BTREEVERSION) {
- __db_err(dbenv,
- "%s: unsupported btree version number %lu",
- fname, (u_long)btm->version);
- goto einval;
- }
- dbp->pgsize = btm->pagesize;
- F_CLR(dbp, DB_AM_PGDEF);
-
- if ((ret = __db_fchk(dbenv,
- "db_open", btm->flags, BTM_MASK)) != 0)
- goto err;
- DBINFO_FCHK(dbp, "DB_DUP",
- btm->flags, BTM_DUP, DB_AM_DUP);
- if (F_ISSET(btm, BTM_RECNO)) {
- DBINFO_FCHK(dbp, "DB_FIXEDLEN",
- btm->flags, BTM_FIXEDLEN, DB_RE_FIXEDLEN);
- DBINFO_FCHK(dbp, "DB_RENUMBER",
- btm->flags, BTM_RENUMBER, DB_RE_RENUMBER);
- type = DB_RECNO;
- } else {
- DBINFO_FCHK(dbp, "DB_RECNUM",
- btm->flags, BTM_RECNUM, DB_BT_RECNUM);
- type = DB_BTREE;
- }
-
- /* Copy the file's unique id. */
- need_fileid = 0;
- memcpy(dbp->fileid, btm->uid, DB_FILE_ID_LEN);
- break;
- case DB_HASHMAGIC:
- if (type != DB_HASH && type != DB_UNKNOWN)
- goto einval;
-
- hashm = (HASHHDR *)mbuf;
- if (swapped && (ret = __ham_mswap((PAGE *)hashm)) != 0)
- goto err;
-
- if (hashm->version < DB_HASHOLDVER ||
- hashm->version > DB_HASHVERSION) {
- __db_err(dbenv,
- "%s: unsupported hash version number %lu",
- fname, hashm->version);
- goto einval;
- }
- dbp->pgsize = hashm->pagesize;
- F_CLR(dbp, DB_AM_PGDEF);
-
- if ((ret = __db_fchk(dbenv,
- "db_open", hashm->flags, DB_HASH_DUP)) != 0)
- goto err;
- DBINFO_FCHK(dbp, "DB_DUP",
- hashm->flags, DB_HASH_DUP, DB_AM_DUP);
- type = DB_HASH;
-
- /* Copy the file's unique id. */
- need_fileid = 0;
- memcpy(dbp->fileid, hashm->uid, DB_FILE_ID_LEN);
- break;
- default:
- if (swapped) {
- __db_err(dbenv, "unrecognized file type");
- goto einval;
- }
- M_32_SWAP(((BTMETA *)mbuf)->magic);
- F_SET(dbp, DB_AM_SWAP);
-
- swapped = 1;
- goto retry;
- }
- } else {
- fname = real_name = NULL;
-
- if (type == DB_UNKNOWN) {
- __db_err(dbenv,
- "DBTYPE of unknown without existing file");
- goto einval;
- }
- F_SET(dbp, DB_AM_INMEM);
- }
-
-empty: /*
- * By the time we get here we've either set the type or we're taking
- * it from the user.
- */
- dbp->type = type;
-
- /*
- * Set the page size to the best value for I/O to this file. Don't
- * overflow the page offset type. The page size must be db_indx_t
- * aligned and >= MIN_PAGE_SIZE.
- *
- * XXX
- * Should we be checking for a page size that's not a multiple of 512?
- */
- if (dbp->pgsize == 0) {
- F_SET(dbp, DB_AM_PGDEF);
- dbp->pgsize = 8 * 1024;
- }
- if (dbp->pgsize < DB_MIN_PGSIZE ||
- dbp->pgsize > DB_MAX_PGSIZE ||
- dbp->pgsize & (sizeof(db_indx_t) - 1)) {
- __db_err(dbenv, "illegal page size");
- goto einval;
- }
-
- /*
- * If no mpool supplied by the application, attach to a local,
- * created buffer pool.
- *
- * XXX
- * If the user has a DB_ENV structure, we have to use a temporary
- * one so that we don't step on their values. If the user doesn't,
- * we have to create one, and keep it around until the call to the
- * memp_close() function. This is all so the mpool functions get
- * the error stuff right.
- */
- if (dbenv == NULL || dbenv->mp_info == NULL) {
- F_SET(dbp, DB_AM_MLOCAL);
-
- if (dbenv == NULL) {
- if ((ret = __os_calloc(1,
- sizeof(DB_ENV), &dbp->mp_dbenv)) != 0)
- goto err;
-
- envp = dbp->mp_dbenv;
- restore = 0;
- } else {
- t_dbenv = *dbenv;
-
- envp = dbenv;
- restore = 1;
- }
-
- /*
- * Set and/or correct the cache size; must be a multiple of
- * the page size.
- */
- if (dbinfo == NULL || dbinfo->db_cachesize == 0)
- cachesize = dbp->pgsize * DB_MINCACHE;
- else {
- cachesize = dbinfo->db_cachesize;
- if (cachesize & (dbp->pgsize - 1))
- cachesize +=
- (~cachesize & (dbp->pgsize - 1)) + 1;
- if (cachesize < dbp->pgsize * DB_MINCACHE)
- cachesize = dbp->pgsize * DB_MINCACHE;
- if (cachesize < 20 * 1024)
- cachesize = 20 * 1024;
- }
- envp->mp_size = cachesize;
-
- if ((ret = memp_open(NULL, DB_CREATE | DB_MPOOL_PRIVATE |
- (F_ISSET(dbp, DB_AM_THREAD) ? DB_THREAD : 0),
- __db_omode("rw----"), envp, &dbp->mp)) != 0)
- goto err;
- if (restore)
- *dbenv = t_dbenv;
- } else
- dbp->mp = dbenv->mp_info;
-
- /* Register DB's pgin/pgout functions. */
- if ((ret = memp_register(dbp->mp,
- DB_FTYPE_BTREE, __bam_pgin, __bam_pgout)) != 0)
- goto err;
- if ((ret = memp_register(dbp->mp,
- DB_FTYPE_HASH, __ham_pgin, __ham_pgout)) != 0)
- goto err;
-
- /*
- * If we don't already have one, get a unique file ID. If the file
- * is a temporary file, then we have to create a unique file ID --
- * no backing file will be created until the mpool cache is filled
- * forcing it to go to disk. The created ID must never match any
- * potential real file ID -- we know it won't because real file IDs
- * contain a time stamp after the dev/ino pair, and we're simply
- * storing a 4-byte locker ID.
- *
- * XXX
- * Store the file id in the locker structure -- we can get it from
- * there as necessary, and it saves having two copies.
- */
- if (need_fileid) {
- if (fname == NULL) {
- memset(dbp->fileid, 0, DB_FILE_ID_LEN);
- if (F_ISSET(dbp, DB_AM_LOCKING) &&
- (ret = lock_id(dbenv->lk_info,
- (u_int32_t *)dbp->fileid)) != 0)
- goto err;
- } else
- if ((ret = __os_fileid(dbenv,
- real_name, 1, dbp->fileid)) != 0)
- goto err;
- }
-
- /* No further use for the real name. */
- if (real_name != NULL)
- __os_freestr(real_name);
- real_name = NULL;
-
- /*
- * Open a backing file in the memory pool.
- *
- * If we need to process the file's pages on I/O, set the file type.
- * If it's a hash file, always call pgin and pgout routines. This
- * means that hash files can never be mapped into process memory. If
- * it's a btree file and requires swapping, we need to page the file
- * in and out. This has to be right -- we can't mmap files that are
- * being paged in and out.
- */
- if (type == DB_HASH)
- ftype = DB_FTYPE_HASH;
- else
- ftype = F_ISSET(dbp, DB_AM_SWAP) ? DB_FTYPE_BTREE : 0;
- pginfo.db_pagesize = dbp->pgsize;
- pginfo.needswap = F_ISSET(dbp, DB_AM_SWAP);
- pgcookie.data = &pginfo;
- pgcookie.size = sizeof(DB_PGINFO);
-
- /*
- * Set up additional memp_fopen information.
- */
- memset(&finfo, 0, sizeof(finfo));
- finfo.ftype = ftype;
- finfo.pgcookie = &pgcookie;
- finfo.fileid = dbp->fileid;
- finfo.lsn_offset = 0;
- finfo.clear_len = DB_PAGE_CLEAR_LEN;
- if ((ret = memp_fopen(dbp->mp, fname,
- F_ISSET(dbp, DB_AM_RDONLY) ? DB_RDONLY : 0,
- 0, dbp->pgsize, &finfo, &dbp->mpf)) != 0)
- goto err;
-
- /*
- * XXX
- * We need a per-thread mutex that lives in shared memory -- HP-UX
- * can't allocate mutexes in malloc'd memory. Allocate it from the
- * shared memory region, since it's the only one that is guaranteed
- * to exist.
- */
- if (F_ISSET(dbp, DB_AM_THREAD)) {
- if ((ret = __memp_reg_alloc(dbp->mp,
- sizeof(db_mutex_t), NULL, &dbp->mutexp)) != 0)
- goto err;
- /*
- * Since we only get here if DB_THREAD was specified, we know
- * we have spinlocks and no file offset argument is needed.
- */
- (void)__db_mutex_init(dbp->mutexp, 0);
- }
-
- /* Get a log file id. */
- if (F_ISSET(dbp, DB_AM_LOGGING) &&
- (ret = log_register(dbenv->lg_info,
- dbp, fname, type, &dbp->log_fileid)) != 0)
- goto err;
-
- /* Call the real open function. */
- switch (type) {
- case DB_BTREE:
- if (dbinfo != NULL && (ret = __db_fchk(dbenv,
- "db_open", dbinfo->flags, DB_RECNUM | DB_DUP)) != 0)
- goto err;
- if (dbinfo != NULL && (ret = __db_fcchk(dbenv,
- "db_open", dbinfo->flags, DB_DUP, DB_RECNUM)) != 0)
- goto err;
- if ((ret = __bam_open(dbp, dbinfo)) != 0)
- goto err;
- break;
- case DB_HASH:
- if (dbinfo != NULL && (ret = __db_fchk(dbenv,
- "db_open", dbinfo->flags, DB_DUP)) != 0)
- goto err;
- if ((ret = __ham_open(dbp, dbinfo)) != 0)
- goto err;
- break;
- case DB_RECNO:
-#define DB_INFO_FLAGS \
- (DB_DELIMITER | DB_FIXEDLEN | DB_PAD | DB_RENUMBER | DB_SNAPSHOT)
- if (dbinfo != NULL && (ret = __db_fchk(dbenv,
- "db_open", dbinfo->flags, DB_INFO_FLAGS)) != 0)
- goto err;
- if ((ret = __ram_open(dbp, dbinfo)) != 0)
- goto err;
- break;
- default:
- abort();
- }
-
- *dbpp = dbp;
- return (0);
-
-einval: ret = EINVAL;
-err: /* Close the file descriptor. */
- if (fd != -1)
- (void)__os_close(fd);
-
- /* Discard the log file id. */
- if (dbp->log_fileid != 0)
- (void)log_unregister(dbenv->lg_info, dbp->log_fileid);
-
- /* Close the memory pool file. */
- if (dbp->mpf != NULL)
- (void)memp_fclose(dbp->mpf);
-
- /* If the memory pool was local, close it. */
- if (F_ISSET(dbp, DB_AM_MLOCAL) && dbp->mp != NULL)
- (void)memp_close(dbp->mp);
-
- /* If we allocated a DB_ENV, discard it. */
- if (dbp->mp_dbenv != NULL)
- __os_free(dbp->mp_dbenv, sizeof(DB_ENV));
-
- if (real_name != NULL)
- __os_freestr(real_name);
- if (dbp != NULL)
- __os_free(dbp, sizeof(DB));
-
- return (ret);
-}
-
-#ifdef _LIBC
-# undef db_open
-weak_alias (__nss_db_open, db_open)
-#endif
-
-/*
- * __db_close --
- * Close a DB tree.
- *
- * PUBLIC: int __db_close __P((DB *, u_int32_t));
- */
-int
-__db_close(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DBC *dbc;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- /* Validate arguments. */
- if ((ret = __db_closechk(dbp, flags)) != 0)
- return (ret);
-
- /* Sync the underlying file. */
- if (flags != DB_NOSYNC &&
- (t_ret = dbp->sync(dbp, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * Go through the active cursors and call the cursor recycle routine,
- * which resolves pending operations and moves the cursors onto the
- * free list. Then, walk the free list and call the cursor destroy
- * routine.
- */
- while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
- if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
- if ((t_ret = __db_c_destroy(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Call the access specific close function. */
- if ((t_ret = dbp->am_close(dbp)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Sync the memory pool. */
- if (flags != DB_NOSYNC && (t_ret = memp_fsync(dbp->mpf)) != 0 &&
- t_ret != DB_INCOMPLETE && ret == 0)
- ret = t_ret;
-
- /* Close the memory pool file. */
- if ((t_ret = memp_fclose(dbp->mpf)) != 0 && ret == 0)
- ret = t_ret;
-
- /* If the memory pool was local, close it. */
- if (F_ISSET(dbp, DB_AM_MLOCAL) &&
- (t_ret = memp_close(dbp->mp)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard the log file id. */
- if (F_ISSET(dbp, DB_AM_LOGGING))
- (void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid);
-
- /* If we allocated a DB_ENV, discard it. */
- if (dbp->mp_dbenv != NULL)
- __os_free(dbp->mp_dbenv, sizeof(DB_ENV));
-
- /* Free the DB. */
- __os_free(dbp, sizeof(*dbp));
-
- return (ret);
-}
diff --git a/db2/db/db_am.c b/db2/db/db_am.c
deleted file mode 100644
index e02ad57..0000000
--- a/db2/db/db_am.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_am.c 10.15 (Sleepycat) 12/30/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "btree.h"
-#include "hash.h"
-#include "db_am.h"
-#include "db_ext.h"
-
-static int __db_c_close __P((DBC *));
-static int __db_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
-static int __db_fd __P((DB *, int *));
-static int __db_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-static int __db_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-
-/*
- * __db_init_wrapper --
- * Wrapper layer to implement generic DB functions.
- *
- * PUBLIC: int __db_init_wrapper __P((DB *));
- */
-int
-__db_init_wrapper(dbp)
- DB *dbp;
-{
- dbp->close = __db_close;
- dbp->cursor = __db_cursor;
- dbp->del = NULL; /* !!! Must be set by access method. */
- dbp->fd = __db_fd;
- dbp->get = __db_get;
- dbp->join = __db_join;
- dbp->put = __db_put;
- dbp->stat = NULL; /* !!! Must be set by access method. */
- dbp->sync = __db_sync;
-
- return (0);
-}
-
-/*
- * __db_cursor --
- * Allocate and return a cursor.
- */
-static int
-__db_cursor(dbp, txn, dbcp, flags)
- DB *dbp;
- DB_TXN *txn;
- DBC **dbcp;
- u_int32_t flags;
-{
- DBC *dbc, *adbc;
- int ret;
- db_lockmode_t mode;
- u_int32_t op;
-
- DB_PANIC_CHECK(dbp);
-
- /* Take one from the free list if it's available. */
- DB_THREAD_LOCK(dbp);
- if ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
- TAILQ_REMOVE(&dbp->free_queue, dbc, links);
- else {
- DB_THREAD_UNLOCK(dbp);
-
- if ((ret = __os_calloc(1, sizeof(DBC), &dbc)) != 0)
- return (ret);
-
- dbc->dbp = dbp;
- dbc->c_close = __db_c_close;
-
- /* Set up locking information. */
- if (F_ISSET(dbp, DB_AM_LOCKING | DB_AM_CDB)) {
- /*
- * If we are not threaded, then there is no need to
- * create new locker ids. We know that no one else
- * is running concurrently using this DB, so we can
- * take a peek at any cursors on the active queue.
- */
- if (!F_ISSET(dbp, DB_AM_THREAD) &&
- (adbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
- dbc->lid = adbc->lid;
- else
- if ((ret = lock_id(dbp->dbenv->lk_info,
- &dbc->lid)) != 0)
- goto err;
-
- memcpy(dbc->lock.fileid, dbp->fileid, DB_FILE_ID_LEN);
- if (F_ISSET(dbp, DB_AM_CDB)) {
- dbc->lock_dbt.size = DB_FILE_ID_LEN;
- dbc->lock_dbt.data = dbc->lock.fileid;
- } else {
- dbc->lock_dbt.size = sizeof(dbc->lock);
- dbc->lock_dbt.data = &dbc->lock;
- }
- }
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_c_init(dbc)) != 0)
- goto err;
- break;
- case DB_HASH:
- if ((ret = __ham_c_init(dbc)) != 0)
- goto err;
- break;
- default:
- ret = EINVAL;
- goto err;
- }
-
- DB_THREAD_LOCK(dbp);
- }
-
- if ((dbc->txn = txn) == NULL)
- dbc->locker = dbc->lid;
- else
- dbc->locker = txn->txnid;
-
- TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
- DB_THREAD_UNLOCK(dbp);
-
- /*
- * If this is the concurrent DB product, then we do all locking
- * in the interface, which is right here.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- op = LF_ISSET(DB_OPFLAGS_MASK);
- mode = (op == DB_WRITELOCK) ? DB_LOCK_WRITE :
- (LF_ISSET(DB_RMW) ? DB_LOCK_IWRITE : DB_LOCK_READ);
- if ((ret = lock_get(dbp->dbenv->lk_info, dbc->locker, 0,
- &dbc->lock_dbt, mode, &dbc->mylock)) != 0) {
- (void)__db_c_close(dbc);
- return (EAGAIN);
- }
- if (LF_ISSET(DB_RMW))
- F_SET(dbc, DBC_RMW);
- if (op == DB_WRITELOCK)
- F_SET(dbc, DBC_WRITER);
- }
-
- *dbcp = dbc;
- return (0);
-
-err: __os_free(dbc, sizeof(*dbc));
- return (ret);
-}
-
-/*
- * __db_c_close --
- * Close the cursor (recycle for later use).
- */
-static int
-__db_c_close(dbc)
- DBC *dbc;
-{
- DB *dbp;
- int ret, t_ret;
-
- dbp = dbc->dbp;
-
- DB_PANIC_CHECK(dbp);
-
- ret = 0;
-
- /*
- * We cannot release the lock until after we've called the
- * access method specific routine, since btrees may have pending
- * deletes.
- */
-
- /* Remove the cursor from the active queue. */
- DB_THREAD_LOCK(dbp);
- TAILQ_REMOVE(&dbp->active_queue, dbc, links);
- DB_THREAD_UNLOCK(dbp);
-
- /* Call the access specific cursor close routine. */
- if ((t_ret = dbc->c_am_close(dbc)) != 0 && ret == 0)
- t_ret = ret;
-
- /* Release the lock. */
- if (F_ISSET(dbc->dbp, DB_AM_CDB) && dbc->mylock != LOCK_INVALID) {
- ret = lock_put(dbc->dbp->dbenv->lk_info, dbc->mylock);
- dbc->mylock = LOCK_INVALID;
- }
-
- /* Clean up the cursor. */
- dbc->flags = 0;
-
-#ifdef DEBUG
- /*
- * Check for leftover locks, unless we're running with transactions.
- *
- * If we're running tests, display any locks currently held. It's
- * possible that some applications may hold locks for long periods,
- * e.g., conference room locks, but the DB tests should never close
- * holding locks.
- */
- if (F_ISSET(dbp, DB_AM_LOCKING) && dbc->lid == dbc->locker) {
- DB_LOCKREQ request;
-
- request.op = DB_LOCK_DUMP;
- if ((t_ret = lock_vec(dbp->dbenv->lk_info,
- dbc->locker, 0, &request, 1, NULL)) != 0 && ret == 0)
- ret = EAGAIN;
- }
-#endif
- /* Move the cursor to the free queue. */
- DB_THREAD_LOCK(dbp);
- TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links);
- DB_THREAD_UNLOCK(dbp);
-
- return (ret);
-}
-
-#ifdef DEBUG
-/*
- * __db_cprint --
- * Display the current cursor list.
- *
- * PUBLIC: int __db_cprint __P((DB *));
- */
-int
-__db_cprint(dbp)
- DB *dbp;
-{
- static const FN fn[] = {
- { DBC_RECOVER, "recover" },
- { DBC_RMW, "read-modify-write" },
- { 0 },
- };
- DBC *dbc;
-
- DB_THREAD_LOCK(dbp);
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- fprintf(stderr,
- "%#0x: dbp: %#0x txn: %#0x lid: %lu locker: %lu",
- (u_int)dbc, (u_int)dbc->dbp, (u_int)dbc->txn,
- (u_long)dbc->lid, (u_long)dbc->locker);
- __db_prflags(dbc->flags, fn, stderr);
- fprintf(stderr, "\n");
- }
- DB_THREAD_UNLOCK(dbp);
-
- return (0);
-}
-#endif /* DEBUG */
-
-/*
- * __db_c_destroy --
- * Destroy the cursor.
- *
- * PUBLIC: int __db_c_destroy __P((DBC *));
- */
-int
-__db_c_destroy(dbc)
- DBC *dbc;
-{
- DB *dbp;
- int ret;
-
- dbp = dbc->dbp;
-
- /* Remove the cursor from the free queue. */
- DB_THREAD_LOCK(dbp);
- TAILQ_REMOVE(&dbp->free_queue, dbc, links);
- DB_THREAD_UNLOCK(dbp);
-
- /* Call the access specific cursor destroy routine. */
- ret = dbc->c_am_destroy == NULL ? 0 : dbc->c_am_destroy(dbc);
-
- /* Free up allocated memory. */
- if (dbc->rkey.data != NULL)
- __os_free(dbc->rkey.data, dbc->rkey.ulen);
- if (dbc->rdata.data != NULL)
- __os_free(dbc->rdata.data, dbc->rdata.ulen);
- __os_free(dbc, sizeof(*dbc));
-
- return (0);
-}
-
-/*
- * db_fd --
- * Return a file descriptor for flock'ing.
- */
-static int
-__db_fd(dbp, fdp)
- DB *dbp;
- int *fdp;
-{
- DB_PANIC_CHECK(dbp);
-
- /*
- * XXX
- * Truly spectacular layering violation.
- */
- return (__mp_xxx_fd(dbp->mpf, fdp));
-}
-
-/*
- * __db_get --
- * Return a key/data pair.
- */
-static int
-__db_get(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret = __db_getchk(dbp, key, data, flags)) != 0)
- return (ret);
-
- if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0)
- return (ret);
-
- DEBUG_LREAD(dbc, txn, "__db_get", key, NULL, flags);
-
- ret = dbc->c_get(dbc, key, data,
- flags == 0 || flags == DB_RMW ? flags | DB_SET : flags);
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_put --
- * Store a key/data pair.
- */
-static int
-__db_put(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- DBT tdata;
- int ret, t_ret;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret = __db_putchk(dbp, key, data,
- flags, F_ISSET(dbp, DB_AM_RDONLY), F_ISSET(dbp, DB_AM_DUP))) != 0)
- return (ret);
-
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "__db_put", key, data, flags);
-
- if (flags == DB_NOOVERWRITE) {
- /*
- * Set DB_DBT_USERMEM, this might be a threaded application and
- * the flags checking will catch us. We don't want the actual
- * data, so request a partial of length 0.
- */
- memset(&tdata, 0, sizeof(tdata));
- F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
- if ((ret = dbc->c_get(dbc, key, &tdata, DB_SET | DB_RMW)) == 0)
- ret = DB_KEYEXIST;
- else
- ret = 0;
- }
- if (ret == 0)
- ret = dbc->c_put(dbc, key, data, DB_KEYLAST);
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_sync --
- * Flush the database cache.
- *
- * PUBLIC: int __db_sync __P((DB *, u_int32_t));
- */
-int
-__db_sync(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- int ret;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret = __db_syncchk(dbp, flags)) != 0)
- return (ret);
-
- /* If it wasn't possible to modify the file, we're done. */
- if (F_ISSET(dbp, DB_AM_INMEM | DB_AM_RDONLY))
- return (0);
-
- /* Flush any dirty pages from the cache to the backing file. */
- if ((ret = memp_fsync(dbp->mpf)) == DB_INCOMPLETE)
- ret = 0;
-
- return (ret);
-}
diff --git a/db2/db/db_auto.c b/db2/db/db_auto.c
deleted file mode 100644
index e3dba23..0000000
--- a/db2/db/db_auto.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __db_addrem_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- * PUBLIC: size_t, const DBT *, const DBT *, DB_LSN *));
- */
-int __db_addrem_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, indx, nbytes, hdr,
- dbt, pagelsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t indx;
- size_t nbytes;
- const DBT *hdr;
- const DBT *dbt;
- DB_LSN * pagelsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_addrem;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(indx)
- + sizeof(nbytes)
- + sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size)
- + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size)
- + sizeof(*pagelsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &indx, sizeof(indx));
- bp += sizeof(indx);
- memcpy(bp, &nbytes, sizeof(nbytes));
- bp += sizeof(nbytes);
- if (hdr == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &hdr->size, sizeof(hdr->size));
- bp += sizeof(hdr->size);
- memcpy(bp, hdr->data, hdr->size);
- bp += hdr->size;
- }
- if (dbt == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &dbt->size, sizeof(dbt->size));
- bp += sizeof(dbt->size);
- memcpy(bp, dbt->data, dbt->size);
- bp += dbt->size;
- }
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_addrem_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_addrem_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_addrem_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_addrem_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_addrem: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tindx: %lu\n", (u_long)argp->indx);
- printf("\tnbytes: %lu\n", (u_long)argp->nbytes);
- printf("\thdr: ");
- for (i = 0; i < argp->hdr.size; i++) {
- ch = ((u_int8_t *)argp->hdr.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tdbt: ");
- for (i = 0; i < argp->dbt.size; i++) {
- ch = ((u_int8_t *)argp->dbt.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_addrem_read __P((void *, __db_addrem_args **));
- */
-int
-__db_addrem_read(recbuf, argpp)
- void *recbuf;
- __db_addrem_args **argpp;
-{
- __db_addrem_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_addrem_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->indx, bp, sizeof(argp->indx));
- bp += sizeof(argp->indx);
- memcpy(&argp->nbytes, bp, sizeof(argp->nbytes));
- bp += sizeof(argp->nbytes);
- memcpy(&argp->hdr.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->hdr.data = bp;
- bp += argp->hdr.size;
- memcpy(&argp->dbt.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->dbt.data = bp;
- bp += argp->dbt.size;
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_split_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, const DBT *,
- * PUBLIC: DB_LSN *));
- */
-int __db_split_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, pageimage, pagelsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- const DBT *pageimage;
- DB_LSN * pagelsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_split;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(u_int32_t) + (pageimage == NULL ? 0 : pageimage->size)
- + sizeof(*pagelsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (pageimage == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &pageimage->size, sizeof(pageimage->size));
- bp += sizeof(pageimage->size);
- memcpy(bp, pageimage->data, pageimage->size);
- bp += pageimage->size;
- }
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_split_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_split_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_split_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_split_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tpageimage: ");
- for (i = 0; i < argp->pageimage.size; i++) {
- ch = ((u_int8_t *)argp->pageimage.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_split_read __P((void *, __db_split_args **));
- */
-int
-__db_split_read(recbuf, argpp)
- void *recbuf;
- __db_split_args **argpp;
-{
- __db_split_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_split_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->pageimage.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->pageimage.data = bp;
- bp += argp->pageimage.size;
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_big_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
- * PUBLIC: db_pgno_t, const DBT *, DB_LSN *, DB_LSN *,
- * PUBLIC: DB_LSN *));
- */
-int __db_big_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, prev_pgno, next_pgno, dbt,
- pagelsn, prevlsn, nextlsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- db_pgno_t prev_pgno;
- db_pgno_t next_pgno;
- const DBT *dbt;
- DB_LSN * pagelsn;
- DB_LSN * prevlsn;
- DB_LSN * nextlsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_big;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(prev_pgno)
- + sizeof(next_pgno)
- + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size)
- + sizeof(*pagelsn)
- + sizeof(*prevlsn)
- + sizeof(*nextlsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &prev_pgno, sizeof(prev_pgno));
- bp += sizeof(prev_pgno);
- memcpy(bp, &next_pgno, sizeof(next_pgno));
- bp += sizeof(next_pgno);
- if (dbt == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &dbt->size, sizeof(dbt->size));
- bp += sizeof(dbt->size);
- memcpy(bp, dbt->data, dbt->size);
- bp += dbt->size;
- }
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- if (prevlsn != NULL)
- memcpy(bp, prevlsn, sizeof(*prevlsn));
- else
- memset(bp, 0, sizeof(*prevlsn));
- bp += sizeof(*prevlsn);
- if (nextlsn != NULL)
- memcpy(bp, nextlsn, sizeof(*nextlsn));
- else
- memset(bp, 0, sizeof(*nextlsn));
- bp += sizeof(*nextlsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_big_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_big_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_big_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_big_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_big: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tprev_pgno: %lu\n", (u_long)argp->prev_pgno);
- printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
- printf("\tdbt: ");
- for (i = 0; i < argp->dbt.size; i++) {
- ch = ((u_int8_t *)argp->dbt.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\tprevlsn: [%lu][%lu]\n",
- (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset);
- printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_big_read __P((void *, __db_big_args **));
- */
-int
-__db_big_read(recbuf, argpp)
- void *recbuf;
- __db_big_args **argpp;
-{
- __db_big_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_big_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->prev_pgno, bp, sizeof(argp->prev_pgno));
- bp += sizeof(argp->prev_pgno);
- memcpy(&argp->next_pgno, bp, sizeof(argp->next_pgno));
- bp += sizeof(argp->next_pgno);
- memcpy(&argp->dbt.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->dbt.data = bp;
- bp += argp->dbt.size;
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->prevlsn, bp, sizeof(argp->prevlsn));
- bp += sizeof(argp->prevlsn);
- memcpy(&argp->nextlsn, bp, sizeof(argp->nextlsn));
- bp += sizeof(argp->nextlsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_ovref_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, int32_t, DB_LSN *));
- */
-int __db_ovref_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, adjust, lsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- int32_t adjust;
- DB_LSN * lsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_ovref;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(adjust)
- + sizeof(*lsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &adjust, sizeof(adjust));
- bp += sizeof(adjust);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_ovref_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_ovref_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_ovref_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_ovref_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_ovref: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tadjust: %ld\n", (long)argp->adjust);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_ovref_read __P((void *, __db_ovref_args **));
- */
-int
-__db_ovref_read(recbuf, argpp)
- void *recbuf;
- __db_ovref_args **argpp;
-{
- __db_ovref_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_ovref_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->adjust, bp, sizeof(argp->adjust));
- bp += sizeof(argp->adjust);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_relink_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, DB_LSN *,
- * PUBLIC: db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *));
- */
-int __db_relink_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, lsn, prev, lsn_prev,
- next, lsn_next)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- db_pgno_t prev;
- DB_LSN * lsn_prev;
- db_pgno_t next;
- DB_LSN * lsn_next;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_relink;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(prev)
- + sizeof(*lsn_prev)
- + sizeof(next)
- + sizeof(*lsn_next);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &prev, sizeof(prev));
- bp += sizeof(prev);
- if (lsn_prev != NULL)
- memcpy(bp, lsn_prev, sizeof(*lsn_prev));
- else
- memset(bp, 0, sizeof(*lsn_prev));
- bp += sizeof(*lsn_prev);
- memcpy(bp, &next, sizeof(next));
- bp += sizeof(next);
- if (lsn_next != NULL)
- memcpy(bp, lsn_next, sizeof(*lsn_next));
- else
- memset(bp, 0, sizeof(*lsn_next));
- bp += sizeof(*lsn_next);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_relink_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_relink_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_relink_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_relink_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_relink: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tprev: %lu\n", (u_long)argp->prev);
- printf("\tlsn_prev: [%lu][%lu]\n",
- (u_long)argp->lsn_prev.file, (u_long)argp->lsn_prev.offset);
- printf("\tnext: %lu\n", (u_long)argp->next);
- printf("\tlsn_next: [%lu][%lu]\n",
- (u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_relink_read __P((void *, __db_relink_args **));
- */
-int
-__db_relink_read(recbuf, argpp)
- void *recbuf;
- __db_relink_args **argpp;
-{
- __db_relink_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_relink_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->prev, bp, sizeof(argp->prev));
- bp += sizeof(argp->prev);
- memcpy(&argp->lsn_prev, bp, sizeof(argp->lsn_prev));
- bp += sizeof(argp->lsn_prev);
- memcpy(&argp->next, bp, sizeof(argp->next));
- bp += sizeof(argp->next);
- memcpy(&argp->lsn_next, bp, sizeof(argp->lsn_next));
- bp += sizeof(argp->lsn_next);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_addpage_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- * PUBLIC: DB_LSN *));
- */
-int __db_addpage_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, lsn, nextpgno, nextlsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * lsn;
- db_pgno_t nextpgno;
- DB_LSN * nextlsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_addpage;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*lsn)
- + sizeof(nextpgno)
- + sizeof(*nextlsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (lsn != NULL)
- memcpy(bp, lsn, sizeof(*lsn));
- else
- memset(bp, 0, sizeof(*lsn));
- bp += sizeof(*lsn);
- memcpy(bp, &nextpgno, sizeof(nextpgno));
- bp += sizeof(nextpgno);
- if (nextlsn != NULL)
- memcpy(bp, nextlsn, sizeof(*nextlsn));
- else
- memset(bp, 0, sizeof(*nextlsn));
- bp += sizeof(*nextlsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_addpage_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_addpage_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_addpage_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_addpage_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_addpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tlsn: [%lu][%lu]\n",
- (u_long)argp->lsn.file, (u_long)argp->lsn.offset);
- printf("\tnextpgno: %lu\n", (u_long)argp->nextpgno);
- printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_addpage_read __P((void *, __db_addpage_args **));
- */
-int
-__db_addpage_read(recbuf, argpp)
- void *recbuf;
- __db_addpage_args **argpp;
-{
- __db_addpage_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_addpage_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->lsn, bp, sizeof(argp->lsn));
- bp += sizeof(argp->lsn);
- memcpy(&argp->nextpgno, bp, sizeof(argp->nextpgno));
- bp += sizeof(argp->nextpgno);
- memcpy(&argp->nextlsn, bp, sizeof(argp->nextlsn));
- bp += sizeof(argp->nextlsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_debug_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: const DBT *, u_int32_t, const DBT *, const DBT *,
- * PUBLIC: u_int32_t));
- */
-int __db_debug_log(logp, txnid, ret_lsnp, flags,
- op, fileid, key, data, arg_flags)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- const DBT *op;
- u_int32_t fileid;
- const DBT *key;
- const DBT *data;
- u_int32_t arg_flags;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_db_debug;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(u_int32_t) + (op == NULL ? 0 : op->size)
- + sizeof(fileid)
- + sizeof(u_int32_t) + (key == NULL ? 0 : key->size)
- + sizeof(u_int32_t) + (data == NULL ? 0 : data->size)
- + sizeof(arg_flags);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- if (op == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &op->size, sizeof(op->size));
- bp += sizeof(op->size);
- memcpy(bp, op->data, op->size);
- bp += op->size;
- }
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- if (key == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &key->size, sizeof(key->size));
- bp += sizeof(key->size);
- memcpy(bp, key->data, key->size);
- bp += key->size;
- }
- if (data == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &data->size, sizeof(data->size));
- bp += sizeof(data->size);
- memcpy(bp, data->data, data->size);
- bp += data->size;
- }
- memcpy(bp, &arg_flags, sizeof(arg_flags));
- bp += sizeof(arg_flags);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __db_debug_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_debug_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __db_debug_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __db_debug_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]db_debug: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\top: ");
- for (i = 0; i < argp->op.size; i++) {
- ch = ((u_int8_t *)argp->op.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tkey: ");
- for (i = 0; i < argp->key.size; i++) {
- ch = ((u_int8_t *)argp->key.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tdata: ");
- for (i = 0; i < argp->data.size; i++) {
- ch = ((u_int8_t *)argp->data.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\targ_flags: %lu\n", (u_long)argp->arg_flags);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_debug_read __P((void *, __db_debug_args **));
- */
-int
-__db_debug_read(recbuf, argpp)
- void *recbuf;
- __db_debug_args **argpp;
-{
- __db_debug_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__db_debug_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->op.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->op.data = bp;
- bp += argp->op.size;
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->key.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->key.data = bp;
- bp += argp->key.size;
- memcpy(&argp->data.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->data.data = bp;
- bp += argp->data.size;
- memcpy(&argp->arg_flags, bp, sizeof(argp->arg_flags));
- bp += sizeof(argp->arg_flags);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __db_init_print __P((DB_ENV *));
- */
-int
-__db_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __db_addrem_print, DB_db_addrem)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_split_print, DB_db_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_big_print, DB_db_big)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_ovref_print, DB_db_ovref)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_relink_print, DB_db_relink)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_addpage_print, DB_db_addpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_debug_print, DB_db_debug)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __db_init_recover __P((DB_ENV *));
- */
-int
-__db_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __db_addrem_recover, DB_db_addrem)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_split_recover, DB_db_split)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_big_recover, DB_db_big)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_ovref_recover, DB_db_ovref)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_relink_recover, DB_db_relink)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_addpage_recover, DB_db_addpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __db_debug_recover, DB_db_debug)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/db/db_conv.c b/db2/db/db_conv.c
deleted file mode 100644
index 8b5cf5f..0000000
--- a/db2/db/db_conv.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_conv.c 10.13 (Sleepycat) 4/26/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_swap.h"
-#include "db_am.h"
-
-static int __db_convert __P((db_pgno_t, void *, size_t, int));
-
-/*
- * __db_pgin --
- *
- * PUBLIC: int __db_pgin __P((db_pgno_t, size_t, void *));
- */
-int
-__db_pgin(pg, pagesize, pp)
- db_pgno_t pg;
- size_t pagesize;
- void *pp;
-{
- return (__db_convert(pg, pp, pagesize, 1));
-}
-
-/*
- * __db_pgout --
- *
- * PUBLIC: int __db_pgout __P((db_pgno_t, size_t, void *));
- */
-int
-__db_pgout(pg, pagesize, pp)
- db_pgno_t pg;
- size_t pagesize;
- void *pp;
-{
- return (__db_convert(pg, pp, pagesize, 0));
-}
-
-/*
- * __db_convert --
- * Actually convert a page.
- */
-static int
-__db_convert(pg, pp, pagesize, pgin)
- db_pgno_t pg;
- void *pp;
- size_t pagesize;
- int pgin;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- BOVERFLOW *bo;
- PAGE *h;
- RINTERNAL *ri;
- db_indx_t i, len, tmp;
- u_int8_t *p, *end;
-
- COMPQUIET(pg, 0);
-
- h = pp;
- if (pgin) {
- M_32_SWAP(h->lsn.file);
- M_32_SWAP(h->lsn.offset);
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prev_pgno);
- M_32_SWAP(h->next_pgno);
- M_16_SWAP(h->entries);
- M_16_SWAP(h->hf_offset);
- }
-
- switch (h->type) {
- case P_HASH:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(h->inp[i]);
-
- switch (HPAGE_TYPE(h, i)) {
- case H_KEYDATA:
- break;
- case H_DUPLICATE:
- len = LEN_HKEYDATA(h, pagesize, i);
- p = HKEYDATA_DATA(P_ENTRY(h, i));
- for (end = p + len; p < end;) {
- if (pgin) {
- P_16_SWAP(p);
- memcpy(&tmp,
- p, sizeof(db_indx_t));
- p += sizeof(db_indx_t);
- } else {
- memcpy(&tmp,
- p, sizeof(db_indx_t));
- SWAP16(p);
- }
- p += tmp;
- SWAP16(p);
- }
- break;
- case H_OFFDUP:
- p = HOFFPAGE_PGNO(P_ENTRY(h, i));
- SWAP32(p); /* pgno */
- break;
- case H_OFFPAGE:
- p = HOFFPAGE_PGNO(P_ENTRY(h, i));
- SWAP32(p); /* pgno */
- SWAP32(p); /* tlen */
- break;
- }
-
- }
-
- /*
- * The offsets in the inp array are used to determine
- * the size of entries on a page; therefore they
- * cannot be converted until we've done all the
- * entries.
- */
- if (!pgin)
- for (i = 0; i < NUM_ENT(h); i++)
- M_16_SWAP(h->inp[i]);
- break;
- case P_LBTREE:
- case P_LRECNO:
- case P_DUPLICATE:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(h->inp[i]);
-
- bk = GET_BKEYDATA(h, i);
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- M_16_SWAP(bk->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- bo = (BOVERFLOW *)bk;
- M_32_SWAP(bo->pgno);
- M_32_SWAP(bo->tlen);
- break;
- }
-
- if (!pgin)
- M_16_SWAP(h->inp[i]);
- }
- break;
- case P_IBTREE:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(h->inp[i]);
-
- bi = GET_BINTERNAL(h, i);
- M_16_SWAP(bi->len);
- M_32_SWAP(bi->pgno);
- M_32_SWAP(bi->nrecs);
-
- switch (B_TYPE(bi->type)) {
- case B_KEYDATA:
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- bo = (BOVERFLOW *)bi->data;
- M_32_SWAP(bo->pgno);
- M_32_SWAP(bo->tlen);
- break;
- }
-
- if (!pgin)
- M_16_SWAP(h->inp[i]);
- }
- break;
- case P_IRECNO:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(h->inp[i]);
-
- ri = GET_RINTERNAL(h, i);
- M_32_SWAP(ri->pgno);
- M_32_SWAP(ri->nrecs);
-
- if (!pgin)
- M_16_SWAP(h->inp[i]);
- }
- break;
- case P_OVERFLOW:
- case P_INVALID:
- /* Nothing to do. */
- break;
- default:
- return (EINVAL);
- }
-
- if (!pgin) {
- /* Swap the header information. */
- M_32_SWAP(h->lsn.file);
- M_32_SWAP(h->lsn.offset);
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prev_pgno);
- M_32_SWAP(h->next_pgno);
- M_16_SWAP(h->entries);
- M_16_SWAP(h->hf_offset);
- }
- return (0);
-}
diff --git a/db2/db/db_dispatch.c b/db2/db/db_dispatch.c
deleted file mode 100644
index 616d08c..0000000
--- a/db2/db/db_dispatch.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_dispatch.c 10.20 (Sleepycat) 10/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <shqueue.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "db_am.h"
-#include "common_ext.h"
-#include "log_auto.h"
-#include "txn.h"
-#include "txn_auto.h"
-
-/*
- * Data structures to manage the DB dispatch table. The dispatch table
- * is a dynamically allocated array of pointers to dispatch functions.
- * The dispatch_size is the number of entries possible in the current
- * dispatch table and the dispatch_valid is the number of valid entries
- * in the dispatch table.
- */
-static int (**dispatch_table) __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-static u_int32_t dispatch_size = 0;
-
-/*
- * __db_dispatch --
- *
- * This is the transaction dispatch function used by the db access methods.
- * It is designed to handle the record format used by all the access
- * methods (the one automatically generated by the db_{h,log,read}.sh
- * scripts in the tools directory). An application using a different
- * recovery paradigm will supply a different dispatch function to txn_open.
- *
- * PUBLIC: int __db_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_dispatch(logp, db, lsnp, redo, info)
- DB_LOG *logp; /* The log file. */
- DBT *db; /* The log record upon which to dispatch. */
- DB_LSN *lsnp; /* The lsn of the record being dispatched. */
- int redo; /* Redo this op (or undo it). */
- void *info;
-{
- u_int32_t rectype, txnid;
-
- memcpy(&rectype, db->data, sizeof(rectype));
- memcpy(&txnid, (u_int8_t *)db->data + sizeof(rectype), sizeof(txnid));
-
- switch (redo) {
- case TXN_REDO:
- case TXN_UNDO:
- return ((dispatch_table[rectype])(logp, db, lsnp, redo, info));
- case TXN_OPENFILES:
- if (rectype < DB_txn_BEGIN )
- return ((dispatch_table[rectype])(logp,
- db, lsnp, redo, info));
- break;
- case TXN_BACKWARD_ROLL:
- /*
- * Running full recovery in the backward pass. If we've
- * seen this txnid before and added to it our commit list,
- * then we do nothing during this pass. If we've never
- * seen it, then we call the appropriate recovery routine
- * in "abort mode".
- */
- if (rectype == DB_log_register || rectype == DB_txn_ckp ||
- __db_txnlist_find(info, txnid) == DB_NOTFOUND)
- return ((dispatch_table[rectype])(logp,
- db, lsnp, TXN_UNDO, info));
- break;
- case TXN_FORWARD_ROLL:
- /*
- * In the forward pass, if we haven't seen the transaction,
- * do nothing, else recovery it.
- */
- if (rectype == DB_log_register || rectype == DB_txn_ckp ||
- __db_txnlist_find(info, txnid) != DB_NOTFOUND)
- return ((dispatch_table[rectype])(logp,
- db, lsnp, TXN_REDO, info));
- break;
- default:
- abort();
- }
- return (0);
-}
-
-/*
- * __db_add_recovery --
- *
- * PUBLIC: int __db_add_recovery __P((DB_ENV *,
- * PUBLIC: int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t));
- */
-int
-__db_add_recovery(dbenv, func, ndx)
- DB_ENV *dbenv;
- int (*func) __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- u_int32_t ndx;
-{
- u_int32_t i;
- int ret;
-
- COMPQUIET(dbenv, NULL); /* !!!: not currently used. */
-
- /* Check if we have to grow the table. */
- if (ndx >= dispatch_size) {
- if ((ret = __os_realloc(&dispatch_table,
- (DB_user_BEGIN + dispatch_size) *
- sizeof(dispatch_table[0]))) != 0)
- return (ret);
- for (i = dispatch_size,
- dispatch_size += DB_user_BEGIN; i < dispatch_size; ++i)
- dispatch_table[i] = NULL;
- }
-
- dispatch_table[ndx] = func;
- return (0);
-}
-
-/*
- * __db_txnlist_init --
- * Initialize transaction linked list.
- *
- * PUBLIC: int __db_txnlist_init __P((void *));
- */
-int
-__db_txnlist_init(retp)
- void *retp;
-{
- DB_TXNHEAD *headp;
- int ret;
-
- if ((ret = __os_malloc(sizeof(DB_TXNHEAD), NULL, &headp)) != 0)
- return (ret);
-
- LIST_INIT(&headp->head);
- headp->maxid = 0;
- headp->generation = 1;
-
- *(void **)retp = headp;
- return (0);
-}
-
-/*
- * __db_txnlist_add --
- * Add an element to our transaction linked list.
- *
- * PUBLIC: int __db_txnlist_add __P((void *, u_int32_t));
- */
-int
-__db_txnlist_add(listp, txnid)
- void *listp;
- u_int32_t txnid;
-{
- DB_TXNHEAD *hp;
- DB_TXNLIST *elp;
- int ret;
-
- if ((ret = __os_malloc(sizeof(DB_TXNLIST), NULL, &elp)) != 0)
- return (ret);
-
- elp->txnid = txnid;
- hp = (DB_TXNHEAD *)listp;
- LIST_INSERT_HEAD(&hp->head, elp, links);
- if (txnid > hp->maxid)
- hp->maxid = txnid;
- elp->generation = hp->generation;
-
- return (0);
-}
-
-/*
- * __db_txnlist_find --
- * Checks to see if a txnid with the current generation is in the
- * txnid list.
- *
- * PUBLIC: int __db_txnlist_find __P((void *, u_int32_t));
- */
-int
-__db_txnlist_find(listp, txnid)
- void *listp;
- u_int32_t txnid;
-{
- DB_TXNHEAD *hp;
- DB_TXNLIST *p;
-
- if ((hp = (DB_TXNHEAD *)listp) == NULL)
- return (DB_NOTFOUND);
-
- for (p = hp->head.lh_first; p != NULL; p = p->links.le_next)
- if (p->txnid == txnid && hp->generation == p->generation)
- return (0);
-
- return (DB_NOTFOUND);
-}
-
-/*
- * __db_txnlist_end --
- * Discard transaction linked list.
- *
- * PUBLIC: void __db_txnlist_end __P((void *));
- */
-void
-__db_txnlist_end(listp)
- void *listp;
-{
- DB_TXNHEAD *hp;
- DB_TXNLIST *p;
-
- hp = (DB_TXNHEAD *)listp;
- while ((p = LIST_FIRST(&hp->head)) != LIST_END(&hp->head)) {
- LIST_REMOVE(p, links);
- __os_free(p, 0);
- }
- __os_free(listp, sizeof(DB_TXNHEAD));
-}
-
-/*
- * __db_txnlist_gen --
- * Change the current generation number.
- *
- * PUBLIC: void __db_txnlist_gen __P((void *, int));
- */
-void
-__db_txnlist_gen(listp, incr)
- void *listp;
- int incr;
-{
- DB_TXNHEAD *hp;
-
- /*
- * During recovery generation numbers keep track of how many "restart"
- * checkpoints we've seen. Restart checkpoints occur whenever we take
- * a checkpoint and there are no outstanding transactions. When that
- * happens, we can reset transaction IDs back to 1. It always happens
- * at recovery and it prevents us from exhausting the transaction IDs
- * name space.
- */
- hp = (DB_TXNHEAD *)listp;
- hp->generation += incr;
-}
-
-#ifdef DEBUG
-/*
- * __db_txnlist_print --
- * Print out the transaction list.
- *
- * PUBLIC: void __db_txnlist_print __P((void *));
- */
-void
-__db_txnlist_print(listp)
- void *listp;
-{
- DB_TXNHEAD *hp;
- DB_TXNLIST *p;
-
- hp = (DB_TXNHEAD *)listp;
- printf("Maxid: %lu Generation: %lu\n", (u_long)hp->maxid,
- (u_long)hp->generation);
- for (p = hp->head.lh_first; p != NULL; p = p->links.le_next)
- printf("TXNID: %lu(%lu)\n", (u_long)p->txnid,
- (u_long)p->generation);
-}
-#endif
diff --git a/db2/db/db_dup.c b/db2/db/db_dup.c
deleted file mode 100644
index 2673bbc..0000000
--- a/db2/db/db_dup.c
+++ /dev/null
@@ -1,947 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_dup.c 10.35 (Sleepycat) 12/2/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "db_am.h"
-
-static int __db_addpage __P((DBC *,
- PAGE **, db_indx_t *, int (*)(DBC *, u_int32_t, PAGE **)));
-static int __db_dsplit __P((DBC *,
- PAGE **, db_indx_t *, u_int32_t, int (*)(DBC *, u_int32_t, PAGE **)));
-
-/*
- * __db_dput --
- * Put a duplicate item onto a duplicate page at the given index.
- *
- * PUBLIC: int __db_dput __P((DBC *, DBT *,
- * PUBLIC: PAGE **, db_indx_t *, int (*)(DBC *, u_int32_t, PAGE **)));
- */
-int
-__db_dput(dbc, dbt, pp, indxp, newfunc)
- DBC *dbc;
- DBT *dbt;
- PAGE **pp;
- db_indx_t *indxp;
- int (*newfunc) __P((DBC *, u_int32_t, PAGE **));
-{
- BOVERFLOW bo;
- DBT *data_dbtp, hdr_dbt, *hdr_dbtp;
- PAGE *pagep;
- db_indx_t size, isize;
- db_pgno_t pgno;
- int ret;
-
- /*
- * We need some access method independent threshold for when we put
- * a duplicate item onto an overflow page.
- */
- if (dbt->size > 0.25 * dbc->dbp->pgsize) {
- if ((ret = __db_poff(dbc, dbt, &pgno, newfunc)) != 0)
- return (ret);
- UMRW(bo.unused1);
- B_TSET(bo.type, B_OVERFLOW, 0);
- UMRW(bo.unused2);
- bo.tlen = dbt->size;
- bo.pgno = pgno;
- hdr_dbt.data = &bo;
- hdr_dbt.size = isize = BOVERFLOW_SIZE;
- hdr_dbtp = &hdr_dbt;
- size = BOVERFLOW_PSIZE;
- data_dbtp = NULL;
- } else {
- size = BKEYDATA_PSIZE(dbt->size);
- isize = BKEYDATA_SIZE(dbt->size);
- hdr_dbtp = NULL;
- data_dbtp = dbt;
- }
-
- pagep = *pp;
- if (size > P_FREESPACE(pagep)) {
- if (*indxp == NUM_ENT(*pp) && NEXT_PGNO(*pp) == PGNO_INVALID)
- ret = __db_addpage(dbc, pp, indxp, newfunc);
- else
- ret = __db_dsplit(dbc, pp, indxp, isize, newfunc);
- if (ret != 0)
- /*
- * XXX
- * Pages not returned to free list.
- */
- return (ret);
- pagep = *pp;
- }
-
- /*
- * Now, pagep references the page on which to insert and indx is the
- * the location to insert.
- */
- if ((ret = __db_pitem(dbc,
- pagep, (u_int32_t)*indxp, isize, hdr_dbtp, data_dbtp)) != 0)
- return (ret);
-
- (void)memp_fset(dbc->dbp->mpf, pagep, DB_MPOOL_DIRTY);
- return (0);
-}
-
-/*
- * __db_drem --
- * Remove a duplicate at the given index on the given page.
- *
- * PUBLIC: int __db_drem __P((DBC *,
- * PUBLIC: PAGE **, u_int32_t, int (*)(DBC *, PAGE *)));
- */
-int
-__db_drem(dbc, pp, indx, freefunc)
- DBC *dbc;
- PAGE **pp;
- u_int32_t indx;
- int (*freefunc) __P((DBC *, PAGE *));
-{
- PAGE *pagep;
- int ret;
-
- pagep = *pp;
-
- /* Check if we are freeing a big item. */
- if (B_TYPE(GET_BKEYDATA(pagep, indx)->type) == B_OVERFLOW) {
- if ((ret = __db_doff(dbc,
- GET_BOVERFLOW(pagep, indx)->pgno, freefunc)) != 0)
- return (ret);
- ret = __db_ditem(dbc, pagep, indx, BOVERFLOW_SIZE);
- } else
- ret = __db_ditem(dbc, pagep, indx,
- BKEYDATA_SIZE(GET_BKEYDATA(pagep, indx)->len));
- if (ret != 0)
- return (ret);
-
- if (NUM_ENT(pagep) == 0) {
- /*
- * If the page is emptied, then the page is freed and the pp
- * parameter is set to reference the next, locked page in the
- * duplicate chain, if one exists. If there was no such page,
- * then it is set to NULL.
- *
- * !!!
- * __db_relink will set the dirty bit for us.
- */
- if ((ret = __db_relink(dbc, DB_REM_PAGE, pagep, pp, 0)) != 0)
- return (ret);
- if ((ret = freefunc(dbc, pagep)) != 0)
- return (ret);
- } else
- (void)memp_fset(dbc->dbp->mpf, pagep, DB_MPOOL_DIRTY);
-
- return (0);
-}
-
-/*
- * __db_dend --
- * Find the last page in a set of offpage duplicates.
- *
- * PUBLIC: int __db_dend __P((DBC *, db_pgno_t, PAGE **));
- */
-int
-__db_dend(dbc, pgno, pp)
- DBC *dbc;
- db_pgno_t pgno;
- PAGE **pp;
-{
- DB *dbp;
- PAGE *h;
- int ret;
-
- dbp = dbc->dbp;
-
- /*
- * This implements DB_KEYLAST. The last page is returned in pp; pgno
- * should be the page number of the first page of the duplicate chain.
- *
- * *pp may be non-NULL -- if given a valid page use it.
- */
- if (*pp != NULL)
- goto started;
- for (;;) {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, pp)) != 0) {
- (void)__db_pgerr(dbp, pgno);
- return (ret);
- }
-started: h = *pp;
-
- if ((pgno = NEXT_PGNO(h)) == PGNO_INVALID)
- break;
-
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
- }
- return (0);
-}
-
-/*
- * __db_dsplit --
- * Split a page of duplicates, calculating the split point based
- * on an element of size "size" being added at "*indxp".
- * On entry hp contains a pointer to the page-pointer of the original
- * page. On exit, it returns a pointer to the page containing "*indxp"
- * and "indxp" has been modified to reflect the index on the new page
- * where the element should be added. The function returns with
- * the page on which the insert should happen, not yet put.
- */
-static int
-__db_dsplit(dbc, hp, indxp, size, newfunc)
- DBC *dbc;
- PAGE **hp;
- db_indx_t *indxp;
- u_int32_t size;
- int (*newfunc) __P((DBC *, u_int32_t, PAGE **));
-{
- PAGE *h, *np, *tp;
- BKEYDATA *bk;
- DBT page_dbt;
- DB *dbp;
- size_t pgsize;
- db_indx_t halfbytes, i, indx, lastsum, nindex, oindex, s, sum;
- int did_indx, ret, t_ret;
-
- h = *hp;
- indx = *indxp;
- ret = 0;
- dbp = dbc->dbp;
- pgsize = dbp->pgsize;
-
- /* Create a temporary page to do compaction onto. */
- if ((ret = __os_malloc(pgsize, NULL, &tp)) != 0)
- return (ret);
-
- /* Create new page for the split. */
- if ((ret = newfunc(dbc, P_DUPLICATE, &np)) != 0) {
- __os_free(tp, pgsize);
- return (ret);
- }
-
- P_INIT(np, pgsize, PGNO(np), PGNO(h), NEXT_PGNO(h), 0,
- P_DUPLICATE);
- P_INIT(tp, pgsize, PGNO(h), PREV_PGNO(h), PGNO(np), 0,
- P_DUPLICATE);
-
- /* Figure out the split point */
- halfbytes = (pgsize - HOFFSET(h)) / 2;
- did_indx = 0;
- for (sum = 0, lastsum = 0, i = 0; i < NUM_ENT(h); i++) {
- if (i == indx) {
- sum += size;
- did_indx = 1;
- if (lastsum < halfbytes && sum >= halfbytes) {
- /* We've crossed the halfway point. */
- if ((db_indx_t)(halfbytes - lastsum) <
- (db_indx_t)(sum - halfbytes)) {
- *hp = np;
- *indxp = 0;
- } else
- *indxp = i;
- break;
- }
- *indxp = i;
- lastsum = sum;
- }
- if (B_TYPE(GET_BKEYDATA(h, i)->type) == B_KEYDATA)
- sum += BKEYDATA_SIZE(GET_BKEYDATA(h, i)->len);
- else
- sum += BOVERFLOW_SIZE;
-
- if (lastsum < halfbytes && sum >= halfbytes) {
- /* We've crossed the halfway point. */
- if ((db_indx_t)(sum - halfbytes) <
- (db_indx_t)(halfbytes - lastsum))
- i++;
- break;
- }
- }
- /*
- * Check if we have set the return values of the index pointer and
- * page pointer.
- */
- if (!did_indx) {
- *hp = np;
- *indxp = indx - i;
- }
-
- if (DB_LOGGING(dbc)) {
- page_dbt.size = dbp->pgsize;
- page_dbt.data = h;
- if ((ret = __db_split_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(h), 0, DB_SPLITOLD, dbp->log_fileid,
- PGNO(h), &page_dbt, &LSN(h))) != 0) {
- __os_free(tp, pgsize);
- return (ret);
- }
- LSN(tp) = LSN(h);
- }
-
- /*
- * If it's a btree, adjust the cursors.
- *
- * i is the index of the first element to move onto the new page.
- */
- if (dbp->type == DB_BTREE)
- __bam_ca_split(dbp, PGNO(h), PGNO(h), PGNO(np), i, 0);
-
- for (nindex = 0, oindex = i; oindex < NUM_ENT(h); oindex++) {
- bk = GET_BKEYDATA(h, oindex);
- if (B_TYPE(bk->type) == B_KEYDATA)
- s = BKEYDATA_SIZE(bk->len);
- else
- s = BOVERFLOW_SIZE;
-
- np->inp[nindex++] = HOFFSET(np) -= s;
- memcpy((u_int8_t *)np + HOFFSET(np), bk, s);
- NUM_ENT(np)++;
- }
-
- /*
- * Now do data compaction by copying the remaining stuff onto the
- * temporary page and then copying it back to the real page.
- */
- for (nindex = 0, oindex = 0; oindex < i; oindex++) {
- bk = GET_BKEYDATA(h, oindex);
- if (B_TYPE(bk->type) == B_KEYDATA)
- s = BKEYDATA_SIZE(bk->len);
- else
- s = BOVERFLOW_SIZE;
-
- tp->inp[nindex++] = HOFFSET(tp) -= s;
- memcpy((u_int8_t *)tp + HOFFSET(tp), bk, s);
- NUM_ENT(tp)++;
- }
-
- /*
- * This page (the temporary) should be only half full, so we do two
- * memcpy's, one for the top of the page and one for the bottom of
- * the page. This way we avoid copying the middle which should be
- * about half a page.
- */
- memcpy(h, tp, LOFFSET(tp));
- memcpy((u_int8_t *)h + HOFFSET(tp),
- (u_int8_t *)tp + HOFFSET(tp), pgsize - HOFFSET(tp));
- __os_free(tp, pgsize);
-
- if (DB_LOGGING(dbc)) {
- /*
- * XXX
- * If either of these fails, are we leaving pages pinned?
- * Yes, but it seems like this happens in error case.
- */
- page_dbt.size = pgsize;
- page_dbt.data = h;
- if ((ret = __db_split_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(h), 0, DB_SPLITNEW, dbp->log_fileid,
- PGNO(h), &page_dbt, &LSN(h))) != 0)
- return (ret);
-
- page_dbt.size = pgsize;
- page_dbt.data = np;
- if ((ret = __db_split_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(np), 0, DB_SPLITNEW, dbp->log_fileid,
- PGNO(np), &page_dbt, &LSN(np))) != 0)
- return (ret);
- }
-
- /*
- * Finally, if there was a next page after the page being
- * split, fix its prev pointer.
- */
- if (np->next_pgno != PGNO_INVALID)
- ret = __db_relink(dbc, DB_ADD_PAGE, np, NULL, 1);
-
- /*
- * Figure out if the location we're interested in is on the new
- * page, and if so, reset the callers' pointer. Push the other
- * page back to the store.
- */
- if (*hp == h)
- t_ret = memp_fput(dbp->mpf, np, DB_MPOOL_DIRTY);
- else
- t_ret = memp_fput(dbp->mpf, h, DB_MPOOL_DIRTY);
-
- return (ret != 0 ? ret : t_ret);
-}
-
-/*
- * __db_ditem --
- * Remove an item from a page.
- *
- * PUBLIC: int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
- */
-int
-__db_ditem(dbc, pagep, indx, nbytes)
- DBC *dbc;
- PAGE *pagep;
- u_int32_t indx, nbytes;
-{
- DB *dbp;
- DBT ldbt;
- db_indx_t cnt, offset;
- int ret;
- u_int8_t *from;
-
- dbp = dbc->dbp;
- if (DB_LOGGING(dbc)) {
- ldbt.data = P_ENTRY(pagep, indx);
- ldbt.size = nbytes;
- if ((ret = __db_addrem_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(pagep), 0, DB_REM_DUP, dbp->log_fileid, PGNO(pagep),
- (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0)
- return (ret);
- }
-
- /*
- * If there's only a single item on the page, we don't have to
- * work hard.
- */
- if (NUM_ENT(pagep) == 1) {
- NUM_ENT(pagep) = 0;
- HOFFSET(pagep) = dbp->pgsize;
- return (0);
- }
-
- /*
- * Pack the remaining key/data items at the end of the page. Use
- * memmove(3), the regions may overlap.
- */
- from = (u_int8_t *)pagep + HOFFSET(pagep);
- memmove(from + nbytes, from, pagep->inp[indx] - HOFFSET(pagep));
- HOFFSET(pagep) += nbytes;
-
- /* Adjust the indices' offsets. */
- offset = pagep->inp[indx];
- for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt)
- if (pagep->inp[cnt] < offset)
- pagep->inp[cnt] += nbytes;
-
- /* Shift the indices down. */
- --NUM_ENT(pagep);
- if (indx != NUM_ENT(pagep))
- memmove(&pagep->inp[indx], &pagep->inp[indx + 1],
- sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
-
- /* If it's a btree, adjust the cursors. */
- if (dbp->type == DB_BTREE)
- __bam_ca_di(dbp, PGNO(pagep), indx, -1);
-
- return (0);
-}
-
-/*
- * __db_pitem --
- * Put an item on a page.
- *
- * PUBLIC: int __db_pitem
- * PUBLIC: __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
- */
-int
-__db_pitem(dbc, pagep, indx, nbytes, hdr, data)
- DBC *dbc;
- PAGE *pagep;
- u_int32_t indx;
- u_int32_t nbytes;
- DBT *hdr, *data;
-{
- DB *dbp;
- BKEYDATA bk;
- DBT thdr;
- int ret;
- u_int8_t *p;
-
- /*
- * Put a single item onto a page. The logic figuring out where to
- * insert and whether it fits is handled in the caller. All we do
- * here is manage the page shuffling. We cheat a little bit in that
- * we don't want to copy the dbt on a normal put twice. If hdr is
- * NULL, we create a BKEYDATA structure on the page, otherwise, just
- * copy the caller's information onto the page.
- *
- * This routine is also used to put entries onto the page where the
- * entry is pre-built, e.g., during recovery. In this case, the hdr
- * will point to the entry, and the data argument will be NULL.
- *
- * !!!
- * There's a tremendous potential for off-by-one errors here, since
- * the passed in header sizes must be adjusted for the structure's
- * placeholder for the trailing variable-length data field.
- */
- dbp = dbc->dbp;
- if (DB_LOGGING(dbc))
- if ((ret = __db_addrem_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(pagep), 0, DB_ADD_DUP, dbp->log_fileid, PGNO(pagep),
- (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep))) != 0)
- return (ret);
-
- if (hdr == NULL) {
- B_TSET(bk.type, B_KEYDATA, 0);
- bk.len = data == NULL ? 0 : data->size;
-
- thdr.data = &bk;
- thdr.size = SSZA(BKEYDATA, data);
- hdr = &thdr;
- }
-
- /* Adjust the index table, then put the item on the page. */
- if (indx != NUM_ENT(pagep))
- memmove(&pagep->inp[indx + 1], &pagep->inp[indx],
- sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
- HOFFSET(pagep) -= nbytes;
- pagep->inp[indx] = HOFFSET(pagep);
- ++NUM_ENT(pagep);
-
- p = P_ENTRY(pagep, indx);
- memcpy(p, hdr->data, hdr->size);
- if (data != NULL)
- memcpy(p + hdr->size, data->data, data->size);
-
- /* If it's a btree, adjust the cursors. */
- if (dbp->type == DB_BTREE)
- __bam_ca_di(dbp, PGNO(pagep), indx, 1);
-
- return (0);
-}
-
-/*
- * __db_relink --
- * Relink around a deleted page.
- *
- * PUBLIC: int __db_relink __P((DBC *, u_int32_t, PAGE *, PAGE **, int));
- */
-int
-__db_relink(dbc, add_rem, pagep, new_next, needlock)
- DBC *dbc;
- u_int32_t add_rem;
- PAGE *pagep, **new_next;
- int needlock;
-{
- DB *dbp;
- PAGE *np, *pp;
- DB_LOCK npl, ppl;
- DB_LSN *nlsnp, *plsnp;
- int ret;
-
- ret = 0;
- np = pp = NULL;
- npl = ppl = LOCK_INVALID;
- nlsnp = plsnp = NULL;
- dbp = dbc->dbp;
-
- /*
- * Retrieve and lock the one/two pages. For a remove, we may need
- * two pages (the before and after). For an add, we only need one
- * because, the split took care of the prev.
- */
- if (pagep->next_pgno != PGNO_INVALID) {
- if (needlock && (ret = __bam_lget(dbc,
- 0, pagep->next_pgno, DB_LOCK_WRITE, &npl)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf,
- &pagep->next_pgno, 0, &np)) != 0) {
- (void)__db_pgerr(dbp, pagep->next_pgno);
- goto err;
- }
- nlsnp = &np->lsn;
- }
- if (add_rem == DB_REM_PAGE && pagep->prev_pgno != PGNO_INVALID) {
- if (needlock && (ret = __bam_lget(dbc,
- 0, pagep->prev_pgno, DB_LOCK_WRITE, &ppl)) != 0)
- goto err;
- if ((ret = memp_fget(dbp->mpf,
- &pagep->prev_pgno, 0, &pp)) != 0) {
- (void)__db_pgerr(dbp, pagep->next_pgno);
- goto err;
- }
- plsnp = &pp->lsn;
- }
-
- /* Log the change. */
- if (DB_LOGGING(dbc)) {
- if ((ret = __db_relink_log(dbp->dbenv->lg_info, dbc->txn,
- &pagep->lsn, 0, add_rem, dbp->log_fileid,
- pagep->pgno, &pagep->lsn,
- pagep->prev_pgno, plsnp, pagep->next_pgno, nlsnp)) != 0)
- goto err;
- if (np != NULL)
- np->lsn = pagep->lsn;
- if (pp != NULL)
- pp->lsn = pagep->lsn;
- }
-
- /*
- * Modify and release the two pages.
- *
- * !!!
- * The parameter new_next gets set to the page following the page we
- * are removing. If there is no following page, then new_next gets
- * set to NULL.
- */
- if (np != NULL) {
- if (add_rem == DB_ADD_PAGE)
- np->prev_pgno = pagep->pgno;
- else
- np->prev_pgno = pagep->prev_pgno;
- if (new_next == NULL)
- ret = memp_fput(dbp->mpf, np, DB_MPOOL_DIRTY);
- else {
- *new_next = np;
- ret = memp_fset(dbp->mpf, np, DB_MPOOL_DIRTY);
- }
- if (ret != 0)
- goto err;
- if (needlock)
- (void)__bam_lput(dbc, npl);
- } else if (new_next != NULL)
- *new_next = NULL;
-
- if (pp != NULL) {
- pp->next_pgno = pagep->next_pgno;
- if ((ret = memp_fput(dbp->mpf, pp, DB_MPOOL_DIRTY)) != 0)
- goto err;
- if (needlock)
- (void)__bam_lput(dbc, ppl);
- }
- return (0);
-
-err: if (np != NULL)
- (void)memp_fput(dbp->mpf, np, 0);
- if (needlock && npl != LOCK_INVALID)
- (void)__bam_lput(dbc, npl);
- if (pp != NULL)
- (void)memp_fput(dbp->mpf, pp, 0);
- if (needlock && ppl != LOCK_INVALID)
- (void)__bam_lput(dbc, ppl);
- return (ret);
-}
-
-/*
- * __db_ddup --
- * Delete an offpage chain of duplicates.
- *
- * PUBLIC: int __db_ddup __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *)));
- */
-int
-__db_ddup(dbc, pgno, freefunc)
- DBC *dbc;
- db_pgno_t pgno;
- int (*freefunc) __P((DBC *, PAGE *));
-{
- DB *dbp;
- PAGE *pagep;
- DBT tmp_dbt;
- int ret;
-
- dbp = dbc->dbp;
- do {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &pagep)) != 0) {
- (void)__db_pgerr(dbp, pgno);
- return (ret);
- }
-
- if (DB_LOGGING(dbc)) {
- tmp_dbt.data = pagep;
- tmp_dbt.size = dbp->pgsize;
- if ((ret = __db_split_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(pagep), 0, DB_SPLITOLD,
- dbp->log_fileid, PGNO(pagep), &tmp_dbt,
- &LSN(pagep))) != 0)
- return (ret);
- }
- pgno = pagep->next_pgno;
- if ((ret = freefunc(dbc, pagep)) != 0)
- return (ret);
- } while (pgno != PGNO_INVALID);
-
- return (0);
-}
-
-/*
- * __db_addpage --
- * Create a new page and link it onto the next_pgno field of the
- * current page.
- */
-static int
-__db_addpage(dbc, hp, indxp, newfunc)
- DBC *dbc;
- PAGE **hp;
- db_indx_t *indxp;
- int (*newfunc) __P((DBC *, u_int32_t, PAGE **));
-{
- DB *dbp;
- PAGE *newpage;
- int ret;
-
- dbp = dbc->dbp;
- if ((ret = newfunc(dbc, P_DUPLICATE, &newpage)) != 0)
- return (ret);
-
- if (DB_LOGGING(dbc)) {
- if ((ret = __db_addpage_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(*hp), 0, dbp->log_fileid,
- PGNO(*hp), &LSN(*hp), PGNO(newpage), &LSN(newpage))) != 0) {
- return (ret);
- }
- LSN(newpage) = LSN(*hp);
- }
-
- PREV_PGNO(newpage) = PGNO(*hp);
- NEXT_PGNO(*hp) = PGNO(newpage);
-
- if ((ret = memp_fput(dbp->mpf, *hp, DB_MPOOL_DIRTY)) != 0)
- return (ret);
- *hp = newpage;
- *indxp = 0;
- return (0);
-}
-
-/*
- * __db_dsearch --
- * Search a set of duplicates for the proper position for a new duplicate.
- *
- * + pgno is the page number of the page on which to begin searching.
- * Since we can continue duplicate searches, it might not be the first
- * page.
- *
- * + If we are continuing a search, then *pp may be non-NULL in which
- * case we do not have to retrieve the page.
- *
- * + If we are continuing a search, then *indxp contains the first
- * on pgno of where we should begin the search.
- *
- * NOTE: if there is no comparison function, then continuing is
- * meaningless, and *pp should always be NULL and *indxp will be
- * ignored.
- *
- * 3 return values::
- *
- * + pp is the returned page pointer of where this element should go.
- * + indxp is the returned index on that page
- * + cmpp is the returned final comparison result.
- *
- * PUBLIC: int __db_dsearch __P((DBC *,
- * PUBLIC: int, DBT *, db_pgno_t, db_indx_t *, PAGE **, int *));
- */
-int
-__db_dsearch(dbc, is_insert, dbt, pgno, indxp, pp, cmpp)
- DBC *dbc;
- int is_insert, *cmpp;
- DBT *dbt;
- db_pgno_t pgno;
- db_indx_t *indxp;
- PAGE **pp;
-{
- DB *dbp;
- PAGE *h;
- db_indx_t base, indx, lim, save_indx;
- db_pgno_t save_pgno;
- int ret;
-
- dbp = dbc->dbp;
-
- if (dbp->dup_compare == NULL) {
- /*
- * We may have been given a valid page, but we may not be
- * able to use it. The problem is that the application is
- * doing a join and we're trying to continue the search,
- * but since the items aren't sorted, we can't. Discard
- * the page if it's not the one we're going to start with
- * anyway.
- */
- if (*pp != NULL && (*pp)->pgno != pgno) {
- if ((ret = memp_fput(dbp->mpf, *pp, 0)) != 0)
- return (ret);
- *pp = NULL;
- }
-
- /*
- * If no duplicate function is specified, just go to the end
- * of the duplicate set.
- */
- if (is_insert) {
- if ((ret = __db_dend(dbc, pgno, pp)) != 0)
- return (ret);
- *indxp = NUM_ENT(*pp);
- return (0);
- }
-
- /*
- * We are looking for a specific duplicate, so do a linear
- * search.
- */
- if (*pp != NULL)
- goto nocmp_started;
- for (;;) {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, pp)) != 0)
- goto pg_err;
-nocmp_started: h = *pp;
-
- for (*indxp = 0; *indxp < NUM_ENT(h); ++*indxp) {
- if ((*cmpp = __bam_cmp(dbp,
- dbt, h, *indxp, __bam_defcmp)) != 0)
- continue;
- /*
- * The duplicate may have already been deleted,
- * if it's a btree page, in which case we skip
- * it.
- */
- if (dbp->type == DB_BTREE &&
- B_DISSET(GET_BKEYDATA(h, *indxp)->type))
- continue;
-
- return (0);
- }
-
- if ((pgno = h->next_pgno) == PGNO_INVALID)
- break;
-
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
- }
- *cmpp = 1; /* We didn't succeed... */
- return (0);
- }
-
- /*
- * We have a comparison routine, i.e., the duplicates are sorted.
- * Walk through the chain of duplicates, checking the last entry
- * on each page to decide if it's the page we want to search.
- *
- * *pp may be non-NULL -- if we were given a valid page (e.g., are
- * in mid-search), then use the provided page.
- */
- if (*pp != NULL)
- goto cmp_started;
- for (;;) {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, pp)) != 0)
- goto pg_err;
-cmp_started: h = *pp;
-
- if ((pgno = h->next_pgno) == PGNO_INVALID || __bam_cmp(dbp,
- dbt, h, h->entries - 1, dbp->dup_compare) <= 0)
- break;
- /*
- * Even when continuing a search, make sure we don't skip
- * entries on a new page
- */
- *indxp = 0;
-
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
- }
-
- /* Next, do a binary search on the page. */
- base = F_ISSET(dbc, DBC_CONTINUE) ? *indxp : 0;
- for (lim = NUM_ENT(h) - base; lim != 0; lim >>= 1) {
- indx = base + (lim >> 1);
- if ((*cmpp = __bam_cmp(dbp,
- dbt, h, indx, dbp->dup_compare)) == 0) {
- *indxp = indx;
-
- if (dbp->type != DB_BTREE ||
- !B_DISSET(GET_BKEYDATA(h, *indxp)->type))
- return (0);
- goto check_delete;
- }
- if (*cmpp > 0) {
- base = indx + 1;
- lim--;
- }
- }
-
- /*
- * Base references the smallest index larger than the supplied DBT's
- * data item, potentially both 0 and NUM_ENT.
- */
- *indxp = base;
- return (0);
-
-check_delete:
- /*
- * The duplicate may have already been deleted, if it's a btree page,
- * in which case we wander around, hoping to find an entry that hasn't
- * been deleted. First, wander in a forwardly direction.
- */
- save_pgno = (*pp)->pgno;
- save_indx = *indxp;
- for (++*indxp;;) {
- for (; *indxp < NUM_ENT(h); ++*indxp) {
- if ((*cmpp = __bam_cmp(dbp,
- dbt, h, *indxp, dbp->dup_compare)) != 0)
- goto check_delete_rev;
-
- if (!B_DISSET(GET_BKEYDATA(h, *indxp)->type))
- return (0);
- }
- if ((pgno = h->next_pgno) == PGNO_INVALID)
- break;
-
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
-
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, pp)) != 0)
- goto pg_err;
- h = *pp;
-
- *indxp = 0;
- }
-
-check_delete_rev:
- /* Go back to where we started, and wander in a backwardly direction. */
- if (h->pgno != save_pgno) {
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
- if ((ret = memp_fget(dbp->mpf, &save_pgno, 0, pp)) != 0)
- goto pg_err;
- h = *pp;
- }
-
- for (;;) {
- while (*indxp > 0) {
- --*indxp;
- if ((*cmpp = __bam_cmp(dbp,
- dbt, h, *indxp, dbp->dup_compare)) != 0)
- goto check_delete_fail;
-
- if (!B_DISSET(GET_BKEYDATA(h, *indxp)->type))
- return (0);
- }
- if ((pgno = h->prev_pgno) == PGNO_INVALID)
- break;
-
- if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
- return (ret);
-
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, pp)) != 0)
- goto pg_err;
- h = *pp;
-
- *indxp = NUM_ENT(h);
- }
-
-check_delete_fail:
- *cmpp = 1; /* We didn't succeed... */
- return (0);
-
-pg_err: __db_pgerr(dbp, pgno);
- return (ret);
-}
diff --git a/db2/db/db_iface.c b/db2/db/db_iface.c
deleted file mode 100644
index 4ebf3ba..0000000
--- a/db2/db/db_iface.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_iface.c 10.40 (Sleepycat) 12/19/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_auto.h"
-#include "db_ext.h"
-#include "common_ext.h"
-
-static int __db_keyempty __P((const DB_ENV *));
-static int __db_rdonly __P((const DB_ENV *, const char *));
-static int __dbt_ferr __P((const DB *, const char *, const DBT *, int));
-
-/*
- * __db_cdelchk --
- * Common cursor delete argument checking routine.
- *
- * PUBLIC: int __db_cdelchk __P((const DB *, u_int32_t, int, int));
- */
-int
-__db_cdelchk(dbp, flags, isrdonly, isvalid)
- const DB *dbp;
- u_int32_t flags;
- int isrdonly, isvalid;
-{
- /* Check for changes to a read-only tree. */
- if (isrdonly)
- return (__db_rdonly(dbp->dbenv, "c_del"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- default:
- return (__db_ferr(dbp->dbenv, "DBcursor->c_del", 0));
- }
-
- /*
- * The cursor must be initialized, return -1 for an invalid cursor,
- * otherwise 0.
- */
- return (isvalid ? 0 : EINVAL);
-}
-
-/*
- * __db_cgetchk --
- * Common cursor get argument checking routine.
- *
- * PUBLIC: int __db_cgetchk __P((const DB *, DBT *, DBT *, u_int32_t, int));
- */
-int
-__db_cgetchk(dbp, key, data, flags, isvalid)
- const DB *dbp;
- DBT *key, *data;
- u_int32_t flags;
- int isvalid;
-{
- int key_einval, key_flags, ret;
-
- key_einval = key_flags = 0;
-
- /* Check for invalid function flags. */
- LF_CLR(DB_RMW);
- switch (flags) {
- case DB_NEXT_DUP:
- if (dbp->type == DB_RECNO)
- goto err;
- /* FALLTHROUGH */
- case DB_CURRENT:
- case DB_FIRST:
- case DB_LAST:
- case DB_NEXT:
- case DB_PREV:
- key_flags = 1;
- break;
- case DB_GET_BOTH:
- case DB_SET_RANGE:
- key_einval = key_flags = 1;
- break;
- case DB_SET:
- key_einval = 1;
- break;
- case DB_GET_RECNO:
- if (!F_ISSET(dbp, DB_BT_RECNUM))
- goto err;
- break;
- case DB_SET_RECNO:
- if (!F_ISSET(dbp, DB_BT_RECNUM))
- goto err;
- key_einval = key_flags = 1;
- break;
- default:
-err: return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0));
- }
-
- /* Check for invalid key/data flags. */
- if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- /* Check for missing keys. */
- if (key_einval && (key->data == NULL || key->size == 0))
- return (__db_keyempty(dbp->dbenv));
-
- /*
- * The cursor must be initialized for DB_CURRENT, return -1 for an
- * invalid cursor, otherwise 0.
- */
- return (isvalid || flags != DB_CURRENT ? 0 : EINVAL);
-}
-
-/*
- * __db_cputchk --
- * Common cursor put argument checking routine.
- *
- * PUBLIC: int __db_cputchk __P((const DB *,
- * PUBLIC: const DBT *, DBT *, u_int32_t, int, int));
- */
-int
-__db_cputchk(dbp, key, data, flags, isrdonly, isvalid)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flags;
- int isrdonly, isvalid;
-{
- int key_einval, key_flags, ret;
-
- key_einval = key_flags = 0;
-
- /* Check for changes to a read-only tree. */
- if (isrdonly)
- return (__db_rdonly(dbp->dbenv, "c_put"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case DB_AFTER:
- case DB_BEFORE:
- if (dbp->dup_compare != NULL)
- goto err;
- if (dbp->type == DB_RECNO && !F_ISSET(dbp, DB_RE_RENUMBER))
- goto err;
- if (dbp->type != DB_RECNO && !F_ISSET(dbp, DB_AM_DUP))
- goto err;
- break;
- case DB_CURRENT:
- /*
- * If there is a comparison function, doing a DB_CURRENT
- * must not change the part of the data item that is used
- * for the comparison.
- */
- break;
- case DB_KEYFIRST:
- case DB_KEYLAST:
- if (dbp->type == DB_RECNO)
- goto err;
- key_einval = key_flags = 1;
- break;
- default:
-err: return (__db_ferr(dbp->dbenv, "DBcursor->c_put", 0));
- }
-
- /* Check for invalid key/data flags. */
- if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- /* Check for missing keys. */
- if (key_einval && (key->data == NULL || key->size == 0))
- return (__db_keyempty(dbp->dbenv));
-
- /*
- * The cursor must be initialized for anything other than DB_KEYFIRST
- * and DB_KEYLAST, return -1 for an invalid cursor, otherwise 0.
- */
- return (isvalid ||
- flags == DB_KEYFIRST || flags == DB_KEYLAST ? 0 : EINVAL);
-}
-
-/*
- * __db_closechk --
- * DB->close flag check.
- *
- * PUBLIC: int __db_closechk __P((const DB *, u_int32_t));
- */
-int
-__db_closechk(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- /* Check for invalid function flags. */
- if (flags != 0 && flags != DB_NOSYNC)
- return (__db_ferr(dbp->dbenv, "DB->close", 0));
-
- return (0);
-}
-
-/*
- * __db_delchk --
- * Common delete argument checking routine.
- *
- * PUBLIC: int __db_delchk __P((const DB *, DBT *, u_int32_t, int));
- */
-int
-__db_delchk(dbp, key, flags, isrdonly)
- const DB *dbp;
- DBT *key;
- u_int32_t flags;
- int isrdonly;
-{
- /* Check for changes to a read-only tree. */
- if (isrdonly)
- return (__db_rdonly(dbp->dbenv, "delete"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- default:
- return (__db_ferr(dbp->dbenv, "DB->del", 0));
- }
-
- /* Check for missing keys. */
- if (key->data == NULL || key->size == 0)
- return (__db_keyempty(dbp->dbenv));
-
- return (0);
-}
-
-/*
- * __db_getchk --
- * Common get argument checking routine.
- *
- * PUBLIC: int __db_getchk __P((const DB *, const DBT *, DBT *, u_int32_t));
- */
-int
-__db_getchk(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- int ret;
-
- /* Check for invalid function flags. */
- LF_CLR(DB_RMW);
- switch (flags) {
- case 0:
- case DB_GET_BOTH:
- break;
- case DB_SET_RECNO:
- if (!F_ISSET(dbp, DB_BT_RECNUM))
- goto err;
- break;
- default:
-err: return (__db_ferr(dbp->dbenv, "DB->get", 0));
- }
-
- /* Check for invalid key/data flags. */
- if ((ret = __dbt_ferr(dbp, "key", key, flags == DB_SET_RECNO)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0)
- return (ret);
-
- /* Check for missing keys. */
- if (key->data == NULL || key->size == 0)
- return (__db_keyempty(dbp->dbenv));
-
- return (0);
-}
-
-/*
- * __db_joinchk --
- * Common join argument checking routine.
- *
- * PUBLIC: int __db_joinchk __P((const DB *, u_int32_t));
- */
-int
-__db_joinchk(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- if (flags != 0)
- return (__db_ferr(dbp->dbenv, "DB->join", 0));
-
- return (0);
-}
-
-/*
- * __db_putchk --
- * Common put argument checking routine.
- *
- * PUBLIC: int __db_putchk
- * PUBLIC: __P((const DB *, DBT *, const DBT *, u_int32_t, int, int));
- */
-int
-__db_putchk(dbp, key, data, flags, isrdonly, isdup)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int32_t flags;
- int isrdonly, isdup;
-{
- int ret;
-
- /* Check for changes to a read-only tree. */
- if (isrdonly)
- return (__db_rdonly(dbp->dbenv, "put"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- case DB_NOOVERWRITE:
- break;
- case DB_APPEND:
- if (dbp->type != DB_RECNO)
- goto err;
- break;
- default:
-err: return (__db_ferr(dbp->dbenv, "DB->put", 0));
- }
-
- /* Check for invalid key/data flags. */
- if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- /* Check for missing keys. */
- if (key->data == NULL || key->size == 0)
- return (__db_keyempty(dbp->dbenv));
-
- /* Check for partial puts in the presence of duplicates. */
- if (isdup && F_ISSET(data, DB_DBT_PARTIAL)) {
- __db_err(dbp->dbenv,
-"a partial put in the presence of duplicates requires a cursor operation");
- return (EINVAL);
- }
-
- return (0);
-}
-
-/*
- * __db_statchk --
- * Common stat argument checking routine.
- *
- * PUBLIC: int __db_statchk __P((const DB *, u_int32_t));
- */
-int
-__db_statchk(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- case DB_RECORDCOUNT:
- if (dbp->type == DB_RECNO)
- break;
- if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_BT_RECNUM))
- break;
- goto err;
- default:
-err: return (__db_ferr(dbp->dbenv, "DB->stat", 0));
- }
-
- return (0);
-}
-
-/*
- * __db_syncchk --
- * Common sync argument checking routine.
- *
- * PUBLIC: int __db_syncchk __P((const DB *, u_int32_t));
- */
-int
-__db_syncchk(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- default:
- return (__db_ferr(dbp->dbenv, "DB->sync", 0));
- }
-
- return (0);
-}
-
-/*
- * __dbt_ferr --
- * Check a DBT for flag errors.
- */
-static int
-__dbt_ferr(dbp, name, dbt, check_thread)
- const DB *dbp;
- const char *name;
- const DBT *dbt;
- int check_thread;
-{
- int ret;
-
- /*
- * Check for invalid DBT flags. We allow any of the flags to be
- * specified to any DB or DBcursor call so that applications can
- * set DB_DBT_MALLOC when retrieving a data item from a secondary
- * database and then specify that same DBT as a key to a primary
- * database, without having to clear flags.
- */
- if ((ret = __db_fchk(dbp->dbenv, name, dbt->flags,
- DB_DBT_MALLOC | DB_DBT_USERMEM | DB_DBT_PARTIAL)) != 0)
- return (ret);
- if ((ret = __db_fcchk(dbp->dbenv, name,
- dbt->flags, DB_DBT_MALLOC, DB_DBT_USERMEM)) != 0)
- return (ret);
-
- if (check_thread && F_ISSET(dbp, DB_AM_THREAD) &&
- !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_USERMEM)) {
- __db_err(dbp->dbenv,
- "missing flag thread flag for %s DBT", name);
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * __db_eopnotsup --
- * Common operation not supported message.
- *
- * PUBLIC: int __db_eopnotsup __P((const DB_ENV *));
- */
-int
-__db_eopnotsup(dbenv)
- const DB_ENV *dbenv;
-{
- __db_err(dbenv, "operation not supported");
-#ifdef EOPNOTSUPP
- return (EOPNOTSUPP);
-#else
- return (EINVAL);
-#endif
-}
-
-/*
- * __db_keyempty --
- * Common missing or empty key value message.
- */
-static int
-__db_keyempty(dbenv)
- const DB_ENV *dbenv;
-{
- __db_err(dbenv, "missing or empty key value specified");
- return (EINVAL);
-}
-
-/*
- * __db_rdonly --
- * Common readonly message.
- */
-static int
-__db_rdonly(dbenv, name)
- const DB_ENV *dbenv;
- const char *name;
-{
- __db_err(dbenv, "%s: attempt to modify a read-only tree", name);
- return (EACCES);
-}
diff --git a/db2/db/db_join.c b/db2/db/db_join.c
deleted file mode 100644
index a4051c2..0000000
--- a/db2/db/db_join.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_join.c 10.10 (Sleepycat) 10/9/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_join.h"
-#include "db_am.h"
-#include "common_ext.h"
-
-static int __db_join_close __P((DBC *));
-static int __db_join_del __P((DBC *, u_int32_t));
-static int __db_join_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_join_put __P((DBC *, DBT *, DBT *, u_int32_t));
-
-/*
- * This is the duplicate-assisted join functionality. Right now we're
- * going to write it such that we return one item at a time, although
- * I think we may need to optimize it to return them all at once.
- * It should be easier to get it working this way, and I believe that
- * changing it should be fairly straightforward.
- *
- * XXX
- * Right now we do not maintain the number of duplicates so we do
- * not optimize the join. If the caller does, then best performance
- * will be achieved by putting the cursor with the smallest cardinality
- * first.
- *
- * The first cursor moves sequentially through the duplicate set while
- * the others search explicitly for the duplicate in question.
- *
- */
-
-/*
- * __db_join --
- * This is the interface to the duplicate-assisted join functionality.
- * In the same way that cursors mark a position in a database, a cursor
- * can mark a position in a join. While most cursors are created by the
- * cursor method of a DB, join cursors are created through an explicit
- * call to DB->join.
- *
- * The curslist is an array of existing, intialized cursors and primary
- * is the DB of the primary file. The data item that joins all the
- * cursors in the curslist is used as the key into the primary and that
- * key and data are returned. When no more items are left in the join
- * set, the c_next operation off the join cursor will return DB_NOTFOUND.
- *
- * PUBLIC: int __db_join __P((DB *, DBC **, u_int32_t, DBC **));
- */
-int
-__db_join(primary, curslist, flags, dbcp)
- DB *primary;
- DBC **curslist, **dbcp;
- u_int32_t flags;
-{
- DBC *dbc;
- JOIN_CURSOR *jc;
- int i, ret;
-
- DB_PANIC_CHECK(primary);
-
- if ((ret = __db_joinchk(primary, flags)) != 0)
- return (ret);
-
- if (curslist == NULL || curslist[0] == NULL)
- return (EINVAL);
-
- dbc = NULL;
- jc = NULL;
-
- if ((ret = __os_calloc(1, sizeof(DBC), &dbc)) != 0)
- goto err;
-
- if ((ret = __os_calloc(1, sizeof(JOIN_CURSOR), &jc)) != 0)
- goto err;
-
- if ((ret = __os_malloc(256, NULL, &jc->j_key.data)) != 0)
- goto err;
- jc->j_key.ulen = 256;
- F_SET(&jc->j_key, DB_DBT_USERMEM);
-
- for (jc->j_curslist = curslist;
- *jc->j_curslist != NULL; jc->j_curslist++)
- ;
- if ((ret = __os_calloc((jc->j_curslist - curslist + 1),
- sizeof(DBC *), &jc->j_curslist)) != 0)
- goto err;
- for (i = 0; curslist[i] != NULL; i++) {
- if (i != 0)
- F_SET(curslist[i], DBC_KEYSET);
- jc->j_curslist[i] = curslist[i];
- }
-
- dbc->c_close = __db_join_close;
- dbc->c_del = __db_join_del;
- dbc->c_get = __db_join_get;
- dbc->c_put = __db_join_put;
- dbc->internal = jc;
- dbc->dbp = primary;
- jc->j_init = 1;
- jc->j_primary = primary;
-
- *dbcp = dbc;
-
- return (0);
-
-err: if (jc != NULL) {
- if (jc->j_curslist != NULL)
- __os_free(jc->j_curslist,
- (jc->j_curslist - curslist + 1) * sizeof(DBC *));
- __os_free(jc, sizeof(JOIN_CURSOR));
- }
- if (dbc != NULL)
- __os_free(dbc, sizeof(DBC));
- return (ret);
-}
-
-static int
-__db_join_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB_PANIC_CHECK(dbc->dbp);
-
- COMPQUIET(key, NULL);
- COMPQUIET(data, NULL);
- COMPQUIET(flags, 0);
- return (EINVAL);
-}
-
-static int
-__db_join_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB_PANIC_CHECK(dbc->dbp);
-
- COMPQUIET(flags, 0);
- return (EINVAL);
-}
-
-static int
-__db_join_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DBC **cpp;
- JOIN_CURSOR *jc;
- int ret;
- u_int32_t operation;
-
- dbp = dbc->dbp;
-
- DB_PANIC_CHECK(dbp);
-
- operation = LF_ISSET(DB_OPFLAGS_MASK);
- if (operation != 0 && operation != DB_JOIN_ITEM)
- return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0));
-
- LF_CLR(DB_OPFLAGS_MASK);
- if ((ret =
- __db_fchk(dbp->dbenv, "DBcursor->c_get", flags, DB_RMW)) != 0)
- return (ret);
-
- jc = (JOIN_CURSOR *)dbc->internal;
-retry:
- ret = jc->j_curslist[0]->c_get(jc->j_curslist[0],
- &jc->j_key, key, jc->j_init ? DB_CURRENT : DB_NEXT_DUP);
-
- if (ret == ENOMEM) {
- jc->j_key.ulen <<= 1;
- if ((ret = __os_realloc(&jc->j_key.data, jc->j_key.ulen)) != 0)
- return (ret);
- goto retry;
- }
- if (ret != 0)
- return (ret);
-
- jc->j_init = 0;
- do {
- /*
- * We have the first element; now look for it in the
- * other cursors.
- */
- for (cpp = jc->j_curslist + 1; *cpp != NULL; cpp++) {
-retry2: if ((ret = ((*cpp)->c_get)(*cpp,
- &jc->j_key, key, DB_GET_BOTH)) == DB_NOTFOUND)
- break;
- if (ret == ENOMEM) {
- jc->j_key.ulen <<= 1;
- if ((ret = __os_realloc(&jc->j_key.data,
- jc->j_key.ulen)) != 0)
- return (ret);
- goto retry2;
- }
- if (F_ISSET(*cpp, DBC_KEYSET)) {
- F_CLR(*cpp, DBC_KEYSET);
- F_SET(*cpp, DBC_CONTINUE);
- }
- }
-
- /*
- * If we got out of here with ret != 0, then we failed to
- * find the duplicate in one of the files, so we go on to
- * the next item in the outermost relation. If ret was
- * equal to 0, then we've got something to return.
- */
- if (ret == 0)
- break;
- } while ((ret = jc->j_curslist[0]->c_get(jc->j_curslist[0],
- &jc->j_key, key, DB_NEXT_DUP)) == 0);
-
- /*
- * If ret != 0 here, we've exhausted the first file. Otherwise,
- * key and data are set and we need to do the lookup on the
- * primary.
- */
- if (ret != 0)
- return (ret);
-
- if (operation == DB_JOIN_ITEM)
- return (0);
- else
- return ((jc->j_primary->get)(jc->j_primary,
- jc->j_curslist[0]->txn, key, data, 0));
-}
-
-static int
-__db_join_close(dbc)
- DBC *dbc;
-{
- JOIN_CURSOR *jc;
- int i;
-
- DB_PANIC_CHECK(dbc->dbp);
-
- jc = (JOIN_CURSOR *)dbc->internal;
-
- /*
- * Clear the optimization flag in the cursors.
- */
- for (i = 0; jc->j_curslist[i] != NULL; i++)
- F_CLR(jc->j_curslist[i], DBC_CONTINUE | DBC_KEYSET);
-
- __os_free(jc->j_curslist, 0);
- __os_free(jc->j_key.data, jc->j_key.ulen);
- __os_free(jc, sizeof(JOIN_CURSOR));
- __os_free(dbc, sizeof(DBC));
-
- return (0);
-}
diff --git a/db2/db/db_overflow.c b/db2/db/db_overflow.c
deleted file mode 100644
index 0efcc9d..0000000
--- a/db2/db/db_overflow.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_overflow.c 10.21 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_am.h"
-#include "common_ext.h"
-
-/*
- * Big key/data code.
- *
- * Big key and data entries are stored on linked lists of pages. The initial
- * reference is a structure with the total length of the item and the page
- * number where it begins. Each entry in the linked list contains a pointer
- * to the next page of data, and so on.
- */
-
-/*
- * __db_goff --
- * Get an offpage item.
- *
- * PUBLIC: int __db_goff __P((DB *, DBT *,
- * PUBLIC: u_int32_t, db_pgno_t, void **, u_int32_t *));
- */
-int
-__db_goff(dbp, dbt, tlen, pgno, bpp, bpsz)
- DB *dbp;
- DBT *dbt;
- u_int32_t tlen;
- db_pgno_t pgno;
- void **bpp;
- u_int32_t *bpsz;
-{
- PAGE *h;
- db_indx_t bytes;
- u_int32_t curoff, needed, start;
- u_int8_t *p, *src;
- int ret;
-
- /*
- * Check if the buffer is big enough; if it is not and we are
- * allowed to malloc space, then we'll malloc it. If we are
- * not (DB_DBT_USERMEM), then we'll set the dbt and return
- * appropriately.
- */
- if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
- start = dbt->doff;
- needed = dbt->dlen;
- } else {
- start = 0;
- needed = tlen;
- }
-
- /* Allocate any necessary memory. */
- if (F_ISSET(dbt, DB_DBT_USERMEM)) {
- if (needed > dbt->ulen) {
- dbt->size = needed;
- return (ENOMEM);
- }
- } else if (F_ISSET(dbt, DB_DBT_MALLOC)) {
- if ((ret =
- __os_malloc(needed, dbp->db_malloc, &dbt->data)) != 0)
- return (ret);
- } else if (*bpsz == 0 || *bpsz < needed) {
- if ((ret = __os_realloc(bpp, needed)) != 0)
- return (ret);
- *bpsz = needed;
- dbt->data = *bpp;
- } else
- dbt->data = *bpp;
-
- /*
- * Step through the linked list of pages, copying the data on each
- * one into the buffer. Never copy more than the total data length.
- */
- dbt->size = needed;
- for (curoff = 0, p = dbt->data; pgno != P_INVALID && needed > 0;) {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
- (void)__db_pgerr(dbp, pgno);
- return (ret);
- }
- /* Check if we need any bytes from this page. */
- if (curoff + OV_LEN(h) >= start) {
- src = (u_int8_t *)h + P_OVERHEAD;
- bytes = OV_LEN(h);
- if (start > curoff) {
- src += start - curoff;
- bytes -= start - curoff;
- }
- if (bytes > needed)
- bytes = needed;
- memcpy(p, src, bytes);
- p += bytes;
- needed -= bytes;
- }
- curoff += OV_LEN(h);
- pgno = h->next_pgno;
- memp_fput(dbp->mpf, h, 0);
- }
- return (0);
-}
-
-/*
- * __db_poff --
- * Put an offpage item.
- *
- * PUBLIC: int __db_poff __P((DBC *, const DBT *, db_pgno_t *,
- * PUBLIC: int (*)(DBC *, u_int32_t, PAGE **)));
- */
-int
-__db_poff(dbc, dbt, pgnop, newfunc)
- DBC *dbc;
- const DBT *dbt;
- db_pgno_t *pgnop;
- int (*newfunc) __P((DBC *, u_int32_t, PAGE **));
-{
- DB *dbp;
- PAGE *pagep, *lastp;
- DB_LSN new_lsn, null_lsn;
- DBT tmp_dbt;
- db_indx_t pagespace;
- u_int32_t sz;
- u_int8_t *p;
- int ret;
-
- /*
- * Allocate pages and copy the key/data item into them. Calculate the
- * number of bytes we get for pages we fill completely with a single
- * item.
- */
- dbp = dbc->dbp;
- pagespace = P_MAXSPACE(dbp->pgsize);
-
- lastp = NULL;
- for (p = dbt->data,
- sz = dbt->size; sz > 0; p += pagespace, sz -= pagespace) {
- /*
- * Reduce pagespace so we terminate the loop correctly and
- * don't copy too much data.
- */
- if (sz < pagespace)
- pagespace = sz;
-
- /*
- * Allocate and initialize a new page and copy all or part of
- * the item onto the page. If sz is less than pagespace, we
- * have a partial record.
- */
- if ((ret = newfunc(dbc, P_OVERFLOW, &pagep)) != 0)
- return (ret);
- if (DB_LOGGING(dbc)) {
- tmp_dbt.data = p;
- tmp_dbt.size = pagespace;
- ZERO_LSN(null_lsn);
- if ((ret = __db_big_log(dbp->dbenv->lg_info, dbc->txn,
- &new_lsn, 0, DB_ADD_BIG, dbp->log_fileid,
- PGNO(pagep), lastp ? PGNO(lastp) : PGNO_INVALID,
- PGNO_INVALID, &tmp_dbt, &LSN(pagep),
- lastp == NULL ? &null_lsn : &LSN(lastp),
- &null_lsn)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- if (lastp)
- LSN(lastp) = new_lsn;
- LSN(pagep) = new_lsn;
- }
-
- P_INIT(pagep, dbp->pgsize,
- PGNO(pagep), PGNO_INVALID, PGNO_INVALID, 0, P_OVERFLOW);
- OV_LEN(pagep) = pagespace;
- OV_REF(pagep) = 1;
- memcpy((u_int8_t *)pagep + P_OVERHEAD, p, pagespace);
-
- /*
- * If this is the first entry, update the user's info.
- * Otherwise, update the entry on the last page filled
- * in and release that page.
- */
- if (lastp == NULL)
- *pgnop = PGNO(pagep);
- else {
- lastp->next_pgno = PGNO(pagep);
- pagep->prev_pgno = PGNO(lastp);
- (void)memp_fput(dbp->mpf, lastp, DB_MPOOL_DIRTY);
- }
- lastp = pagep;
- }
- (void)memp_fput(dbp->mpf, lastp, DB_MPOOL_DIRTY);
- return (0);
-}
-
-/*
- * __db_ovref --
- * Increment/decrement the reference count on an overflow page.
- *
- * PUBLIC: int __db_ovref __P((DBC *, db_pgno_t, int32_t));
- */
-int
-__db_ovref(dbc, pgno, adjust)
- DBC *dbc;
- db_pgno_t pgno;
- int32_t adjust;
-{
- DB *dbp;
- PAGE *h;
- int ret;
-
- dbp = dbc->dbp;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
- (void)__db_pgerr(dbp, pgno);
- return (ret);
- }
-
- if (DB_LOGGING(dbc))
- if ((ret = __db_ovref_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(h), 0, dbp->log_fileid, h->pgno, adjust,
- &LSN(h))) != 0)
- return (ret);
- OV_REF(h) += adjust;
-
- (void)memp_fput(dbp->mpf, h, DB_MPOOL_DIRTY);
- return (0);
-}
-
-/*
- * __db_doff --
- * Delete an offpage chain of overflow pages.
- *
- * PUBLIC: int __db_doff __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *)));
- */
-int
-__db_doff(dbc, pgno, freefunc)
- DBC *dbc;
- db_pgno_t pgno;
- int (*freefunc) __P((DBC *, PAGE *));
-{
- DB *dbp;
- PAGE *pagep;
- DB_LSN null_lsn;
- DBT tmp_dbt;
- int ret;
-
- dbp = dbc->dbp;
- do {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &pagep)) != 0) {
- (void)__db_pgerr(dbp, pgno);
- return (ret);
- }
-
- /*
- * If it's an overflow page and it's referenced by more than
- * one key/data item, decrement the reference count and return.
- */
- if (TYPE(pagep) == P_OVERFLOW && OV_REF(pagep) > 1) {
- (void)memp_fput(dbp->mpf, pagep, 0);
- return (__db_ovref(dbc, pgno, -1));
- }
-
- if (DB_LOGGING(dbc)) {
- tmp_dbt.data = (u_int8_t *)pagep + P_OVERHEAD;
- tmp_dbt.size = OV_LEN(pagep);
- ZERO_LSN(null_lsn);
- if ((ret = __db_big_log(dbp->dbenv->lg_info, dbc->txn,
- &LSN(pagep), 0, DB_REM_BIG, dbp->log_fileid,
- PGNO(pagep), PREV_PGNO(pagep), NEXT_PGNO(pagep),
- &tmp_dbt, &LSN(pagep), &null_lsn, &null_lsn)) != 0)
- return (ret);
- }
- pgno = pagep->next_pgno;
- if ((ret = freefunc(dbc, pagep)) != 0)
- return (ret);
- } while (pgno != PGNO_INVALID);
-
- return (0);
-}
-
-/*
- * __db_moff --
- * Match on overflow pages.
- *
- * Given a starting page number and a key, return <0, 0, >0 to indicate if the
- * key on the page is less than, equal to or greater than the key specified.
- * We optimize this by doing chunk at a time comparison unless the user has
- * specified a comparison function. In this case, we need to materialize
- * the entire object and call their comparison routine.
- *
- * PUBLIC: int __db_moff __P((DB *, const DBT *, db_pgno_t, u_int32_t,
- * PUBLIC: int (*)(const DBT *, const DBT *), int *));
- */
-int
-__db_moff(dbp, dbt, pgno, tlen, cmpfunc, cmpp)
- DB *dbp;
- const DBT *dbt;
- db_pgno_t pgno;
- u_int32_t tlen;
- int (*cmpfunc) __P((const DBT *, const DBT *)), *cmpp;
-{
- PAGE *pagep;
- DBT local_dbt;
- void *buf;
- u_int32_t bufsize, cmp_bytes, key_left;
- u_int8_t *p1, *p2;
- int ret;
-
- /*
- * If there is a user-specified comparison function, build a
- * contiguous copy of the key, and call it.
- */
- if (cmpfunc != NULL) {
- memset(&local_dbt, 0, sizeof(local_dbt));
- buf = NULL;
- bufsize = 0;
-
- if ((ret = __db_goff(dbp,
- &local_dbt, tlen, pgno, &buf, &bufsize)) != 0)
- return (ret);
- *cmpp = cmpfunc(&local_dbt, dbt);
- __os_free(buf, bufsize);
- return (0);
- }
-
- /* While there are both keys to compare. */
- for (*cmpp = 0, p1 = dbt->data,
- key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) {
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &pagep)) != 0)
- return (ret);
-
- cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left;
- key_left -= cmp_bytes;
- for (p2 =
- (u_int8_t *)pagep + P_OVERHEAD; cmp_bytes-- > 0; ++p1, ++p2)
- if (*p1 != *p2) {
- *cmpp = (long)*p1 - (long)*p2;
- break;
- }
- pgno = NEXT_PGNO(pagep);
- if ((ret = memp_fput(dbp->mpf, pagep, 0)) != 0)
- return (ret);
- if (*cmpp != 0)
- return (0);
- }
- if (key_left > 0) /* DBT is longer than page key. */
- *cmpp = -1;
- else if (pgno != PGNO_INVALID) /* DBT is shorter than page key. */
- *cmpp = 1;
- else
- *cmpp = 0;
-
- return (0);
-}
diff --git a/db2/db/db_pr.c b/db2/db/db_pr.c
deleted file mode 100644
index 7f4364c..0000000
--- a/db2/db/db_pr.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_pr.c 10.40 (Sleepycat) 11/22/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "hash.h"
-#include "db_am.h"
-
-static void __db_proff __P((void *));
-static void __db_psize __P((DB_MPOOLFILE *));
-
-/*
- * __db_loadme --
- * Force loading of this file.
- *
- * PUBLIC: void __db_loadme __P((void));
- */
-void
-__db_loadme()
-{
- getpid();
-}
-
-static FILE *set_fp;
-
-/*
- * 64K is the maximum page size, so by default we check for offsets
- * larger than that, and, where possible, we refine the test.
- */
-#define PSIZE_BOUNDARY (64 * 1024 + 1)
-static size_t set_psize = PSIZE_BOUNDARY;
-
-/*
- * __db_prinit --
- * Initialize tree printing routines.
- *
- * PUBLIC: FILE *__db_prinit __P((FILE *));
- */
-FILE *
-__db_prinit(fp)
- FILE *fp;
-{
- if (set_fp == NULL)
- set_fp = fp == NULL ? stdout : fp;
- return (set_fp);
-}
-
-/*
- * __db_dump --
- * Dump the tree to a file.
- *
- * PUBLIC: int __db_dump __P((DB *, char *, int));
- */
-int
-__db_dump(dbp, name, all)
- DB *dbp;
- char *name;
- int all;
-{
- FILE *fp, *save_fp;
-
- COMPQUIET(save_fp, NULL);
-
- if (set_psize == PSIZE_BOUNDARY)
- __db_psize(dbp->mpf);
-
- if (name != NULL) {
- if ((fp = fopen(name, "w")) == NULL)
- return (errno);
- save_fp = set_fp;
- set_fp = fp;
- } else
- fp = __db_prinit(NULL);
-
- (void)__db_prdb(dbp);
- if (dbp->type == DB_HASH)
- (void)__db_prhash(dbp);
- else
- (void)__db_prbtree(dbp);
- fprintf(fp, "%s\n", DB_LINE);
- __db_prtree(dbp->mpf, all);
-
- if (name != NULL) {
- (void)fclose(fp);
- set_fp = save_fp;
- }
- return (0);
-}
-
-/*
- * __db_prdb --
- * Print out the DB structure information.
- *
- * PUBLIC: int __db_prdb __P((DB *));
- */
-int
-__db_prdb(dbp)
- DB *dbp;
-{
- static const FN fn[] = {
- { DB_AM_DUP, "duplicates" },
- { DB_AM_INMEM, "in-memory" },
- { DB_AM_LOCKING, "locking" },
- { DB_AM_LOGGING, "logging" },
- { DB_AM_MLOCAL, "local mpool" },
- { DB_AM_PGDEF, "default page size" },
- { DB_AM_RDONLY, "read-only" },
- { DB_AM_SWAP, "needswap" },
- { DB_AM_THREAD, "thread" },
- { DB_BT_RECNUM, "btree:recnum" },
- { DB_DBM_ERROR, "dbm/ndbm error" },
- { DB_RE_DELIMITER, "recno:delimiter" },
- { DB_RE_FIXEDLEN, "recno:fixed-length" },
- { DB_RE_PAD, "recno:pad" },
- { DB_RE_RENUMBER, "recno:renumber" },
- { DB_RE_SNAPSHOT, "recno:snapshot" },
- { 0 },
- };
- FILE *fp;
- const char *t;
-
- fp = __db_prinit(NULL);
-
- switch (dbp->type) {
- case DB_BTREE:
- t = "btree";
- break;
- case DB_HASH:
- t = "hash";
- break;
- case DB_RECNO:
- t = "recno";
- break;
- default:
- t = "UNKNOWN";
- break;
- }
-
- fprintf(fp, "%s ", t);
- __db_prflags(dbp->flags, fn, fp);
- fprintf(fp, "\n");
-
- return (0);
-}
-
-/*
- * __db_prbtree --
- * Print out the btree internal information.
- *
- * PUBLIC: int __db_prbtree __P((DB *));
- */
-int
-__db_prbtree(dbp)
- DB *dbp;
-{
- static const FN mfn[] = {
- { BTM_DUP, "duplicates" },
- { BTM_RECNO, "recno" },
- { BTM_RECNUM, "btree:recnum" },
- { BTM_FIXEDLEN, "recno:fixed-length" },
- { BTM_RENUMBER, "recno:renumber" },
- { 0 },
- };
- DBC *dbc;
- BTMETA *mp;
- BTREE *t;
- FILE *fp;
- PAGE *h;
- RECNO *rp;
- db_pgno_t i;
- int cnt, ret;
- const char *sep;
-
- t = dbp->internal;
- fp = __db_prinit(NULL);
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
-
- (void)fprintf(fp, "%s\nOn-page metadata:\n", DB_LINE);
-
- i = PGNO_METADATA;
- if ((ret = memp_fget(dbp->mpf, &i, 0, (PAGE **)&mp)) != 0) {
- (void)dbc->c_close(dbc);
- return (ret);
- }
-
- fprintf(fp, "lsn.file: %lu lsn.offset: %lu\n",
- (u_long)LSN(mp).file, (u_long)LSN(mp).offset);
- (void)fprintf(fp, "magic %#lx\n", (u_long)mp->magic);
- (void)fprintf(fp, "version %#lx\n", (u_long)mp->version);
- (void)fprintf(fp, "pagesize %lu\n", (u_long)mp->pagesize);
- (void)fprintf(fp, "maxkey: %lu minkey: %lu\n",
- (u_long)mp->maxkey, (u_long)mp->minkey);
-
- (void)fprintf(fp, "free list: %lu", (u_long)mp->free);
- for (i = mp->free, cnt = 0, sep = ", "; i != PGNO_INVALID;) {
- if ((ret = memp_fget(dbp->mpf, &i, 0, &h)) != 0)
- return (ret);
- i = h->next_pgno;
- (void)memp_fput(dbp->mpf, h, 0);
- (void)fprintf(fp, "%s%lu", sep, (u_long)i);
- if (++cnt % 10 == 0) {
- (void)fprintf(fp, "\n");
- cnt = 0;
- sep = "";
- } else
- sep = ", ";
- }
- (void)fprintf(fp, "\n");
-
- (void)fprintf(fp, "flags %#lx", (u_long)mp->flags);
- __db_prflags(mp->flags, mfn, fp);
- (void)fprintf(fp, "\n");
- (void)memp_fput(dbp->mpf, mp, 0);
-
- (void)fprintf(fp, "%s\nDB_INFO:\n", DB_LINE);
- (void)fprintf(fp, "bt_maxkey: %lu bt_minkey: %lu\n",
- (u_long)t->bt_maxkey, (u_long)t->bt_minkey);
- (void)fprintf(fp, "bt_compare: %#lx bt_prefix: %#lx\n",
- (u_long)t->bt_compare, (u_long)t->bt_prefix);
- if ((rp = t->recno) != NULL) {
- (void)fprintf(fp,
- "re_delim: %#lx re_pad: %#lx re_len: %lu re_source: %s\n",
- (u_long)rp->re_delim, (u_long)rp->re_pad,
- (u_long)rp->re_len,
- rp->re_source == NULL ? "" : rp->re_source);
- (void)fprintf(fp,
- "cmap: %#lx smap: %#lx emap: %#lx msize: %lu\n",
- (u_long)rp->re_cmap, (u_long)rp->re_smap,
- (u_long)rp->re_emap, (u_long)rp->re_msize);
- }
- (void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize);
- (void)fflush(fp);
- return (dbc->c_close(dbc));
-}
-
-/*
- * __db_prhash --
- * Print out the hash internal information.
- *
- * PUBLIC: int __db_prhash __P((DB *));
- */
-int
-__db_prhash(dbp)
- DB *dbp;
-{
- FILE *fp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- int i, put_page, ret;
- db_pgno_t pgno;
-
- fp = __db_prinit(NULL);
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- /*
- * In this case, hcp->hdr will never be null, if we decide
- * to pass dbc's to this routine instead, then it could be.
- */
- if (hcp->hdr == NULL) {
- pgno = PGNO_METADATA;
- if ((ret = memp_fget(dbp->mpf, &pgno, 0, &hcp->hdr)) != 0)
- return (ret);
- put_page = 1;
- } else
- put_page = 0;
-
- fprintf(fp, "\tmagic %#lx\n", (u_long)hcp->hdr->magic);
- fprintf(fp, "\tversion %lu\n", (u_long)hcp->hdr->version);
- fprintf(fp, "\tpagesize %lu\n", (u_long)hcp->hdr->pagesize);
- fprintf(fp, "\tovfl_point %lu\n", (u_long)hcp->hdr->ovfl_point);
- fprintf(fp, "\tlast_freed %lu\n", (u_long)hcp->hdr->last_freed);
- fprintf(fp, "\tmax_bucket %lu\n", (u_long)hcp->hdr->max_bucket);
- fprintf(fp, "\thigh_mask %#lx\n", (u_long)hcp->hdr->high_mask);
- fprintf(fp, "\tlow_mask %#lx\n", (u_long)hcp->hdr->low_mask);
- fprintf(fp, "\tffactor %lu\n", (u_long)hcp->hdr->ffactor);
- fprintf(fp, "\tnelem %lu\n", (u_long)hcp->hdr->nelem);
- fprintf(fp, "\th_charkey %#lx\n", (u_long)hcp->hdr->h_charkey);
-
- for (i = 0; i < NCACHED; i++)
- fprintf(fp, "%lu ", (u_long)hcp->hdr->spares[i]);
- fprintf(fp, "\n");
-
- (void)fflush(fp);
- if (put_page) {
- (void)memp_fput(dbp->mpf, (PAGE *)hcp->hdr, 0);
- hcp->hdr = NULL;
- }
- return (dbc->c_close(dbc));
-}
-
-/*
- * __db_prtree --
- * Print out the entire tree.
- *
- * PUBLIC: int __db_prtree __P((DB_MPOOLFILE *, int));
- */
-int
-__db_prtree(mpf, all)
- DB_MPOOLFILE *mpf;
- int all;
-{
- PAGE *h;
- db_pgno_t i;
-
- if (set_psize == PSIZE_BOUNDARY)
- __db_psize(mpf);
-
- for (i = PGNO_ROOT;; ++i) {
- if (memp_fget(mpf, &i, 0, &h) != 0)
- break;
- (void)__db_prpage(h, all);
- (void)memp_fput(mpf, h, 0);
- }
- (void)fflush(__db_prinit(NULL));
- return (0);
-}
-
-/*
- * __db_prnpage
- * -- Print out a specific page.
- *
- * PUBLIC: int __db_prnpage __P((DB_MPOOLFILE *, db_pgno_t));
- */
-int
-__db_prnpage(mpf, pgno)
- DB_MPOOLFILE *mpf;
- db_pgno_t pgno;
-{
- PAGE *h;
- int ret;
-
- if (set_psize == PSIZE_BOUNDARY)
- __db_psize(mpf);
-
- if ((ret = memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- ret = __db_prpage(h, 1);
- (void)fflush(__db_prinit(NULL));
-
- (void)memp_fput(mpf, h, 0);
- return (ret);
-}
-
-/*
- * __db_prpage
- * -- Print out a page.
- *
- * PUBLIC: int __db_prpage __P((PAGE *, int));
- */
-int
-__db_prpage(h, all)
- PAGE *h;
- int all;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- HOFFPAGE a_hkd;
- FILE *fp;
- RINTERNAL *ri;
- db_indx_t dlen, len, i;
- db_pgno_t pgno;
- int deleted, ret;
- const char *s;
- u_int8_t *ep, *hk, *p;
- void *sp;
-
- fp = __db_prinit(NULL);
-
- switch (TYPE(h)) {
- case P_DUPLICATE:
- s = "duplicate";
- break;
- case P_HASH:
- s = "hash";
- break;
- case P_IBTREE:
- s = "btree internal";
- break;
- case P_INVALID:
- s = "invalid";
- break;
- case P_IRECNO:
- s = "recno internal";
- break;
- case P_LBTREE:
- s = "btree leaf";
- break;
- case P_LRECNO:
- s = "recno leaf";
- break;
- case P_OVERFLOW:
- s = "overflow";
- break;
- default:
- fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n",
- (u_long)h->pgno, (u_long)TYPE(h));
- return (1);
- }
- fprintf(fp, "page %4lu: (%s)\n", (u_long)h->pgno, s);
- fprintf(fp, " lsn.file: %lu lsn.offset: %lu",
- (u_long)LSN(h).file, (u_long)LSN(h).offset);
- if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO ||
- (TYPE(h) == P_LRECNO && h->pgno == PGNO_ROOT))
- fprintf(fp, " total records: %4lu", (u_long)RE_NREC(h));
- fprintf(fp, "\n");
- if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO)
- fprintf(fp, " prev: %4lu next: %4lu",
- (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
- if (TYPE(h) == P_IBTREE || TYPE(h) == P_LBTREE)
- fprintf(fp, " level: %2lu", (u_long)h->level);
- if (TYPE(h) == P_OVERFLOW) {
- fprintf(fp, " ref cnt: %4lu ", (u_long)OV_REF(h));
- __db_pr((u_int8_t *)h + P_OVERHEAD, OV_LEN(h));
- return (0);
- }
- fprintf(fp, " entries: %4lu", (u_long)NUM_ENT(h));
- fprintf(fp, " offset: %4lu\n", (u_long)HOFFSET(h));
-
- if (!all || TYPE(h) == P_INVALID)
- return (0);
-
- ret = 0;
- for (i = 0; i < NUM_ENT(h); i++) {
- if (P_ENTRY(h, i) - (u_int8_t *)h < P_OVERHEAD ||
- (size_t)(P_ENTRY(h, i) - (u_int8_t *)h) >= set_psize) {
- fprintf(fp,
- "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
- (u_long)i, (u_long)h->inp[i]);
- ret = EINVAL;
- continue;
- }
- deleted = 0;
- switch (TYPE(h)) {
- case P_HASH:
- case P_IBTREE:
- case P_IRECNO:
- sp = P_ENTRY(h, i);
- break;
- case P_LBTREE:
- sp = P_ENTRY(h, i);
- deleted = i % 2 == 0 &&
- B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
- break;
- case P_LRECNO:
- case P_DUPLICATE:
- sp = P_ENTRY(h, i);
- deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
- break;
- default:
- fprintf(fp,
- "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h));
- ret = EINVAL;
- continue;
- }
- fprintf(fp, " %s[%03lu] %4lu ",
- deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]);
- switch (TYPE(h)) {
- case P_HASH:
- hk = sp;
- switch (HPAGE_PTYPE(hk)) {
- case H_OFFDUP:
- memcpy(&pgno,
- HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
- fprintf(fp,
- "%4lu [offpage dups]\n", (u_long)pgno);
- break;
- case H_DUPLICATE:
- /*
- * If this is the first item on a page, then
- * we cannot figure out how long it is, so
- * we only print the first one in the duplicate
- * set.
- */
- if (i != 0)
- len = LEN_HKEYDATA(h, 0, i);
- else
- len = 1;
-
- fprintf(fp, "Duplicates:\n");
- for (p = HKEYDATA_DATA(hk),
- ep = p + len; p < ep;) {
- memcpy(&dlen, p, sizeof(db_indx_t));
- p += sizeof(db_indx_t);
- fprintf(fp, "\t\t");
- __db_pr(p, dlen);
- p += sizeof(db_indx_t) + dlen;
- }
- break;
- case H_KEYDATA:
- if (i != 0)
- __db_pr(HKEYDATA_DATA(hk),
- LEN_HKEYDATA(h, 0, i));
- else
- fprintf(fp, "%s\n", HKEYDATA_DATA(hk));
- break;
- case H_OFFPAGE:
- memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
- fprintf(fp,
- "overflow: total len: %4lu page: %4lu\n",
- (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
- break;
- }
- break;
- case P_IBTREE:
- bi = sp;
- fprintf(fp, "count: %4lu pgno: %4lu ",
- (u_long)bi->nrecs, (u_long)bi->pgno);
- switch (B_TYPE(bi->type)) {
- case B_KEYDATA:
- __db_pr(bi->data, bi->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- __db_proff(bi->data);
- break;
- default:
- fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n",
- (u_long)B_TYPE(bi->type));
- ret = EINVAL;
- break;
- }
- break;
- case P_IRECNO:
- ri = sp;
- fprintf(fp, "entries %4lu pgno %4lu\n",
- (u_long)ri->nrecs, (u_long)ri->pgno);
- break;
- case P_LBTREE:
- case P_LRECNO:
- case P_DUPLICATE:
- bk = sp;
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- __db_pr(bk->data, bk->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- __db_proff(bk);
- break;
- default:
- fprintf(fp,
- "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n",
- (u_long)B_TYPE(bk->type));
- ret = EINVAL;
- break;
- }
- break;
- }
- }
- (void)fflush(fp);
- return (ret);
-}
-
-/*
- * __db_isbad
- * -- Decide if a page is corrupted.
- *
- * PUBLIC: int __db_isbad __P((PAGE *, int));
- */
-int
-__db_isbad(h, die)
- PAGE *h;
- int die;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- FILE *fp;
- db_indx_t i;
- u_int type;
-
- fp = __db_prinit(NULL);
-
- switch (TYPE(h)) {
- case P_DUPLICATE:
- case P_HASH:
- case P_IBTREE:
- case P_INVALID:
- case P_IRECNO:
- case P_LBTREE:
- case P_LRECNO:
- case P_OVERFLOW:
- break;
- default:
- fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n",
- (u_long)h->pgno, (u_long)TYPE(h));
- goto bad;
- }
-
- for (i = 0; i < NUM_ENT(h); i++) {
- if (P_ENTRY(h, i) - (u_int8_t *)h < P_OVERHEAD ||
- (size_t)(P_ENTRY(h, i) - (u_int8_t *)h) >= set_psize) {
- fprintf(fp,
- "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
- (u_long)i, (u_long)h->inp[i]);
- goto bad;
- }
- switch (TYPE(h)) {
- case P_HASH:
- type = HPAGE_TYPE(h, i);
- if (type != H_OFFDUP &&
- type != H_DUPLICATE &&
- type != H_KEYDATA &&
- type != H_OFFPAGE) {
- fprintf(fp, "ILLEGAL HASH TYPE: %lu\n",
- (u_long)type);
- goto bad;
- }
- break;
- case P_IBTREE:
- bi = GET_BINTERNAL(h, i);
- if (B_TYPE(bi->type) != B_KEYDATA &&
- B_TYPE(bi->type) != B_DUPLICATE &&
- B_TYPE(bi->type) != B_OVERFLOW) {
- fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n",
- (u_long)B_TYPE(bi->type));
- goto bad;
- }
- break;
- case P_IRECNO:
- case P_LBTREE:
- case P_LRECNO:
- break;
- case P_DUPLICATE:
- bk = GET_BKEYDATA(h, i);
- if (B_TYPE(bk->type) != B_KEYDATA &&
- B_TYPE(bk->type) != B_DUPLICATE &&
- B_TYPE(bk->type) != B_OVERFLOW) {
- fprintf(fp,
- "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n",
- (u_long)B_TYPE(bk->type));
- goto bad;
- }
- break;
- default:
- fprintf(fp,
- "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h));
- goto bad;
- }
- }
- return (0);
-
-bad: if (die) {
- abort();
- /* NOTREACHED */
- }
- return (1);
-}
-
-/*
- * __db_pr --
- * Print out a data element.
- *
- * PUBLIC: void __db_pr __P((u_int8_t *, u_int32_t));
- */
-void
-__db_pr(p, len)
- u_int8_t *p;
- u_int32_t len;
-{
- FILE *fp;
- u_int lastch;
- int i;
-
- fp = __db_prinit(NULL);
-
- fprintf(fp, "len: %3lu", (u_long)len);
- lastch = '.';
- if (len != 0) {
- fprintf(fp, " data: ");
- for (i = len <= 20 ? len : 20; i > 0; --i, ++p) {
- lastch = *p;
- if (isprint(*p) || *p == '\n')
- fprintf(fp, "%c", *p);
- else
- fprintf(fp, "0x%.2x", (u_int)*p);
- }
- if (len > 20) {
- fprintf(fp, "...");
- lastch = '.';
- }
- }
- if (lastch != '\n')
- fprintf(fp, "\n");
-}
-
-/*
- * __db_prdbt --
- * Print out a DBT data element.
- *
- * PUBLIC: int __db_prdbt __P((DBT *, int, FILE *));
- */
-int
-__db_prdbt(dbtp, checkprint, fp)
- DBT *dbtp;
- int checkprint;
- FILE *fp;
-{
- static const char hex[] = "0123456789abcdef";
- u_int8_t *p;
- u_int32_t len;
-
- /*
- * !!!
- * This routine is the routine that dumps out items in the format
- * used by db_dump(1) and db_load(1). This means that the format
- * cannot change.
- */
- if (checkprint) {
- for (len = dbtp->size, p = dbtp->data; len--; ++p)
- if (isprint(*p)) {
- if (*p == '\\' && fprintf(fp, "\\") != 1)
- return (EIO);
- if (fprintf(fp, "%c", *p) != 1)
- return (EIO);
- } else
- if (fprintf(fp, "\\%c%c",
- hex[(u_int8_t)(*p & 0xf0) >> 4],
- hex[*p & 0x0f]) != 3)
- return (EIO);
- } else
- for (len = dbtp->size, p = dbtp->data; len--; ++p)
- if (fprintf(fp, "%c%c",
- hex[(u_int8_t)(*p & 0xf0) >> 4],
- hex[*p & 0x0f]) != 2)
- return (EIO);
-
- return (fprintf(fp, "\n") == 1 ? 0 : EIO);
-}
-
-/*
- * __db_proff --
- * Print out an off-page element.
- */
-static void
-__db_proff(vp)
- void *vp;
-{
- FILE *fp;
- BOVERFLOW *bo;
-
- fp = __db_prinit(NULL);
-
- bo = vp;
- switch (B_TYPE(bo->type)) {
- case B_OVERFLOW:
- fprintf(fp, "overflow: total len: %4lu page: %4lu\n",
- (u_long)bo->tlen, (u_long)bo->pgno);
- break;
- case B_DUPLICATE:
- fprintf(fp, "duplicate: page: %4lu\n", (u_long)bo->pgno);
- break;
- }
-}
-
-/*
- * __db_prflags --
- * Print out flags values.
- *
- * PUBLIC: void __db_prflags __P((u_int32_t, const FN *, FILE *));
- */
-void
-__db_prflags(flags, fn, fp)
- u_int32_t flags;
- FN const *fn;
- FILE *fp;
-{
- const FN *fnp;
- int found;
- const char *sep;
-
- sep = " (";
- for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
- if (LF_ISSET(fnp->mask)) {
- fprintf(fp, "%s%s", sep, fnp->name);
- sep = ", ";
- found = 1;
- }
- if (found)
- fprintf(fp, ")");
-}
-
-/*
- * __db_psize --
- * Get the page size.
- */
-static void
-__db_psize(mpf)
- DB_MPOOLFILE *mpf;
-{
- BTMETA *mp;
- db_pgno_t pgno;
-
- set_psize = PSIZE_BOUNDARY - 1;
-
- pgno = PGNO_METADATA;
- if (memp_fget(mpf, &pgno, 0, &mp) != 0)
- return;
-
- switch (mp->magic) {
- case DB_BTREEMAGIC:
- case DB_HASHMAGIC:
- set_psize = mp->pagesize;
- break;
- }
- (void)memp_fput(mpf, mp, 0);
-}
diff --git a/db2/db/db_rec.c b/db2/db/db_rec.c
deleted file mode 100644
index 7f577b5..0000000
--- a/db2/db/db_rec.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_rec.c 10.19 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "hash.h"
-#include "btree.h"
-
-/*
- * PUBLIC: int __db_addrem_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- *
- * This log message is generated whenever we add or remove a duplicate
- * to/from a duplicate page. On recover, we just do the opposite.
- */
-int
-__db_addrem_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_addrem_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- REC_PRINT(__db_addrem_print);
- REC_INTRO(__db_addrem_read);
-
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else
- if ((ret = memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- change = 0;
- if ((cmp_p == 0 && redo && argp->opcode == DB_ADD_DUP) ||
- (cmp_n == 0 && !redo && argp->opcode == DB_REM_DUP)) {
-
- /* Need to redo an add, or undo a delete. */
- if ((ret = __db_pitem(dbc, pagep, argp->indx, argp->nbytes,
- argp->hdr.size == 0 ? NULL : &argp->hdr,
- argp->dbt.size == 0 ? NULL : &argp->dbt)) != 0)
- goto out;
-
- change = DB_MPOOL_DIRTY;
-
- } else if ((cmp_n == 0 && !redo && argp->opcode == DB_ADD_DUP) ||
- (cmp_p == 0 && redo && argp->opcode == DB_REM_DUP)) {
- /* Need to undo an add, or redo a delete. */
- if ((ret = __db_ditem(dbc,
- pagep, argp->indx, argp->nbytes)) != 0)
- goto out;
- change = DB_MPOOL_DIRTY;
- }
-
- if (change) {
- if (redo)
- LSN(pagep) = *lsnp;
- else
- LSN(pagep) = argp->pagelsn;
- }
-
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * PUBLIC: int __db_split_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_split_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_split_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int change, cmp_n, cmp_p, ret;
-
- REC_PRINT(__db_split_print);
- REC_INTRO(__db_split_read);
-
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else
- if ((ret = memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- /*
- * There are two types of log messages here, one for the old page
- * and one for the new pages created. The original image in the
- * SPLITOLD record is used for undo. The image in the SPLITNEW
- * is used for redo. We should never have a case where there is
- * a redo operation and the SPLITOLD record is on disk, but not
- * the SPLITNEW record. Therefore, we only redo NEW messages
- * and only undo OLD messages.
- */
-
- change = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- if (cmp_p == 0 && redo) {
- if (argp->opcode == DB_SPLITNEW) {
- /* Need to redo the split described. */
- memcpy(pagep,
- argp->pageimage.data, argp->pageimage.size);
- }
- LSN(pagep) = *lsnp;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && !redo) {
- if (argp->opcode == DB_SPLITOLD) {
- /* Put back the old image. */
- memcpy(pagep,
- argp->pageimage.data, argp->pageimage.size);
- }
- LSN(pagep) = argp->pagelsn;
- change = DB_MPOOL_DIRTY;
- }
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * PUBLIC: int __db_big_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_big_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_big_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- REC_PRINT(__db_big_print);
- REC_INTRO(__db_big_read);
-
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto ppage;
- } else
- if ((ret = memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- /*
- * There are three pages we need to check. The one on which we are
- * adding data, the previous one whose next_pointer may have
- * been updated, and the next one whose prev_pointer may have
- * been updated.
- */
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- change = 0;
- if ((cmp_p == 0 && redo && argp->opcode == DB_ADD_BIG) ||
- (cmp_n == 0 && !redo && argp->opcode == DB_REM_BIG)) {
- /* We are either redo-ing an add, or undoing a delete. */
- P_INIT(pagep, file_dbp->pgsize, argp->pgno, argp->prev_pgno,
- argp->next_pgno, 0, P_OVERFLOW);
- OV_LEN(pagep) = argp->dbt.size;
- OV_REF(pagep) = 1;
- memcpy((u_int8_t *)pagep + P_OVERHEAD, argp->dbt.data,
- argp->dbt.size);
- PREV_PGNO(pagep) = argp->prev_pgno;
- change = DB_MPOOL_DIRTY;
- } else if ((cmp_n == 0 && !redo && argp->opcode == DB_ADD_BIG) ||
- (cmp_p == 0 && redo && argp->opcode == DB_REM_BIG)) {
- /*
- * We are either undo-ing an add or redo-ing a delete.
- * The page is about to be reclaimed in either case, so
- * there really isn't anything to do here.
- */
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = redo ? *lsnp : argp->pagelsn;
-
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
-
- /* Now check the previous page. */
-ppage: if (argp->prev_pgno != PGNO_INVALID) {
- change = 0;
- if ((ret = memp_fget(mpf, &argp->prev_pgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- *lsnp = argp->prev_lsn;
- ret = 0;
- goto npage;
- } else
- if ((ret = memp_fget(mpf, &argp->prev_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
-
- if ((cmp_p == 0 && redo && argp->opcode == DB_ADD_BIG) ||
- (cmp_n == 0 && !redo && argp->opcode == DB_REM_BIG)) {
- /* Redo add, undo delete. */
- NEXT_PGNO(pagep) = argp->pgno;
- change = DB_MPOOL_DIRTY;
- } else if ((cmp_n == 0 &&
- !redo && argp->opcode == DB_ADD_BIG) ||
- (cmp_p == 0 && redo && argp->opcode == DB_REM_BIG)) {
- /* Redo delete, undo add. */
- NEXT_PGNO(pagep) = argp->next_pgno;
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = redo ? *lsnp : argp->prevlsn;
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
- }
-
- /* Now check the next page. Can only be set on a delete. */
-npage: if (argp->next_pgno != PGNO_INVALID) {
- change = 0;
- if ((ret = memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- goto done;
- } else
- if ((ret = memp_fget(mpf, &argp->next_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
- if (cmp_p == 0 && redo) {
- PREV_PGNO(pagep) = PGNO_INVALID;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && !redo) {
- PREV_PGNO(pagep) = argp->pgno;
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = redo ? *lsnp : argp->nextlsn;
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
- }
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __db_ovref_recover --
- * Recovery function for __db_ovref().
- *
- * PUBLIC: int __db_ovref_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_ovref_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_ovref_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int modified, ret;
-
- REC_PRINT(__db_ovref_print);
- REC_INTRO(__db_ovref_read);
-
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
-
- modified = 0;
- if (log_compare(&LSN(pagep), &argp->lsn) == 0 && redo) {
- /* Need to redo update described. */
- OV_REF(pagep) += argp->adjust;
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (log_compare(lsnp, &LSN(pagep)) == 0 && !redo) {
- /* Need to undo update described. */
- OV_REF(pagep) -= argp->adjust;
-
- pagep->lsn = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __db_relink_recover --
- * Recovery function for relink.
- *
- * PUBLIC: int __db_relink_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_relink_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_relink_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret;
-
- REC_PRINT(__db_relink_print);
- REC_INTRO(__db_relink_read);
-
- /*
- * There are up to three pages we need to check -- the page, and the
- * previous and next pages, if they existed. For a page add operation,
- * the current page is the result of a split and is being recovered
- * elsewhere, so all we need do is recover the next page.
- */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (redo) {
- (void)__db_pgerr(file_dbp, argp->pgno);
- goto out;
- }
- goto next;
- }
- if (argp->opcode == DB_ADD_PAGE)
- goto next;
-
- modified = 0;
- if (log_compare(&LSN(pagep), &argp->lsn) == 0 && redo) {
- /* Redo the relink. */
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (log_compare(lsnp, &LSN(pagep)) == 0 && !redo) {
- /* Undo the relink. */
- pagep->next_pgno = argp->next;
- pagep->prev_pgno = argp->prev;
-
- pagep->lsn = argp->lsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-next: if ((ret = memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
- if (redo) {
- (void)__db_pgerr(file_dbp, argp->next);
- goto out;
- }
- goto prev;
- }
- modified = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn_next);
- if ((argp->opcode == DB_REM_PAGE && cmp_p == 0 && redo) ||
- (argp->opcode == DB_ADD_PAGE && cmp_n == 0 && !redo)) {
- /* Redo the remove or undo the add. */
- pagep->prev_pgno = argp->prev;
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if ((argp->opcode == DB_REM_PAGE && cmp_n == 0 && !redo) ||
- (argp->opcode == DB_ADD_PAGE && cmp_p == 0 && redo)) {
- /* Undo the remove or redo the add. */
- pagep->prev_pgno = argp->pgno;
-
- pagep->lsn = argp->lsn_next;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- if (argp->opcode == DB_ADD_PAGE)
- goto done;
-
-prev: if ((ret = memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
- if (redo) {
- (void)__db_pgerr(file_dbp, argp->prev);
- goto out;
- }
- goto done;
- }
- modified = 0;
- if (log_compare(&LSN(pagep), &argp->lsn_prev) == 0 && redo) {
- /* Redo the relink. */
- pagep->next_pgno = argp->next;
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (log_compare(lsnp, &LSN(pagep)) == 0 && !redo) {
- /* Undo the relink. */
- pagep->next_pgno = argp->pgno;
-
- pagep->lsn = argp->lsn_prev;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * PUBLIC: int __db_addpage_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_addpage_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_addpage_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- REC_PRINT(__db_addpage_print);
- REC_INTRO(__db_addpage_read);
-
- /*
- * We need to check two pages: the old one and the new one onto
- * which we're going to add duplicates. Do the old one first.
- */
- if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0)
- goto out;
-
- change = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- if (cmp_p == 0 && redo) {
- NEXT_PGNO(pagep) = argp->nextpgno;
-
- LSN(pagep) = *lsnp;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && !redo) {
- NEXT_PGNO(pagep) = PGNO_INVALID;
-
- LSN(pagep) = argp->lsn;
- change = DB_MPOOL_DIRTY;
- }
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
-
- if ((ret = memp_fget(mpf, &argp->nextpgno, 0, &pagep)) != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else
- if ((ret = memp_fget(mpf,
- &argp->nextpgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- change = 0;
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
- if (cmp_p == 0 && redo) {
- PREV_PGNO(pagep) = argp->pgno;
-
- LSN(pagep) = *lsnp;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && !redo) {
- PREV_PGNO(pagep) = PGNO_INVALID;
-
- LSN(pagep) = argp->nextlsn;
- change = DB_MPOOL_DIRTY;
- }
- if ((ret = memp_fput(mpf, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-}
-
-/*
- * __db_debug_recover --
- * Recovery function for debug.
- *
- * PUBLIC: int __db_debug_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__db_debug_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __db_debug_args *argp;
- int ret;
-
- COMPQUIET(redo, 0);
- COMPQUIET(logp, NULL);
-
- REC_PRINT(__db_debug_print);
- REC_NOOP_INTRO(__db_debug_read);
-
- *lsnp = argp->prev_lsn;
- ret = 0;
-
- REC_NOOP_CLOSE;
-}
diff --git a/db2/db/db_ret.c b/db2/db/db_ret.c
deleted file mode 100644
index 9f0d0ec..0000000
--- a/db2/db/db_ret.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)db_ret.c 10.16 (Sleepycat) 10/4/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "db_am.h"
-
-/*
- * __db_ret --
- * Build return DBT.
- *
- * PUBLIC: int __db_ret __P((DB *,
- * PUBLIC: PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
- */
-int
-__db_ret(dbp, h, indx, dbt, memp, memsize)
- DB *dbp;
- PAGE *h;
- u_int32_t indx;
- DBT *dbt;
- void **memp;
- u_int32_t *memsize;
-{
- BKEYDATA *bk;
- HOFFPAGE ho;
- BOVERFLOW *bo;
- u_int32_t len;
- u_int8_t *hk;
- void *data;
-
- switch (TYPE(h)) {
- case P_HASH:
- hk = P_ENTRY(h, indx);
- if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
- memcpy(&ho, hk, sizeof(HOFFPAGE));
- return (__db_goff(dbp, dbt,
- ho.tlen, ho.pgno, memp, memsize));
- }
- len = LEN_HKEYDATA(h, dbp->pgsize, indx);
- data = HKEYDATA_DATA(hk);
- break;
- case P_DUPLICATE:
- case P_LBTREE:
- case P_LRECNO:
- bk = GET_BKEYDATA(h, indx);
- if (B_TYPE(bk->type) == B_OVERFLOW) {
- bo = (BOVERFLOW *)bk;
- return (__db_goff(dbp, dbt,
- bo->tlen, bo->pgno, memp, memsize));
- }
- len = bk->len;
- data = bk->data;
- break;
- default:
- return (__db_pgfmt(dbp, h->pgno));
- }
-
- return (__db_retcopy(dbt, data, len, memp, memsize,
- F_ISSET(dbt, DB_DBT_INTERNAL) ? NULL : dbp->db_malloc));
-}
-
-/*
- * __db_retcopy --
- * Copy the returned data into the user's DBT, handling special flags.
- *
- * PUBLIC: int __db_retcopy __P((DBT *,
- * PUBLIC: void *, u_int32_t, void **, u_int32_t *, void *(*)(size_t)));
- */
-int
-__db_retcopy(dbt, data, len, memp, memsize, db_malloc)
- DBT *dbt;
- void *data;
- u_int32_t len;
- void **memp;
- u_int32_t *memsize;
- void *(*db_malloc) __P((size_t));
-{
- int ret;
-
- /* If returning a partial record, reset the length. */
- if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
- data = (u_int8_t *)data + dbt->doff;
- if (len > dbt->doff) {
- len -= dbt->doff;
- if (len > dbt->dlen)
- len = dbt->dlen;
- } else
- len = 0;
- }
-
- /*
- * Return the length of the returned record in the DBT size field.
- * This satisfies the requirement that if we're using user memory
- * and insufficient memory was provided, return the amount necessary
- * in the size field.
- */
- dbt->size = len;
-
- /*
- * Allocate memory to be owned by the application: DB_DBT_MALLOC.
- *
- * !!!
- * We always allocate memory, even if we're copying out 0 bytes. This
- * guarantees consistency, i.e., the application can always free memory
- * without concern as to how many bytes of the record were requested.
- *
- * Use the memory specified by the application: DB_DBT_USERMEM.
- *
- * !!!
- * If the length we're going to copy is 0, the application-supplied
- * memory pointer is allowed to be NULL.
- */
- if (F_ISSET(dbt, DB_DBT_MALLOC)) {
- if ((ret = __os_malloc(len, db_malloc, &dbt->data)) != 0)
- return (ret);
- } else if (F_ISSET(dbt, DB_DBT_USERMEM)) {
- if (len != 0 && (dbt->data == NULL || dbt->ulen < len))
- return (ENOMEM);
- } else if (memp == NULL || memsize == NULL) {
- return (EINVAL);
- } else {
- if (len != 0 && (*memsize == 0 || *memsize < len)) {
- if ((ret = __os_realloc(memp, len)) != 0) {
- *memsize = 0;
- return (ret);
- }
- *memsize = len;
- }
- dbt->data = *memp;
- }
-
- if (len != 0)
- memcpy(dbt->data, data, len);
- return (0);
-}
diff --git a/db2/db185/db185.c b/db2/db185/db185.c
deleted file mode 100644
index 739ada8..0000000
--- a/db2/db185/db185.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db185.c 8.21 (Sleepycat) 11/22/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db185_int.h"
-#include "common_ext.h"
-
-#ifndef STDERR_FILENO
-#define STDERR_FILENO 2
-#endif
-
-static int db185_close __P((DB185 *));
-static int db185_del __P((const DB185 *, const DBT185 *, u_int));
-static int db185_fd __P((const DB185 *));
-static int db185_get __P((const DB185 *, const DBT185 *, DBT185 *, u_int));
-static int db185_put __P((const DB185 *, DBT185 *, const DBT185 *, u_int));
-static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int));
-static int db185_sync __P((const DB185 *, u_int));
-
-DB185 *
-dbopen(file, oflags, mode, type, openinfo)
- const char *file;
- int oflags, mode;
- DBTYPE type;
- const void *openinfo;
-{
- const BTREEINFO *bi;
- const HASHINFO *hi;
- const RECNOINFO *ri;
- DB *dbp;
- DB185 *db185p;
- DB_INFO dbinfo, *dbinfop;
- ssize_t nw;
- int fd, s_errno;
-
- if ((errno = __os_calloc(1, sizeof(DB185), &db185p)) != 0)
- return (NULL);
- dbinfop = NULL;
- memset(&dbinfo, 0, sizeof(dbinfo));
-
- /*
- * !!!
- * The DBTYPE enum wasn't initialized in DB 185, so it's off-by-one
- * from DB 2.0.
- */
- switch (type) {
- case 0: /* DB_BTREE */
- type = DB_BTREE;
- if ((bi = openinfo) != NULL) {
- dbinfop = &dbinfo;
- if (bi->flags & ~R_DUP)
- goto einval;
- if (bi->flags & R_DUP)
- dbinfop->flags |= DB_DUP;
- dbinfop->db_cachesize = bi->cachesize;
- dbinfop->bt_maxkey = bi->maxkeypage;
- dbinfop->bt_minkey = bi->minkeypage;
- dbinfop->db_pagesize = bi->psize;
- /*
- * !!!
- * Comparisons and prefix calls work because the DBT
- * structures in 1.85 and 2.0 have the same initial
- * fields.
- */
- dbinfop->bt_compare = bi->compare;
- dbinfop->bt_prefix = bi->prefix;
- dbinfop->db_lorder = bi->lorder;
- }
- break;
- case 1: /* DB_HASH */
- type = DB_HASH;
- if ((hi = openinfo) != NULL) {
- dbinfop = &dbinfo;
- dbinfop->db_pagesize = hi->bsize;
- dbinfop->h_ffactor = hi->ffactor;
- dbinfop->h_nelem = hi->nelem;
- dbinfop->db_cachesize = hi->cachesize;
- dbinfop->h_hash = (u_int32_t (*)
- __P((const void *, u_int32_t)))hi->hash;
- dbinfop->db_lorder = hi->lorder;
- }
-
- break;
- case 2: /* DB_RECNO */
- type = DB_RECNO;
- dbinfop = &dbinfo;
-
- /* DB 1.85 did renumbering by default. */
- dbinfop->flags |= DB_RENUMBER;
-
- /*
- * !!!
- * The file name given to DB 1.85 recno is the name of the DB
- * 2.0 backing file. If the file doesn't exist, create it if
- * the user has the O_CREAT flag set, DB 1.85 did it for you,
- * and DB 2.0 doesn't.
- *
- * !!!
- * Setting the file name to NULL specifies that we're creating
- * a temporary backing file, in DB 2.X. If we're opening the
- * DB file read-only, change the flags to read-write, because
- * temporary backing files cannot be opened read-only, and DB
- * 2.X will return an error. We are cheating here -- if the
- * application does a put on the database, it will succeed --
- * although that would be a stupid thing for the application
- * to do.
- *
- * !!!
- * Note, the file name in DB 1.85 was a const -- we don't do
- * that in DB 2.0, so do that cast.
- */
- if (file != NULL) {
- if (oflags & O_CREAT && __os_exists(file, NULL) != 0)
- if (__os_open(file, oflags, mode, &fd) == 0)
- (void)__os_close(fd);
- dbinfop->re_source = (char *)file;
-
- if (O_RDONLY)
- oflags &= ~O_RDONLY;
- oflags |= O_RDWR;
- file = NULL;
- }
-
- if ((ri = openinfo) != NULL) {
- /*
- * !!!
- * We can't support the bfname field.
- */
-#define BFMSG "DB: DB 1.85's recno bfname field is not supported.\n"
- if (ri->bfname != NULL) {
- (void)__os_write(STDERR_FILENO,
- BFMSG, sizeof(BFMSG) - 1, &nw);
- goto einval;
- }
-
- if (ri->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
- goto einval;
- if (ri->flags & R_FIXEDLEN) {
- dbinfop->flags |= DB_FIXEDLEN;
- if (ri->bval != 0) {
- dbinfop->flags |= DB_PAD;
- dbinfop->re_pad = ri->bval;
- }
- } else
- if (ri->bval != 0) {
- dbinfop->flags |= DB_DELIMITER;
- dbinfop->re_delim = ri->bval;
- }
-
- /*
- * !!!
- * We ignore the R_NOKEY flag, but that's okay, it was
- * only an optimization that was never implemented.
- */
-
- if (ri->flags & R_SNAPSHOT)
- dbinfop->flags |= DB_SNAPSHOT;
-
- dbinfop->db_cachesize = ri->cachesize;
- dbinfop->db_pagesize = ri->psize;
- dbinfop->db_lorder = ri->lorder;
- dbinfop->re_len = ri->reclen;
- }
- break;
- default:
- goto einval;
- }
-
- db185p->close = db185_close;
- db185p->del = db185_del;
- db185p->fd = db185_fd;
- db185p->get = db185_get;
- db185p->put = db185_put;
- db185p->seq = db185_seq;
- db185p->sync = db185_sync;
-
- /*
- * !!!
- * Store the returned pointer to the real DB 2.0 structure in the
- * internal pointer. Ugly, but we're not going for pretty, here.
- */
- if ((errno = db_open(file,
- type, __db_oflags(oflags), mode, NULL, dbinfop, &dbp)) != 0) {
- __os_free(db185p, sizeof(DB185));
- return (NULL);
- }
-
- /* Create the cursor used for sequential ops. */
- if ((errno = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc, 0)) != 0) {
- s_errno = errno;
- (void)dbp->close(dbp, 0);
- __os_free(db185p, sizeof(DB185));
- errno = s_errno;
- return (NULL);
- }
-
- db185p->internal = dbp;
- return (db185p);
-
-einval: __os_free(db185p, sizeof(DB185));
- errno = EINVAL;
- return (NULL);
-}
-
-static int
-db185_close(db185p)
- DB185 *db185p;
-{
- DB *dbp;
-
- dbp = (DB *)db185p->internal;
-
- errno = dbp->close(dbp, 0);
-
- __os_free(db185p, sizeof(DB185));
-
- return (errno == 0 ? 0 : -1);
-}
-
-static int
-db185_del(db185p, key185, flags)
- const DB185 *db185p;
- const DBT185 *key185;
- u_int flags;
-{
- DB *dbp;
- DBT key;
-
- dbp = (DB *)db185p->internal;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
-
- if (flags & ~R_CURSOR)
- goto einval;
- if (flags & R_CURSOR)
- errno = db185p->dbc->c_del(db185p->dbc, 0);
- else
- errno = dbp->del(dbp, NULL, &key, 0);
-
- switch (errno) {
- case 0:
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
- return (-1);
-
-einval: errno = EINVAL;
- return (-1);
-}
-
-static int
-db185_fd(db185p)
- const DB185 *db185p;
-{
- DB *dbp;
- int fd;
-
- dbp = (DB *)db185p->internal;
-
- return ((errno = dbp->fd(dbp, &fd)) == 0 ? fd : -1);
-}
-
-static int
-db185_get(db185p, key185, data185, flags)
- const DB185 *db185p;
- const DBT185 *key185;
- DBT185 *data185;
- u_int flags;
-{
- DB *dbp;
- DBT key, data;
-
- dbp = (DB *)db185p->internal;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- if (flags)
- goto einval;
-
- switch (errno = dbp->get(dbp, NULL, &key, &data, 0)) {
- case 0:
- data185->data = data.data;
- data185->size = data.size;
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
- return (-1);
-
-einval: errno = EINVAL;
- return (-1);
-}
-
-static int
-db185_put(db185p, key185, data185, flags)
- const DB185 *db185p;
- DBT185 *key185;
- const DBT185 *data185;
- u_int flags;
-{
- DB *dbp;
- DBC *dbcp_put;
- DBT key, data;
- int s_errno;
-
- dbp = (DB *)db185p->internal;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- switch (flags) {
- case 0:
- errno = dbp->put(dbp, NULL, &key, &data, 0);
- break;
- case R_CURSOR:
- errno =
- db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT);
- break;
- case R_IAFTER:
- case R_IBEFORE:
- if (dbp->type != DB_RECNO)
- goto einval;
-
- if ((errno = dbp->cursor(dbp, NULL, &dbcp_put, 0)) != 0)
- return (-1);
- if ((errno =
- dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) != 0) {
- s_errno = errno;
- (void)dbcp_put->c_close(dbcp_put);
- errno = s_errno;
- return (-1);
- }
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
- errno = dbcp_put->c_put(dbcp_put,
- &key, &data, flags == R_IAFTER ? DB_AFTER : DB_BEFORE);
- s_errno = errno;
- (void)dbcp_put->c_close(dbcp_put);
- errno = s_errno;
- break;
- case R_NOOVERWRITE:
- errno = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
- break;
- case R_SETCURSOR:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
-
- if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
- break;
- errno =
- db185p->dbc->c_get(db185p->dbc, &key, &data, DB_SET_RANGE);
- break;
- default:
- goto einval;
- }
-
- switch (errno) {
- case 0:
- key185->data = key.data;
- key185->size = key.size;
- return (0);
- case DB_KEYEXIST:
- return (1);
- }
- return (-1);
-
-einval: errno = EINVAL;
- return (-1);
-}
-
-static int
-db185_seq(db185p, key185, data185, flags)
- const DB185 *db185p;
- DBT185 *key185, *data185;
- u_int flags;
-{
- DB *dbp;
- DBT key, data;
-
- dbp = (DB *)db185p->internal;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- switch (flags) {
- case R_CURSOR:
- flags = DB_SET_RANGE;
- break;
- case R_FIRST:
- flags = DB_FIRST;
- break;
- case R_LAST:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
- flags = DB_LAST;
- break;
- case R_NEXT:
- flags = DB_NEXT;
- break;
- case R_PREV:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
- flags = DB_PREV;
- break;
- default:
- goto einval;
- }
- switch (errno = db185p->dbc->c_get(db185p->dbc, &key, &data, flags)) {
- case 0:
- key185->data = key.data;
- key185->size = key.size;
- data185->data = data.data;
- data185->size = data.size;
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
- return (-1);
-
-einval: errno = EINVAL;
- return (-1);
-}
-
-static int
-db185_sync(db185p, flags)
- const DB185 *db185p;
- u_int flags;
-{
- DB *dbp;
- ssize_t nw;
-
- dbp = (DB *)db185p->internal;
-
- switch (flags) {
- case 0:
- break;
- case R_RECNOSYNC:
- /*
- * !!!
- * We can't support the R_RECNOSYNC flag.
- */
-#define RSMSG "DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n"
- (void)__os_write(STDERR_FILENO, RSMSG, sizeof(RSMSG) - 1, &nw);
- goto einval;
- default:
- goto einval;
- }
-
- return ((errno = dbp->sync(dbp, 0)) == 0 ? 0 : -1);
-
-einval: errno = EINVAL;
- return (-1);
-}
diff --git a/db2/db185/db185_int.h b/db2/db185/db185_int.h
deleted file mode 100644
index f7d7af5..0000000
--- a/db2/db185/db185_int.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db185_int.h 8.7 (Sleepycat) 4/10/98
- */
-
-#ifndef _DB185_H_
-#define _DB185_H_
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT185;
-
-/* Access method description structure. */
-typedef struct __db185 {
- DBTYPE type; /* Underlying db type. */
- int (*close) __P((struct __db185 *));
- int (*del) __P((const struct __db185 *, const DBT185 *, u_int));
- int (*get)
- __P((const struct __db185 *, const DBT185 *, DBT185 *, u_int));
- int (*put)
- __P((const struct __db185 *, DBT185 *, const DBT185 *, u_int));
- int (*seq)
- __P((const struct __db185 *, DBT185 *, DBT185 *, u_int));
- int (*sync) __P((const struct __db185 *, u_int));
- void *internal; /* Access method private. */
- int (*fd) __P((const struct __db185 *));
-
- /*
- * !!!
- * Added to the end of the DB 1.85 DB structure, it's needed to
- * hold the DB 2.0 cursor used for DB 1.85 sequential operations.
- */
- DBC *dbc; /* DB 1.85 sequential cursor. */
-} DB185;
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t maxkeypage; /* maximum keys per page */
- u_int32_t minkeypage; /* minimum keys per page */
- u_int32_t psize; /* page size */
- int (*compare) /* comparison function */
- __P((const DBT *, const DBT *));
- size_t (*prefix) /* prefix function */
- __P((const DBT *, const DBT *));
- int lorder; /* byte order */
-} BTREEINFO;
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int32_t bsize; /* bucket size */
- u_int32_t ffactor; /* fill factor */
- u_int32_t nelem; /* number of elements */
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) __P((const void *, size_t));
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-DB185 *__dbopen __P((const char *, int, int, DBTYPE, const void *));
-DB185 *dbopen __P((const char *, int, int, DBTYPE, const void *));
-#if defined(__cplusplus)
-};
-#endif
-#endif /* !_DB185_H_ */
diff --git a/db2/db_185.h b/db2/db_185.h
deleted file mode 100644
index 456a8b4..0000000
--- a/db2/db_185.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db_185.h.src 8.7 (Sleepycat) 4/10/98
- */
-
-#ifndef _DB_185_H_
-#define _DB_185_H_
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-/*
- * XXX
- * Handle function prototypes and the keyword "const". This steps on name
- * space that DB doesn't control, but all of the other solutions are worse.
- */
-#undef __P
-#if defined(__STDC__) || defined(__cplusplus)
-#define __P(protos) protos /* ANSI C prototypes */
-#else
-#define const
-#define __P(protos) () /* K&R C preprocessor */
-#endif
-
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-@u_int8_decl@
-@int16_decl@
-@u_int16_decl@
-@int32_decl@
-@u_int32_decl@
-#endif
-
-/*
- * XXX
- * SGI/IRIX already has a pgno_t.
- */
-#ifdef sgi
-#define pgno_t db_pgno_t
-#endif
-
-#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
-typedef u_int32_t pgno_t;
-#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
-typedef u_int16_t indx_t;
-#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
-typedef u_int32_t recno_t;
-
-/* Key/data structure -- a Data-Base Thang. */
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT;
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-/* Access method description structure. */
-typedef struct __db {
- DBTYPE type; /* Underlying db type. */
- int (*close) (struct __db *);
- int (*del) (const struct __db *, const DBT *, u_int);
- int (*get) (const struct __db *, const DBT *, DBT *, u_int);
- int (*put) (const struct __db *, DBT *, const DBT *, u_int);
- int (*seq) (const struct __db *, DBT *, DBT *, u_int);
- int (*sync) (const struct __db *, u_int);
- void *internal; /* Access method private. */
- int (*fd) (const struct __db *);
-} DB;
-
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t maxkeypage; /* maximum keys per page */
- u_int32_t minkeypage; /* minimum keys per page */
- u_int32_t psize; /* page size */
- int (*compare) /* comparison function */
- (const DBT *, const DBT *);
- size_t (*prefix) /* prefix function */
- (const DBT *, const DBT *);
- int lorder; /* byte order */
-} BTREEINFO;
-
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int32_t bsize; /* bucket size */
- u_int32_t ffactor; /* fill factor */
- u_int32_t nelem; /* number of elements */
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) (const void *, size_t);
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-DB *dbopen (const char *, int, int, DBTYPE, const void *);
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* !_DB_185_H_ */
diff --git a/db2/db_int.h b/db2/db_int.h
deleted file mode 100644
index 228c7ab..0000000
--- a/db2/db_int.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_int.h 10.77 (Sleepycat) 1/3/99
- */
-
-#ifndef _DB_INTERNAL_H_
-#define _DB_INTERNAL_H_
-
-#include <db.h> /* Standard DB include file. */
-#include "queue.h"
-#include "shqueue.h"
-
-/*******************************************************
- * General purpose constants and macros.
- *******************************************************/
-#define UINT16_T_MAX 0xffff /* Maximum 16 bit unsigned. */
-#define UINT32_T_MAX 0xffffffff /* Maximum 32 bit unsigned. */
-
-#define DB_MIN_PGSIZE 0x000200 /* Minimum page size. */
-#define DB_MAX_PGSIZE 0x010000 /* Maximum page size. */
-
-#define DB_MINCACHE 10 /* Minimum cached pages */
-
-#define MEGABYTE 1048576
-
-/*
- * If we are unable to determine the underlying filesystem block size, use
- * 8K on the grounds that most OS's use less than 8K as their VM page size.
- */
-#define DB_DEF_IOSIZE (8 * 1024)
-
-/*
- * Aligning items to particular sizes or in pages or memory. ALIGNP is a
- * separate macro, as we've had to cast the pointer to different integral
- * types on different architectures.
- *
- * We cast pointers into unsigned longs when manipulating them because C89
- * guarantees that u_long is the largest available integral type and further,
- * to never generate overflows. However, neither C89 or C9X requires that
- * any integer type be large enough to hold a pointer, although C9X created
- * the intptr_t type, which is guaranteed to hold a pointer but may or may
- * not exist. At some point in the future, we should test for intptr_t and
- * use it where available.
- */
-#undef ALIGNTYPE
-#define ALIGNTYPE u_long
-#undef ALIGNP
-#define ALIGNP(value, bound) ALIGN((ALIGNTYPE)value, bound)
-#undef ALIGN
-#define ALIGN(value, bound) (((value) + (bound) - 1) & ~((bound) - 1))
-
-/*
- * There are several on-page structures that are declared to have a number of
- * fields followed by a variable length array of items. The structure size
- * without including the variable length array or the address of the first of
- * those elements can be found using SSZ.
- *
- * This macro can also be used to find the offset of a structure element in a
- * structure. This is used in various places to copy structure elements from
- * unaligned memory references, e.g., pointers into a packed page.
- *
- * There are two versions because compilers object if you take the address of
- * an array.
- */
-#undef SSZ
-#define SSZ(name, field) ((int)&(((name *)0)->field))
-
-#undef SSZA
-#define SSZA(name, field) ((int)&(((name *)0)->field[0]))
-
-/* Macros to return per-process address, offsets based on shared regions. */
-#define R_ADDR(base, offset) ((void *)((u_int8_t *)((base)->addr) + offset))
-#define R_OFFSET(base, p) ((u_int8_t *)(p) - (u_int8_t *)(base)->addr)
-
-#define DB_DEFAULT 0x000000 /* No flag was specified. */
-
-/* Structure used to print flag values. */
-typedef struct __fn {
- u_int32_t mask; /* Flag value. */
- const char *name; /* Flag name. */
-} FN;
-
-/* Set, clear and test flags. */
-#define F_SET(p, f) (p)->flags |= (f)
-#define F_CLR(p, f) (p)->flags &= ~(f)
-#define F_ISSET(p, f) ((p)->flags & (f))
-#define LF_SET(f) (flags |= (f))
-#define LF_CLR(f) (flags &= ~(f))
-#define LF_ISSET(f) (flags & (f))
-
-/*
- * Panic check:
- * All interfaces check the panic flag, if it's set, the tree is dead.
- */
-#define DB_PANIC_CHECK(dbp) { \
- if ((dbp)->dbenv != NULL && (dbp)->dbenv->db_panic != 0) \
- return (DB_RUNRECOVERY); \
-}
-
-/* Display separator string. */
-#undef DB_LINE
-#define DB_LINE "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
-
-/* Unused, or not-used-yet variable. "Shut that bloody compiler up!" */
-#define COMPQUIET(n, v) (n) = (v)
-
-/*
- * Purify and similar run-time tools complain about unitialized reads/writes
- * for structure fields whose only purpose is padding.
- */
-#define UMRW(v) (v) = 0
-
-/*
- * Win16 needs specific syntax on callback functions. Nobody else cares.
- */
-#ifndef DB_CALLBACK
-#define DB_CALLBACK /* Nothing. */
-#endif
-
-/*******************************************************
- * Files.
- *******************************************************/
- /*
- * We use 1024 as the maximum path length. It's too hard to figure out what
- * the real path length is, as it was traditionally stored in <sys/param.h>,
- * and that file isn't always available.
- */
-#undef MAXPATHLEN
-#define MAXPATHLEN 1024
-
-#define PATH_DOT "." /* Current working directory. */
-#define PATH_SEPARATOR "/" /* Path separator character. */
-
-/*******************************************************
- * Mutex support.
- *******************************************************/
-typedef u_int32_t tsl_t;
-
-/*
- * !!!
- * Various systems require different alignments for mutexes (the worst we've
- * seen so far is 16-bytes on some HP architectures). The mutex (tsl_t) must
- * be first in the db_mutex_t structure, which must itself be first in the
- * region. This ensures the alignment is as returned by mmap(2), which should
- * be sufficient. All other mutex users must ensure proper alignment locally.
- */
-#define MUTEX_ALIGNMENT 1
-
-/*
- * The offset of a mutex in memory.
- *
- * !!!
- * Not an off_t, so backing file offsets MUST be less than 4Gb. See the
- * off field of the db_mutex_t as well.
- */
-#define MUTEX_LOCK_OFFSET(a, b) ((u_int32_t)((u_int8_t *)b - (u_int8_t *)a))
-
-typedef struct _db_mutex_t {
-#ifdef HAVE_SPINLOCKS
- tsl_t tsl_resource; /* Resource test and set. */
-#ifdef DIAGNOSTIC
- u_int32_t pid; /* Lock holder: 0 or process pid. */
-#endif
-#else
- u_int32_t off; /* Backing file offset. */
- u_int32_t pid; /* Lock holder: 0 or process pid. */
-#endif
- u_int32_t spins; /* Spins before block. */
- u_int32_t mutex_set_wait; /* Granted after wait. */
- u_int32_t mutex_set_nowait; /* Granted without waiting. */
-} db_mutex_t;
-
-#include "mutex_ext.h"
-
-/*******************************************************
- * Access methods.
- *******************************************************/
-/* Lock/unlock a DB thread. */
-#define DB_THREAD_LOCK(dbp) \
- if (F_ISSET(dbp, DB_AM_THREAD)) \
- (void)__db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1);
-#define DB_THREAD_UNLOCK(dbp) \
- if (F_ISSET(dbp, DB_AM_THREAD)) \
- (void)__db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1);
-
-/*******************************************************
- * Environment.
- *******************************************************/
-/* Type passed to __db_appname(). */
-typedef enum {
- DB_APP_NONE=0, /* No type (region). */
- DB_APP_DATA, /* Data file. */
- DB_APP_LOG, /* Log file. */
- DB_APP_TMP /* Temporary file. */
-} APPNAME;
-
-/*******************************************************
- * Shared memory regions.
- *******************************************************/
-/*
- * The shared memory regions share an initial structure so that the general
- * region code can handle races between the region being deleted and other
- * processes waiting on the region mutex.
- *
- * !!!
- * Note, the mutex must be the first entry in the region; see comment above.
- */
-typedef struct _rlayout {
- db_mutex_t lock; /* Region mutex. */
-#define DB_REGIONMAGIC 0x120897
- u_int32_t valid; /* Valid magic number. */
- u_int32_t refcnt; /* Region reference count. */
- size_t size; /* Region length. */
- int majver; /* Major version number. */
- int minver; /* Minor version number. */
- int patch; /* Patch version number. */
- int panic; /* Region is dead. */
-#define INVALID_SEGID -1
- int segid; /* shmget(2) ID, or Win16 segment ID. */
-
-#define REGION_ANONYMOUS 0x01 /* Region is/should be in anon mem. */
- u_int32_t flags;
-} RLAYOUT;
-
-/*
- * DB creates all regions on 4K boundaries out of sheer paranoia, so that
- * we don't make the underlying VM unhappy.
- */
-#define DB_VMPAGESIZE (4 * 1024)
-#define DB_ROUNDOFF(n, round) { \
- (n) += (round) - 1; \
- (n) -= (n) % (round); \
-}
-
-/*
- * The interface to region attach is nasty, there is a lot of complex stuff
- * going on, which has to be retained between create/attach and detach. The
- * REGINFO structure keeps track of it.
- */
-struct __db_reginfo; typedef struct __db_reginfo REGINFO;
-struct __db_reginfo {
- /* Arguments. */
- DB_ENV *dbenv; /* Region naming info. */
- APPNAME appname; /* Region naming info. */
- char *path; /* Region naming info. */
- const char *file; /* Region naming info. */
- int mode; /* Region mode, if a file. */
- size_t size; /* Region size. */
- u_int32_t dbflags; /* Region file open flags, if a file. */
-
- /* Results. */
- char *name; /* Region name. */
- void *addr; /* Region address. */
- int fd; /* Fcntl(2) locking file descriptor.
- NB: this is only valid if a regular
- file is backing the shared region,
- and mmap(2) is being used to map it
- into our address space. */
- int segid; /* shmget(2) ID, or Win16 segment ID. */
- void *wnt_handle; /* Win/NT HANDLE. */
-
- /* Shared flags. */
-/* 0x0001 COMMON MASK with RLAYOUT structure. */
-#define REGION_CANGROW 0x0002 /* Can grow. */
-#define REGION_CREATED 0x0004 /* Created. */
-#define REGION_HOLDINGSYS 0x0008 /* Holding system resources. */
-#define REGION_LASTDETACH 0x0010 /* Delete on last detach. */
-#define REGION_MALLOC 0x0020 /* Created in malloc'd memory. */
-#define REGION_PRIVATE 0x0040 /* Private to thread/process. */
-#define REGION_REMOVED 0x0080 /* Already deleted. */
-#define REGION_SIZEDEF 0x0100 /* Use default region size if exists. */
- u_int32_t flags;
-};
-
-/*******************************************************
- * Mpool.
- *******************************************************/
-/*
- * File types for DB access methods. Negative numbers are reserved to DB.
- */
-#define DB_FTYPE_BTREE -1 /* Btree. */
-#define DB_FTYPE_HASH -2 /* Hash. */
-
-/* Structure used as the DB pgin/pgout pgcookie. */
-typedef struct __dbpginfo {
- size_t db_pagesize; /* Underlying page size. */
- int needswap; /* If swapping required. */
-} DB_PGINFO;
-
-/*******************************************************
- * Log.
- *******************************************************/
-/* Initialize an LSN to 'zero'. */
-#define ZERO_LSN(LSN) { \
- (LSN).file = 0; \
- (LSN).offset = 0; \
-}
-
-/* Return 1 if LSN is a 'zero' lsn, otherwise return 0. */
-#define IS_ZERO_LSN(LSN) ((LSN).file == 0)
-
-/* Test if we need to log a change. */
-#define DB_LOGGING(dbc) \
- (F_ISSET((dbc)->dbp, DB_AM_LOGGING) && !F_ISSET(dbc, DBC_RECOVER))
-
-#ifdef DIAGNOSTIC
-/*
- * Debugging macro to log operations.
- * If DEBUG_WOP is defined, log operations that modify the database.
- * If DEBUG_ROP is defined, log operations that read the database.
- *
- * D dbp
- * T txn
- * O operation (string)
- * K key
- * A data
- * F flags
- */
-#define LOG_OP(C, T, O, K, A, F) { \
- DB_LSN _lsn; \
- DBT _op; \
- if (DB_LOGGING((C))) { \
- memset(&_op, 0, sizeof(_op)); \
- _op.data = O; \
- _op.size = strlen(O) + 1; \
- (void)__db_debug_log((C)->dbp->dbenv->lg_info, \
- T, &_lsn, 0, &_op, (C)->dbp->log_fileid, K, A, F); \
- } \
-}
-#ifdef DEBUG_ROP
-#define DEBUG_LREAD(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F)
-#else
-#define DEBUG_LREAD(C, T, O, K, A, F)
-#endif
-#ifdef DEBUG_WOP
-#define DEBUG_LWRITE(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F)
-#else
-#define DEBUG_LWRITE(C, T, O, K, A, F)
-#endif
-#else
-#define DEBUG_LREAD(C, T, O, K, A, F)
-#define DEBUG_LWRITE(C, T, O, K, A, F)
-#endif /* DIAGNOSTIC */
-
-/*******************************************************
- * Transactions and recovery.
- *******************************************************/
-/*
- * Out of band value for a lock. The locks are returned to callers as offsets
- * into the lock regions. Since the RLAYOUT structure begins all regions, an
- * offset of 0 is guaranteed not to be a valid lock.
- */
-#define LOCK_INVALID 0
-
-/* The structure allocated for every transaction. */
-struct __db_txn {
- DB_TXNMGR *mgrp; /* Pointer to transaction manager. */
- DB_TXN *parent; /* Pointer to transaction's parent. */
- DB_LSN last_lsn; /* Lsn of last log write. */
- u_int32_t txnid; /* Unique transaction id. */
- size_t off; /* Detail structure within region. */
- TAILQ_ENTRY(__db_txn) links; /* Links transactions off manager. */
- TAILQ_HEAD(__kids, __db_txn) kids; /* Child transactions. */
- TAILQ_ENTRY(__db_txn) klinks; /* Links child transactions. */
-
-#define TXN_MALLOC 0x01 /* Structure allocated by TXN system. */
- u_int32_t flags;
-};
-
-/*******************************************************
- * Global variables.
- *******************************************************/
-/*
- * !!!
- * Initialized in os/os_config.c, don't change this unless you change it
- * as well.
- */
-
-struct __rmname {
- char *dbhome;
- int rmid;
- TAILQ_ENTRY(__rmname) links;
-};
-
-typedef struct __db_globals {
- int db_mutexlocks; /* DB_MUTEXLOCKS */
- int db_pageyield; /* DB_PAGEYIELD */
- int db_region_anon; /* DB_REGION_ANON, DB_REGION_NAME */
- int db_region_init; /* DB_REGION_INIT */
- int db_tsl_spins; /* DB_TSL_SPINS */
- /* XA: list of opened environments. */
- TAILQ_HEAD(__db_envq, __db_env) db_envq;
- /* XA: list of id to dbhome mappings. */
- TAILQ_HEAD(__db_nameq, __rmname) db_nameq;
-} DB_GLOBALS;
-
-extern DB_GLOBALS __db_global_values;
-#define DB_GLOBAL(v) __db_global_values.v
-
-#include "os.h"
-#include "os_ext.h"
-
-#endif /* !_DB_INTERNAL_H_ */
diff --git a/db2/hash/hash.c b/db2/hash/hash.c
deleted file mode 100644
index 0d202fc..0000000
--- a/db2/hash/hash.c
+++ /dev/null
@@ -1,1337 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * Margo Seltzer. All rights reserved.
- */
-/*
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash.c 10.63 (Sleepycat) 12/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_am.h"
-#include "db_ext.h"
-#include "hash.h"
-#include "btree.h"
-#include "log.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "lock_ext.h"
-
-static int __ham_c_close __P((DBC *));
-static int __ham_c_del __P((DBC *, u_int32_t));
-static int __ham_c_destroy __P((DBC *));
-static int __ham_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __ham_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __ham_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-static int __ham_dup_return __P((DBC *, DBT *, u_int32_t));
-static int __ham_expand_table __P((DBC *));
-static void __ham_init_htab __P((DBC *, u_int32_t, u_int32_t));
-static int __ham_lookup __P((DBC *, const DBT *, u_int32_t, db_lockmode_t));
-static int __ham_overwrite __P((DBC *, DBT *));
-
-/************************** INTERFACE ROUTINES ***************************/
-/* OPEN/CLOSE */
-
-/*
- * __ham_open --
- *
- * PUBLIC: int __ham_open __P((DB *, DB_INFO *));
- */
-int
-__ham_open(dbp, dbinfo)
- DB *dbp;
- DB_INFO *dbinfo;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- HASH_CURSOR *hcp;
- int file_existed, ret;
-
- dbc = NULL;
- dbenv = dbp->dbenv;
-
- /* Set the hash function if specified by the user. */
- if (dbinfo != NULL && dbinfo->h_hash != NULL)
- dbp->h_hash = dbinfo->h_hash;
-
- /*
- * Initialize the remaining fields of the dbp. The only function
- * that differs from the default set is __ham_stat().
- */
- dbp->internal = NULL;
- dbp->am_close = __ham_close;
- dbp->del = __ham_delete;
- dbp->stat = __ham_stat;
-
- /* Get a cursor we can use for the rest of this function. */
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- goto out;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- goto out;
-
- /*
- * If this is a new file, initialize it, and put it back dirty.
- */
-
- /* Initialize the hdr structure */
- if (hcp->hdr->magic == DB_HASHMAGIC) {
- file_existed = 1;
- /* File exists, verify the data in the header. */
- if (dbp->h_hash == NULL)
- dbp->h_hash =
- hcp->hdr->version < 5 ? __ham_func4 : __ham_func5;
- if (dbp->h_hash(CHARKEY, sizeof(CHARKEY)) !=
- hcp->hdr->h_charkey) {
- __db_err(dbp->dbenv, "hash: incompatible hash function");
- ret = EINVAL;
- goto out;
- }
- if (F_ISSET(hcp->hdr, DB_HASH_DUP))
- F_SET(dbp, DB_AM_DUP);
- } else {
- /*
- * File does not exist, we must initialize the header. If
- * locking is enabled that means getting a write lock first.
- */
- file_existed = 0;
- if (F_ISSET(dbp, DB_AM_LOCKING) &&
- ((ret = lock_put(dbenv->lk_info, hcp->hlock)) != 0 ||
- (ret = lock_get(dbenv->lk_info, dbc->locker, 0,
- &dbc->lock_dbt, DB_LOCK_WRITE, &hcp->hlock)) != 0)) {
- if (ret < 0)
- ret = EAGAIN;
- goto out;
- }
-
- __ham_init_htab(dbc, dbinfo != NULL ? dbinfo->h_nelem : 0,
- dbinfo != NULL ? dbinfo->h_ffactor : 0);
- if (F_ISSET(dbp, DB_AM_DUP))
- F_SET(hcp->hdr, DB_HASH_DUP);
- if ((ret = __ham_dirty_page(dbp, (PAGE *)hcp->hdr)) != 0)
- goto out;
- }
-
- /* Release the meta data page */
- RELEASE_META(dbp, hcp);
- if ((ret = dbc->c_close(dbc)) != 0)
- goto out;
-
- /* Sync the file so that we know that the meta data goes to disk. */
- if (!file_existed && (ret = dbp->sync(dbp, 0)) != 0)
- goto out;
- return (0);
-
-out: (void)__ham_close(dbp);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_close __P((DB *));
- */
-int
-__ham_close(dbp)
- DB *dbp;
-{
- COMPQUIET(dbp, NULL);
- return (0);
-}
-
-/************************** LOCAL CREATION ROUTINES **********************/
-/*
- * Returns 0 on No Error
- */
-static void
-__ham_init_htab(dbc, nelem, ffactor)
- DBC *dbc;
- u_int32_t nelem, ffactor;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- int32_t l2, nbuckets;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- dbp = dbc->dbp;
- memset(hcp->hdr, 0, sizeof(HASHHDR));
- hcp->hdr->ffactor = ffactor;
- hcp->hdr->pagesize = dbp->pgsize;
- ZERO_LSN(hcp->hdr->lsn);
- hcp->hdr->magic = DB_HASHMAGIC;
- hcp->hdr->version = DB_HASHVERSION;
-
- if (dbp->h_hash == NULL)
- dbp->h_hash = hcp->hdr->version < 5 ? __ham_func4 : __ham_func5;
- hcp->hdr->h_charkey = dbp->h_hash(CHARKEY, sizeof(CHARKEY));
- if (nelem != 0 && hcp->hdr->ffactor != 0) {
- nelem = (nelem - 1) / hcp->hdr->ffactor + 1;
- l2 = __db_log2(nelem > 2 ? nelem : 2);
- } else
- l2 = 2;
-
- nbuckets = 1 << l2;
-
- hcp->hdr->ovfl_point = l2;
- hcp->hdr->last_freed = PGNO_INVALID;
-
- hcp->hdr->max_bucket = hcp->hdr->high_mask = nbuckets - 1;
- hcp->hdr->low_mask = (nbuckets >> 1) - 1;
- memcpy(hcp->hdr->uid, dbp->fileid, DB_FILE_ID_LEN);
-}
-
-static int
-__ham_delete(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DBC *dbc;
- HASH_CURSOR *hcp;
- int ret, tret;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret =
- __db_delchk(dbp, key, flags, F_ISSET(dbp, DB_AM_RDONLY))) != 0)
- return (ret);
-
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "ham_delete", key, NULL, flags);
-
- hcp = (HASH_CURSOR *)dbc->internal;
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- goto out;
-
- hcp->stats.hash_deleted++;
- if ((ret = __ham_lookup(dbc, key, 0, DB_LOCK_WRITE)) == 0) {
- if (F_ISSET(hcp, H_OK))
- ret = __ham_del_pair(dbc, 1);
- else
- ret = DB_NOTFOUND;
- }
-
- RELEASE_META(dbp, hcp);
-out: if ((tret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = tret;
- return (ret);
-}
-
-/* ****************** CURSORS ********************************** */
-/*
- * __ham_c_init --
- * Initialize the hash-specific portion of a cursor.
- *
- * PUBLIC: int __ham_c_init __P((DBC *));
- */
-int
-__ham_c_init(dbc)
- DBC *dbc;
- {
- HASH_CURSOR *new_curs;
- int ret;
-
- if ((ret = __os_calloc(1, sizeof(struct cursor_t), &new_curs)) != 0)
- return (ret);
- if ((ret =
- __os_malloc(dbc->dbp->pgsize, NULL, &new_curs->split_buf)) != 0) {
- __os_free(new_curs, sizeof(*new_curs));
- return (ret);
- }
-
- new_curs->dbc = dbc;
-
- dbc->internal = new_curs;
- dbc->c_am_close = __ham_c_close;
- dbc->c_am_destroy = __ham_c_destroy;
- dbc->c_del = __ham_c_del;
- dbc->c_get = __ham_c_get;
- dbc->c_put = __ham_c_put;
-
- __ham_item_init(new_curs);
-
- return (0);
-}
-
-/*
- * __ham_c_close --
- * Close down the cursor from a single use.
- */
-static int
-__ham_c_close(dbc)
- DBC *dbc;
-{
- int ret;
-
- if ((ret = __ham_item_done(dbc, 0)) != 0)
- return (ret);
-
- __ham_item_init((HASH_CURSOR *)dbc->internal);
- return (0);
-}
-
-/*
- * __ham_c_destroy --
- * Cleanup the access method private part of a cursor.
- */
-static int
-__ham_c_destroy(dbc)
- DBC *dbc;
-{
- HASH_CURSOR *hcp;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- if (hcp->split_buf != NULL)
- __os_free(hcp->split_buf, dbc->dbp->pgsize);
- __os_free(hcp, sizeof(HASH_CURSOR));
-
- return (0);
-}
-
-static int
-__ham_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB *dbp;
- DBT repldbt;
- HASH_CURSOR *hcp;
- HASH_CURSOR save_curs;
- db_pgno_t ppgno, chg_pgno;
- int ret, t_ret;
-
- DEBUG_LWRITE(dbc, dbc->txn, "ham_c_del", NULL, NULL, flags);
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if ((ret = __db_cdelchk(dbc->dbp, flags,
- F_ISSET(dbc->dbp, DB_AM_RDONLY), IS_VALID(hcp))) != 0)
- return (ret);
-
- if (F_ISSET(hcp, H_DELETED))
- return (DB_NOTFOUND);
-
- /*
- * If we are in the concurrent DB product and this cursor
- * is not a write cursor, then this request is invalid.
- * If it is a simple write cursor, then we need to upgrade its
- * lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- /* Make sure it's a valid update cursor. */
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
-
- SAVE_CURSOR(hcp, &save_curs);
- hcp->stats.hash_deleted++;
-
- if ((ret = __ham_get_cpage(dbc, DB_LOCK_WRITE)) != 0)
- goto out;
- if (F_ISSET(hcp, H_ISDUP) && hcp->dpgno != PGNO_INVALID) {
- /*
- * We are about to remove a duplicate from offpage.
- *
- * There are 4 cases.
- * 1. We will remove an item on a page, but there are more
- * items on that page.
- * 2. We will remove the last item on a page, but there is a
- * following page of duplicates.
- * 3. We will remove the last item on a page, this page was the
- * last page in a duplicate set, but there were dups before
- * it.
- * 4. We will remove the last item on a page, removing the last
- * duplicate.
- * In case 1 hcp->dpagep is unchanged.
- * In case 2 hcp->dpagep comes back pointing to the next dup
- * page.
- * In case 3 hcp->dpagep comes back NULL.
- * In case 4 hcp->dpagep comes back NULL.
- *
- * Case 4 results in deleting the pair off the master page.
- * The normal code for doing this knows how to delete the
- * duplicates, so we will handle this case in the normal code.
- */
- ppgno = PREV_PGNO(hcp->dpagep);
- if (ppgno == PGNO_INVALID &&
- NEXT_PGNO(hcp->dpagep) == PGNO_INVALID &&
- NUM_ENT(hcp->dpagep) == 1)
- goto normal;
-
- /* Remove item from duplicate page. */
- chg_pgno = hcp->dpgno;
- if ((ret = __db_drem(dbc,
- &hcp->dpagep, hcp->dndx, __ham_del_page)) != 0)
- goto out;
-
- if (hcp->dpagep == NULL) {
- if (ppgno != PGNO_INVALID) { /* Case 3 */
- hcp->dpgno = ppgno;
- if ((ret = __ham_get_cpage(dbc,
- DB_LOCK_READ)) != 0)
- goto out;
- hcp->dndx = NUM_ENT(hcp->dpagep);
- F_SET(hcp, H_DELETED);
- } else { /* Case 4 */
- ret = __ham_del_pair(dbc, 1);
- hcp->dpgno = PGNO_INVALID;
- /*
- * Delpair updated the cursor queue, so we
- * don't have to do that here.
- */
- chg_pgno = PGNO_INVALID;
- }
- } else if (PGNO(hcp->dpagep) != hcp->dpgno) {
- hcp->dndx = 0; /* Case 2 */
- hcp->dpgno = PGNO(hcp->dpagep);
- if (ppgno == PGNO_INVALID)
- memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,
- H_DATAINDEX(hcp->bndx))),
- &hcp->dpgno, sizeof(db_pgno_t));
- /*
- * We need to put the master page here, because
- * although we have a duplicate page, the master
- * page is dirty, and ham_item_done assumes that
- * if you have a duplicate page, it's the only one
- * that can be dirty.
- */
- ret = __ham_put_page(dbp, hcp->pagep, 1);
- hcp->pagep = NULL;
- F_SET(hcp, H_DELETED);
- } else /* Case 1 */
- F_SET(hcp, H_DELETED);
- if (chg_pgno != PGNO_INVALID)
- __ham_c_update(hcp, chg_pgno, 0, 0, 1);
- } else if (F_ISSET(hcp, H_ISDUP)) { /* on page */
- if (hcp->dup_off == 0 && DUP_SIZE(hcp->dup_len) ==
- LEN_HDATA(hcp->pagep, hcp->hdr->pagesize, hcp->bndx))
- ret = __ham_del_pair(dbc, 1);
- else {
- repldbt.flags = 0;
- F_SET(&repldbt, DB_DBT_PARTIAL);
- repldbt.doff = hcp->dup_off;
- repldbt.dlen = DUP_SIZE(hcp->dup_len);
- repldbt.size = 0;
- repldbt.data =
- HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- ret = __ham_replpair(dbc, &repldbt, 0);
- hcp->dup_tlen -= DUP_SIZE(hcp->dup_len);
- F_SET(hcp, H_DELETED);
- __ham_c_update(hcp, hcp->pgno,
- DUP_SIZE(hcp->dup_len), 0, 1);
- }
-
- } else
- /* Not a duplicate */
-normal: ret = __ham_del_pair(dbc, 1);
-
-out: if ((t_ret = __ham_item_done(dbc, ret == 0)) != 0 && ret == 0)
- ret = t_ret;
- RELEASE_META(dbp, hcp);
- RESTORE_CURSOR(dbp, hcp, &save_curs, ret);
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
- return (ret);
-}
-
-static int
-__ham_c_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *dbp;
- HASH_CURSOR *hcp, save_curs;
- db_lockmode_t lock_type;
- int get_key, ret, t_ret;
-
- DEBUG_LREAD(dbc, dbc->txn, "ham_c_get",
- flags == DB_SET || flags == DB_SET_RANGE ? key : NULL,
- NULL, flags);
-
- hcp = (HASH_CURSOR *)dbc->internal;
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- SAVE_CURSOR(hcp, &save_curs);
- if ((ret =
- __db_cgetchk(dbp, key, data, flags, IS_VALID(hcp))) != 0)
- return (ret);
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- if (LF_ISSET(DB_RMW)) {
- lock_type = DB_LOCK_WRITE;
- LF_CLR(DB_RMW);
- } else
- lock_type = DB_LOCK_READ;
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
- hcp->stats.hash_get++;
- hcp->seek_size = 0;
-
- ret = 0;
- get_key = 1;
- switch (flags) {
- case DB_PREV:
- if (hcp->bucket != BUCKET_INVALID) {
- ret = __ham_item_prev(dbc, lock_type);
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST:
- ret = __ham_item_last(dbc, lock_type);
- break;
- case DB_FIRST:
- ret = __ham_item_first(dbc, lock_type);
- break;
- case DB_NEXT_DUP:
- if (hcp->bucket == BUCKET_INVALID)
- ret = EINVAL;
- else {
- F_SET(hcp, H_DUPONLY);
- ret = __ham_item_next(dbc, lock_type);
- }
- break;
- case DB_NEXT:
- if (hcp->bucket == BUCKET_INVALID)
- hcp->bucket = 0;
- ret = __ham_item_next(dbc, lock_type);
- break;
- case DB_SET:
- case DB_SET_RANGE:
- case DB_GET_BOTH:
- if (F_ISSET(dbc, DBC_CONTINUE)) {
- F_SET(hcp, H_DUPONLY);
- ret = __ham_item_next(dbc, lock_type);
- } else if (F_ISSET(dbc, DBC_KEYSET))
- ret = __ham_item(dbc, lock_type);
- else
- ret = __ham_lookup(dbc, key, 0, lock_type);
- get_key = 0;
- break;
- case DB_CURRENT:
- if (F_ISSET(hcp, H_DELETED)) {
- ret = DB_KEYEMPTY;
- goto out;
- }
-
- ret = __ham_item(dbc, lock_type);
- break;
- }
-
- /*
- * Must always enter this loop to do error handling and
- * check for big key/data pair.
- */
- while (1) {
- if (ret != 0 && ret != DB_NOTFOUND)
- goto out1;
- else if (F_ISSET(hcp, H_OK)) {
- /* Get the key. */
- if (get_key && (ret = __db_ret(dbp, hcp->pagep,
- H_KEYINDEX(hcp->bndx), key, &dbc->rkey.data,
- &dbc->rkey.size)) != 0)
- goto out1;
-
- ret = __ham_dup_return(dbc, data, flags);
- break;
- } else if (!F_ISSET(hcp, H_NOMORE)) {
- abort();
- break;
- }
-
- /*
- * Ran out of entries in a bucket; change buckets.
- */
- switch (flags) {
- case DB_LAST:
- case DB_PREV:
- ret = __ham_item_done(dbc, 0);
- if (hcp->bucket == 0) {
- ret = DB_NOTFOUND;
- goto out1;
- }
- hcp->bucket--;
- hcp->bndx = NDX_INVALID;
- if (ret == 0)
- ret = __ham_item_prev(dbc, lock_type);
- break;
- case DB_FIRST:
- case DB_NEXT:
- ret = __ham_item_done(dbc, 0);
- hcp->bndx = NDX_INVALID;
- hcp->bucket++;
- hcp->pgno = PGNO_INVALID;
- hcp->pagep = NULL;
- if (hcp->bucket > hcp->hdr->max_bucket) {
- ret = DB_NOTFOUND;
- goto out1;
- }
- if (ret == 0)
- ret = __ham_item_next(dbc, lock_type);
- break;
- case DB_GET_BOTH:
- case DB_NEXT_DUP:
- case DB_SET:
- case DB_SET_RANGE:
- /* Key not found. */
- ret = DB_NOTFOUND;
- goto out1;
- }
- }
-out1: if ((t_ret = __ham_item_done(dbc, 0)) != 0 && ret == 0)
- ret = t_ret;
-out: RELEASE_META(dbp, hcp);
- RESTORE_CURSOR(dbp, hcp, &save_curs, ret);
- return (ret);
-}
-
-static int
-__ham_c_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *dbp;
- DBT tmp_val, *myval;
- HASH_CURSOR *hcp, save_curs;
- u_int32_t nbytes;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- DEBUG_LWRITE(dbc, dbc->txn, "ham_c_put",
- flags == DB_KEYFIRST || flags == DB_KEYLAST ? key : NULL,
- data, flags);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if ((ret = __db_cputchk(dbp, key, data, flags,
- F_ISSET(dbp, DB_AM_RDONLY), IS_VALID(hcp))) != 0)
- return (ret);
-
- if (F_ISSET(hcp, H_DELETED) &&
- flags != DB_KEYFIRST && flags != DB_KEYLAST)
- return (DB_NOTFOUND);
-
- /*
- * If we are in the concurrent DB product and this cursor
- * is not a write cursor, then this request is invalid.
- * If it is a simple write cursor, then we need to upgrade its
- * lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- /* Make sure it's a valid update cursor. */
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
-
- SAVE_CURSOR(hcp, &save_curs);
- hcp->stats.hash_put++;
-
- switch (flags) {
- case DB_KEYLAST:
- case DB_KEYFIRST:
- nbytes = (ISBIG(hcp, key->size) ? HOFFPAGE_PSIZE :
- HKEYDATA_PSIZE(key->size)) +
- (ISBIG(hcp, data->size) ? HOFFPAGE_PSIZE :
- HKEYDATA_PSIZE(data->size));
- if ((ret = __ham_lookup(dbc,
- key, nbytes, DB_LOCK_WRITE)) == DB_NOTFOUND) {
- ret = 0;
- if (hcp->seek_found_page != PGNO_INVALID &&
- hcp->seek_found_page != hcp->pgno) {
- if ((ret = __ham_item_done(dbc, 0)) != 0)
- goto out;
- hcp->pgno = hcp->seek_found_page;
- hcp->bndx = NDX_INVALID;
- }
-
- if (F_ISSET(data, DB_DBT_PARTIAL) && data->doff != 0) {
- /*
- * A partial put, but the key does not exist
- * and we are not beginning the write at 0.
- * We must create a data item padded up to doff
- * and then write the new bytes represented by
- * val.
- */
- if ((ret = __ham_init_dbt(&tmp_val,
- data->size + data->doff,
- &dbc->rdata.data, &dbc->rdata.size)) == 0) {
- memset(tmp_val.data, 0, data->doff);
- memcpy((u_int8_t *)tmp_val.data +
- data->doff, data->data, data->size);
- myval = &tmp_val;
- }
- } else
- myval = (DBT *)data;
-
- if (ret == 0)
- ret = __ham_add_el(dbc, key, myval, H_KEYDATA);
- goto done;
- }
- break;
- case DB_BEFORE:
- case DB_AFTER:
- case DB_CURRENT:
- ret = __ham_item(dbc, DB_LOCK_WRITE);
- break;
- }
-
- if (ret == 0) {
- if ((flags == DB_CURRENT && !F_ISSET(hcp, H_ISDUP)) ||
- ((flags == DB_KEYFIRST || flags == DB_KEYLAST) &&
- !F_ISSET(dbp, DB_AM_DUP)))
- ret = __ham_overwrite(dbc, data);
- else
- ret = __ham_add_dup(dbc, data, flags);
- }
-
-done: if (ret == 0 && F_ISSET(hcp, H_EXPAND)) {
- ret = __ham_expand_table(dbc);
- F_CLR(hcp, H_EXPAND);
- }
-
- if ((t_ret = __ham_item_done(dbc, ret == 0)) != 0 && ret == 0)
- ret = t_ret;
-
-out: RELEASE_META(dbp, hcp);
- RESTORE_CURSOR(dbp, hcp, &save_curs, ret);
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
- return (ret);
-}
-
-/********************************* UTILITIES ************************/
-
-/*
- * __ham_expand_table --
- */
-static int
-__ham_expand_table(dbc)
- DBC *dbc;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DB_LSN new_lsn;
- u_int32_t old_bucket, new_bucket, spare_ndx;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- ret = 0;
- DIRTY_META(dbp, hcp, ret);
- if (ret)
- return (ret);
-
- /*
- * If the split point is about to increase, make sure that we
- * have enough extra pages. The calculation here is weird.
- * We'd like to do this after we've upped max_bucket, but it's
- * too late then because we've logged the meta-data split. What
- * we'll do between then and now is increment max bucket and then
- * see what the log of one greater than that is; here we have to
- * look at the log of max + 2. VERY NASTY STUFF.
- */
- if (__db_log2(hcp->hdr->max_bucket + 2) > hcp->hdr->ovfl_point) {
- /*
- * We are about to shift the split point. Make sure that
- * if the next doubling is going to be big (more than 8
- * pages), we have some extra pages around.
- */
- if (hcp->hdr->max_bucket + 1 >= 8 &&
- hcp->hdr->spares[hcp->hdr->ovfl_point] <
- hcp->hdr->spares[hcp->hdr->ovfl_point - 1] +
- hcp->hdr->ovfl_point + 1)
- __ham_init_ovflpages(dbc);
- }
-
- /* Now we can log the meta-data split. */
- if (DB_LOGGING(dbc)) {
- if ((ret = __ham_splitmeta_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid,
- hcp->hdr->max_bucket, hcp->hdr->ovfl_point,
- hcp->hdr->spares[hcp->hdr->ovfl_point],
- &hcp->hdr->lsn)) != 0)
- return (ret);
-
- hcp->hdr->lsn = new_lsn;
- }
-
- hcp->stats.hash_expansions++;
- new_bucket = ++hcp->hdr->max_bucket;
- old_bucket = (hcp->hdr->max_bucket & hcp->hdr->low_mask);
-
- /*
- * If the split point is increasing, copy the current contents
- * of the spare split bucket to the next bucket.
- */
- spare_ndx = __db_log2(hcp->hdr->max_bucket + 1);
- if (spare_ndx > hcp->hdr->ovfl_point) {
- hcp->hdr->spares[spare_ndx] =
- hcp->hdr->spares[hcp->hdr->ovfl_point];
- hcp->hdr->ovfl_point = spare_ndx;
- }
-
- if (new_bucket > hcp->hdr->high_mask) {
- /* Starting a new doubling */
- hcp->hdr->low_mask = hcp->hdr->high_mask;
- hcp->hdr->high_mask = new_bucket | hcp->hdr->low_mask;
- }
-
- if (BUCKET_TO_PAGE(hcp, new_bucket) > MAX_PAGES(hcp)) {
- __db_err(dbp->dbenv,
- "hash: Cannot allocate new bucket. Pages exhausted.");
- return (ENOSPC);
- }
-
- /* Relocate records to the new bucket */
- return (__ham_split_page(dbc, old_bucket, new_bucket));
-}
-
-/*
- * PUBLIC: u_int32_t __ham_call_hash __P((HASH_CURSOR *, u_int8_t *, int32_t));
- */
-u_int32_t
-__ham_call_hash(hcp, k, len)
- HASH_CURSOR *hcp;
- u_int8_t *k;
- int32_t len;
-{
- u_int32_t n, bucket;
-
- n = (u_int32_t)(hcp->dbc->dbp->h_hash(k, len));
-
- bucket = n & hcp->hdr->high_mask;
- if (bucket > hcp->hdr->max_bucket)
- bucket = bucket & hcp->hdr->low_mask;
- return (bucket);
-}
-
-/*
- * Check for duplicates, and call __db_ret appropriately. Release
- * everything held by the cursor.
- */
-static int
-__ham_dup_return(dbc, val, flags)
- DBC *dbc;
- DBT *val;
- u_int32_t flags;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- PAGE *pp;
- DBT *myval, tmp_val;
- db_indx_t ndx;
- db_pgno_t pgno;
- u_int32_t off, tlen;
- u_int8_t *hk, type;
- int cmp, ret;
- db_indx_t len;
-
- /* Check for duplicate and return the first one. */
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- ndx = H_DATAINDEX(hcp->bndx);
- type = HPAGE_TYPE(hcp->pagep, ndx);
- pp = hcp->pagep;
- myval = val;
-
- /*
- * There are 4 cases:
- * 1. We are not in duplicate, simply call db_ret.
- * 2. We are looking at keys and stumbled onto a duplicate.
- * 3. We are in the middle of a duplicate set. (ISDUP set)
- * 4. This is a duplicate and we need to return a specific item.
- */
-
- /*
- * Here we check for the case where we just stumbled onto a
- * duplicate. In this case, we do initialization and then
- * let the normal duplicate code handle it.
- */
- if (!F_ISSET(hcp, H_ISDUP)) {
- if (type == H_DUPLICATE) {
- F_SET(hcp, H_ISDUP);
- hcp->dup_tlen = LEN_HDATA(hcp->pagep,
- hcp->hdr->pagesize, hcp->bndx);
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- if (flags == DB_LAST || flags == DB_PREV) {
- hcp->dndx = 0;
- hcp->dup_off = 0;
- do {
- memcpy(&len,
- HKEYDATA_DATA(hk) + hcp->dup_off,
- sizeof(db_indx_t));
- hcp->dup_off += DUP_SIZE(len);
- hcp->dndx++;
- } while (hcp->dup_off < hcp->dup_tlen);
- hcp->dup_off -= DUP_SIZE(len);
- hcp->dndx--;
- } else {
- memcpy(&len,
- HKEYDATA_DATA(hk), sizeof(db_indx_t));
- hcp->dup_off = 0;
- hcp->dndx = 0;
- }
- hcp->dup_len = len;
- } else if (type == H_OFFDUP) {
- F_SET(hcp, H_ISDUP);
- memcpy(&pgno, HOFFDUP_PGNO(P_ENTRY(hcp->pagep, ndx)),
- sizeof(db_pgno_t));
- if (flags == DB_LAST || flags == DB_PREV) {
- if ((ret = __db_dend(dbc,
- pgno, &hcp->dpagep)) != 0)
- return (ret);
- hcp->dpgno = PGNO(hcp->dpagep);
- hcp->dndx = NUM_ENT(hcp->dpagep) - 1;
- } else if ((ret = __ham_next_cpage(dbc,
- pgno, 0, H_ISDUP)) != 0)
- return (ret);
- }
- }
-
- /*
- * If we are retrieving a specific key/data pair, then we
- * may need to adjust the cursor before returning data.
- */
- if (flags == DB_GET_BOTH) {
- if (F_ISSET(hcp, H_ISDUP)) {
- if (hcp->dpgno != PGNO_INVALID) {
- if ((ret = __db_dsearch(dbc, 0, val,
- hcp->dpgno, &hcp->dndx, &hcp->dpagep, &cmp))
- != 0)
- return (ret);
- if (cmp == 0)
- hcp->dpgno = PGNO(hcp->dpagep);
- } else {
- __ham_dsearch(dbc, val, &off, &cmp);
- hcp->dup_off = off;
- }
- } else {
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- if (((HKEYDATA *)hk)->type == H_OFFPAGE) {
- memcpy(&tlen,
- HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
- memcpy(&pgno,
- HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));
- if ((ret = __db_moff(dbp, val,
- pgno, tlen, dbp->dup_compare, &cmp)) != 0)
- return (ret);
- } else {
- /*
- * We do not zero tmp_val since the comparison
- * routines may only look at data and size.
- */
- tmp_val.data = HKEYDATA_DATA(hk);
- tmp_val.size = LEN_HDATA(hcp->pagep,
- dbp->pgsize, hcp->bndx);
- cmp = dbp->dup_compare == NULL ?
- __bam_defcmp(&tmp_val, val) :
- dbp->dup_compare(&tmp_val, val);
- }
- }
-
- if (cmp != 0)
- return (DB_NOTFOUND);
- }
-
- /*
- * Now, everything is initialized, grab a duplicate if
- * necessary.
- */
- if (F_ISSET(hcp, H_ISDUP)) {
- if (hcp->dpgno != PGNO_INVALID) {
- pp = hcp->dpagep;
- ndx = hcp->dndx;
- } else {
- /*
- * Copy the DBT in case we are retrieving into user
- * memory and we need the parameters for it. If the
- * user requested a partial, then we need to adjust
- * the user's parameters to get the partial of the
- * duplicate which is itself a partial.
- */
- memcpy(&tmp_val, val, sizeof(*val));
- if (F_ISSET(&tmp_val, DB_DBT_PARTIAL)) {
- /*
- * Take the user's length unless it would go
- * beyond the end of the duplicate.
- */
- if (tmp_val.doff + hcp->dup_off > hcp->dup_len)
- tmp_val.dlen = 0;
- else if (tmp_val.dlen + tmp_val.doff >
- hcp->dup_len)
- tmp_val.dlen =
- hcp->dup_len - tmp_val.doff;
-
- /*
- * Calculate the new offset.
- */
- tmp_val.doff += hcp->dup_off;
- } else {
- F_SET(&tmp_val, DB_DBT_PARTIAL);
- tmp_val.dlen = hcp->dup_len;
- tmp_val.doff = hcp->dup_off + sizeof(db_indx_t);
- }
- myval = &tmp_val;
- }
- }
-
- /*
- * Finally, if we had a duplicate, pp, ndx, and myval should be
- * set appropriately.
- */
- if ((ret = __db_ret(dbp, pp, ndx, myval, &dbc->rdata.data,
- &dbc->rdata.size)) != 0)
- return (ret);
-
- /*
- * In case we sent a temporary off to db_ret, set the real
- * return values.
- */
- val->data = myval->data;
- val->size = myval->size;
-
- return (0);
-}
-
-static int
-__ham_overwrite(dbc, nval)
- DBC *dbc;
- DBT *nval;
-{
- HASH_CURSOR *hcp;
- DBT *myval, tmp_val;
- u_int8_t *hk;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- if (F_ISSET(dbc->dbp, DB_AM_DUP))
- return (__ham_add_dup(dbc, nval, DB_KEYLAST));
- else if (!F_ISSET(nval, DB_DBT_PARTIAL)) {
- /* Put/overwrite */
- memcpy(&tmp_val, nval, sizeof(*nval));
- F_SET(&tmp_val, DB_DBT_PARTIAL);
- tmp_val.doff = 0;
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- if (HPAGE_PTYPE(hk) == H_OFFPAGE)
- memcpy(&tmp_val.dlen,
- HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
- else
- tmp_val.dlen = LEN_HDATA(hcp->pagep,
- hcp->hdr->pagesize,hcp->bndx);
- myval = &tmp_val;
- } else /* Regular partial put */
- myval = nval;
-
- return (__ham_replpair(dbc, myval, 0));
-}
-
-/*
- * Given a key and a cursor, sets the cursor to the page/ndx on which
- * the key resides. If the key is found, the cursor H_OK flag is set
- * and the pagep, bndx, pgno (dpagep, dndx, dpgno) fields are set.
- * If the key is not found, the H_OK flag is not set. If the sought
- * field is non-0, the pagep, bndx, pgno (dpagep, dndx, dpgno) fields
- * are set indicating where an add might take place. If it is 0,
- * non of the cursor pointer field are valid.
- */
-static int
-__ham_lookup(dbc, key, sought, mode)
- DBC *dbc;
- const DBT *key;
- u_int32_t sought;
- db_lockmode_t mode;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- db_pgno_t pgno;
- u_int32_t tlen;
- int match, ret, t_ret;
- u_int8_t *hk;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- /*
- * Set up cursor so that we're looking for space to add an item
- * as we cycle through the pages looking for the key.
- */
- if ((ret = __ham_item_reset(dbc)) != 0)
- return (ret);
- hcp->seek_size = sought;
-
- hcp->bucket = __ham_call_hash(hcp, (u_int8_t *)key->data, key->size);
- while (1) {
- if ((ret = __ham_item_next(dbc, mode)) != 0)
- return (ret);
-
- if (F_ISSET(hcp, H_NOMORE))
- break;
-
- hk = H_PAIRKEY(hcp->pagep, hcp->bndx);
- switch (HPAGE_PTYPE(hk)) {
- case H_OFFPAGE:
- memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
- if (tlen == key->size) {
- memcpy(&pgno,
- HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));
- if ((ret = __db_moff(dbp,
- key, pgno, tlen, NULL, &match)) != 0)
- return (ret);
- if (match == 0) {
- F_SET(hcp, H_OK);
- return (0);
- }
- }
- break;
- case H_KEYDATA:
- if (key->size == LEN_HKEY(hcp->pagep,
- hcp->hdr->pagesize, hcp->bndx) &&
- memcmp(key->data,
- HKEYDATA_DATA(hk), key->size) == 0) {
- F_SET(hcp, H_OK);
- return (0);
- }
- break;
- case H_DUPLICATE:
- case H_OFFDUP:
- /*
- * These are errors because keys are never
- * duplicated, only data items are.
- */
- return (__db_pgfmt(dbp, PGNO(hcp->pagep)));
- }
- hcp->stats.hash_collisions++;
- }
-
- /*
- * Item was not found, adjust cursor properly.
- */
-
- if (sought != 0)
- return (ret);
-
- if ((t_ret = __ham_item_done(dbc, 0)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * Initialize a dbt using some possibly already allocated storage
- * for items.
- * PUBLIC: int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *));
- */
-int
-__ham_init_dbt(dbt, size, bufp, sizep)
- DBT *dbt;
- u_int32_t size;
- void **bufp;
- u_int32_t *sizep;
-{
- int ret;
-
- memset(dbt, 0, sizeof(*dbt));
- if (*sizep < size) {
- if ((ret = __os_realloc(bufp, size)) != 0) {
- *sizep = 0;
- return (ret);
- }
- *sizep = size;
- }
- dbt->data = *bufp;
- dbt->size = size;
- return (0);
-}
-
-/*
- * Adjust the cursor after an insert or delete. The cursor passed is
- * the one that was operated upon; we just need to check any of the
- * others.
- *
- * len indicates the length of the item added/deleted
- * add indicates if the item indicated by the cursor has just been
- * added (add == 1) or deleted (add == 0).
- * dup indicates if the addition occurred into a duplicate set.
- *
- * PUBLIC: void __ham_c_update
- * PUBLIC: __P((HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
- */
-void
-__ham_c_update(hcp, chg_pgno, len, add, is_dup)
- HASH_CURSOR *hcp;
- db_pgno_t chg_pgno;
- u_int32_t len;
- int add, is_dup;
-{
- DB *dbp;
- DBC *cp;
- HASH_CURSOR *lcp;
- int page_deleted;
-
- /*
- * Regular adds are always at the end of a given page, so we never
- * have to adjust anyone's cursor after a regular add.
- */
- if (!is_dup && add)
- return;
-
- /*
- * Determine if a page was deleted. If this is a regular update
- * (i.e., not is_dup) then the deleted page's number will be that in
- * chg_pgno, and the pgno in the cursor will be different. If this
- * was an onpage-duplicate, then the same conditions apply. If this
- * was an off-page duplicate, then we need to verify if hcp->dpgno
- * is the same (no delete) or different (delete) than chg_pgno.
- */
- if (!is_dup || hcp->dpgno == PGNO_INVALID)
- page_deleted =
- chg_pgno != PGNO_INVALID && chg_pgno != hcp->pgno;
- else
- page_deleted =
- chg_pgno != PGNO_INVALID && chg_pgno != hcp->dpgno;
-
- dbp = hcp->dbc->dbp;
- DB_THREAD_LOCK(dbp);
-
- for (cp = TAILQ_FIRST(&dbp->active_queue); cp != NULL;
- cp = TAILQ_NEXT(cp, links)) {
- if (cp->internal == hcp)
- continue;
-
- lcp = (HASH_CURSOR *)cp->internal;
-
- if (!is_dup && lcp->pgno != chg_pgno)
- continue;
-
- if (is_dup) {
- if (F_ISSET(hcp, H_DELETED) && lcp->pgno != chg_pgno)
- continue;
- if (!F_ISSET(hcp, H_DELETED) && lcp->dpgno != chg_pgno)
- continue;
- }
-
- if (page_deleted) {
- if (is_dup) {
- lcp->dpgno = hcp->dpgno;
- lcp->dndx = hcp->dndx;
- } else {
- lcp->pgno = hcp->pgno;
- lcp->bndx = hcp->bndx;
- lcp->bucket = hcp->bucket;
- }
- F_CLR(lcp, H_ISDUP);
- continue;
- }
-
- if (!is_dup && lcp->bndx > hcp->bndx)
- lcp->bndx--;
- else if (!is_dup && lcp->bndx == hcp->bndx)
- F_SET(lcp, H_DELETED);
- else if (is_dup && lcp->bndx == hcp->bndx) {
- /* Assign dpgno in case there was page conversion. */
- lcp->dpgno = hcp->dpgno;
- if (add && lcp->dndx >= hcp->dndx )
- lcp->dndx++;
- else if (!add && lcp->dndx > hcp->dndx)
- lcp->dndx--;
- else if (!add && lcp->dndx == hcp->dndx)
- F_SET(lcp, H_DELETED);
-
- /* Now adjust on-page information. */
- if (lcp->dpgno == PGNO_INVALID) {
- if (add) {
- lcp->dup_tlen += len;
- if (lcp->dndx > hcp->dndx)
- lcp->dup_off += len;
- } else {
- lcp->dup_tlen -= len;
- if (lcp->dndx > hcp->dndx)
- lcp->dup_off -= len;
- }
- }
- }
- }
- DB_THREAD_UNLOCK(dbp);
-}
diff --git a/db2/hash/hash.src b/db2/hash/hash.src
deleted file mode 100644
index 8a51283..0000000
--- a/db2/hash/hash.src
+++ /dev/null
@@ -1,231 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * Margo Seltzer. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)hash.src 10.3 (Sleepycat) 4/10/98
- */
-
-/*
- * This is the source file used to create the logging functions for the
- * hash package. Each access method (or set of routines wishing to register
- * record types with the transaction system) should have a file like this.
- * Each type of log record and its parameters is defined. The basic
- * format of a record definition is:
- *
- * BEGIN <RECORD_TYPE>
- * ARG|STRING|POINTER <variable name> <variable type> <printf format>
- * ...
- * END
- * ARG the argument is a simple parameter of the type * specified.
- * DBT the argument is a DBT (db.h) containing a length and pointer.
- * PTR the argument is a pointer to the data type specified; the entire
- * type should be logged.
- *
- * There are a set of shell scripts of the form xxx.sh that generate c
- * code and or h files to process these. (This is probably better done
- * in a single PERL script, but for now, this works.)
- *
- * The DB recovery system requires the following three fields appear in
- * every record, and will assign them to the per-record-type structures
- * as well as making them the first parameters to the appropriate logging
- * call.
- * rectype: record-type, identifies the structure and log/read call
- * txnid: transaction id, a DBT in this implementation
- * prev: the last LSN for this transaction
- */
-
-/*
- * Use the argument of PREFIX as the prefix for all record types,
- * routines, id numbers, etc.
- */
-PREFIX ham
-
-/*
- * HASH-insdel: used for hash to insert/delete a pair of entries onto a master
- * page. The pair might be regular key/data pairs or they might be the
- * structures that refer to off page items, duplicates or offpage duplicates.
- * opcode - PUTPAIR/DELPAIR + big masks
- * fileid - identifies the file referenced
- * pgno - page within file
- * ndx - index on the page of the item being added (item index)
- * pagelsn - lsn on the page before the update
- * key - the key being inserted
- * data - the data being inserted
- */
-BEGIN insdel
-ARG opcode u_int32_t lu
-ARG fileid u_int32_t lu
-ARG pgno db_pgno_t lu
-ARG ndx u_int32_t lu
-POINTER pagelsn DB_LSN * lu
-DBT key DBT s
-DBT data DBT s
-END
-
-/*
- * Used to add and remove overflow pages.
- * prev_pgno is the previous page that is going to get modified to
- * point to this one. If this is the first page in a chain
- * then prev_pgno should be PGNO_INVALID.
- * new_pgno is the page being allocated.
- * next_pgno is the page that follows this one. On allocation,
- * this should be PGNO_INVALID. For deletes, it may exist.
- * pagelsn is the old lsn on the page.
- */
-BEGIN newpage
-ARG opcode u_int32_t lu
-ARG fileid u_int32_t lu
-ARG prev_pgno db_pgno_t lu
-POINTER prevlsn DB_LSN * lu
-ARG new_pgno db_pgno_t lu
-POINTER pagelsn DB_LSN * lu
-ARG next_pgno db_pgno_t lu
-POINTER nextlsn DB_LSN * lu
-END
-
-/*
- * Splitting requires two types of log messages. The first
- * logs the meta-data of the split. The second logs the
- * data on the original page. To redo the split, we have
- * to visit the new page (pages) and add the items back
- * on the page if they are not yet there.
- * For the meta-data split
- * bucket: max_bucket in table before split
- * ovflpoint: overflow point before split.
- * spares: spares[ovflpoint] before split.
- */
-BEGIN splitmeta
-ARG fileid u_int32_t lu
-ARG bucket u_int32_t lu
-ARG ovflpoint u_int32_t lu
-ARG spares u_int32_t lu
-POINTER metalsn DB_LSN * lu
-END
-
-BEGIN splitdata
-ARG fileid u_int32_t lu
-ARG opcode u_int32_t lu
-ARG pgno db_pgno_t lu
-DBT pageimage DBT s
-POINTER pagelsn DB_LSN * lu
-END
-
-/*
- * HASH-replace: is used for hash to handle partial puts that only
- * affect a single master page.
- * fileid - identifies the file referenced
- * pgno - page within file
- * ndx - index on the page of the item being modified (item index)
- * pagelsn - lsn on the page before the update
- * off - offset in the old item where the new item is going.
- * olditem - DBT that describes the part of the item being replaced.
- * newitem - DBT of the new item.
- * makedup - this was a replacement that made an item a duplicate.
- */
-BEGIN replace
-ARG fileid u_int32_t lu
-ARG pgno db_pgno_t lu
-ARG ndx u_int32_t lu
-POINTER pagelsn DB_LSN * lu
-ARG off int32_t ld
-DBT olditem DBT s
-DBT newitem DBT s
-ARG makedup u_int32_t lu
-END
-
-/*
- * HASH-newpgno: is used to record getting/deleting a new page number.
- * This doesn't require much data modification, just modifying the
- * meta-data.
- * pgno is the page being allocated/freed.
- * free_pgno is the next_pgno on the free list.
- * old_type was the type of a page being deallocated.
- * old_pgno was the next page number before the deallocation. We use it
- * to indicate whether we incremented the spares count or not
- * during this allocation.
- */
-BEGIN newpgno
-ARG opcode u_int32_t lu
-ARG fileid u_int32_t lu
-ARG pgno db_pgno_t lu
-ARG free_pgno db_pgno_t lu
-ARG old_type u_int32_t lu
-ARG old_pgno db_pgno_t lu
-ARG new_type u_int32_t lu
-POINTER pagelsn DB_LSN * lu
-POINTER metalsn DB_LSN * lu
-END
-
-/*
- * ovfl: initialize a set of overflow pages.
- */
-BEGIN ovfl
-ARG fileid u_int32_t lu
-ARG start_pgno db_pgno_t lu
-ARG npages u_int32_t lu
-ARG free_pgno db_pgno_t lu
-ARG ovflpoint u_int32_t lu
-POINTER metalsn DB_LSN * lu
-END
-
-/*
- * Used when we empty the first page in a bucket and there are pages
- * after it. The page after it gets copied into the bucket page (since
- * bucket pages have to be in fixed locations).
- * pgno: the bucket page
- * pagelsn: the old LSN on the bucket page
- * next_pgno: the page number of the next page
- * nnext_pgno: page after next_pgno (may need to change its prev)
- * nnextlsn: the LSN of nnext_pgno.
- */
-BEGIN copypage
-ARG fileid u_int32_t lu
-ARG pgno db_pgno_t lu
-POINTER pagelsn DB_LSN * lu
-ARG next_pgno db_pgno_t lu
-POINTER nextlsn DB_LSN * lu
-ARG nnext_pgno db_pgno_t lu
-POINTER nnextlsn DB_LSN * lu
-DBT page DBT s
-END
diff --git a/db2/hash/hash_auto.c b/db2/hash/hash_auto.c
deleted file mode 100644
index 94a1dff..0000000
--- a/db2/hash/hash_auto.c
+++ /dev/null
@@ -1,1554 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "hash.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __ham_insdel_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- * PUBLIC: DB_LSN *, const DBT *, const DBT *));
- */
-int __ham_insdel_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, ndx, pagelsn, key,
- data)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t ndx;
- DB_LSN * pagelsn;
- const DBT *key;
- const DBT *data;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_insdel;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(ndx)
- + sizeof(*pagelsn)
- + sizeof(u_int32_t) + (key == NULL ? 0 : key->size)
- + sizeof(u_int32_t) + (data == NULL ? 0 : data->size);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &ndx, sizeof(ndx));
- bp += sizeof(ndx);
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- if (key == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &key->size, sizeof(key->size));
- bp += sizeof(key->size);
- memcpy(bp, key->data, key->size);
- bp += key->size;
- }
- if (data == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &data->size, sizeof(data->size));
- bp += sizeof(data->size);
- memcpy(bp, data->data, data->size);
- bp += data->size;
- }
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_insdel_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_insdel_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_insdel_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_insdel_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_insdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tndx: %lu\n", (u_long)argp->ndx);
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\tkey: ");
- for (i = 0; i < argp->key.size; i++) {
- ch = ((u_int8_t *)argp->key.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tdata: ");
- for (i = 0; i < argp->data.size; i++) {
- ch = ((u_int8_t *)argp->data.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_insdel_read __P((void *, __ham_insdel_args **));
- */
-int
-__ham_insdel_read(recbuf, argpp)
- void *recbuf;
- __ham_insdel_args **argpp;
-{
- __ham_insdel_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_insdel_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->ndx, bp, sizeof(argp->ndx));
- bp += sizeof(argp->ndx);
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->key.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->key.data = bp;
- bp += argp->key.size;
- memcpy(&argp->data.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->data.data = bp;
- bp += argp->data.size;
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_newpage_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, DB_LSN *,
- * PUBLIC: db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *));
- */
-int __ham_newpage_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, prev_pgno, prevlsn, new_pgno, pagelsn,
- next_pgno, nextlsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t prev_pgno;
- DB_LSN * prevlsn;
- db_pgno_t new_pgno;
- DB_LSN * pagelsn;
- db_pgno_t next_pgno;
- DB_LSN * nextlsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_newpage;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(prev_pgno)
- + sizeof(*prevlsn)
- + sizeof(new_pgno)
- + sizeof(*pagelsn)
- + sizeof(next_pgno)
- + sizeof(*nextlsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &prev_pgno, sizeof(prev_pgno));
- bp += sizeof(prev_pgno);
- if (prevlsn != NULL)
- memcpy(bp, prevlsn, sizeof(*prevlsn));
- else
- memset(bp, 0, sizeof(*prevlsn));
- bp += sizeof(*prevlsn);
- memcpy(bp, &new_pgno, sizeof(new_pgno));
- bp += sizeof(new_pgno);
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- memcpy(bp, &next_pgno, sizeof(next_pgno));
- bp += sizeof(next_pgno);
- if (nextlsn != NULL)
- memcpy(bp, nextlsn, sizeof(*nextlsn));
- else
- memset(bp, 0, sizeof(*nextlsn));
- bp += sizeof(*nextlsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_newpage_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_newpage_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_newpage_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_newpage_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_newpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tprev_pgno: %lu\n", (u_long)argp->prev_pgno);
- printf("\tprevlsn: [%lu][%lu]\n",
- (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset);
- printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno);
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
- printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_newpage_read __P((void *, __ham_newpage_args **));
- */
-int
-__ham_newpage_read(recbuf, argpp)
- void *recbuf;
- __ham_newpage_args **argpp;
-{
- __ham_newpage_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_newpage_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->prev_pgno, bp, sizeof(argp->prev_pgno));
- bp += sizeof(argp->prev_pgno);
- memcpy(&argp->prevlsn, bp, sizeof(argp->prevlsn));
- bp += sizeof(argp->prevlsn);
- memcpy(&argp->new_pgno, bp, sizeof(argp->new_pgno));
- bp += sizeof(argp->new_pgno);
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->next_pgno, bp, sizeof(argp->next_pgno));
- bp += sizeof(argp->next_pgno);
- memcpy(&argp->nextlsn, bp, sizeof(argp->nextlsn));
- bp += sizeof(argp->nextlsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_splitmeta_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, u_int32_t, u_int32_t,
- * PUBLIC: DB_LSN *));
- */
-int __ham_splitmeta_log(logp, txnid, ret_lsnp, flags,
- fileid, bucket, ovflpoint, spares, metalsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- u_int32_t bucket;
- u_int32_t ovflpoint;
- u_int32_t spares;
- DB_LSN * metalsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_splitmeta;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(bucket)
- + sizeof(ovflpoint)
- + sizeof(spares)
- + sizeof(*metalsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &bucket, sizeof(bucket));
- bp += sizeof(bucket);
- memcpy(bp, &ovflpoint, sizeof(ovflpoint));
- bp += sizeof(ovflpoint);
- memcpy(bp, &spares, sizeof(spares));
- bp += sizeof(spares);
- if (metalsn != NULL)
- memcpy(bp, metalsn, sizeof(*metalsn));
- else
- memset(bp, 0, sizeof(*metalsn));
- bp += sizeof(*metalsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_splitmeta_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_splitmeta_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_splitmeta_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_splitmeta: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tbucket: %lu\n", (u_long)argp->bucket);
- printf("\tovflpoint: %lu\n", (u_long)argp->ovflpoint);
- printf("\tspares: %lu\n", (u_long)argp->spares);
- printf("\tmetalsn: [%lu][%lu]\n",
- (u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_splitmeta_read __P((void *, __ham_splitmeta_args **));
- */
-int
-__ham_splitmeta_read(recbuf, argpp)
- void *recbuf;
- __ham_splitmeta_args **argpp;
-{
- __ham_splitmeta_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_splitmeta_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->bucket, bp, sizeof(argp->bucket));
- bp += sizeof(argp->bucket);
- memcpy(&argp->ovflpoint, bp, sizeof(argp->ovflpoint));
- bp += sizeof(argp->ovflpoint);
- memcpy(&argp->spares, bp, sizeof(argp->spares));
- bp += sizeof(argp->spares);
- memcpy(&argp->metalsn, bp, sizeof(argp->metalsn));
- bp += sizeof(argp->metalsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_splitdata_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, const DBT *,
- * PUBLIC: DB_LSN *));
- */
-int __ham_splitdata_log(logp, txnid, ret_lsnp, flags,
- fileid, opcode, pgno, pageimage, pagelsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- u_int32_t opcode;
- db_pgno_t pgno;
- const DBT *pageimage;
- DB_LSN * pagelsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_splitdata;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(opcode)
- + sizeof(pgno)
- + sizeof(u_int32_t) + (pageimage == NULL ? 0 : pageimage->size)
- + sizeof(*pagelsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (pageimage == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &pageimage->size, sizeof(pageimage->size));
- bp += sizeof(pageimage->size);
- memcpy(bp, pageimage->data, pageimage->size);
- bp += pageimage->size;
- }
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_splitdata_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_splitdata_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_splitdata_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_splitdata: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tpageimage: ");
- for (i = 0; i < argp->pageimage.size; i++) {
- ch = ((u_int8_t *)argp->pageimage.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_splitdata_read __P((void *, __ham_splitdata_args **));
- */
-int
-__ham_splitdata_read(recbuf, argpp)
- void *recbuf;
- __ham_splitdata_args **argpp;
-{
- __ham_splitdata_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_splitdata_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->pageimage.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->pageimage.data = bp;
- bp += argp->pageimage.size;
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_replace_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
- * PUBLIC: int32_t, const DBT *, const DBT *, u_int32_t));
- */
-int __ham_replace_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, ndx, pagelsn, off, olditem,
- newitem, makedup)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t ndx;
- DB_LSN * pagelsn;
- int32_t off;
- const DBT *olditem;
- const DBT *newitem;
- u_int32_t makedup;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_replace;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(ndx)
- + sizeof(*pagelsn)
- + sizeof(off)
- + sizeof(u_int32_t) + (olditem == NULL ? 0 : olditem->size)
- + sizeof(u_int32_t) + (newitem == NULL ? 0 : newitem->size)
- + sizeof(makedup);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &ndx, sizeof(ndx));
- bp += sizeof(ndx);
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- memcpy(bp, &off, sizeof(off));
- bp += sizeof(off);
- if (olditem == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &olditem->size, sizeof(olditem->size));
- bp += sizeof(olditem->size);
- memcpy(bp, olditem->data, olditem->size);
- bp += olditem->size;
- }
- if (newitem == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &newitem->size, sizeof(newitem->size));
- bp += sizeof(newitem->size);
- memcpy(bp, newitem->data, newitem->size);
- bp += newitem->size;
- }
- memcpy(bp, &makedup, sizeof(makedup));
- bp += sizeof(makedup);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_replace_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_replace_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_replace_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_replace_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_replace: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tndx: %lu\n", (u_long)argp->ndx);
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\toff: %ld\n", (long)argp->off);
- printf("\tolditem: ");
- for (i = 0; i < argp->olditem.size; i++) {
- ch = ((u_int8_t *)argp->olditem.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tnewitem: ");
- for (i = 0; i < argp->newitem.size; i++) {
- ch = ((u_int8_t *)argp->newitem.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tmakedup: %lu\n", (u_long)argp->makedup);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_replace_read __P((void *, __ham_replace_args **));
- */
-int
-__ham_replace_read(recbuf, argpp)
- void *recbuf;
- __ham_replace_args **argpp;
-{
- __ham_replace_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_replace_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->ndx, bp, sizeof(argp->ndx));
- bp += sizeof(argp->ndx);
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->off, bp, sizeof(argp->off));
- bp += sizeof(argp->off);
- memcpy(&argp->olditem.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->olditem.data = bp;
- bp += argp->olditem.size;
- memcpy(&argp->newitem.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->newitem.data = bp;
- bp += argp->newitem.size;
- memcpy(&argp->makedup, bp, sizeof(argp->makedup));
- bp += sizeof(argp->makedup);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_newpgno_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
- * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
- * PUBLIC: DB_LSN *));
- */
-int __ham_newpgno_log(logp, txnid, ret_lsnp, flags,
- opcode, fileid, pgno, free_pgno, old_type, old_pgno,
- new_type, pagelsn, metalsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- db_pgno_t free_pgno;
- u_int32_t old_type;
- db_pgno_t old_pgno;
- u_int32_t new_type;
- DB_LSN * pagelsn;
- DB_LSN * metalsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_newpgno;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(free_pgno)
- + sizeof(old_type)
- + sizeof(old_pgno)
- + sizeof(new_type)
- + sizeof(*pagelsn)
- + sizeof(*metalsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- memcpy(bp, &free_pgno, sizeof(free_pgno));
- bp += sizeof(free_pgno);
- memcpy(bp, &old_type, sizeof(old_type));
- bp += sizeof(old_type);
- memcpy(bp, &old_pgno, sizeof(old_pgno));
- bp += sizeof(old_pgno);
- memcpy(bp, &new_type, sizeof(new_type));
- bp += sizeof(new_type);
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- if (metalsn != NULL)
- memcpy(bp, metalsn, sizeof(*metalsn));
- else
- memset(bp, 0, sizeof(*metalsn));
- bp += sizeof(*metalsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_newpgno_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_newpgno_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_newpgno_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_newpgno: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tfree_pgno: %lu\n", (u_long)argp->free_pgno);
- printf("\told_type: %lu\n", (u_long)argp->old_type);
- printf("\told_pgno: %lu\n", (u_long)argp->old_pgno);
- printf("\tnew_type: %lu\n", (u_long)argp->new_type);
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\tmetalsn: [%lu][%lu]\n",
- (u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_newpgno_read __P((void *, __ham_newpgno_args **));
- */
-int
-__ham_newpgno_read(recbuf, argpp)
- void *recbuf;
- __ham_newpgno_args **argpp;
-{
- __ham_newpgno_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_newpgno_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->free_pgno, bp, sizeof(argp->free_pgno));
- bp += sizeof(argp->free_pgno);
- memcpy(&argp->old_type, bp, sizeof(argp->old_type));
- bp += sizeof(argp->old_type);
- memcpy(&argp->old_pgno, bp, sizeof(argp->old_pgno));
- bp += sizeof(argp->old_pgno);
- memcpy(&argp->new_type, bp, sizeof(argp->new_type));
- bp += sizeof(argp->new_type);
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->metalsn, bp, sizeof(argp->metalsn));
- bp += sizeof(argp->metalsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_ovfl_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, db_pgno_t,
- * PUBLIC: u_int32_t, DB_LSN *));
- */
-int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
- fileid, start_pgno, npages, free_pgno, ovflpoint, metalsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t start_pgno;
- u_int32_t npages;
- db_pgno_t free_pgno;
- u_int32_t ovflpoint;
- DB_LSN * metalsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_ovfl;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(start_pgno)
- + sizeof(npages)
- + sizeof(free_pgno)
- + sizeof(ovflpoint)
- + sizeof(*metalsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &start_pgno, sizeof(start_pgno));
- bp += sizeof(start_pgno);
- memcpy(bp, &npages, sizeof(npages));
- bp += sizeof(npages);
- memcpy(bp, &free_pgno, sizeof(free_pgno));
- bp += sizeof(free_pgno);
- memcpy(bp, &ovflpoint, sizeof(ovflpoint));
- bp += sizeof(ovflpoint);
- if (metalsn != NULL)
- memcpy(bp, metalsn, sizeof(*metalsn));
- else
- memset(bp, 0, sizeof(*metalsn));
- bp += sizeof(*metalsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_ovfl_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_ovfl_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_ovfl_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_ovfl: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tstart_pgno: %lu\n", (u_long)argp->start_pgno);
- printf("\tnpages: %lu\n", (u_long)argp->npages);
- printf("\tfree_pgno: %lu\n", (u_long)argp->free_pgno);
- printf("\tovflpoint: %lu\n", (u_long)argp->ovflpoint);
- printf("\tmetalsn: [%lu][%lu]\n",
- (u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_ovfl_read __P((void *, __ham_ovfl_args **));
- */
-int
-__ham_ovfl_read(recbuf, argpp)
- void *recbuf;
- __ham_ovfl_args **argpp;
-{
- __ham_ovfl_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_ovfl_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->start_pgno, bp, sizeof(argp->start_pgno));
- bp += sizeof(argp->start_pgno);
- memcpy(&argp->npages, bp, sizeof(argp->npages));
- bp += sizeof(argp->npages);
- memcpy(&argp->free_pgno, bp, sizeof(argp->free_pgno));
- bp += sizeof(argp->free_pgno);
- memcpy(&argp->ovflpoint, bp, sizeof(argp->ovflpoint));
- bp += sizeof(argp->ovflpoint);
- memcpy(&argp->metalsn, bp, sizeof(argp->metalsn));
- bp += sizeof(argp->metalsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_copypage_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- * PUBLIC: DB_LSN *, db_pgno_t, DB_LSN *, const DBT *));
- */
-int __ham_copypage_log(logp, txnid, ret_lsnp, flags,
- fileid, pgno, pagelsn, next_pgno, nextlsn, nnext_pgno,
- nnextlsn, page)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN * pagelsn;
- db_pgno_t next_pgno;
- DB_LSN * nextlsn;
- db_pgno_t nnext_pgno;
- DB_LSN * nnextlsn;
- const DBT *page;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_ham_copypage;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(fileid)
- + sizeof(pgno)
- + sizeof(*pagelsn)
- + sizeof(next_pgno)
- + sizeof(*nextlsn)
- + sizeof(nnext_pgno)
- + sizeof(*nnextlsn)
- + sizeof(u_int32_t) + (page == NULL ? 0 : page->size);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &fileid, sizeof(fileid));
- bp += sizeof(fileid);
- memcpy(bp, &pgno, sizeof(pgno));
- bp += sizeof(pgno);
- if (pagelsn != NULL)
- memcpy(bp, pagelsn, sizeof(*pagelsn));
- else
- memset(bp, 0, sizeof(*pagelsn));
- bp += sizeof(*pagelsn);
- memcpy(bp, &next_pgno, sizeof(next_pgno));
- bp += sizeof(next_pgno);
- if (nextlsn != NULL)
- memcpy(bp, nextlsn, sizeof(*nextlsn));
- else
- memset(bp, 0, sizeof(*nextlsn));
- bp += sizeof(*nextlsn);
- memcpy(bp, &nnext_pgno, sizeof(nnext_pgno));
- bp += sizeof(nnext_pgno);
- if (nnextlsn != NULL)
- memcpy(bp, nnextlsn, sizeof(*nnextlsn));
- else
- memset(bp, 0, sizeof(*nnextlsn));
- bp += sizeof(*nnextlsn);
- if (page == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &page->size, sizeof(page->size));
- bp += sizeof(page->size);
- memcpy(bp, page->data, page->size);
- bp += page->size;
- }
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_copypage_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_copypage_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __ham_copypage_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __ham_copypage_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]ham_copypage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tfileid: %lu\n", (u_long)argp->fileid);
- printf("\tpgno: %lu\n", (u_long)argp->pgno);
- printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
- printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- printf("\tnnext_pgno: %lu\n", (u_long)argp->nnext_pgno);
- printf("\tnnextlsn: [%lu][%lu]\n",
- (u_long)argp->nnextlsn.file, (u_long)argp->nnextlsn.offset);
- printf("\tpage: ");
- for (i = 0; i < argp->page.size; i++) {
- ch = ((u_int8_t *)argp->page.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_copypage_read __P((void *, __ham_copypage_args **));
- */
-int
-__ham_copypage_read(recbuf, argpp)
- void *recbuf;
- __ham_copypage_args **argpp;
-{
- __ham_copypage_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__ham_copypage_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->fileid, bp, sizeof(argp->fileid));
- bp += sizeof(argp->fileid);
- memcpy(&argp->pgno, bp, sizeof(argp->pgno));
- bp += sizeof(argp->pgno);
- memcpy(&argp->pagelsn, bp, sizeof(argp->pagelsn));
- bp += sizeof(argp->pagelsn);
- memcpy(&argp->next_pgno, bp, sizeof(argp->next_pgno));
- bp += sizeof(argp->next_pgno);
- memcpy(&argp->nextlsn, bp, sizeof(argp->nextlsn));
- bp += sizeof(argp->nextlsn);
- memcpy(&argp->nnext_pgno, bp, sizeof(argp->nnext_pgno));
- bp += sizeof(argp->nnext_pgno);
- memcpy(&argp->nnextlsn, bp, sizeof(argp->nnextlsn));
- bp += sizeof(argp->nnextlsn);
- memcpy(&argp->page.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->page.data = bp;
- bp += argp->page.size;
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_init_print __P((DB_ENV *));
- */
-int
-__ham_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __ham_insdel_print, DB_ham_insdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_newpage_print, DB_ham_newpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_splitmeta_print, DB_ham_splitmeta)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_splitdata_print, DB_ham_splitdata)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_replace_print, DB_ham_replace)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_newpgno_print, DB_ham_newpgno)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_ovfl_print, DB_ham_ovfl)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_copypage_print, DB_ham_copypage)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_init_recover __P((DB_ENV *));
- */
-int
-__ham_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __ham_insdel_recover, DB_ham_insdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_newpage_recover, DB_ham_newpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_splitmeta_recover, DB_ham_splitmeta)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_splitdata_recover, DB_ham_splitdata)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_replace_recover, DB_ham_replace)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_newpgno_recover, DB_ham_newpgno)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_ovfl_recover, DB_ham_ovfl)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __ham_copypage_recover, DB_ham_copypage)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/hash/hash_conv.c b/db2/hash/hash_conv.c
deleted file mode 100644
index c6d0ba4..0000000
--- a/db2/hash/hash_conv.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_conv.c 10.5 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_swap.h"
-#include "hash.h"
-
-/*
- * __ham_pgin --
- * Convert host-specific page layout from the host-independent format
- * stored on disk.
- *
- * PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *));
- */
-int
-__ham_pgin(pg, pp, cookie)
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB_PGINFO *pginfo;
- u_int32_t tpgno;
-
- pginfo = (DB_PGINFO *)cookie->data;
- tpgno = PGNO((PAGE *)pp);
- if (pginfo->needswap)
- M_32_SWAP(tpgno);
-
- if (pg != PGNO_METADATA && pg != tpgno) {
- P_INIT(pp, pginfo->db_pagesize,
- pg, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
- return (0);
- }
-
- if (!pginfo->needswap)
- return (0);
- return (pg == PGNO_METADATA ?
- __ham_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
-}
-
-/*
- * __ham_pgout --
- * Convert host-specific page layout to the host-independent format
- * stored on disk.
- *
- * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
- */
-int
-__ham_pgout(pg, pp, cookie)
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB_PGINFO *pginfo;
-
- pginfo = (DB_PGINFO *)cookie->data;
- if (!pginfo->needswap)
- return (0);
- return (pg == PGNO_METADATA ?
- __ham_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
-}
-
-/*
- * __ham_mswap --
- * Swap the bytes on the hash metadata page.
- *
- * PUBLIC: int __ham_mswap __P((void *));
- */
-int
-__ham_mswap(pg)
- void *pg;
-{
- u_int8_t *p;
- int i;
-
- p = (u_int8_t *)pg;
- SWAP32(p); /* lsn part 1 */
- SWAP32(p); /* lsn part 2 */
- SWAP32(p); /* pgno */
- SWAP32(p); /* magic */
- SWAP32(p); /* version */
- SWAP32(p); /* pagesize */
- SWAP32(p); /* ovfl_point */
- SWAP32(p); /* last_freed */
- SWAP32(p); /* max_bucket */
- SWAP32(p); /* high_mask */
- SWAP32(p); /* low_mask */
- SWAP32(p); /* ffactor */
- SWAP32(p); /* nelem */
- SWAP32(p); /* h_charkey */
- SWAP32(p); /* flags */
- for (i = 0; i < NCACHED; ++i)
- SWAP32(p); /* spares */
- return (0);
-}
diff --git a/db2/hash/hash_dup.c b/db2/hash/hash_dup.c
deleted file mode 100644
index bb34664..0000000
--- a/db2/hash/hash_dup.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_dup.c 10.27 (Sleepycat) 12/6/98";
-#endif /* not lint */
-
-/*
- * PACKAGE: hashing
- *
- * DESCRIPTION:
- * Manipulation of duplicates for the hash package.
- *
- * ROUTINES:
- *
- * External
- * __add_dup
- * Internal
- */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "hash.h"
-#include "btree.h"
-
-static int __ham_check_move __P((DBC *, int32_t));
-static int __ham_dup_convert __P((DBC *));
-static int __ham_make_dup __P((const DBT *, DBT *d, void **, u_int32_t *));
-
-/*
- * Called from hash_access to add a duplicate key. nval is the new
- * value that we want to add. The flags correspond to the flag values
- * to cursor_put indicating where to add the new element.
- * There are 4 cases.
- * Case 1: The existing duplicate set already resides on a separate page.
- * We can use common code for this.
- * Case 2: The element is small enough to just be added to the existing set.
- * Case 3: The element is large enough to be a big item, so we're going to
- * have to push the set onto a new page.
- * Case 4: The element is large enough to push the duplicate set onto a
- * separate page.
- *
- * PUBLIC: int __ham_add_dup __P((DBC *, DBT *, u_int32_t));
- */
-int
-__ham_add_dup(dbc, nval, flags)
- DBC *dbc;
- DBT *nval;
- u_int32_t flags;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT dbt, pval, tmp_val;
- u_int32_t del_len, new_size;
- int cmp, ret;
- u_int8_t *hk;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID)
- del_len = hcp->dup_len;
- else
- del_len = 0;
-
- if ((ret = __ham_check_move(dbc,
- (int32_t)DUP_SIZE(nval->size) - (int32_t)del_len)) != 0)
- return (ret);
-
- /*
- * Check if resulting duplicate set is going to need to go
- * onto a separate duplicate page. If so, convert the
- * duplicate set and add the new one. After conversion,
- * hcp->dndx is the first free ndx or the index of the
- * current pointer into the duplicate set.
- */
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- new_size = DUP_SIZE(nval->size) - del_len + LEN_HKEYDATA(hcp->pagep,
- hcp->hdr->pagesize, H_DATAINDEX(hcp->bndx));
-
- /*
- * We convert to off-page duplicates if the item is a big item,
- * the addition of the new item will make the set large, or
- * if there isn't enough room on this page to add the next item.
- */
- if (HPAGE_PTYPE(hk) != H_OFFDUP &&
- (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hcp, new_size) ||
- DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) {
-
- if ((ret = __ham_dup_convert(dbc)) != 0)
- return (ret);
- else
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- }
-
- /* There are two separate cases here: on page and off page. */
- if (HPAGE_PTYPE(hk) != H_OFFDUP) {
- if (HPAGE_PTYPE(hk) != H_DUPLICATE) {
- HPAGE_PTYPE(hk) = H_DUPLICATE;
- pval.flags = 0;
- pval.data = HKEYDATA_DATA(hk);
- pval.size = LEN_HDATA(hcp->pagep, dbp->pgsize,
- hcp->bndx);
- if ((ret =
- __ham_make_dup(&pval, &tmp_val, &dbc->rdata.data,
- &dbc->rdata.size)) != 0 || (ret =
- __ham_replpair(dbc, &tmp_val, 1)) != 0)
- return (ret);
- }
-
- /* Now make the new entry a duplicate. */
- if ((ret = __ham_make_dup(nval,
- &tmp_val, &dbc->rdata.data, &dbc->rdata.size)) != 0)
- return (ret);
-
- tmp_val.dlen = 0;
- switch (flags) { /* On page. */
- case DB_KEYFIRST:
- case DB_KEYLAST:
- if (dbp->dup_compare != NULL)
- __ham_dsearch(dbc, nval, &tmp_val.doff, &cmp);
- else if (flags == DB_KEYFIRST)
- tmp_val.doff = 0;
- else
- tmp_val.doff = LEN_HDATA(hcp->pagep,
- hcp->hdr->pagesize, hcp->bndx);
- break;
- case DB_CURRENT:
- /*
- * If we have a sort function, we need to verify that
- * the new item sorts identically to the old item.
- */
- if (dbp->dup_compare != NULL) {
- dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep,
- hcp->bndx)) + hcp->dup_off;
- dbt.size = DUP_SIZE(hcp->dup_len);
- if (dbp->dup_compare(nval, &dbt) != 0)
- return (EINVAL);
- }
- tmp_val.doff = hcp->dup_off;
- tmp_val.dlen = DUP_SIZE(hcp->dup_len);
- break;
- case DB_BEFORE:
- tmp_val.doff = hcp->dup_off;
- break;
- case DB_AFTER:
- tmp_val.doff = hcp->dup_off + DUP_SIZE(hcp->dup_len);
- break;
- }
- /* Add the duplicate. */
- ret = __ham_replpair(dbc, &tmp_val, 0);
- if (ret == 0)
- ret = __ham_dirty_page(dbp, hcp->pagep);
- __ham_c_update(hcp, hcp->pgno, tmp_val.size, 1, 1);
- return (ret);
- }
-
- /* If we get here, then we're on duplicate pages. */
- if (hcp->dpgno == PGNO_INVALID) {
- memcpy(&hcp->dpgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
- hcp->dndx = 0;
- }
-
- switch (flags) {
- case DB_KEYFIRST:
- if (dbp->dup_compare != NULL)
- goto sorted_dups;
- /*
- * The only way that we are already on a dup page is
- * if we just converted the on-page representation.
- * In that case, we've only got one page of duplicates.
- */
- if (hcp->dpagep == NULL && (ret =
- __db_dend(dbc, hcp->dpgno, &hcp->dpagep)) != 0)
- return (ret);
- hcp->dndx = 0;
- break;
- case DB_KEYLAST:
- if (dbp->dup_compare != NULL) {
-sorted_dups: if ((ret = __db_dsearch(dbc, 1, nval,
- hcp->dpgno, &hcp->dndx, &hcp->dpagep, &cmp)) != 0)
- return (ret);
- if (cmp == 0)
- hcp->dpgno = PGNO(hcp->dpagep);
- } else {
- if (hcp->dpagep == NULL && (ret =
- __db_dend(dbc, hcp->dpgno, &hcp->dpagep)) != 0)
- return (ret);
- hcp->dpgno = PGNO(hcp->dpagep);
- hcp->dndx = NUM_ENT(hcp->dpagep);
- }
- break;
- case DB_CURRENT:
- if (dbp->dup_compare != NULL && __bam_cmp(dbp,
- nval, hcp->dpagep, hcp->dndx, dbp->dup_compare) != 0)
- return (EINVAL);
- switch (GET_BKEYDATA(hcp->dpagep, hcp->dndx)->type) {
- case B_KEYDATA:
- del_len = BKEYDATA_SIZE(GET_BKEYDATA(hcp->dpagep,
- hcp->dndx)->len);
- break;
- case B_OVERFLOW:
- del_len = BOVERFLOW_SIZE;
- break;
- }
- if ((ret =
- __db_ditem(dbc, hcp->dpagep, hcp->dndx, del_len)) != 0)
- return (ret);
- break;
- case DB_BEFORE: /* The default behavior is correct. */
- break;
- case DB_AFTER:
- hcp->dndx++;
- break;
- }
-
- ret = __db_dput(dbc,
- nval, &hcp->dpagep, &hcp->dndx, __ham_overflow_page);
- hcp->pgno = PGNO(hcp->pagep);
- __ham_c_update(hcp, hcp->pgno, nval->size, 1, 1);
- return (ret);
-}
-
-/*
- * Convert an on-page set of duplicates to an offpage set of duplicates.
- */
-static int
-__ham_dup_convert(dbc)
- DBC *dbc;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- BOVERFLOW bo;
- DBT dbt;
- HOFFPAGE ho;
- db_indx_t dndx, i, len, off;
- int ret;
- u_int8_t *p, *pend;
-
- /*
- * Create a new page for the duplicates.
- */
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- if ((ret =
- __ham_overflow_page(dbc, P_DUPLICATE, &hcp->dpagep)) != 0)
- return (ret);
- hcp->dpagep->type = P_DUPLICATE;
- hcp->dpgno = PGNO(hcp->dpagep);
-
- /*
- * Now put the duplicates onto the new page.
- */
- dndx = 0;
- dbt.flags = 0;
- switch (HPAGE_PTYPE(H_PAIRDATA(hcp->pagep, hcp->bndx))) {
- case H_KEYDATA:
- /* Simple case, one key on page; move it to dup page. */
- dbt.size =
- LEN_HDATA(hcp->pagep, hcp->hdr->pagesize, hcp->bndx);
- dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- ret = __db_pitem(dbc, hcp->dpagep,
- (u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt);
- if (ret == 0)
- __ham_dirty_page(dbp, hcp->dpagep);
- break;
- case H_OFFPAGE:
- /* Simple case, one key on page; move it to dup page. */
- memcpy(&ho,
- P_ENTRY(hcp->pagep, H_DATAINDEX(hcp->bndx)), HOFFPAGE_SIZE);
- UMRW(bo.unused1);
- B_TSET(bo.type, ho.type, 0);
- UMRW(bo.unused2);
- bo.pgno = ho.pgno;
- bo.tlen = ho.tlen;
- dbt.size = BOVERFLOW_SIZE;
- dbt.data = &bo;
-
- ret = __db_pitem(dbc, hcp->dpagep,
- (u_int32_t)dndx, dbt.size, &dbt, NULL);
- if (ret == 0)
- __ham_dirty_page(dbp, hcp->dpagep);
- break;
- case H_DUPLICATE:
- p = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- pend = p +
- LEN_HDATA(hcp->pagep, hcp->hdr->pagesize, hcp->bndx);
-
- /*
- * We need to maintain the duplicate cursor position.
- * Keep track of where we are in the duplicate set via
- * the offset, and when it matches the one in the cursor,
- * set the off-page duplicate cursor index to the current
- * index.
- */
- for (off = 0, i = 0; p < pend; i++) {
- if (off == hcp->dup_off)
- dndx = i;
- memcpy(&len, p, sizeof(db_indx_t));
- dbt.size = len;
- p += sizeof(db_indx_t);
- dbt.data = p;
- p += len + sizeof(db_indx_t);
- off += len + 2 * sizeof(db_indx_t);
- ret = __db_dput(dbc, &dbt,
- &hcp->dpagep, &i, __ham_overflow_page);
- if (ret != 0)
- break;
- }
- break;
- default:
- ret = __db_pgfmt(dbp, (u_long)hcp->pgno);
- break;
- }
- if (ret == 0) {
- /*
- * Now attach this to the source page in place of
- * the old duplicate item.
- */
- __ham_move_offpage(dbc, hcp->pagep,
- (u_int32_t)H_DATAINDEX(hcp->bndx), hcp->dpgno);
-
- /* Can probably just do a "put" here. */
- ret = __ham_dirty_page(dbp, hcp->pagep);
- hcp->dndx = dndx;
- } else {
- (void)__ham_del_page(dbc, hcp->dpagep);
- hcp->dpagep = NULL;
- }
- return (ret);
-}
-
-static int
-__ham_make_dup(notdup, duplicate, bufp, sizep)
- const DBT *notdup;
- DBT *duplicate;
- void **bufp;
- u_int32_t *sizep;
-{
- db_indx_t tsize, item_size;
- int ret;
- u_int8_t *p;
-
- item_size = (db_indx_t)notdup->size;
- tsize = DUP_SIZE(item_size);
- if ((ret = __ham_init_dbt(duplicate, tsize, bufp, sizep)) != 0)
- return (ret);
-
- duplicate->dlen = 0;
- duplicate->flags = notdup->flags;
- F_SET(duplicate, DB_DBT_PARTIAL);
-
- p = duplicate->data;
- memcpy(p, &item_size, sizeof(db_indx_t));
- p += sizeof(db_indx_t);
- memcpy(p, notdup->data, notdup->size);
- p += notdup->size;
- memcpy(p, &item_size, sizeof(db_indx_t));
-
- duplicate->doff = 0;
- duplicate->dlen = notdup->size;
-
- return (0);
-}
-
-static int
-__ham_check_move(dbc, add_len)
- DBC *dbc;
- int32_t add_len;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT k, d;
- DB_LSN new_lsn;
- PAGE *next_pagep;
- db_pgno_t next_pgno;
- u_int32_t new_datalen, old_len, rectype;
- u_int8_t *hk;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- /*
- * Check if we can do whatever we need to on this page. If not,
- * then we'll have to move the current element to a new page.
- */
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
-
- /*
- * If the item is already off page duplicates or an offpage item,
- * then we know we can do whatever we need to do in-place
- */
- if (HPAGE_PTYPE(hk) == H_OFFDUP || HPAGE_PTYPE(hk) == H_OFFPAGE)
- return (0);
-
- old_len =
- LEN_HITEM(hcp->pagep, hcp->hdr->pagesize, H_DATAINDEX(hcp->bndx));
- new_datalen = old_len - HKEYDATA_SIZE(0) + add_len;
-
- /*
- * We need to add a new page under two conditions:
- * 1. The addition makes the total data length cross the BIG
- * threshold and the OFFDUP structure won't fit on this page.
- * 2. The addition does not make the total data cross the
- * threshold, but the new data won't fit on the page.
- * If neither of these is true, then we can return.
- */
- if (ISBIG(hcp, new_datalen) && (old_len > HOFFDUP_SIZE ||
- HOFFDUP_SIZE - old_len <= P_FREESPACE(hcp->pagep)))
- return (0);
-
- if (!ISBIG(hcp, new_datalen) &&
- add_len <= (int32_t)P_FREESPACE(hcp->pagep))
- return (0);
-
- /*
- * If we get here, then we need to move the item to a new page.
- * Check if there are more pages in the chain.
- */
-
- new_datalen = ISBIG(hcp, new_datalen) ?
- HOFFDUP_SIZE : HKEYDATA_SIZE(new_datalen);
-
- next_pagep = NULL;
- for (next_pgno = NEXT_PGNO(hcp->pagep); next_pgno != PGNO_INVALID;
- next_pgno = NEXT_PGNO(next_pagep)) {
- if (next_pagep != NULL &&
- (ret = __ham_put_page(dbp, next_pagep, 0)) != 0)
- return (ret);
-
- if ((ret =
- __ham_get_page(dbp, next_pgno, &next_pagep)) != 0)
- return (ret);
-
- if (P_FREESPACE(next_pagep) >= new_datalen)
- break;
- }
-
- /* No more pages, add one. */
- if (next_pagep == NULL && (ret = __ham_add_ovflpage(dbc,
- hcp->pagep, 0, &next_pagep)) != 0)
- return (ret);
-
- /* Add new page at the end of the chain. */
- if (P_FREESPACE(next_pagep) < new_datalen && (ret =
- __ham_add_ovflpage(dbc, next_pagep, 1, &next_pagep)) != 0)
- return (ret);
-
- /* Copy the item to the new page. */
- if (DB_LOGGING(hcp->dbc)) {
- rectype = PUTPAIR;
- k.flags = 0;
- d.flags = 0;
- if (HPAGE_PTYPE(
- H_PAIRKEY(hcp->pagep, hcp->bndx)) == H_OFFPAGE) {
- rectype |= PAIR_KEYMASK;
- k.data = H_PAIRKEY(hcp->pagep, hcp->bndx);
- k.size = HOFFPAGE_SIZE;
- } else {
- k.data =
- HKEYDATA_DATA(H_PAIRKEY(hcp->pagep, hcp->bndx));
- k.size = LEN_HKEY(hcp->pagep,
- hcp->hdr->pagesize, hcp->bndx);
- }
-
- if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
- rectype |= PAIR_DATAMASK;
- d.data = H_PAIRDATA(hcp->pagep, hcp->bndx);
- d.size = HOFFPAGE_SIZE;
- } else {
- d.data =
- HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- d.size = LEN_HDATA(hcp->pagep,
- hcp->hdr->pagesize, hcp->bndx);
- }
-
-
- if ((ret = __ham_insdel_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, rectype,
- dbp->log_fileid, PGNO(next_pagep),
- (u_int32_t)H_NUMPAIRS(next_pagep), &LSN(next_pagep),
- &k, &d)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(next_pagep) = new_lsn; /* Structure assignment. */
- }
-
- __ham_copy_item(dbp->pgsize,
- hcp->pagep, H_KEYINDEX(hcp->bndx), next_pagep);
- __ham_copy_item(dbp->pgsize,
- hcp->pagep, H_DATAINDEX(hcp->bndx), next_pagep);
-
- /* Now delete the pair from the current page. */
- ret = __ham_del_pair(dbc, 0);
-
- (void)__ham_put_page(dbp, hcp->pagep, 1);
- hcp->pagep = next_pagep;
- hcp->pgno = PGNO(hcp->pagep);
- hcp->bndx = H_NUMPAIRS(hcp->pagep) - 1;
- F_SET(hcp, H_EXPAND);
- return (ret);
-}
-
-/*
- * __ham_move_offpage --
- * Replace an onpage set of duplicates with the OFFDUP structure
- * that references the duplicate page.
- *
- * XXX
- * This is really just a special case of __onpage_replace; we should
- * probably combine them.
- *
- * PUBLIC: void __ham_move_offpage __P((DBC *, PAGE *, u_int32_t, db_pgno_t));
- */
-void
-__ham_move_offpage(dbc, pagep, ndx, pgno)
- DBC *dbc;
- PAGE *pagep;
- u_int32_t ndx;
- db_pgno_t pgno;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT new_dbt;
- DBT old_dbt;
- HOFFDUP od;
- db_indx_t i;
- int32_t shrink;
- u_int8_t *src;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- od.type = H_OFFDUP;
- UMRW(od.unused[0]);
- UMRW(od.unused[1]);
- UMRW(od.unused[2]);
- od.pgno = pgno;
-
- if (DB_LOGGING(dbc)) {
- new_dbt.data = &od;
- new_dbt.size = HOFFDUP_SIZE;
- old_dbt.data = P_ENTRY(pagep, ndx);
- old_dbt.size = LEN_HITEM(pagep, hcp->hdr->pagesize, ndx);
- (void)__ham_replace_log(dbp->dbenv->lg_info,
- dbc->txn, &LSN(pagep), 0, dbp->log_fileid,
- PGNO(pagep), (u_int32_t)ndx, &LSN(pagep), -1,
- &old_dbt, &new_dbt, 0);
- }
-
- shrink =
- LEN_HITEM(pagep, hcp->hdr->pagesize, ndx) - HOFFDUP_SIZE;
-
- if (shrink != 0) {
- /* Copy data. */
- src = (u_int8_t *)(pagep) + HOFFSET(pagep);
- memmove(src + shrink, src, pagep->inp[ndx] - HOFFSET(pagep));
- HOFFSET(pagep) += shrink;
-
- /* Update index table. */
- for (i = ndx; i < NUM_ENT(pagep); i++)
- pagep->inp[i] += shrink;
- }
-
- /* Now copy the offdup entry onto the page. */
- memcpy(P_ENTRY(pagep, ndx), &od, HOFFDUP_SIZE);
-}
-
-/*
- * __ham_dsearch:
- * Locate a particular duplicate in a duplicate set.
- *
- * PUBLIC: void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *));
- */
-void
-__ham_dsearch(dbc, dbt, offp, cmpp)
- DBC *dbc;
- DBT *dbt;
- u_int32_t *offp;
- int *cmpp;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT cur;
- db_indx_t i, len;
- int (*func) __P((const DBT *, const DBT *));
- u_int8_t *data;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- if (dbp->dup_compare == NULL)
- func = __bam_defcmp;
- else
- func = dbp->dup_compare;
-
- i = F_ISSET(dbc, DBC_CONTINUE) ? hcp->dup_off: 0;
- data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)) + i;
- while (i < LEN_HDATA(hcp->pagep, hcp->hdr->pagesize, hcp->bndx)) {
- memcpy(&len, data, sizeof(db_indx_t));
- data += sizeof(db_indx_t);
- cur.data = data;
- cur.size = (u_int32_t)len;
- *cmpp = func(dbt, &cur);
- if (*cmpp == 0 || (*cmpp < 0 && dbp->dup_compare != NULL))
- break;
- i += len + 2 * sizeof(db_indx_t);
- data += len + sizeof(db_indx_t);
- }
- *offp = i;
-}
diff --git a/db2/hash/hash_func.c b/db2/hash/hash_func.c
deleted file mode 100644
index 9131098..0000000
--- a/db2/hash/hash_func.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993
- * Margo Seltzer. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_func.c 10.8 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "hash.h"
-
-/*
- * __ham_func2 --
- * Phong Vo's linear congruential hash.
- *
- * PUBLIC: u_int32_t __ham_func2 __P((const void *, u_int32_t));
- */
-#define DCHARHASH(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
-
-u_int32_t
-__ham_func2(key, len)
- const void *key;
- u_int32_t len;
-{
- const u_int8_t *e, *k;
- u_int32_t h;
- u_int8_t c;
-
- k = key;
- e = k + len;
- for (h = 0; k != e;) {
- c = *k++;
- if (!c && k > e)
- break;
- DCHARHASH(h, c);
- }
- return (h);
-}
-
-/*
- * __ham_func3 --
- * Ozan Yigit's original sdbm hash.
- *
- * Ugly, but fast. Break the string up into 8 byte units. On the first time
- * through the loop get the "leftover bytes" (strlen % 8). On every other
- * iteration, perform 8 HASHC's so we handle all 8 bytes. Essentially, this
- * saves us 7 cmp & branch instructions.
- *
- * PUBLIC: u_int32_t __ham_func3 __P((const void *, u_int32_t));
- */
-u_int32_t
-__ham_func3(key, len)
- const void *key;
- u_int32_t len;
-{
- const u_int8_t *k;
- u_int32_t n, loop;
-
- if (len == 0)
- return (0);
-
-#define HASHC n = *k++ + 65599 * n
- n = 0;
- k = key;
-
- loop = (len + 8 - 1) >> 3;
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASHC;
- case 7:
- HASHC;
- case 6:
- HASHC;
- case 5:
- HASHC;
- case 4:
- HASHC;
- case 3:
- HASHC;
- case 2:
- HASHC;
- case 1:
- HASHC;
- } while (--loop);
- }
- return (n);
-}
-
-/*
- * __ham_func4 --
- * Chris Torek's hash function. Although this function performs only
- * slightly worse than __ham_func5 on strings, it performs horribly on
- * numbers.
- *
- * PUBLIC: u_int32_t __ham_func4 __P((const void *, u_int32_t));
- */
-u_int32_t
-__ham_func4(key, len)
- const void *key;
- u_int32_t len;
-{
- const u_int8_t *k;
- u_int32_t h, loop;
-
- if (len == 0)
- return (0);
-
-#define HASH4a h = (h << 5) - h + *k++;
-#define HASH4b h = (h << 5) + h + *k++;
-#define HASH4 HASH4b
- h = 0;
- k = key;
-
- loop = (len + 8 - 1) >> 3;
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASH4;
- case 7:
- HASH4;
- case 6:
- HASH4;
- case 5:
- HASH4;
- case 4:
- HASH4;
- case 3:
- HASH4;
- case 2:
- HASH4;
- case 1:
- HASH4;
- } while (--loop);
- }
- return (h);
-}
-
-/*
- * Fowler/Noll/Vo hash
- *
- * The basis of the hash algorithm was taken from an idea sent by email to the
- * IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
- * Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com)
- * later improved on their algorithm.
- *
- * The magic is in the interesting relationship between the special prime
- * 16777619 (2^24 + 403) and 2^32 and 2^8.
- *
- * This hash produces the fewest collisions of any function that we've seen so
- * far, and works well on both numbers and strings.
- *
- * PUBLIC: u_int32_t __ham_func5 __P((const void *, u_int32_t));
- */
-u_int32_t
-__ham_func5(key, len)
- const void *key;
- u_int32_t len;
-{
- const u_int8_t *k, *e;
- u_int32_t h;
-
- k = key;
- e = k + len;
- for (h = 0; k < e; ++k) {
- h *= 16777619;
- h ^= *k;
- }
- return (h);
-}
diff --git a/db2/hash/hash_page.c b/db2/hash/hash_page.c
deleted file mode 100644
index 3419c12..0000000
--- a/db2/hash/hash_page.c
+++ /dev/null
@@ -1,1929 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * Margo Seltzer. All rights reserved.
- */
-/*
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_page.c 10.55 (Sleepycat) 1/3/99";
-#endif /* not lint */
-
-/*
- * PACKAGE: hashing
- *
- * DESCRIPTION:
- * Page manipulation for hashing package.
- *
- * ROUTINES:
- *
- * External
- * __get_page
- * __add_ovflpage
- * __overflow_page
- * Internal
- * open_temp
- */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "hash.h"
-
-static int __ham_lock_bucket __P((DBC *, db_lockmode_t));
-
-#ifdef DEBUG_SLOW
-static void __account_page(DB *, db_pgno_t, int);
-#endif
-
-/*
- * PUBLIC: int __ham_item __P((DBC *, db_lockmode_t));
- */
-int
-__ham_item(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- db_pgno_t next_pgno;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if (F_ISSET(hcp, H_DELETED))
- return (EINVAL);
- F_CLR(hcp, H_OK | H_NOMORE);
-
- /* Check if we need to get a page for this cursor. */
- if ((ret = __ham_get_cpage(dbc, mode)) != 0)
- return (ret);
-
- /* Check if we are looking for space in which to insert an item. */
- if (hcp->seek_size && hcp->seek_found_page == PGNO_INVALID
- && hcp->seek_size < P_FREESPACE(hcp->pagep))
- hcp->seek_found_page = hcp->pgno;
-
- /* Check if we need to go on to the next page. */
- if (F_ISSET(hcp, H_ISDUP) && hcp->dpgno == PGNO_INVALID)
- /*
- * ISDUP is set, and offset is at the beginning of the datum.
- * We need to grab the length of the datum, then set the datum
- * pointer to be the beginning of the datum.
- */
- memcpy(&hcp->dup_len,
- HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)) +
- hcp->dup_off, sizeof(db_indx_t));
- else if (F_ISSET(hcp, H_ISDUP)) {
- /* Make sure we're not about to run off the page. */
- if (hcp->dpagep == NULL && (ret = __ham_get_page(dbp,
- hcp->dpgno, &hcp->dpagep)) != 0)
- return (ret);
-
- if (hcp->dndx >= NUM_ENT(hcp->dpagep)) {
- if (NEXT_PGNO(hcp->dpagep) == PGNO_INVALID) {
- if (F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- }
- if ((ret = __ham_put_page(dbp,
- hcp->dpagep, 0)) != 0)
- return (ret);
- F_CLR(hcp, H_ISDUP);
- hcp->dpagep = NULL;
- hcp->dpgno = PGNO_INVALID;
- hcp->dndx = NDX_INVALID;
- hcp->bndx++;
- } else if ((ret = __ham_next_cpage(dbc,
- NEXT_PGNO(hcp->dpagep), 0, H_ISDUP)) != 0)
- return (ret);
- }
- }
-
- if (hcp->bndx >= (db_indx_t)H_NUMPAIRS(hcp->pagep)) {
- /* Fetch next page. */
- if (NEXT_PGNO(hcp->pagep) == PGNO_INVALID) {
- F_SET(hcp, H_NOMORE);
- if (hcp->dpagep != NULL &&
- (ret = __ham_put_page(dbp, hcp->dpagep, 0)) != 0)
- return (ret);
- hcp->dpgno = PGNO_INVALID;
- return (DB_NOTFOUND);
- }
- next_pgno = NEXT_PGNO(hcp->pagep);
- hcp->bndx = 0;
- if ((ret = __ham_next_cpage(dbc, next_pgno, 0, 0)) != 0)
- return (ret);
- }
-
- F_SET(hcp, H_OK);
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_item_reset __P((DBC *));
- */
-int
-__ham_item_reset(dbc)
- DBC *dbc;
-{
- HASH_CURSOR *hcp;
- DB *dbp;
- int ret;
-
- ret = 0;
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- if (hcp->pagep != NULL)
- ret = __ham_put_page(dbp, hcp->pagep, 0);
- if (ret == 0 && hcp->dpagep != NULL)
- ret = __ham_put_page(dbp, hcp->dpagep, 0);
-
- __ham_item_init(hcp);
- return (ret);
-}
-
-/*
- * PUBLIC: void __ham_item_init __P((HASH_CURSOR *));
- */
-void
-__ham_item_init(hcp)
- HASH_CURSOR *hcp;
-{
- /*
- * If this cursor still holds any locks, we must
- * release them if we are not running with transactions.
- */
- if (hcp->lock && hcp->dbc->txn == NULL)
- (void)lock_put(hcp->dbc->dbp->dbenv->lk_info, hcp->lock);
-
- /*
- * The following fields must *not* be initialized here
- * because they may have meaning across inits.
- * hlock, hdr, split_buf, stats
- */
- hcp->bucket = BUCKET_INVALID;
- hcp->lbucket = BUCKET_INVALID;
- hcp->lock = 0;
- hcp->pagep = NULL;
- hcp->pgno = PGNO_INVALID;
- hcp->bndx = NDX_INVALID;
- hcp->dpagep = NULL;
- hcp->dpgno = PGNO_INVALID;
- hcp->dndx = NDX_INVALID;
- hcp->dup_off = 0;
- hcp->dup_len = 0;
- hcp->dup_tlen = 0;
- hcp->seek_size = 0;
- hcp->seek_found_page = PGNO_INVALID;
- hcp->flags = 0;
-}
-
-/*
- * PUBLIC: int __ham_item_done __P((DBC *, int));
- */
-int
-__ham_item_done(dbc, dirty)
- DBC *dbc;
- int dirty;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- t_ret = ret = 0;
-
- if (hcp->pagep)
- ret = __ham_put_page(dbp, hcp->pagep,
- dirty && hcp->dpagep == NULL);
- hcp->pagep = NULL;
-
- if (hcp->dpagep)
- t_ret = __ham_put_page(dbp, hcp->dpagep, dirty);
- hcp->dpagep = NULL;
-
- if (ret == 0 && t_ret != 0)
- ret = t_ret;
-
- /*
- * We don't throw out the page number since we might want to
- * continue getting on this page.
- */
- return (ret != 0 ? ret : t_ret);
-}
-
-/*
- * Returns the last item in a bucket.
- *
- * PUBLIC: int __ham_item_last __P((DBC *, db_lockmode_t));
- */
-int
-__ham_item_last(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- HASH_CURSOR *hcp;
- int ret;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- if ((ret = __ham_item_reset(dbc)) != 0)
- return (ret);
-
- hcp->bucket = hcp->hdr->max_bucket;
- F_SET(hcp, H_OK);
- return (__ham_item_prev(dbc, mode));
-}
-
-/*
- * PUBLIC: int __ham_item_first __P((DBC *, db_lockmode_t));
- */
-int
-__ham_item_first(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- HASH_CURSOR *hcp;
- int ret;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- if ((ret = __ham_item_reset(dbc)) != 0)
- return (ret);
- F_SET(hcp, H_OK);
- hcp->bucket = 0;
- return (__ham_item_next(dbc, mode));
-}
-
-/*
- * __ham_item_prev --
- * Returns a pointer to key/data pair on a page. In the case of
- * bigkeys, just returns the page number and index of the bigkey
- * pointer pair.
- *
- * PUBLIC: int __ham_item_prev __P((DBC *, db_lockmode_t));
- */
-int
-__ham_item_prev(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- db_pgno_t next_pgno;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- /*
- * There are N cases for backing up in a hash file.
- * Case 1: In the middle of a page, no duplicates, just dec the index.
- * Case 2: In the middle of a duplicate set, back up one.
- * Case 3: At the beginning of a duplicate set, get out of set and
- * back up to next key.
- * Case 4: At the beginning of a page; go to previous page.
- * Case 5: At the beginning of a bucket; go to prev bucket.
- */
- F_CLR(hcp, H_OK | H_NOMORE | H_DELETED);
-
- /*
- * First handle the duplicates. Either you'll get the key here
- * or you'll exit the duplicate set and drop into the code below
- * to handle backing up through keys.
- */
- if (F_ISSET(hcp, H_ISDUP)) {
- if (hcp->dpgno == PGNO_INVALID) {
- /* Duplicates are on-page. */
- if (hcp->dup_off != 0) {
- if ((ret = __ham_get_cpage(dbc, mode)) != 0)
- return (ret);
- else {
- HASH_CURSOR *h;
- h = hcp;
- memcpy(&h->dup_len, HKEYDATA_DATA(
- H_PAIRDATA(h->pagep, h->bndx))
- + h->dup_off - sizeof(db_indx_t),
- sizeof(db_indx_t));
- hcp->dup_off -=
- DUP_SIZE(hcp->dup_len);
- hcp->dndx--;
- return (__ham_item(dbc, mode));
- }
- }
- } else if (hcp->dndx > 0) { /* Duplicates are off-page. */
- hcp->dndx--;
- return (__ham_item(dbc, mode));
- } else if ((ret = __ham_get_cpage(dbc, mode)) != 0)
- return (ret);
- else if (PREV_PGNO(hcp->dpagep) == PGNO_INVALID) {
- if (F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- } else {
- F_CLR(hcp, H_ISDUP); /* End of dups */
- hcp->dpgno = PGNO_INVALID;
- if (hcp->dpagep != NULL)
- (void)__ham_put_page(dbp,
- hcp->dpagep, 0);
- hcp->dpagep = NULL;
- }
- } else if ((ret = __ham_next_cpage(dbc,
- PREV_PGNO(hcp->dpagep), 0, H_ISDUP)) != 0)
- return (ret);
- else {
- hcp->dndx = NUM_ENT(hcp->pagep) - 1;
- return (__ham_item(dbc, mode));
- }
- }
-
- /*
- * If we get here, we are not in a duplicate set, and just need
- * to back up the cursor. There are still three cases:
- * midpage, beginning of page, beginning of bucket.
- */
-
- if (F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- }
-
- if (hcp->bndx == 0) { /* Beginning of page. */
- if ((ret = __ham_get_cpage(dbc, mode)) != 0)
- return (ret);
- hcp->pgno = PREV_PGNO(hcp->pagep);
- if (hcp->pgno == PGNO_INVALID) {
- /* Beginning of bucket. */
- F_SET(hcp, H_NOMORE);
- return (DB_NOTFOUND);
- } else if ((ret =
- __ham_next_cpage(dbc, hcp->pgno, 0, 0)) != 0)
- return (ret);
- else
- hcp->bndx = H_NUMPAIRS(hcp->pagep);
- }
-
- /*
- * Either we've got the cursor set up to be decremented, or we
- * have to find the end of a bucket.
- */
- if (hcp->bndx == NDX_INVALID) {
- if (hcp->pagep == NULL)
- next_pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);
- else
- goto got_page;
-
- do {
- if ((ret = __ham_next_cpage(dbc, next_pgno, 0, 0)) != 0)
- return (ret);
-got_page: next_pgno = NEXT_PGNO(hcp->pagep);
- hcp->bndx = H_NUMPAIRS(hcp->pagep);
- } while (next_pgno != PGNO_INVALID);
-
- if (hcp->bndx == 0) {
- /* Bucket was empty. */
- F_SET(hcp, H_NOMORE);
- return (DB_NOTFOUND);
- }
- }
-
- hcp->bndx--;
-
- return (__ham_item(dbc, mode));
-}
-
-/*
- * Sets the cursor to the next key/data pair on a page.
- *
- * PUBLIC: int __ham_item_next __P((DBC *, db_lockmode_t));
- */
-int
-__ham_item_next(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- HASH_CURSOR *hcp;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- /*
- * Deleted on-page duplicates are a weird case. If we delete the last
- * one, then our cursor is at the very end of a duplicate set and
- * we actually need to go on to the next key.
- */
- if (F_ISSET(hcp, H_DELETED)) {
- if (hcp->bndx != NDX_INVALID &&
- F_ISSET(hcp, H_ISDUP) &&
- hcp->dpgno == PGNO_INVALID &&
- hcp->dup_tlen == hcp->dup_off) {
- if (F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- } else {
- F_CLR(hcp, H_ISDUP);
- hcp->dpgno = PGNO_INVALID;
- hcp->bndx++;
- }
- } else if (!F_ISSET(hcp, H_ISDUP) &&
- F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- }
- F_CLR(hcp, H_DELETED);
- } else if (hcp->bndx == NDX_INVALID) {
- hcp->bndx = 0;
- hcp->dpgno = PGNO_INVALID;
- F_CLR(hcp, H_ISDUP);
- } else if (F_ISSET(hcp, H_ISDUP) && hcp->dpgno != PGNO_INVALID)
- hcp->dndx++;
- else if (F_ISSET(hcp, H_ISDUP)) {
- if (hcp->dup_off + DUP_SIZE(hcp->dup_len) >=
- hcp->dup_tlen && F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- }
- hcp->dndx++;
- hcp->dup_off += DUP_SIZE(hcp->dup_len);
- if (hcp->dup_off >= hcp->dup_tlen) {
- F_CLR(hcp, H_ISDUP);
- hcp->dpgno = PGNO_INVALID;
- hcp->bndx++;
- }
- } else if (F_ISSET(hcp, H_DUPONLY)) {
- F_CLR(hcp, H_OK);
- F_SET(hcp, H_NOMORE);
- return (0);
- } else
- hcp->bndx++;
-
- return (__ham_item(dbc, mode));
-}
-
-/*
- * PUBLIC: void __ham_putitem __P((PAGE *p, const DBT *, int));
- *
- * This is a little bit sleazy in that we're overloading the meaning
- * of the H_OFFPAGE type here. When we recover deletes, we have the
- * entire entry instead of having only the DBT, so we'll pass type
- * H_OFFPAGE to mean, "copy the whole entry" as opposed to constructing
- * an H_KEYDATA around it.
- */
-void
-__ham_putitem(p, dbt, type)
- PAGE *p;
- const DBT *dbt;
- int type;
-{
- u_int16_t n, off;
-
- n = NUM_ENT(p);
-
- /* Put the item element on the page. */
- if (type == H_OFFPAGE) {
- off = HOFFSET(p) - dbt->size;
- HOFFSET(p) = p->inp[n] = off;
- memcpy(P_ENTRY(p, n), dbt->data, dbt->size);
- } else {
- off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size);
- HOFFSET(p) = p->inp[n] = off;
- PUT_HKEYDATA(P_ENTRY(p, n), dbt->data, dbt->size, type);
- }
-
- /* Adjust page info. */
- NUM_ENT(p) += 1;
-}
-
-/*
- * PUBLIC: void __ham_reputpair
- * PUBLIC: __P((PAGE *p, u_int32_t, u_int32_t, const DBT *, const DBT *));
- *
- * This is a special case to restore a key/data pair to its original
- * location during recovery. We are guaranteed that the pair fits
- * on the page and is not the last pair on the page (because if it's
- * the last pair, the normal insert works).
- */
-void
-__ham_reputpair(p, psize, ndx, key, data)
- PAGE *p;
- u_int32_t psize, ndx;
- const DBT *key, *data;
-{
- db_indx_t i, movebytes, newbytes;
- u_int8_t *from;
-
- /* First shuffle the existing items up on the page. */
- movebytes =
- (ndx == 0 ? psize : p->inp[H_DATAINDEX(ndx - 1)]) - HOFFSET(p);
- newbytes = key->size + data->size;
- from = (u_int8_t *)p + HOFFSET(p);
- memmove(from - newbytes, from, movebytes);
-
- /*
- * Adjust the indices and move them up 2 spaces. Note that we
- * have to check the exit condition inside the loop just in case
- * we are dealing with index 0 (db_indx_t's are unsigned).
- */
- for (i = NUM_ENT(p) - 1; ; i-- ) {
- p->inp[i + 2] = p->inp[i] - newbytes;
- if (i == H_KEYINDEX(ndx))
- break;
- }
-
- /* Put the key and data on the page. */
- p->inp[H_KEYINDEX(ndx)] =
- (ndx == 0 ? psize : p->inp[H_DATAINDEX(ndx - 1)]) - key->size;
- p->inp[H_DATAINDEX(ndx)] = p->inp[H_KEYINDEX(ndx)] - data->size;
- memcpy(P_ENTRY(p, H_KEYINDEX(ndx)), key->data, key->size);
- memcpy(P_ENTRY(p, H_DATAINDEX(ndx)), data->data, data->size);
-
- /* Adjust page info. */
- HOFFSET(p) -= newbytes;
- NUM_ENT(p) += 2;
-}
-
-
-/*
- * PUBLIC: int __ham_del_pair __P((DBC *, int));
- */
-int
-__ham_del_pair(dbc, reclaim_page)
- DBC *dbc;
- int reclaim_page;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT data_dbt, key_dbt;
- DB_ENV *dbenv;
- DB_LSN new_lsn, *n_lsn, tmp_lsn;
- PAGE *p;
- db_indx_t ndx;
- db_pgno_t chg_pgno, pgno;
- int ret, tret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- dbenv = dbp->dbenv;
- ndx = hcp->bndx;
- if (hcp->pagep == NULL &&
- (ret = __ham_get_page(dbp, hcp->pgno, &hcp->pagep)) != 0)
- return (ret);
-
- p = hcp->pagep;
-
- /*
- * We optimize for the normal case which is when neither the key nor
- * the data are large. In this case, we write a single log record
- * and do the delete. If either is large, we'll call __big_delete
- * to remove the big item and then update the page to remove the
- * entry referring to the big item.
- */
- ret = 0;
- if (HPAGE_PTYPE(H_PAIRKEY(p, ndx)) == H_OFFPAGE) {
- memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(p, H_KEYINDEX(ndx))),
- sizeof(db_pgno_t));
- ret = __db_doff(dbc, pgno, __ham_del_page);
- }
-
- if (ret == 0)
- switch (HPAGE_PTYPE(H_PAIRDATA(p, ndx))) {
- case H_OFFPAGE:
- memcpy(&pgno,
- HOFFPAGE_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
- sizeof(db_pgno_t));
- ret = __db_doff(dbc, pgno, __ham_del_page);
- break;
- case H_OFFDUP:
- memcpy(&pgno,
- HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
- sizeof(db_pgno_t));
- ret = __db_ddup(dbc, pgno, __ham_del_page);
- F_CLR(hcp, H_ISDUP);
- break;
- case H_DUPLICATE:
- /*
- * If we delete a pair that is/was a duplicate, then
- * we had better clear the flag so that we update the
- * cursor appropriately.
- */
- F_CLR(hcp, H_ISDUP);
- break;
- }
-
- if (ret)
- return (ret);
-
- /* Now log the delete off this page. */
- if (DB_LOGGING(dbc)) {
- key_dbt.data = P_ENTRY(p, H_KEYINDEX(ndx));
- key_dbt.size =
- LEN_HITEM(p, hcp->hdr->pagesize, H_KEYINDEX(ndx));
- data_dbt.data = P_ENTRY(p, H_DATAINDEX(ndx));
- data_dbt.size =
- LEN_HITEM(p, hcp->hdr->pagesize, H_DATAINDEX(ndx));
-
- if ((ret = __ham_insdel_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, DELPAIR,
- dbp->log_fileid, PGNO(p), (u_int32_t)ndx,
- &LSN(p), &key_dbt, &data_dbt)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(p) = new_lsn;
- }
-
- __ham_dpair(dbp, p, ndx);
-
- /*
- * If we are locking, we will not maintain this, because it is
- * a hot spot.
- * XXX perhaps we can retain incremental numbers and apply them
- * later.
- */
- if (!F_ISSET(dbp, DB_AM_LOCKING))
- --hcp->hdr->nelem;
-
- /*
- * If we need to reclaim the page, then check if the page is empty.
- * There are two cases. If it's empty and it's not the first page
- * in the bucket (i.e., the bucket page) then we can simply remove
- * it. If it is the first chain in the bucket, then we need to copy
- * the second page into it and remove the second page.
- */
- if (reclaim_page && NUM_ENT(p) == 0 && PREV_PGNO(p) == PGNO_INVALID &&
- NEXT_PGNO(p) != PGNO_INVALID) {
- PAGE *n_pagep, *nn_pagep;
- db_pgno_t tmp_pgno;
-
- /*
- * First page in chain is empty and we know that there
- * are more pages in the chain.
- */
- if ((ret =
- __ham_get_page(dbp, NEXT_PGNO(p), &n_pagep)) != 0)
- return (ret);
-
- if (NEXT_PGNO(n_pagep) != PGNO_INVALID) {
- if ((ret =
- __ham_get_page(dbp, NEXT_PGNO(n_pagep),
- &nn_pagep)) != 0) {
- (void) __ham_put_page(dbp, n_pagep, 0);
- return (ret);
- }
- }
-
- if (DB_LOGGING(dbc)) {
- key_dbt.data = n_pagep;
- key_dbt.size = hcp->hdr->pagesize;
- if ((ret = __ham_copypage_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid, PGNO(p),
- &LSN(p), PGNO(n_pagep), &LSN(n_pagep),
- NEXT_PGNO(n_pagep),
- NEXT_PGNO(n_pagep) == PGNO_INVALID ? NULL :
- &LSN(nn_pagep), &key_dbt)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(p) = new_lsn; /* Structure assignment. */
- LSN(n_pagep) = new_lsn;
- if (NEXT_PGNO(n_pagep) != PGNO_INVALID)
- LSN(nn_pagep) = new_lsn;
- }
- if (NEXT_PGNO(n_pagep) != PGNO_INVALID) {
- PREV_PGNO(nn_pagep) = PGNO(p);
- (void)__ham_put_page(dbp, nn_pagep, 1);
- }
-
- tmp_pgno = PGNO(p);
- tmp_lsn = LSN(p);
- memcpy(p, n_pagep, hcp->hdr->pagesize);
- PGNO(p) = tmp_pgno;
- LSN(p) = tmp_lsn;
- PREV_PGNO(p) = PGNO_INVALID;
-
- /*
- * Cursor is advanced to the beginning of the next page.
- */
- hcp->bndx = 0;
- hcp->pgno = PGNO(p);
- F_SET(hcp, H_DELETED);
- chg_pgno = PGNO(p);
- if ((ret = __ham_dirty_page(dbp, p)) != 0 ||
- (ret = __ham_del_page(dbc, n_pagep)) != 0)
- return (ret);
- } else if (reclaim_page &&
- NUM_ENT(p) == 0 && PREV_PGNO(p) != PGNO_INVALID) {
- PAGE *n_pagep, *p_pagep;
-
- if ((ret =
- __ham_get_page(dbp, PREV_PGNO(p), &p_pagep)) != 0)
- return (ret);
-
- if (NEXT_PGNO(p) != PGNO_INVALID) {
- if ((ret = __ham_get_page(dbp,
- NEXT_PGNO(p), &n_pagep)) != 0) {
- (void)__ham_put_page(dbp, p_pagep, 0);
- return (ret);
- }
- n_lsn = &LSN(n_pagep);
- } else {
- n_pagep = NULL;
- n_lsn = NULL;
- }
-
- NEXT_PGNO(p_pagep) = NEXT_PGNO(p);
- if (n_pagep != NULL)
- PREV_PGNO(n_pagep) = PGNO(p_pagep);
-
- if (DB_LOGGING(dbc)) {
- if ((ret = __ham_newpage_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, DELOVFL,
- dbp->log_fileid, PREV_PGNO(p), &LSN(p_pagep),
- PGNO(p), &LSN(p), NEXT_PGNO(p), n_lsn)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(p_pagep) = new_lsn; /* Structure assignment. */
- if (n_pagep)
- LSN(n_pagep) = new_lsn;
- LSN(p) = new_lsn;
- }
- hcp->pgno = NEXT_PGNO(p);
- hcp->bndx = 0;
- /*
- * Since we are about to delete the cursor page and we have
- * just moved the cursor, we need to make sure that the
- * old page pointer isn't left hanging around in the cursor.
- */
- hcp->pagep = NULL;
- chg_pgno = PGNO(p);
- ret = __ham_del_page(dbc, p);
- if ((tret = __ham_put_page(dbp, p_pagep, 1)) != 0 &&
- ret == 0)
- ret = tret;
- if (n_pagep != NULL &&
- (tret = __ham_put_page(dbp, n_pagep, 1)) != 0 &&
- ret == 0)
- ret = tret;
- if (ret != 0)
- return (ret);
- } else {
- /*
- * Mark item deleted so that we don't try to return it, and
- * so that we update the cursor correctly on the next call
- * to next.
- */
- F_SET(hcp, H_DELETED);
- chg_pgno = hcp->pgno;
- ret = __ham_dirty_page(dbp, p);
- }
- __ham_c_update(hcp, chg_pgno, 0, 0, 0);
-
- /*
- * Since we just deleted a pair from the master page, anything
- * in hcp->dpgno should be cleared.
- */
- hcp->dpgno = PGNO_INVALID;
-
- F_CLR(hcp, H_OK);
- return (ret);
-}
-
-/*
- * __ham_replpair --
- * Given the key data indicated by the cursor, replace part/all of it
- * according to the fields in the dbt.
- *
- * PUBLIC: int __ham_replpair __P((DBC *, DBT *, u_int32_t));
- */
-int
-__ham_replpair(dbc, dbt, make_dup)
- DBC *dbc;
- DBT *dbt;
- u_int32_t make_dup;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT old_dbt, tdata, tmp;
- DB_LSN new_lsn;
- int32_t change; /* XXX: Possible overflow. */
- u_int32_t len;
- int is_big, ret, type;
- u_int8_t *beg, *dest, *end, *hk, *src;
-
- /*
- * Big item replacements are handled in generic code.
- * Items that fit on the current page fall into 4 classes.
- * 1. On-page element, same size
- * 2. On-page element, new is bigger (fits)
- * 3. On-page element, new is bigger (does not fit)
- * 4. On-page element, old is bigger
- * Numbers 1, 2, and 4 are essentially the same (and should
- * be the common case). We handle case 3 as a delete and
- * add.
- */
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- /*
- * We need to compute the number of bytes that we are adding or
- * removing from the entry. Normally, we can simply substract
- * the number of bytes we are replacing (dbt->dlen) from the
- * number of bytes we are inserting (dbt->size). However, if
- * we are doing a partial put off the end of a record, then this
- * formula doesn't work, because we are essentially adding
- * new bytes.
- */
- change = dbt->size - dbt->dlen;
-
- hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
- is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;
-
- if (is_big)
- memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
- else
- len = LEN_HKEYDATA(hcp->pagep,
- dbp->pgsize, H_DATAINDEX(hcp->bndx));
-
- if (dbt->doff + dbt->dlen > len)
- change += dbt->doff + dbt->dlen - len;
-
-
- if (change > (int32_t)P_FREESPACE(hcp->pagep) || is_big) {
- /*
- * Case 3 -- two subcases.
- * A. This is not really a partial operation, but an overwrite.
- * Simple del and add works.
- * B. This is a partial and we need to construct the data that
- * we are really inserting (yuck).
- * In both cases, we need to grab the key off the page (in
- * some cases we could do this outside of this routine; for
- * cleanliness we do it here. If you happen to be on a big
- * key, this could be a performance hit).
- */
- tmp.flags = 0;
- F_SET(&tmp, DB_DBT_MALLOC | DB_DBT_INTERNAL);
- if ((ret =
- __db_ret(dbp, hcp->pagep, H_KEYINDEX(hcp->bndx),
- &tmp, &dbc->rkey.data, &dbc->rkey.size)) != 0)
- return (ret);
-
- if (dbt->doff == 0 && dbt->dlen == len) {
- ret = __ham_del_pair(dbc, 0);
- if (ret == 0)
- ret = __ham_add_el(dbc, &tmp, dbt, H_KEYDATA);
- } else { /* Case B */
- type = HPAGE_PTYPE(hk) != H_OFFPAGE ?
- HPAGE_PTYPE(hk) : H_KEYDATA;
- tdata.flags = 0;
- F_SET(&tdata, DB_DBT_MALLOC | DB_DBT_INTERNAL);
-
- if ((ret = __db_ret(dbp, hcp->pagep,
- H_DATAINDEX(hcp->bndx), &tdata, &dbc->rdata.data,
- &dbc->rdata.size)) != 0)
- goto err;
-
- /* Now we can delete the item. */
- if ((ret = __ham_del_pair(dbc, 0)) != 0) {
- __os_free(tdata.data, tdata.size);
- goto err;
- }
-
- /* Now shift old data around to make room for new. */
- if (change > 0) {
- if ((ret = __os_realloc(&tdata.data,
- tdata.size + change)) != 0)
- return (ret);
- memset((u_int8_t *)tdata.data + tdata.size,
- 0, change);
- }
- end = (u_int8_t *)tdata.data + tdata.size;
-
- src = (u_int8_t *)tdata.data + dbt->doff + dbt->dlen;
- if (src < end && tdata.size > dbt->doff + dbt->dlen) {
- len = tdata.size - dbt->doff - dbt->dlen;
- dest = src + change;
- memmove(dest, src, len);
- }
- memcpy((u_int8_t *)tdata.data + dbt->doff,
- dbt->data, dbt->size);
- tdata.size += change;
-
- /* Now add the pair. */
- ret = __ham_add_el(dbc, &tmp, &tdata, type);
- __os_free(tdata.data, tdata.size);
- }
-err: __os_free(tmp.data, tmp.size);
- return (ret);
- }
-
- /*
- * Set up pointer into existing data. Do it before the log
- * message so we can use it inside of the log setup.
- */
- beg = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- beg += dbt->doff;
-
- /*
- * If we are going to have to move bytes at all, figure out
- * all the parameters here. Then log the call before moving
- * anything around.
- */
- if (DB_LOGGING(dbc)) {
- old_dbt.data = beg;
- old_dbt.size = dbt->dlen;
- if ((ret = __ham_replace_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid, PGNO(hcp->pagep),
- (u_int32_t)H_DATAINDEX(hcp->bndx), &LSN(hcp->pagep),
- (u_int32_t)dbt->doff, &old_dbt, dbt, make_dup)) != 0)
- return (ret);
-
- LSN(hcp->pagep) = new_lsn; /* Structure assignment. */
- }
-
- __ham_onpage_replace(hcp->pagep, dbp->pgsize,
- (u_int32_t)H_DATAINDEX(hcp->bndx), (int32_t)dbt->doff, change, dbt);
-
- return (0);
-}
-
-/*
- * Replace data on a page with new data, possibly growing or shrinking what's
- * there. This is called on two different occasions. On one (from replpair)
- * we are interested in changing only the data. On the other (from recovery)
- * we are replacing the entire data (header and all) with a new element. In
- * the latter case, the off argument is negative.
- * pagep: the page that we're changing
- * ndx: page index of the element that is growing/shrinking.
- * off: Offset at which we are beginning the replacement.
- * change: the number of bytes (+ or -) that the element is growing/shrinking.
- * dbt: the new data that gets written at beg.
- * PUBLIC: void __ham_onpage_replace __P((PAGE *, size_t, u_int32_t, int32_t,
- * PUBLIC: int32_t, DBT *));
- */
-void
-__ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
- PAGE *pagep;
- size_t pgsize;
- u_int32_t ndx;
- int32_t off;
- int32_t change;
- DBT *dbt;
-{
- db_indx_t i;
- int32_t len;
- u_int8_t *src, *dest;
- int zero_me;
-
- if (change != 0) {
- zero_me = 0;
- src = (u_int8_t *)(pagep) + HOFFSET(pagep);
- if (off < 0)
- len = pagep->inp[ndx] - HOFFSET(pagep);
- else if ((u_int32_t)off >= LEN_HKEYDATA(pagep, pgsize, ndx)) {
- len = HKEYDATA_DATA(P_ENTRY(pagep, ndx)) +
- LEN_HKEYDATA(pagep, pgsize, ndx) - src;
- zero_me = 1;
- } else
- len = (HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off) - src;
- dest = src - change;
- memmove(dest, src, len);
- if (zero_me)
- memset(dest + len, 0, change);
-
- /* Now update the indices. */
- for (i = ndx; i < NUM_ENT(pagep); i++)
- pagep->inp[i] -= change;
- HOFFSET(pagep) -= change;
- }
- if (off >= 0)
- memcpy(HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off,
- dbt->data, dbt->size);
- else
- memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size);
-}
-
-/*
- * PUBLIC: int __ham_split_page __P((DBC *, u_int32_t, u_int32_t));
- */
-int
-__ham_split_page(dbc, obucket, nbucket)
- DBC *dbc;
- u_int32_t obucket, nbucket;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DBT key, page_dbt;
- DB_ENV *dbenv;
- DB_LSN new_lsn;
- PAGE **pp, *old_pagep, *temp_pagep, *new_pagep;
- db_indx_t n;
- db_pgno_t bucket_pgno, next_pgno;
- u_int32_t big_len, len;
- int ret, tret;
- void *big_buf;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- dbenv = dbp->dbenv;
- temp_pagep = old_pagep = new_pagep = NULL;
-
- bucket_pgno = BUCKET_TO_PAGE(hcp, obucket);
- if ((ret = __ham_get_page(dbp, bucket_pgno, &old_pagep)) != 0)
- return (ret);
- if ((ret = __ham_new_page(dbp, BUCKET_TO_PAGE(hcp, nbucket), P_HASH,
- &new_pagep)) != 0)
- goto err;
-
- temp_pagep = hcp->split_buf;
- memcpy(temp_pagep, old_pagep, hcp->hdr->pagesize);
-
- if (DB_LOGGING(dbc)) {
- page_dbt.size = hcp->hdr->pagesize;
- page_dbt.data = old_pagep;
- if ((ret = __ham_splitdata_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid, SPLITOLD,
- PGNO(old_pagep), &page_dbt, &LSN(old_pagep))) != 0)
- goto err;
- }
-
- P_INIT(old_pagep, hcp->hdr->pagesize, PGNO(old_pagep), PGNO_INVALID,
- PGNO_INVALID, 0, P_HASH);
-
- if (DB_LOGGING(dbc))
- LSN(old_pagep) = new_lsn; /* Structure assignment. */
-
- big_len = 0;
- big_buf = NULL;
- key.flags = 0;
- while (temp_pagep != NULL) {
- for (n = 0; n < (db_indx_t)H_NUMPAIRS(temp_pagep); n++) {
- if ((ret =
- __db_ret(dbp, temp_pagep, H_KEYINDEX(n),
- &key, &big_buf, &big_len)) != 0)
- goto err;
-
- if (__ham_call_hash(hcp, key.data, key.size)
- == obucket)
- pp = &old_pagep;
- else
- pp = &new_pagep;
-
- /*
- * Figure out how many bytes we need on the new
- * page to store the key/data pair.
- */
-
- len = LEN_HITEM(temp_pagep, hcp->hdr->pagesize,
- H_DATAINDEX(n)) +
- LEN_HITEM(temp_pagep, hcp->hdr->pagesize,
- H_KEYINDEX(n)) +
- 2 * sizeof(db_indx_t);
-
- if (P_FREESPACE(*pp) < len) {
- if (DB_LOGGING(dbc)) {
- page_dbt.size = hcp->hdr->pagesize;
- page_dbt.data = *pp;
- if ((ret = __ham_splitdata_log(
- dbenv->lg_info, dbc->txn,
- &new_lsn, 0, dbp->log_fileid,
- SPLITNEW, PGNO(*pp), &page_dbt,
- &LSN(*pp))) != 0)
- goto err;
- LSN(*pp) = new_lsn;
- }
- if ((ret =
- __ham_add_ovflpage(dbc, *pp, 1, pp)) != 0)
- goto err;
- }
- __ham_copy_item(dbp->pgsize,
- temp_pagep, H_KEYINDEX(n), *pp);
- __ham_copy_item(dbp->pgsize,
- temp_pagep, H_DATAINDEX(n), *pp);
- }
- next_pgno = NEXT_PGNO(temp_pagep);
-
- /* Clear temp_page; if it's a link overflow page, free it. */
- if (PGNO(temp_pagep) != bucket_pgno && (ret =
- __ham_del_page(dbc, temp_pagep)) != 0)
- goto err;
-
- if (next_pgno == PGNO_INVALID)
- temp_pagep = NULL;
- else if ((ret =
- __ham_get_page(dbp, next_pgno, &temp_pagep)) != 0)
- goto err;
-
- if (temp_pagep != NULL && DB_LOGGING(dbc)) {
- page_dbt.size = hcp->hdr->pagesize;
- page_dbt.data = temp_pagep;
- if ((ret = __ham_splitdata_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid,
- SPLITOLD, PGNO(temp_pagep),
- &page_dbt, &LSN(temp_pagep))) != 0)
- goto err;
- LSN(temp_pagep) = new_lsn;
- }
- }
- if (big_buf != NULL)
- __os_free(big_buf, big_len);
-
- /*
- * If the original bucket spanned multiple pages, then we've got
- * a pointer to a page that used to be on the bucket chain. It
- * should be deleted.
- */
- if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno &&
- (ret = __ham_del_page(dbc, temp_pagep)) != 0)
- goto err;
-
- /*
- * Write new buckets out.
- */
- if (DB_LOGGING(dbc)) {
- page_dbt.size = hcp->hdr->pagesize;
- page_dbt.data = old_pagep;
- if ((ret = __ham_splitdata_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid,
- SPLITNEW, PGNO(old_pagep),
- &page_dbt, &LSN(old_pagep))) != 0)
- goto err;
- LSN(old_pagep) = new_lsn;
-
- page_dbt.data = new_pagep;
- if ((ret = __ham_splitdata_log(dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid,
- SPLITNEW, PGNO(new_pagep), &page_dbt, &LSN(new_pagep))) != 0)
- goto err;
- LSN(new_pagep) = new_lsn;
- }
- ret = __ham_put_page(dbp, old_pagep, 1);
- if ((tret = __ham_put_page(dbp, new_pagep, 1)) != 0 &&
- ret == 0)
- ret = tret;
-
- if (0) {
-err: if (old_pagep != NULL)
- (void)__ham_put_page(dbp, old_pagep, 1);
- if (new_pagep != NULL)
- (void)__ham_put_page(dbp, new_pagep, 1);
- if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno)
- (void)__ham_put_page(dbp, temp_pagep, 1);
- }
- return (ret);
-}
-
-/*
- * Add the given pair to the page. The page in question may already be
- * held (i.e. it was already gotten). If it is, then the page is passed
- * in via the pagep parameter. On return, pagep will contain the page
- * to which we just added something. This allows us to link overflow
- * pages and return the new page having correctly put the last page.
- *
- * PUBLIC: int __ham_add_el __P((DBC *, const DBT *, const DBT *, int));
- */
-int
-__ham_add_el(dbc, key, val, type)
- DBC *dbc;
- const DBT *key, *val;
- int type;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- const DBT *pkey, *pdata;
- DBT key_dbt, data_dbt;
- DB_LSN new_lsn;
- HOFFPAGE doff, koff;
- db_pgno_t next_pgno;
- u_int32_t data_size, key_size, pairsize, rectype;
- int do_expand, is_keybig, is_databig, ret;
- int key_type, data_type;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- do_expand = 0;
-
- if (hcp->pagep == NULL && (ret = __ham_get_page(dbp,
- hcp->seek_found_page != PGNO_INVALID ? hcp->seek_found_page :
- hcp->pgno, &hcp->pagep)) != 0)
- return (ret);
-
- key_size = HKEYDATA_PSIZE(key->size);
- data_size = HKEYDATA_PSIZE(val->size);
- is_keybig = ISBIG(hcp, key->size);
- is_databig = ISBIG(hcp, val->size);
- if (is_keybig)
- key_size = HOFFPAGE_PSIZE;
- if (is_databig)
- data_size = HOFFPAGE_PSIZE;
-
- pairsize = key_size + data_size;
-
- /* Advance to first page in chain with room for item. */
- while (H_NUMPAIRS(hcp->pagep) && NEXT_PGNO(hcp->pagep) !=
- PGNO_INVALID) {
- /*
- * This may not be the end of the chain, but the pair may fit
- * anyway. Check if it's a bigpair that fits or a regular
- * pair that fits.
- */
- if (P_FREESPACE(hcp->pagep) >= pairsize)
- break;
- next_pgno = NEXT_PGNO(hcp->pagep);
- if ((ret =
- __ham_next_cpage(dbc, next_pgno, 0, 0)) != 0)
- return (ret);
- }
-
- /*
- * Check if we need to allocate a new page.
- */
- if (P_FREESPACE(hcp->pagep) < pairsize) {
- do_expand = 1;
- if ((ret = __ham_add_ovflpage(dbc,
- hcp->pagep, 1, &hcp->pagep)) != 0)
- return (ret);
- hcp->pgno = PGNO(hcp->pagep);
- }
-
- /*
- * Update cursor.
- */
- hcp->bndx = H_NUMPAIRS(hcp->pagep);
- F_CLR(hcp, H_DELETED);
- if (is_keybig) {
- koff.type = H_OFFPAGE;
- UMRW(koff.unused[0]);
- UMRW(koff.unused[1]);
- UMRW(koff.unused[2]);
- if ((ret = __db_poff(dbc,
- key, &koff.pgno, __ham_overflow_page)) != 0)
- return (ret);
- koff.tlen = key->size;
- key_dbt.data = &koff;
- key_dbt.size = sizeof(koff);
- pkey = &key_dbt;
- key_type = H_OFFPAGE;
- } else {
- pkey = key;
- key_type = H_KEYDATA;
- }
-
- if (is_databig) {
- doff.type = H_OFFPAGE;
- UMRW(doff.unused[0]);
- UMRW(doff.unused[1]);
- UMRW(doff.unused[2]);
- if ((ret = __db_poff(dbc,
- val, &doff.pgno, __ham_overflow_page)) != 0)
- return (ret);
- doff.tlen = val->size;
- data_dbt.data = &doff;
- data_dbt.size = sizeof(doff);
- pdata = &data_dbt;
- data_type = H_OFFPAGE;
- } else {
- pdata = val;
- data_type = type;
- }
-
- if (DB_LOGGING(dbc)) {
- rectype = PUTPAIR;
- if (is_databig)
- rectype |= PAIR_DATAMASK;
- if (is_keybig)
- rectype |= PAIR_KEYMASK;
-
- if ((ret = __ham_insdel_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, rectype,
- dbp->log_fileid, PGNO(hcp->pagep),
- (u_int32_t)H_NUMPAIRS(hcp->pagep),
- &LSN(hcp->pagep), pkey, pdata)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(hcp->pagep) = new_lsn; /* Structure assignment. */
- }
-
- __ham_putitem(hcp->pagep, pkey, key_type);
- __ham_putitem(hcp->pagep, pdata, data_type);
-
- /*
- * For splits, we are going to update item_info's page number
- * field, so that we can easily return to the same page the
- * next time we come in here. For other operations, this shouldn't
- * matter, since odds are this is the last thing that happens before
- * we return to the user program.
- */
- hcp->pgno = PGNO(hcp->pagep);
-
- /*
- * XXX Maybe keep incremental numbers here
- */
- if (!F_ISSET(dbp, DB_AM_LOCKING))
- hcp->hdr->nelem++;
-
- if (do_expand || (hcp->hdr->ffactor != 0 &&
- (u_int32_t)H_NUMPAIRS(hcp->pagep) > hcp->hdr->ffactor))
- F_SET(hcp, H_EXPAND);
- return (0);
-}
-
-
-/*
- * Special __putitem call used in splitting -- copies one entry to
- * another. Works for all types of hash entries (H_OFFPAGE, H_KEYDATA,
- * H_DUPLICATE, H_OFFDUP). Since we log splits at a high level, we
- * do not need to do any logging here.
- *
- * PUBLIC: void __ham_copy_item __P((size_t, PAGE *, u_int32_t, PAGE *));
- */
-void
-__ham_copy_item(pgsize, src_page, src_ndx, dest_page)
- size_t pgsize;
- PAGE *src_page;
- u_int32_t src_ndx;
- PAGE *dest_page;
-{
- u_int32_t len;
- void *src, *dest;
-
- /*
- * Copy the key and data entries onto this new page.
- */
- src = P_ENTRY(src_page, src_ndx);
-
- /* Set up space on dest. */
- len = LEN_HITEM(src_page, pgsize, src_ndx);
- HOFFSET(dest_page) -= len;
- dest_page->inp[NUM_ENT(dest_page)] = HOFFSET(dest_page);
- dest = P_ENTRY(dest_page, NUM_ENT(dest_page));
- NUM_ENT(dest_page)++;
-
- memcpy(dest, src, len);
-}
-
-/*
- *
- * Returns:
- * pointer on success
- * NULL on error
- *
- * PUBLIC: int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **));
- */
-int
-__ham_add_ovflpage(dbc, pagep, release, pp)
- DBC *dbc;
- PAGE *pagep;
- int release;
- PAGE **pp;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DB_LSN new_lsn;
- PAGE *new_pagep;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if ((ret = __ham_overflow_page(dbc, P_HASH, &new_pagep)) != 0)
- return (ret);
-
- if (DB_LOGGING(dbc)) {
- if ((ret = __ham_newpage_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, PUTOVFL,
- dbp->log_fileid, PGNO(pagep), &LSN(pagep),
- PGNO(new_pagep), &LSN(new_pagep), PGNO_INVALID, NULL)) != 0)
- return (ret);
-
- /* Move lsn onto page. */
- LSN(pagep) = LSN(new_pagep) = new_lsn;
- }
- NEXT_PGNO(pagep) = PGNO(new_pagep);
- PREV_PGNO(new_pagep) = PGNO(pagep);
-
- if (release)
- ret = __ham_put_page(dbp, pagep, 1);
-
- hcp->stats.hash_overflows++;
- *pp = new_pagep;
- return (ret);
-}
-
-
-/*
- * PUBLIC: int __ham_new_page __P((DB *, u_int32_t, u_int32_t, PAGE **));
- */
-int
-__ham_new_page(dbp, addr, type, pp)
- DB *dbp;
- u_int32_t addr, type;
- PAGE **pp;
-{
- PAGE *pagep;
- int ret;
-
- if ((ret = memp_fget(dbp->mpf,
- &addr, DB_MPOOL_CREATE, &pagep)) != 0)
- return (ret);
-
- /* This should not be necessary because page-in should do it. */
- P_INIT(pagep, dbp->pgsize, addr, PGNO_INVALID, PGNO_INVALID, 0, type);
-
- *pp = pagep;
- return (0);
-}
-
-/*
- * PUBLIC: int __ham_del_page __P((DBC *, PAGE *));
- */
-int
-__ham_del_page(dbc, pagep)
- DBC *dbc;
- PAGE *pagep;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DB_LSN new_lsn;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- ret = 0;
- DIRTY_META(dbp, hcp, ret);
- if (ret != 0) {
- if (ret != EAGAIN)
- __db_err(dbp->dbenv,
- "free_ovflpage: unable to lock meta data page %s\n",
- strerror(ret));
- /*
- * If we are going to return an error, then we should free
- * the page, so it doesn't stay pinned forever.
- */
- (void)__ham_put_page(dbp, pagep, 0);
- return (ret);
- }
-
- if (DB_LOGGING(dbc)) {
- if ((ret = __ham_newpgno_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, DELPGNO,
- dbp->log_fileid, PGNO(pagep), hcp->hdr->last_freed,
- (u_int32_t)TYPE(pagep), NEXT_PGNO(pagep), P_INVALID,
- &LSN(pagep), &hcp->hdr->lsn)) != 0)
- return (ret);
-
- hcp->hdr->lsn = new_lsn;
- LSN(pagep) = new_lsn;
- }
-
-#ifdef DIAGNOSTIC
- {
- db_pgno_t __pgno;
- DB_LSN __lsn;
- __pgno = pagep->pgno;
- __lsn = pagep->lsn;
- memset(pagep, 0xdb, dbp->pgsize);
- pagep->pgno = __pgno;
- pagep->lsn = __lsn;
- }
-#endif
- TYPE(pagep) = P_INVALID;
- NEXT_PGNO(pagep) = hcp->hdr->last_freed;
- hcp->hdr->last_freed = PGNO(pagep);
-
- return (__ham_put_page(dbp, pagep, 1));
-}
-
-
-/*
- * PUBLIC: int __ham_put_page __P((DB *, PAGE *, int32_t));
- */
-int
-__ham_put_page(dbp, pagep, is_dirty)
- DB *dbp;
- PAGE *pagep;
- int32_t is_dirty;
-{
-#ifdef DEBUG_SLOW
- __account_page(dbp, ((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1);
-#endif
- return (memp_fput(dbp->mpf, pagep, (is_dirty ? DB_MPOOL_DIRTY : 0)));
-}
-
-/*
- * __ham_dirty_page --
- * Mark a page dirty.
- *
- * PUBLIC: int __ham_dirty_page __P((DB *, PAGE *));
- */
-int
-__ham_dirty_page(dbp, pagep)
- DB *dbp;
- PAGE *pagep;
-{
- return (memp_fset(dbp->mpf, pagep, DB_MPOOL_DIRTY));
-}
-
-/*
- * PUBLIC: int __ham_get_page __P((DB *, db_pgno_t, PAGE **));
- */
-int
-__ham_get_page(dbp, addr, pagep)
- DB *dbp;
- db_pgno_t addr;
- PAGE **pagep;
-{
- int ret;
-
- ret = memp_fget(dbp->mpf, &addr, DB_MPOOL_CREATE, pagep);
-#ifdef DEBUG_SLOW
- if (*pagep != NULL)
- __account_page(dbp, addr, 1);
-#endif
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_overflow_page
- * PUBLIC: __P((DBC *, u_int32_t, PAGE **));
- */
-int
-__ham_overflow_page(dbc, type, pp)
- DBC *dbc;
- u_int32_t type;
- PAGE **pp;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DB_LSN *lsnp, new_lsn;
- PAGE *p;
- db_pgno_t new_addr, next_free, newalloc_flag;
- u_int32_t offset, splitnum;
- int ret;
-
- ret = 0;
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- DIRTY_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
-
- /*
- * This routine is split up into two parts. First we have
- * to figure out the address of the new page that we are
- * allocating. Then we have to log the allocation. Only
- * after the log do we get to complete allocation of the
- * new page.
- */
- new_addr = hcp->hdr->last_freed;
- if (new_addr != PGNO_INVALID) {
- if ((ret = __ham_get_page(dbp, new_addr, &p)) != 0)
- return (ret);
- next_free = NEXT_PGNO(p);
- lsnp = &LSN(p);
- newalloc_flag = 0;
- } else {
- splitnum = hcp->hdr->ovfl_point;
- hcp->hdr->spares[splitnum]++;
- offset = hcp->hdr->spares[splitnum] -
- (splitnum ? hcp->hdr->spares[splitnum - 1] : 0);
- new_addr = PGNO_OF(hcp, hcp->hdr->ovfl_point, offset);
- if (new_addr > MAX_PAGES(hcp)) {
- __db_err(dbp->dbenv, "hash: out of file pages");
- hcp->hdr->spares[splitnum]--;
- return (ENOMEM);
- }
- next_free = PGNO_INVALID;
- p = NULL;
- lsnp = NULL;
- newalloc_flag = 1;
- }
-
- if (DB_LOGGING(dbc)) {
- if ((ret = __ham_newpgno_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, ALLOCPGNO,
- dbp->log_fileid, new_addr, next_free,
- 0, newalloc_flag, type, lsnp, &hcp->hdr->lsn)) != 0)
- return (ret);
-
- hcp->hdr->lsn = new_lsn;
- if (lsnp != NULL)
- *lsnp = new_lsn;
- }
-
- if (p != NULL) {
- /* We just took something off the free list, initialize it. */
- hcp->hdr->last_freed = next_free;
- P_INIT(p, hcp->hdr->pagesize, PGNO(p), PGNO_INVALID,
- PGNO_INVALID, 0, (u_int8_t)type);
- } else {
- /* Get the new page. */
- if ((ret = __ham_new_page(dbp, new_addr, type, &p)) != 0)
- return (ret);
- }
- if (DB_LOGGING(dbc))
- LSN(p) = new_lsn;
-
- *pp = p;
- return (0);
-}
-
-#ifdef DEBUG
-/*
- * PUBLIC: #ifdef DEBUG
- * PUBLIC: db_pgno_t __bucket_to_page __P((HASH_CURSOR *, db_pgno_t));
- * PUBLIC: #endif
- */
-db_pgno_t
-__bucket_to_page(hcp, n)
- HASH_CURSOR *hcp;
- db_pgno_t n;
-{
- int ret_val;
-
- ret_val = n + 1;
- if (n != 0)
- ret_val += hcp->hdr->spares[__db_log2(n + 1) - 1];
- return (ret_val);
-}
-#endif
-
-/*
- * Create a bunch of overflow pages at the current split point.
- * PUBLIC: void __ham_init_ovflpages __P((DBC *));
- */
-void
-__ham_init_ovflpages(dbc)
- DBC *dbc;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- DB_LSN new_lsn;
- PAGE *p;
- db_pgno_t last_pgno, new_pgno;
- u_int32_t i, curpages, numpages;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- curpages = hcp->hdr->spares[hcp->hdr->ovfl_point] -
- hcp->hdr->spares[hcp->hdr->ovfl_point - 1];
- numpages = hcp->hdr->ovfl_point + 1 - curpages;
-
- last_pgno = hcp->hdr->last_freed;
- new_pgno = PGNO_OF(hcp, hcp->hdr->ovfl_point, curpages + 1);
- if (DB_LOGGING(dbc)) {
- (void)__ham_ovfl_log(dbp->dbenv->lg_info,
- dbc->txn, &new_lsn, 0, dbp->log_fileid, new_pgno,
- numpages, last_pgno, hcp->hdr->ovfl_point, &hcp->hdr->lsn);
- hcp->hdr->lsn = new_lsn;
- } else
- ZERO_LSN(new_lsn);
-
- hcp->hdr->spares[hcp->hdr->ovfl_point] += numpages;
- for (i = numpages; i > 0; i--) {
- if (__ham_new_page(dbp,
- PGNO_OF(hcp, hcp->hdr->ovfl_point, curpages + i),
- P_INVALID, &p) != 0)
- break;
- LSN(p) = new_lsn;
- NEXT_PGNO(p) = last_pgno;
- last_pgno = PGNO(p);
- (void)__ham_put_page(dbp, p, 1);
- }
- hcp->hdr->last_freed = last_pgno;
-}
-
-/*
- * PUBLIC: int __ham_get_cpage __P((DBC *, db_lockmode_t));
- */
-int
-__ham_get_cpage(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
-
- /*
- * There are three cases with respect to buckets and locks. If there
- * is no lock held, then if we are locking, we should get the lock.
- * If there is a lock held and it's for the current bucket, we don't
- * need to do anything. If there is a lock, but it's for a different
- * bucket, then we need to release and get.
- */
- if (F_ISSET(dbp, DB_AM_LOCKING)) {
- if (hcp->lock != 0 && hcp->lbucket != hcp->bucket) {
- /*
- * If this is the original lock, don't release it,
- * because we may need to restore it upon exit.
- */
- if (dbc->txn == NULL &&
- !F_ISSET(hcp, H_ORIGINAL) && (ret =
- lock_put(dbp->dbenv->lk_info, hcp->lock)) != 0)
- return (ret);
- F_CLR(hcp, H_ORIGINAL);
- hcp->lock = 0;
- }
- if (hcp->lock == 0 && (ret = __ham_lock_bucket(dbc, mode)) != 0)
- return (ret);
- hcp->lbucket = hcp->bucket;
- }
-
- if (hcp->pagep == NULL) {
- if (hcp->pgno == PGNO_INVALID) {
- hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);
- hcp->bndx = 0;
- }
-
- if ((ret =
- __ham_get_page(dbp, hcp->pgno, &hcp->pagep)) != 0)
- return (ret);
- }
-
- if (hcp->dpgno != PGNO_INVALID && hcp->dpagep == NULL)
- if ((ret =
- __ham_get_page(dbp, hcp->dpgno, &hcp->dpagep)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * Get a new page at the cursor, putting the last page if necessary.
- * If the flag is set to H_ISDUP, then we are talking about the
- * duplicate page, not the main page.
- *
- * PUBLIC: int __ham_next_cpage __P((DBC *, db_pgno_t, int, u_int32_t));
- */
-int
-__ham_next_cpage(dbc, pgno, dirty, flags)
- DBC *dbc;
- db_pgno_t pgno;
- int dirty;
- u_int32_t flags;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- PAGE *p;
- int ret;
-
- dbp = dbc->dbp;
- hcp = (HASH_CURSOR *)dbc->internal;
- if (LF_ISSET(H_ISDUP) && hcp->dpagep != NULL &&
- (ret = __ham_put_page(dbp, hcp->dpagep, dirty)) != 0)
- return (ret);
- else if (!LF_ISSET(H_ISDUP) && hcp->pagep != NULL &&
- (ret = __ham_put_page(dbp, hcp->pagep, dirty)) != 0)
- return (ret);
-
- if ((ret = __ham_get_page(dbp, pgno, &p)) != 0)
- return (ret);
-
- if (LF_ISSET(H_ISDUP)) {
- hcp->dpagep = p;
- hcp->dpgno = pgno;
- hcp->dndx = 0;
- } else {
- hcp->pagep = p;
- hcp->pgno = pgno;
- hcp->bndx = 0;
- }
-
- return (0);
-}
-
-/*
- * __ham_lock_bucket --
- * Get the lock on a particular bucket.
- */
-static int
-__ham_lock_bucket(dbc, mode)
- DBC *dbc;
- db_lockmode_t mode;
-{
- HASH_CURSOR *hcp;
- int ret;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- dbc->lock.pgno = (db_pgno_t)(hcp->bucket);
- if (dbc->txn == NULL)
- ret = lock_get(dbc->dbp->dbenv->lk_info, dbc->locker, 0,
- &dbc->lock_dbt, mode, &hcp->lock);
- else
- ret = lock_tget(dbc->dbp->dbenv->lk_info, dbc->txn, 0,
- &dbc->lock_dbt, mode, &hcp->lock);
-
- return (ret < 0 ? EAGAIN : ret);
-}
-
-/*
- * __ham_dpair --
- * Delete a pair on a page, paying no attention to what the pair
- * represents. The caller is responsible for freeing up duplicates
- * or offpage entries that might be referenced by this pair.
- *
- * PUBLIC: void __ham_dpair __P((DB *, PAGE *, u_int32_t));
- */
-void
-__ham_dpair(dbp, p, pndx)
- DB *dbp;
- PAGE *p;
- u_int32_t pndx;
-{
- db_indx_t delta, n;
- u_int8_t *dest, *src;
-
- /*
- * Compute "delta", the amount we have to shift all of the
- * offsets. To find the delta, we just need to calculate
- * the size of the pair of elements we are removing.
- */
- delta = H_PAIRSIZE(p, dbp->pgsize, pndx);
-
- /*
- * The hard case: we want to remove something other than
- * the last item on the page. We need to shift data and
- * offsets down.
- */
- if ((db_indx_t)pndx != H_NUMPAIRS(p) - 1) {
- /*
- * Move the data: src is the first occupied byte on
- * the page. (Length is delta.)
- */
- src = (u_int8_t *)p + HOFFSET(p);
-
- /*
- * Destination is delta bytes beyond src. This might
- * be an overlapping copy, so we have to use memmove.
- */
- dest = src + delta;
- memmove(dest, src, p->inp[H_DATAINDEX(pndx)] - HOFFSET(p));
- }
-
- /* Adjust the offsets. */
- for (n = (db_indx_t)pndx; n < (db_indx_t)(H_NUMPAIRS(p) - 1); n++) {
- p->inp[H_KEYINDEX(n)] = p->inp[H_KEYINDEX(n+1)] + delta;
- p->inp[H_DATAINDEX(n)] = p->inp[H_DATAINDEX(n+1)] + delta;
- }
-
- /* Adjust page metadata. */
- HOFFSET(p) = HOFFSET(p) + delta;
- NUM_ENT(p) = NUM_ENT(p) - 2;
-}
diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c
deleted file mode 100644
index b58f2c6..0000000
--- a/db2/hash/hash_rec.c
+++ /dev/null
@@ -1,986 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * Margo Seltzer. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_rec.c 10.22 (Sleepycat) 10/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "hash.h"
-#include "btree.h"
-#include "log.h"
-#include "common_ext.h"
-
-/*
- * __ham_insdel_recover --
- *
- * PUBLIC: int __ham_insdel_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_insdel_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_insdel_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t op;
- int cmp_n, cmp_p, getmeta, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_insdel_print);
- REC_INTRO(__ham_insdel_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = memp_fget(mpf, &argp->pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- GET_META(file_dbp, hcp, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- /*
- * Two possible things going on:
- * redo a delete/undo a put: delete the item from the page.
- * redo a put/undo a delete: add the item to the page.
- * If we are undoing a delete, then the information logged is the
- * entire entry off the page, not just the data of a dbt. In
- * this case, we want to copy it back onto the page verbatim.
- * We do this by calling __putitem with the type H_OFFPAGE instead
- * of H_KEYDATA.
- */
- op = OPCODE_OF(argp->opcode);
-
- if ((op == DELPAIR && cmp_n == 0 && !redo) ||
- (op == PUTPAIR && cmp_p == 0 && redo)) {
- /*
- * Need to redo a PUT or undo a delete. If we are undoing a
- * delete, we've got to restore the item back to its original
- * position. That's a royal pain in the butt (because we do
- * not store item lengths on the page), but there's no choice.
- */
- if (op != DELPAIR ||
- argp->ndx == (u_int32_t)H_NUMPAIRS(pagep)) {
- __ham_putitem(pagep, &argp->key,
- !redo || PAIR_ISKEYBIG(argp->opcode) ?
- H_OFFPAGE : H_KEYDATA);
- __ham_putitem(pagep, &argp->data,
- !redo || PAIR_ISDATABIG(argp->opcode) ?
- H_OFFPAGE : H_KEYDATA);
- } else
- (void) __ham_reputpair(pagep, hcp->hdr->pagesize,
- argp->ndx, &argp->key, &argp->data);
-
- LSN(pagep) = redo ? *lsnp : argp->pagelsn;
- if ((ret = __ham_put_page(file_dbp, pagep, 1)) != 0)
- goto out;
-
- } else if ((op == DELPAIR && cmp_p == 0 && redo)
- || (op == PUTPAIR && cmp_n == 0 && !redo)) {
- /* Need to undo a put or redo a delete. */
- __ham_dpair(file_dbp, pagep, argp->ndx);
- LSN(pagep) = redo ? *lsnp : argp->pagelsn;
- if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
- goto out;
- } else
- if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
- goto out;
-
- /* Return the previous LSN. */
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-/*
- * __ham_newpage_recover --
- * This log message is used when we add/remove overflow pages. This
- * message takes care of the pointer chains, not the data on the pages.
- *
- * PUBLIC: int __ham_newpage_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_newpage_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_newpage_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, change, getmeta, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_newpage_print);
- REC_INTRO(__ham_newpage_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- ret = memp_fget(mpf, &argp->new_pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto ppage;
- } else if ((ret = memp_fget(mpf, &argp->new_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- /*
- * There are potentially three pages we need to check: the one
- * that we created/deleted, the one before it and the one after
- * it.
- */
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- change = 0;
-
- if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
- /* Redo a create new page or undo a delete new page. */
- P_INIT(pagep, file_dbp->pgsize, argp->new_pgno,
- argp->prev_pgno, argp->next_pgno, 0, P_HASH);
- change = 1;
- } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
- /*
- * Redo a delete or undo a create new page. All we
- * really need to do is change the LSN.
- */
- change = 1;
- }
-
- if (!change) {
- if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
- goto out;
- } else {
- LSN(pagep) = redo ? *lsnp : argp->pagelsn;
- if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
- goto out;
- }
-
- /* Now do the prev page. */
-ppage: if (argp->prev_pgno != PGNO_INVALID) {
- ret = memp_fget(mpf, &argp->prev_pgno, 0, &pagep);
-
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- ret = 0;
- goto npage;
- } else if ((ret =
- memp_fget(mpf, &argp->prev_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
- change = 0;
-
- if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
- /* Redo a create new page or undo a delete new page. */
- pagep->next_pgno = argp->new_pgno;
- change = 1;
- } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
- /* Redo a delete or undo a create new page. */
- pagep->next_pgno = argp->next_pgno;
- change = 1;
- }
-
- if (!change) {
- if ((ret =
- __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
- goto out;
- } else {
- LSN(pagep) = redo ? *lsnp : argp->prevlsn;
- if ((ret =
- __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
- goto out;
- }
- }
-
- /* Now time to do the next page */
-npage: if (argp->next_pgno != PGNO_INVALID) {
- ret = memp_fget(mpf, &argp->next_pgno, 0, &pagep);
-
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- goto done;
- } else if ((ret =
- memp_fget(mpf, &argp->next_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
- change = 0;
-
- if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
- /* Redo a create new page or undo a delete new page. */
- pagep->prev_pgno = argp->new_pgno;
- change = 1;
- } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
- (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
- /* Redo a delete or undo a create new page. */
- pagep->prev_pgno = argp->prev_pgno;
- change = 1;
- }
-
- if (!change) {
- if ((ret =
- __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
- goto out;
- } else {
- LSN(pagep) = redo ? *lsnp : argp->nextlsn;
- if ((ret =
- __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
- goto out;
- }
- }
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-
-/*
- * __ham_replace_recover --
- * This log message refers to partial puts that are local to a single
- * page. You can think of them as special cases of the more general
- * insdel log message.
- *
- * PUBLIC: int __ham_replace_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_replace_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_replace_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- DBT dbt;
- PAGE *pagep;
- int32_t grow;
- int change, cmp_n, cmp_p, getmeta, ret;
- u_int8_t *hk;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_replace_print);
- REC_INTRO(__ham_replace_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = memp_fget(mpf, &argp->pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
-
- if (cmp_p == 0 && redo) {
- change = 1;
- /* Reapply the change as specified. */
- dbt.data = argp->newitem.data;
- dbt.size = argp->newitem.size;
- grow = argp->newitem.size - argp->olditem.size;
- LSN(pagep) = *lsnp;
- } else if (cmp_n == 0 && !redo) {
- change = 1;
- /* Undo the already applied change. */
- dbt.data = argp->olditem.data;
- dbt.size = argp->olditem.size;
- grow = argp->olditem.size - argp->newitem.size;
- LSN(pagep) = argp->pagelsn;
- } else {
- change = 0;
- grow = 0;
- }
-
- if (change) {
- __ham_onpage_replace(pagep,
- file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
- if (argp->makedup) {
- hk = P_ENTRY(pagep, argp->ndx);
- if (redo)
- HPAGE_PTYPE(hk) = H_DUPLICATE;
- else
- HPAGE_PTYPE(hk) = H_KEYDATA;
- }
- }
-
- if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-/*
- * __ham_newpgno_recover --
- * This log message is used when allocating or deleting an overflow
- * page. It takes care of modifying the meta data.
- *
- * PUBLIC: int __ham_newpgno_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_newpgno_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_newpgno_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int change, cmp_n, cmp_p, getmeta, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_newpgno_print);
- REC_INTRO(__ham_newpgno_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- /*
- * There are two phases to the recovery here. First we need
- * to update the meta data; then we need to update the page.
- * We'll do the meta-data first.
- */
- cmp_n = log_compare(lsnp, &hcp->hdr->lsn);
- cmp_p = log_compare(&hcp->hdr->lsn, &argp->metalsn);
-
- change = 0;
- if ((cmp_p == 0 && redo && argp->opcode == ALLOCPGNO) ||
- (cmp_n == 0 && !redo && argp->opcode == DELPGNO)) {
- /* Need to redo an allocation or undo a deletion. */
- hcp->hdr->last_freed = argp->free_pgno;
- if (redo && argp->old_pgno != 0) /* Must be ALLOCPGNO */
- hcp->hdr->spares[hcp->hdr->ovfl_point]++;
- change = 1;
- } else if (cmp_p == 0 && redo && argp->opcode == DELPGNO) {
- /* Need to redo a deletion */
- hcp->hdr->last_freed = argp->pgno;
- change = 1;
- } else if (cmp_n == 0 && !redo && argp->opcode == ALLOCPGNO) {
- /* undo an allocation. */
- if (argp->old_pgno == 0)
- hcp->hdr->last_freed = argp->pgno;
- else {
- hcp->hdr->spares[hcp->hdr->ovfl_point]--;
- hcp->hdr->last_freed = 0;
- }
- change = 1;
- }
- if (change) {
- hcp->hdr->lsn = redo ? *lsnp : argp->metalsn;
- F_SET(hcp, H_DIRTY);
- }
-
-
- /* Now check the newly allocated/freed page. */
- ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
-
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = memp_fget(mpf, &argp->pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
-
- change = 0;
- if (cmp_p == 0 && redo && argp->opcode == ALLOCPGNO) {
- /* Need to redo an allocation. */
- P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
- PGNO_INVALID, 0, argp->new_type);
- change = 1;
- } else if (cmp_n == 0 && !redo && argp->opcode == DELPGNO) {
- /* Undoing a delete. */
- P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
- argp->old_pgno, 0, argp->old_type);
- change = 1;
- } else if ((cmp_p == 0 && redo && argp->opcode == DELPGNO) ||
- (cmp_n == 0 && !redo && argp->opcode == ALLOCPGNO)) {
- /* Need to redo a deletion or undo an allocation. */
- NEXT_PGNO(pagep) = argp->free_pgno;
- TYPE(pagep) = P_INVALID;
- change = 1;
- }
- if (change)
- LSN(pagep) = redo ? *lsnp : argp->pagelsn;
-
- if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-
-}
-
-/*
- * __ham_splitmeta_recover --
- * This is the meta-data part of the split. Records the new and old
- * bucket numbers and the new/old mask information.
- *
- * PUBLIC: int __ham_splitmeta_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_splitmeta_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_splitmeta_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- int change, cmp_n, cmp_p, getmeta, ret;
- u_int32_t pow;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_splitmeta_print);
- REC_INTRO(__ham_splitmeta_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- /*
- * There are two phases to the recovery here. First we need
- * to update the meta data; then we need to update the page.
- * We'll do the meta-data first.
- */
- cmp_n = log_compare(lsnp, &hcp->hdr->lsn);
- cmp_p = log_compare(&hcp->hdr->lsn, &argp->metalsn);
-
- change = 0;
- if (cmp_p == 0 && redo) {
- /* Need to redo the split information. */
- hcp->hdr->max_bucket = argp->bucket + 1;
- pow = __db_log2(hcp->hdr->max_bucket + 1);
- if (pow > hcp->hdr->ovfl_point) {
- hcp->hdr->spares[pow] =
- hcp->hdr->spares[hcp->hdr->ovfl_point];
- hcp->hdr->ovfl_point = pow;
- }
- if (hcp->hdr->max_bucket > hcp->hdr->high_mask) {
- hcp->hdr->low_mask = hcp->hdr->high_mask;
- hcp->hdr->high_mask =
- hcp->hdr->max_bucket | hcp->hdr->low_mask;
- }
- change = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo the split information. */
- hcp->hdr->max_bucket = argp->bucket;
- hcp->hdr->ovfl_point = argp->ovflpoint;
- hcp->hdr->spares[hcp->hdr->ovfl_point] = argp->spares;
- pow = 1 << __db_log2(hcp->hdr->max_bucket + 1);
- hcp->hdr->high_mask = pow - 1;
- hcp->hdr->low_mask = (pow >> 1) - 1;
- change = 1;
- }
- if (change) {
- hcp->hdr->lsn = redo ? *lsnp : argp->metalsn;
- F_SET(hcp, H_DIRTY);
- }
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-/*
- * __ham_splitdata_recover --
- *
- * PUBLIC: int __ham_splitdata_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_splitdata_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_splitdata_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int change, cmp_n, cmp_p, getmeta, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_splitdata_print);
- REC_INTRO(__ham_splitdata_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = memp_fget(mpf, &argp->pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
-
- /*
- * There are two types of log messages here, one for the old page
- * and one for the new pages created. The original image in the
- * SPLITOLD record is used for undo. The image in the SPLITNEW
- * is used for redo. We should never have a case where there is
- * a redo operation and the SPLITOLD record is on disk, but not
- * the SPLITNEW record. Therefore, we only have work to do when
- * redo NEW messages and undo OLD messages, but we have to update
- * LSNs in both cases.
- */
- change = 0;
- if (cmp_p == 0 && redo) {
- if (argp->opcode == SPLITNEW)
- /* Need to redo the split described. */
- memcpy(pagep, argp->pageimage.data,
- argp->pageimage.size);
- LSN(pagep) = *lsnp;
- change = 1;
- } else if (cmp_n == 0 && !redo) {
- if (argp->opcode == SPLITOLD) {
- /* Put back the old image. */
- memcpy(pagep, argp->pageimage.data,
- argp->pageimage.size);
- } else
- P_INIT(pagep, file_dbp->pgsize, argp->pgno,
- PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
- LSN(pagep) = argp->pagelsn;
- change = 1;
- }
- if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-/*
- * __ham_ovfl_recover --
- * This message is generated when we initialize a set of overflow pages.
- *
- * PUBLIC: int __ham_ovfl_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_ovfl_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t max_pgno, pgno;
- int cmp_n, cmp_p, getmeta, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_ovfl_print);
- REC_INTRO(__ham_ovfl_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
-
- cmp_n = log_compare(lsnp, &hcp->hdr->lsn);
- cmp_p = log_compare(&hcp->hdr->lsn, &argp->metalsn);
-
- if (cmp_p == 0 && redo) {
- /* Redo the allocation. */
- hcp->hdr->last_freed = argp->start_pgno;
- hcp->hdr->spares[argp->ovflpoint] += argp->npages;
- hcp->hdr->lsn = *lsnp;
- F_SET(hcp, H_DIRTY);
- } else if (cmp_n == 0 && !redo) {
- hcp->hdr->last_freed = argp->free_pgno;
- hcp->hdr->spares[argp->ovflpoint] -= argp->npages;
- hcp->hdr->lsn = argp->metalsn;
- F_SET(hcp, H_DIRTY);
- }
-
- max_pgno = argp->start_pgno + argp->npages - 1;
- ret = 0;
- for (pgno = argp->start_pgno; pgno <= max_pgno; pgno++) {
- if ((ret = memp_fget(mpf, &pgno, 0, &pagep)) != 0) {
- if (!redo) {
- ret = 0;
- continue;
- }
- if ((ret = memp_fget(mpf,
- &pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
- if (redo && log_compare((const DB_LSN *)lsnp,
- (const DB_LSN *)&LSN(pagep)) > 0) {
- P_INIT(pagep, file_dbp->pgsize, pgno, PGNO_INVALID,
- pgno == max_pgno ? argp->free_pgno : pgno + 1,
- 0, P_HASH);
- LSN(pagep) = *lsnp;
- ret = __ham_put_page(file_dbp, pagep, 1);
- } else if (!redo) {
- ZERO_LSN(pagep->lsn);
- ret = __ham_put_page(file_dbp, pagep, 1);
- } else
- ret = __ham_put_page(file_dbp, pagep, 0);
- if (ret)
- goto out;
- }
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
-
-/*
- * __ham_copypage_recover --
- * Recovery function for copypage.
- *
- * PUBLIC: int __ham_copypage_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__ham_copypage_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __ham_copypage_args *argp;
- DB *file_dbp;
- DBC *dbc;
- HASH_CURSOR *hcp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, getmeta, modified, ret;
-
- getmeta = 0;
- hcp = NULL;
- REC_PRINT(__ham_copypage_print);
- REC_INTRO(__ham_copypage_read);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- GET_META(file_dbp, (HASH_CURSOR *)dbc->internal, ret);
- if (ret != 0)
- goto out;
- getmeta = 1;
- modified = 0;
-
- /* This is the bucket page. */
- ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto donext;
- } else if ((ret = memp_fget(mpf, &argp->pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
-
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- memcpy(pagep, argp->page.data, argp->page.size);
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- P_INIT(pagep, hcp->hdr->pagesize, argp->pgno, PGNO_INVALID,
- argp->next_pgno, 0, P_HASH);
- LSN(pagep) = argp->pagelsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
- /* Now fix up the "next" page. */
-donext: ret = memp_fget(mpf, &argp->next_pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto do_nn;
- } else if ((ret = memp_fget(mpf, &argp->next_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- /* There is nothing to do in the REDO case; only UNDO. */
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- memcpy(pagep, argp->page.data, argp->page.size);
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
- /* Now fix up the next's next page. */
-do_nn: if (argp->nnext_pgno == PGNO_INVALID)
- goto done;
-
- ret = memp_fget(mpf, &argp->nnext_pgno, 0, &pagep);
- if (ret != 0) {
- if (!redo) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = memp_fget(mpf, &argp->nnext_pgno,
- DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->nnextlsn);
-
- if (cmp_p == 0 && redo) {
- /* Need to redo update described. */
- PREV_PGNO(pagep) = argp->pgno;
- LSN(pagep) = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && !redo) {
- /* Need to undo update described. */
- PREV_PGNO(pagep) = argp->next_pgno;
- LSN(pagep) = argp->nnextlsn;
- modified = 1;
- }
- if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (getmeta)
- RELEASE_META(file_dbp, hcp);
- REC_CLOSE;
-}
diff --git a/db2/hash/hash_stat.c b/db2/hash/hash_stat.c
deleted file mode 100644
index 1b493d5..0000000
--- a/db2/hash/hash_stat.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash_stat.c 10.12 (Sleepycat) 12/19/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "hash.h"
-
-/*
- * __ham_stat --
- * Gather/print the hash statistics
- *
- * PUBLIC: int __ham_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
- */
-int
-__ham_stat(dbp, spp, db_malloc, flags)
- DB *dbp;
- void *spp;
- void *(*db_malloc) __P((size_t));
- u_int32_t flags;
-{
- COMPQUIET(spp, NULL);
- COMPQUIET(db_malloc, NULL);
- COMPQUIET(flags, 0);
-
- DB_PANIC_CHECK(dbp);
-
- return (__db_eopnotsup(dbp->dbenv));
-}
diff --git a/db2/include/btree.h b/db2/include/btree.h
deleted file mode 100644
index b0c04b1..0000000
--- a/db2/include/btree.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)btree.h 10.26 (Sleepycat) 12/16/98
- */
-
-/* Forward structure declarations. */
-struct __btree; typedef struct __btree BTREE;
-struct __cursor; typedef struct __cursor CURSOR;
-struct __epg; typedef struct __epg EPG;
-struct __recno; typedef struct __recno RECNO;
-
-#define DEFMINKEYPAGE (2)
-
-#define ISINTERNAL(p) (TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO)
-#define ISLEAF(p) (TYPE(p) == P_LBTREE || TYPE(p) == P_LRECNO)
-
-/*
- * If doing transactions we have to hold the locks associated with a data item
- * from a page for the entire transaction. However, we don't have to hold the
- * locks associated with walking the tree. Distinguish between the two so that
- * we don't tie up the internal pages of the tree longer than necessary.
- */
-#define __BT_LPUT(dbc, lock) \
- (F_ISSET((dbc)->dbp, DB_AM_LOCKING) ? \
- lock_put((dbc)->dbp->dbenv->lk_info, lock) : 0)
-#define __BT_TLPUT(dbc, lock) \
- (F_ISSET((dbc)->dbp, DB_AM_LOCKING) && (dbc)->txn == NULL ? \
- lock_put((dbc)->dbp->dbenv->lk_info, lock) : 0)
-
-/*
- * Flags to __bam_search() and __bam_rsearch().
- *
- * Note, internal page searches must find the largest record less than key in
- * the tree so that descents work. Leaf page searches must find the smallest
- * record greater than key so that the returned index is the record's correct
- * position for insertion.
- *
- * The flags parameter to the search routines describes three aspects of the
- * search: the type of locking required (including if we're locking a pair of
- * pages), the item to return in the presence of duplicates and whether or not
- * to return deleted entries. To simplify both the mnemonic representation
- * and the code that checks for various cases, we construct a set of bitmasks.
- */
-#define S_READ 0x00001 /* Read locks. */
-#define S_WRITE 0x00002 /* Write locks. */
-
-#define S_APPEND 0x00040 /* Append to the tree. */
-#define S_DELNO 0x00080 /* Don't return deleted items. */
-#define S_DUPFIRST 0x00100 /* Return first duplicate. */
-#define S_DUPLAST 0x00200 /* Return last duplicate. */
-#define S_EXACT 0x00400 /* Exact items only. */
-#define S_PARENT 0x00800 /* Lock page pair. */
-#define S_STACK 0x01000 /* Need a complete stack. */
-#define S_PAST_EOF 0x02000 /* If doing insert search (or keyfirst
- * or keylast operations), or a split
- * on behalf of an insert, it's okay to
- * return an entry one past end-of-page.
- */
-
-#define S_DELETE (S_WRITE | S_DUPFIRST | S_DELNO | S_EXACT | S_STACK)
-#define S_FIND (S_READ | S_DUPFIRST | S_DELNO)
-#define S_FIND_WR (S_WRITE | S_DUPFIRST | S_DELNO)
-#define S_INSERT (S_WRITE | S_DUPLAST | S_PAST_EOF | S_STACK)
-#define S_KEYFIRST (S_WRITE | S_DUPFIRST | S_PAST_EOF | S_STACK)
-#define S_KEYLAST (S_WRITE | S_DUPLAST | S_PAST_EOF | S_STACK)
-#define S_WRPAIR (S_WRITE | S_DUPLAST | S_PAST_EOF | S_PARENT)
-
-/*
- * Flags to __bam_iitem().
- */
-#define BI_DELETED 0x01 /* Key/data pair only placeholder. */
-#define BI_DOINCR 0x02 /* Increment the record count. */
-#define BI_NEWKEY 0x04 /* New key. */
-
-/*
- * Various routines pass around page references. A page reference can be a
- * pointer to the page or a page number; for either, an indx can designate
- * an item on the page.
- */
-struct __epg {
- PAGE *page; /* The page. */
- db_indx_t indx; /* The index on the page. */
- DB_LOCK lock; /* The page's lock. */
-};
-
-/*
- * We maintain a stack of the pages that we're locking in the tree. Btree's
- * (currently) only save two levels of the tree at a time, so the default
- * stack is always large enough. Recno trees have to lock the entire tree to
- * do inserts/deletes, however. Grow the stack as necessary.
- */
-#define BT_STK_CLR(c) \
- ((c)->csp = (c)->sp)
-
-#define BT_STK_ENTER(c, pagep, page_indx, lock, ret) do { \
- if ((ret = \
- (c)->csp == (c)->esp ? __bam_stkgrow(c) : 0) == 0) { \
- (c)->csp->page = pagep; \
- (c)->csp->indx = page_indx; \
- (c)->csp->lock = lock; \
- } \
-} while (0)
-
-#define BT_STK_PUSH(c, pagep, page_indx, lock, ret) do { \
- BT_STK_ENTER(c, pagep, page_indx, lock, ret); \
- ++(c)->csp; \
-} while (0)
-
-#define BT_STK_POP(c) \
- ((c)->csp == (c)->stack ? NULL : --(c)->csp)
-
-/*
- * Arguments passed to __bam_ca_replace().
- */
-typedef enum {
- REPLACE_SETUP,
- REPLACE_SUCCESS,
- REPLACE_FAILED
-} ca_replace_arg;
-
-/* Arguments passed to __ram_ca(). */
-typedef enum {
- CA_DELETE,
- CA_IAFTER,
- CA_IBEFORE
-} ca_recno_arg;
-
-#define RECNO_OOB 0 /* Illegal record number. */
-
-/* Btree/Recno cursor. */
-struct __cursor {
- DBC *dbc; /* Enclosing DBC. */
-
- /* Per-thread information: shared by btree/recno. */
- EPG *sp; /* Stack pointer. */
- EPG *csp; /* Current stack entry. */
- EPG *esp; /* End stack pointer. */
- EPG stack[5];
-
- /* Per-thread information: btree private. */
- PAGE *page; /* Cursor page. */
-
- db_pgno_t pgno; /* Page. */
- db_indx_t indx; /* Page item ref'd by the cursor. */
-
- db_pgno_t dpgno; /* Duplicate page. */
- db_indx_t dindx; /* Page item ref'd by the cursor. */
-
- DB_LOCK lock; /* Cursor read lock. */
- db_lockmode_t mode; /* Lock mode. */
-
- /* Per-thread information: recno private. */
- db_recno_t recno; /* Current record number. */
-
- /*
- * Btree:
- * We set a flag in the cursor structure if the underlying object has
- * been deleted. It's not strictly necessary, we could get the same
- * information by looking at the page itself.
- *
- * Recno:
- * When renumbering recno databases during deletes, cursors referencing
- * "deleted" records end up positioned between two records, and so must
- * be specially adjusted on the next operation.
- */
-#define C_DELETED 0x0001 /* Record was deleted. */
- u_int32_t flags;
-};
-
-/*
- * The in-memory recno data structure.
- *
- * !!!
- * These fields are ignored as far as multi-threading is concerned. There
- * are no transaction semantics associated with backing files, nor is there
- * any thread protection.
- */
-struct __recno {
- int re_delim; /* Variable-length delimiting byte. */
- int re_pad; /* Fixed-length padding byte. */
- u_int32_t re_len; /* Length for fixed-length records. */
-
- char *re_source; /* Source file name. */
- int re_fd; /* Source file descriptor */
- db_recno_t re_last; /* Last record number read. */
- void *re_cmap; /* Current point in mapped space. */
- void *re_smap; /* Start of mapped space. */
- void *re_emap; /* End of mapped space. */
- size_t re_msize; /* Size of mapped region. */
- /* Recno input function. */
- int (*re_irec) __P((DBC *, db_recno_t));
-
-#define RECNO_EOF 0x0001 /* EOF on backing source file. */
-#define RECNO_MODIFIED 0x0002 /* Tree was modified. */
- u_int32_t flags;
-};
-
-/*
- * The in-memory, per-tree btree data structure.
- */
-struct __btree {
- db_pgno_t bt_lpgno; /* Last insert location. */
-
- db_indx_t bt_maxkey; /* Maximum keys per page. */
- db_indx_t bt_minkey; /* Minimum keys per page. */
-
- int (*bt_compare) /* Comparison function. */
- __P((const DBT *, const DBT *));
- size_t(*bt_prefix) /* Prefix function. */
- __P((const DBT *, const DBT *));
-
- db_indx_t bt_ovflsize; /* Maximum key/data on-page size. */
-
- RECNO *recno; /* Private recno structure. */
-};
-
-#include "btree_auto.h"
-#include "btree_ext.h"
-#include "db_am.h"
-#include "common_ext.h"
diff --git a/db2/include/btree_auto.h b/db2/include/btree_auto.h
deleted file mode 100644
index 041b80f..0000000
--- a/db2/include/btree_auto.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#ifndef bam_AUTO_H
-#define bam_AUTO_H
-
-#define DB_bam_pg_alloc (DB_bam_BEGIN + 1)
-
-typedef struct _bam_pg_alloc_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- DB_LSN meta_lsn;
- DB_LSN page_lsn;
- db_pgno_t pgno;
- u_int32_t ptype;
- db_pgno_t next;
-} __bam_pg_alloc_args;
-
-
-#define DB_bam_pg_free (DB_bam_BEGIN + 2)
-
-typedef struct _bam_pg_free_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN meta_lsn;
- DBT header;
- db_pgno_t next;
-} __bam_pg_free_args;
-
-
-#define DB_bam_split (DB_bam_BEGIN + 3)
-
-typedef struct _bam_split_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t left;
- DB_LSN llsn;
- db_pgno_t right;
- DB_LSN rlsn;
- u_int32_t indx;
- db_pgno_t npgno;
- DB_LSN nlsn;
- DBT pg;
-} __bam_split_args;
-
-
-#define DB_bam_rsplit (DB_bam_BEGIN + 4)
-
-typedef struct _bam_rsplit_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DBT pgdbt;
- db_pgno_t nrec;
- DBT rootent;
- DB_LSN rootlsn;
-} __bam_rsplit_args;
-
-
-#define DB_bam_adj (DB_bam_BEGIN + 5)
-
-typedef struct _bam_adj_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- u_int32_t indx;
- u_int32_t indx_copy;
- u_int32_t is_insert;
-} __bam_adj_args;
-
-
-#define DB_bam_cadjust (DB_bam_BEGIN + 6)
-
-typedef struct _bam_cadjust_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- u_int32_t indx;
- int32_t adjust;
- int32_t total;
-} __bam_cadjust_args;
-
-
-#define DB_bam_cdel (DB_bam_BEGIN + 7)
-
-typedef struct _bam_cdel_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- u_int32_t indx;
-} __bam_cdel_args;
-
-
-#define DB_bam_repl (DB_bam_BEGIN + 8)
-
-typedef struct _bam_repl_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- u_int32_t indx;
- u_int32_t isdeleted;
- DBT orig;
- DBT repl;
- u_int32_t prefix;
- u_int32_t suffix;
-} __bam_repl_args;
-
-#endif
diff --git a/db2/include/btree_ext.h b/db2/include/btree_ext.h
deleted file mode 100644
index fbc2ed9..0000000
--- a/db2/include/btree_ext.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _btree_ext_h_
-#define _btree_ext_h_
-int __bam_cmp __P((DB *, const DBT *,
- PAGE *, u_int32_t, int (*)(const DBT *, const DBT *)));
-int __bam_defcmp __P((const DBT *, const DBT *));
-size_t __bam_defpfx __P((const DBT *, const DBT *));
-int __bam_pgin __P((db_pgno_t, void *, DBT *));
-int __bam_pgout __P((db_pgno_t, void *, DBT *));
-int __bam_mswap __P((PAGE *));
-int __bam_cprint __P((DB *));
-int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
-void __bam_ca_di __P((DB *, db_pgno_t, u_int32_t, int));
-void __bam_ca_dup __P((DB *,
- db_pgno_t, u_int32_t, u_int32_t, db_pgno_t, u_int32_t));
-void __bam_ca_rsplit __P((DB *, db_pgno_t, db_pgno_t));
-void __bam_ca_split __P((DB *,
- db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
-int __bam_c_init __P((DBC *));
-int __bam_dup __P((DBC *, CURSOR *, u_int32_t, int));
-int __bam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
-int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
-int __bam_dpage __P((DBC *, const DBT *));
-int __bam_dpages __P((DBC *));
-int __bam_open __P((DB *, DB_INFO *));
-int __bam_close __P((DB *));
-void __bam_setovflsize __P((DB *));
-int __bam_read_root __P((DB *));
-int __bam_new __P((DBC *, u_int32_t, PAGE **));
-int __bam_lput __P((DBC *, DB_LOCK));
-int __bam_free __P((DBC *, PAGE *));
-int __bam_lt __P((DBC *));
-int __bam_lget
- __P((DBC *, int, db_pgno_t, db_lockmode_t, DB_LOCK *));
-int __bam_iitem __P((DBC *,
- PAGE **, db_indx_t *, DBT *, DBT *, u_int32_t, u_int32_t));
-int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *));
-int __bam_pg_alloc_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_pg_free_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_split_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_rsplit_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_adj_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_cadjust_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_cdel_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_repl_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ram_open __P((DB *, DB_INFO *));
-int __ram_close __P((DB *));
-int __ram_c_del __P((DBC *, u_int32_t));
-int __ram_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
-int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
-void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
-int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
-int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
-int __bam_adjust __P((DBC *, int32_t));
-int __bam_nrecs __P((DBC *, db_recno_t *));
-db_recno_t __bam_total __P((PAGE *));
-int __bam_search __P((DBC *,
- const DBT *, u_int32_t, int, db_recno_t *, int *));
-int __bam_stkrel __P((DBC *, int));
-int __bam_stkgrow __P((CURSOR *));
-int __bam_split __P((DBC *, void *));
-int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
-int __bam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-int __bam_pg_alloc_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, DB_LSN *, DB_LSN *, db_pgno_t,
- u_int32_t, db_pgno_t));
-int __bam_pg_alloc_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_pg_alloc_read __P((void *, __bam_pg_alloc_args **));
-int __bam_pg_free_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, const DBT *,
- db_pgno_t));
-int __bam_pg_free_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_pg_free_read __P((void *, __bam_pg_free_args **));
-int __bam_split_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *,
- const DBT *));
-int __bam_split_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_split_read __P((void *, __bam_split_args **));
-int __bam_rsplit_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, const DBT *, db_pgno_t,
- const DBT *, DB_LSN *));
-int __bam_rsplit_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_rsplit_read __P((void *, __bam_rsplit_args **));
-int __bam_adj_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t));
-int __bam_adj_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_adj_read __P((void *, __bam_adj_args **));
-int __bam_cadjust_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- int32_t, int32_t));
-int __bam_cadjust_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_cadjust_read __P((void *, __bam_cadjust_args **));
-int __bam_cdel_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, u_int32_t));
-int __bam_cdel_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_cdel_read __P((void *, __bam_cdel_args **));
-int __bam_repl_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, u_int32_t,
- u_int32_t, const DBT *, const DBT *, u_int32_t,
- u_int32_t));
-int __bam_repl_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __bam_repl_read __P((void *, __bam_repl_args **));
-int __bam_init_print __P((DB_ENV *));
-int __bam_init_recover __P((DB_ENV *));
-#endif /* _btree_ext_h_ */
diff --git a/db2/include/clib_ext.h b/db2/include/clib_ext.h
deleted file mode 100644
index 2566b84..0000000
--- a/db2/include/clib_ext.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _clib_ext_h_
-#define _clib_ext_h_
-#ifdef __STDC__
-void err __P((int eval, const char *, ...));
-#else
-void err();
-#endif
-#ifdef __STDC__
-void errx __P((int eval, const char *, ...));
-#else
-void errx();
-#endif
-#ifdef __STDC__
-void warn __P((const char *, ...));
-#else
-void warn();
-#endif
-#ifdef __STDC__
-void warnx __P((const char *, ...));
-#else
-void warnx();
-#endif
-#ifndef HAVE_GETCWD
-char *getcwd __P((char *, size_t));
-#endif
-void get_long __P((char *, long, long, long *));
-#ifndef HAVE_GETOPT
-int getopt __P((int, char * const *, const char *));
-#endif
-#ifndef HAVE_MEMCMP
-int memcmp __P((const void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMCPY
-void *memcpy __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMMOVE
-void *memmove __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_RAISE
-int raise __P((int));
-#endif
-#ifndef HAVE_SNPRINTF
-#ifdef __STDC__
-int snprintf __P((char *, size_t, const char *, ...));
-#else
-int snprintf();
-#endif
-#endif
-#ifndef HAVE_STRERROR
-char *strerror __P((int));
-#endif
-#ifndef HAVE_STRSEP
-char *strsep __P((char **, const char *));
-#endif
-#ifndef HAVE_VSNPRINTF
-int vsnprintf();
-#endif
-#endif /* _clib_ext_h_ */
diff --git a/db2/include/common_ext.h b/db2/include/common_ext.h
deleted file mode 100644
index 33fb0cb..0000000
--- a/db2/include/common_ext.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _common_ext_h_
-#define _common_ext_h_
-int __db_appname __P((DB_ENV *,
- APPNAME, const char *, const char *, u_int32_t, int *, char **));
-int __db_apprec __P((DB_ENV *, u_int32_t));
-int __db_byteorder __P((DB_ENV *, int));
-int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
-int __db_fcchk
- __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
-int __db_ferr __P((const DB_ENV *, const char *, int));
-#ifdef __STDC__
-void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
-#else
-void __db_err();
-#endif
-int __db_pgerr __P((DB *, db_pgno_t));
-int __db_pgfmt __P((DB *, db_pgno_t));
-int __db_panic __P((DB_ENV *, int));
-u_int32_t __db_log2 __P((u_int32_t));
-int __db_rattach __P((REGINFO *));
-int __db_rdetach __P((REGINFO *));
-int __db_runlink __P((REGINFO *, int));
-int __db_rgrow __P((REGINFO *, size_t));
-int __db_rreattach __P((REGINFO *, size_t));
-void __db_shalloc_init __P((void *, size_t));
-int __db_shalloc __P((void *, size_t, size_t, void *));
-void __db_shalloc_free __P((void *, void *));
-size_t __db_shalloc_count __P((void *));
-size_t __db_shsizeof __P((void *));
-void __db_shalloc_dump __P((void *, FILE *));
-int __db_tablesize __P((u_int32_t));
-void __db_hashinit __P((void *, u_int32_t));
-#endif /* _common_ext_h_ */
diff --git a/db2/include/cxx_int.h b/db2/include/cxx_int.h
deleted file mode 100644
index 0a59de4..0000000
--- a/db2/include/cxx_int.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)cxx_int.h 10.5 (Sleepycat) 4/10/98
- */
-
-#ifndef _CXX_INT_H_
-#define _CXX_INT_H_
-
-// private data structures known to the implementation only
-
-#include <assert.h> // used by defines below
-
-//
-// Using FooImp classes will allow the implementation to change in the
-// future without any modification to user code or even to header files
-// that the user includes. FooImp * is just like void * except that it
-// provides a little extra protection, since you cannot randomly assign
-// any old pointer to a FooImp* as you can with void *. Currently, a
-// pointer to such an opaque class is always just a pointer to the
-// appropriate underlying implementation struct. These are converted
-// back and forth using the various overloaded wrap()/unwrap() methods.
-// This is essentially a use of the "Bridge" Design Pattern.
-//
-// WRAPPED_CLASS implements the appropriate wrap() and unwrap() methods
-// for a wrapper class that has an underlying pointer representation.
-//
-#define WRAPPED_CLASS(_WRAPPER_CLASS, _IMP_CLASS, _WRAPPED_TYPE) \
- \
- class _IMP_CLASS {}; \
- \
- inline _WRAPPED_TYPE unwrap(_WRAPPER_CLASS *val) \
- { \
- if (!val) return 0; \
- return (_WRAPPED_TYPE)(val->imp()); \
- } \
- \
- inline const _WRAPPED_TYPE unwrapConst(const _WRAPPER_CLASS *val) \
- { \
- if (!val) return 0; \
- return (const _WRAPPED_TYPE)(val->imp()); \
- } \
- \
- inline _IMP_CLASS *wrap(_WRAPPED_TYPE val) \
- { \
- return (_IMP_CLASS*)val; \
- }
-
-WRAPPED_CLASS(DbLockTab, DbLockTabImp, DB_LOCKTAB*)
-WRAPPED_CLASS(DbLog, DbLogImp, DB_LOG*)
-WRAPPED_CLASS(DbMpool, DbMpoolImp, DB_MPOOL*)
-WRAPPED_CLASS(DbMpoolFile, DbMpoolFileImp, DB_MPOOLFILE*)
-WRAPPED_CLASS(Db, DbImp, DB*)
-WRAPPED_CLASS(DbTxn, DbTxnImp, DB_TXN*)
-WRAPPED_CLASS(DbTxnMgr, DbTxnMgrImp, DB_TXNMGR*)
-
-// Macros that handle detected errors, in case we want to
-// change the default behavior. runtime_error() throws an
-// exception by default.
-//
-// Since it's unusual to throw an exception in a destructor,
-// we have a separate macro. For now, we silently ignore such
-// detected errors.
-//
-#define DB_ERROR(caller, ecode) \
- DbEnv::runtime_error(caller, ecode)
-
-#define DB_DESTRUCTOR_ERROR(caller, ecode) \
- DbEnv::runtime_error(caller, ecode, 1)
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// These defines are for tedious flag or field set/get access methods.
-//
-
-// Define setName() and getName() methods that twiddle
-// the _flags field.
-//
-#define DB_FLAG_METHODS(_class, _flags, _cxx_name, _flag_name) \
- \
-void _class::set##_cxx_name(int onOrOff) \
-{ \
- if (onOrOff) \
- _flags |= _flag_name; \
- else \
- _flags &= ~(_flag_name); \
-} \
- \
-int _class::get##_cxx_name() const \
-{ \
- return (_flags & _flag_name) ? 1 : 0; \
-}
-
-
-#define DB_RO_ACCESS(_class, _type, _cxx_name, _field) \
- \
-_type _class::get_##_cxx_name() const \
-{ \
- return _field; \
-}
-
-#define DB_WO_ACCESS(_class, _type, _cxx_name, _field) \
- \
-void _class::set_##_cxx_name(_type value) \
-{ \
- _field = value; \
-} \
-
-#define DB_RW_ACCESS(_class, _type, _cxx_name, _field) \
- DB_RO_ACCESS(_class, _type, _cxx_name, _field) \
- DB_WO_ACCESS(_class, _type, _cxx_name, _field)
-
-#endif /* !_CXX_INT_H_ */
diff --git a/db2/include/db_185.h.src b/db2/include/db_185.h.src
deleted file mode 100644
index a928ca8..0000000
--- a/db2/include/db_185.h.src
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db_185.h.src 8.7 (Sleepycat) 4/10/98
- */
-
-#ifndef _DB_185_H_
-#define _DB_185_H_
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-/*
- * XXX
- * Handle function prototypes and the keyword "const". This steps on name
- * space that DB doesn't control, but all of the other solutions are worse.
- */
-#undef __P
-#if defined(__STDC__) || defined(__cplusplus)
-#define __P(protos) protos /* ANSI C prototypes */
-#else
-#define const
-#define __P(protos) () /* K&R C preprocessor */
-#endif
-
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-@u_int8_decl@
-@int16_decl@
-@u_int16_decl@
-@int32_decl@
-@u_int32_decl@
-#endif
-
-/*
- * XXX
- * SGI/IRIX already has a pgno_t.
- */
-#ifdef sgi
-#define pgno_t db_pgno_t
-#endif
-
-#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
-typedef u_int32_t pgno_t;
-#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
-typedef u_int16_t indx_t;
-#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
-typedef u_int32_t recno_t;
-
-/* Key/data structure -- a Data-Base Thang. */
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT;
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-/* Access method description structure. */
-typedef struct __db {
- DBTYPE type; /* Underlying db type. */
- int (*close) __P((struct __db *));
- int (*del) __P((const struct __db *, const DBT *, u_int));
- int (*get) __P((const struct __db *, const DBT *, DBT *, u_int));
- int (*put) __P((const struct __db *, DBT *, const DBT *, u_int));
- int (*seq) __P((const struct __db *, DBT *, DBT *, u_int));
- int (*sync) __P((const struct __db *, u_int));
- void *internal; /* Access method private. */
- int (*fd) __P((const struct __db *));
-} DB;
-
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t maxkeypage; /* maximum keys per page */
- u_int32_t minkeypage; /* minimum keys per page */
- u_int32_t psize; /* page size */
- int (*compare) /* comparison function */
- __P((const DBT *, const DBT *));
- size_t (*prefix) /* prefix function */
- __P((const DBT *, const DBT *));
- int lorder; /* byte order */
-} BTREEINFO;
-
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int32_t bsize; /* bucket size */
- u_int32_t ffactor; /* fill factor */
- u_int32_t nelem; /* number of elements */
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) __P((const void *, size_t));
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* !_DB_185_H_ */
diff --git a/db2/include/db_am.h b/db2/include/db_am.h
deleted file mode 100644
index fe2176d..0000000
--- a/db2/include/db_am.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_am.h 10.15 (Sleepycat) 11/22/98
- */
-#ifndef _DB_AM_H
-#define _DB_AM_H
-
-#define DB_ISBIG 0x01
-#define DB_ADD_DUP 0x10
-#define DB_REM_DUP 0x20
-#define DB_ADD_BIG 0x30
-#define DB_REM_BIG 0x40
-#define DB_SPLITOLD 0x50
-#define DB_SPLITNEW 0x60
-#define DB_ADD_PAGE 0x70
-#define DB_REM_PAGE 0x80
-
-/*
- * Standard initialization and shutdown macros for all recovery functions.
- *
- * Requires the following local variables:
- *
- * DB *file_dbp, *mdbp;
- * DB_MPOOLFILE *mpf;
- * int ret;
- */
-#define REC_INTRO(func) { \
- file_dbp = NULL; \
- dbc = NULL; \
- if ((ret = func(dbtp->data, &argp)) != 0) \
- goto out; \
- if ((ret = \
- __db_fileid_to_db(logp, &file_dbp, argp->fileid)) != 0) { \
- if (ret == DB_DELETED) { \
- ret = 0; \
- goto done; \
- } \
- goto out; \
- } \
- if (file_dbp == NULL) \
- goto out; \
- if ((ret = file_dbp->cursor(file_dbp, NULL, &dbc, 0)) != 0) \
- goto out; \
- F_SET(dbc, DBC_RECOVER); \
- mpf = file_dbp->mpf; \
-}
-
-#define REC_CLOSE { \
- if (argp != NULL) \
- __os_free(argp, sizeof(*argp)); \
- if (dbc != NULL) \
- dbc->c_close(dbc); \
- return (ret); \
-}
-
-/*
- * No-op versions of the same macros.
- */
-#define REC_NOOP_INTRO(func) { \
- if ((ret = func(dbtp->data, &argp)) != 0) \
- return (ret); \
-}
-#define REC_NOOP_CLOSE { \
- if (argp != NULL) \
- __os_free(argp, sizeof(*argp)); \
- return (ret); \
-}
-
-/*
- * Standard debugging macro for all recovery functions.
- */
-#ifdef DEBUG_RECOVER
-#define REC_PRINT(func) \
- (void)func(logp, dbtp, lsnp, redo, info);
-#else
-#define REC_PRINT(func) \
- COMPQUIET(info, NULL);
-#endif
-
-#include "db_auto.h"
-#include "db_ext.h"
-#endif
diff --git a/db2/include/db_auto.h b/db2/include/db_auto.h
deleted file mode 100644
index 0d1e43a..0000000
--- a/db2/include/db_auto.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#ifndef db_AUTO_H
-#define db_AUTO_H
-
-#define DB_db_addrem (DB_db_BEGIN + 1)
-
-typedef struct _db_addrem_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t indx;
- size_t nbytes;
- DBT hdr;
- DBT dbt;
- DB_LSN pagelsn;
-} __db_addrem_args;
-
-
-#define DB_db_split (DB_db_BEGIN + 2)
-
-typedef struct _db_split_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- DBT pageimage;
- DB_LSN pagelsn;
-} __db_split_args;
-
-
-#define DB_db_big (DB_db_BEGIN + 3)
-
-typedef struct _db_big_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- db_pgno_t prev_pgno;
- db_pgno_t next_pgno;
- DBT dbt;
- DB_LSN pagelsn;
- DB_LSN prevlsn;
- DB_LSN nextlsn;
-} __db_big_args;
-
-
-#define DB_db_ovref (DB_db_BEGIN + 4)
-
-typedef struct _db_ovref_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- int32_t adjust;
- DB_LSN lsn;
-} __db_ovref_args;
-
-
-#define DB_db_relink (DB_db_BEGIN + 5)
-
-typedef struct _db_relink_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- db_pgno_t prev;
- DB_LSN lsn_prev;
- db_pgno_t next;
- DB_LSN lsn_next;
-} __db_relink_args;
-
-
-#define DB_db_addpage (DB_db_BEGIN + 6)
-
-typedef struct _db_addpage_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN lsn;
- db_pgno_t nextpgno;
- DB_LSN nextlsn;
-} __db_addpage_args;
-
-
-#define DB_db_debug (DB_db_BEGIN + 7)
-
-typedef struct _db_debug_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- DBT op;
- u_int32_t fileid;
- DBT key;
- DBT data;
- u_int32_t arg_flags;
-} __db_debug_args;
-
-#endif
diff --git a/db2/include/db_cxx.h b/db2/include/db_cxx.h
deleted file mode 100644
index f415d59..0000000
--- a/db2/include/db_cxx.h
+++ /dev/null
@@ -1,861 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_cxx.h 10.30 (Sleepycat) 11/22/98
- */
-
-#ifndef _DB_CXX_H_
-#define _DB_CXX_H_
-//
-// C++ assumptions:
-//
-// To ensure portability to many platforms, both new and old, we make
-// few assumptions about the C++ compiler and library. For example,
-// we do not expect STL, templates or namespaces to be available. The
-// "newest" C++ feature used is exceptions, which are used liberally
-// to transmit error information. Even the use of exceptions can be
-// disabled at runtime, see setErrorModel().
-//
-// C++ naming conventions:
-//
-// - All top level class names start with Db.
-// - All class members start with lower case letter.
-// - All private data members are suffixed with underscore.
-// - Use underscores to divide names into multiple words.
-// - Simple data accessors are named with get_ or set_ prefix.
-// - All method names are taken from names of functions in the C
-// layer of db (usually by dropping a prefix like "db_").
-// These methods have the same argument types and order,
-// other than dropping the explicit arg that acts as "this".
-//
-// As a rule, each DbFoo object has exactly one underlying DB_FOO struct
-// (defined in db.h) associated with it. In many cases, we inherit directly
-// from the DB_FOO structure to make this relationship explicit. Often,
-// the underlying C layer allocates and deallocates these structures, so
-// there is no easy way to add any data to the DbFoo class. When you see
-// a comment about whether data is permitted to be added, this is what
-// is going on. Of course, if we need to add data to such C++ classes
-// in the future, we will arrange to have an indirect pointer to the
-// DB_FOO struct (as some of the classes already have).
-//
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Forward declarations
-//
-
-#include <iostream.h>
-#include <db.h>
-
-class Db; // forward
-class Dbc; // forward
-class DbEnv; // forward
-class DbException; // forward
-class DbInfo; // forward
-class DbLock; // forward
-class DbLockTab; // forward
-class DbLog; // forward
-class DbLsn; // forward
-class DbMpool; // forward
-class DbMpoolFile; // forward
-class Dbt; // forward
-class DbTxn; // forward
-class DbTxnMgr; // forward
-
-// These classes are not defined here and should be invisible
-// to the user, but some compilers require forward references.
-// There is one for each use of the DEFINE_DB_CLASS macro.
-
-class DbLockTabImp;
-class DbLogImp;
-class DbMpoolImp;
-class DbMpoolFileImp;
-class DbImp;
-class DbTxnImp;
-class DbTxnMgrImp;
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Mechanisms for declaring classes
-//
-
-//
-// Every class defined in this file has an _exported next to the class name.
-// This is needed for WinTel machines so that the class methods can
-// be exported or imported in a DLL as appropriate. Users of the DLL
-// use the define DB_USE_DLL. When the DLL is built, DB_CREATE_DLL
-// must be defined.
-//
-#if defined(_MSC_VER)
-
-# if defined(DB_CREATE_DLL)
-# define _exported __declspec(dllexport) // creator of dll
-# elif defined(DB_USE_DLL)
-# define _exported __declspec(dllimport) // user of dll
-# else
-# define _exported // static lib creator or user
-# endif
-
-#else
-
-# define _exported
-
-#endif
-
-// DEFINE_DB_CLASS defines an imp_ data member and imp() accessor.
-// The underlying type is a pointer to an opaque *Imp class, that
-// gets converted to the correct implementation class by the implementation.
-//
-// Since these defines use "private/public" labels, and leave the access
-// being "private", we always use these by convention before any data
-// members in the private section of a class. Keeping them in the
-// private section also emphasizes that they are off limits to user code.
-//
-#define DEFINE_DB_CLASS(name) \
- public: class name##Imp* imp() { return imp_; } \
- public: const class name##Imp* imp() const { return imp_; } \
- private: class name##Imp* imp_
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Turn off inappropriate compiler warnings
-//
-
-#ifdef _MSC_VER
-
-// These are level 4 warnings that are explicitly disabled.
-// With Visual C++, by default you do not see above level 3 unless
-// you use /W4. But we like to compile with the highest level
-// warnings to catch other errors.
-//
-// 4201: nameless struct/union
-// triggered by standard include file <winnt.h>
-//
-// 4514: unreferenced inline function has been removed
-// certain include files in MSVC define methods that are not called
-//
-#pragma warning(disable: 4201 4514)
-
-#endif
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Exception classes
-//
-
-// Almost any error in the DB library throws a DbException.
-// Every exception should be considered an abnormality
-// (e.g. bug, misuse of DB, file system error).
-//
-// NOTE: We would like to inherit from class exception and
-// let it handle what(), but there are
-// MSVC++ problems when <exception> is included.
-//
-class _exported DbException
-{
-public:
- virtual ~DbException();
- DbException(int err);
- DbException(const char *description);
- DbException(const char *prefix, int err);
- DbException(const char *prefix1, const char *prefix2, int err);
- const int get_errno();
- virtual const char *what() const;
-
- DbException(const DbException &);
- DbException &operator = (const DbException &);
-
-private:
- char *what_;
- int err_; // errno
-};
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Lock classes
-//
-
-class _exported DbLock
-{
- friend class DbLockTab;
-
-public:
- DbLock();
-
- int put(DbLockTab *locktab);
-
- DbLock(const DbLock &);
- DbLock &operator = (const DbLock &);
-
-protected:
- // We can add data to this class if needed
- // since its contained class is not allocated by db.
- // (see comment at top)
-
- DbLock(DB_LOCK);
- DB_LOCK lock_;
-};
-
-class _exported DbLockTab
-{
- friend class DbEnv;
-
-public:
- int close();
- int detect(u_int32_t flags, int atype);
- int get(u_int32_t locker, u_int32_t flags, const Dbt *obj,
- db_lockmode_t lock_mode, DbLock *lock);
- int id(u_int32_t *idp);
- int stat(DB_LOCK_STAT **statp, void *(*db_malloc)(size_t));
- int vec(u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[],
- int nlist, DB_LOCKREQ **elistp);
-
- // Create or remove new locktab files
- //
- static int open(const char *dir, u_int32_t flags, int mode,
- DbEnv* dbenv, DbLockTab **regionp);
- static int unlink(const char *dir, int force, DbEnv* dbenv);
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // copying not allowed
- //
- DbLockTab(const DbLockTab &);
- DbLockTab &operator = (const DbLockTab &);
-
- // Note: use DbLockTab::open() or DbEnv::get_lk_info()
- // to get pointers to a DbLockTab,
- // and call DbLockTab::close() rather than delete to release them.
- //
- DbLockTab();
- ~DbLockTab();
-
- DEFINE_DB_CLASS(DbLockTab);
-};
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Log classes
-//
-
-class _exported DbLsn : protected DB_LSN
-{
- friend class DbLog; // friendship needed to cast to base class
- friend class DbMpool;
-};
-
-class _exported DbLog
-{
- friend class DbEnv;
-
-public:
- int archive(char **list[], u_int32_t flags, void *(*db_malloc)(size_t));
- int close();
- static int compare(const DbLsn *lsn0, const DbLsn *lsn1);
- int file(DbLsn *lsn, char *namep, int len);
- int flush(const DbLsn *lsn);
- int get(DbLsn *lsn, Dbt *data, u_int32_t flags);
- int put(DbLsn *lsn, const Dbt *data, u_int32_t flags);
-
- // Normally these would be called register and unregister to
- // parallel the C interface, but "register" is a reserved word.
- //
- int db_register(Db *dbp, const char *name, DBTYPE type, u_int32_t *fidp);
- int db_unregister(u_int32_t fid);
-
- // Create or remove new log files
- //
- static int open(const char *dir, u_int32_t flags, int mode,
- DbEnv* dbenv, DbLog **regionp);
- static int unlink(const char *dir, int force, DbEnv* dbenv);
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use DbLog::open() or DbEnv::get_lg_info()
- // to get pointers to a DbLog,
- // and call DbLog::close() rather than delete to release them.
- //
- DbLog();
- ~DbLog();
-
- // no copying
- DbLog(const DbLog &);
- operator = (const DbLog &);
-
- DEFINE_DB_CLASS(DbLog);
-};
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Memory pool classes
-//
-
-class _exported DbMpoolFile
-{
- friend class DbEnv;
-
-public:
- int close();
- int get(db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep);
- int put(void *pgaddr, u_int32_t flags);
- int set(void *pgaddr, u_int32_t flags);
- int sync();
-
- static int open(DbMpool *mp, const char *file,
- u_int32_t flags, int mode, size_t pagesize,
- DB_MPOOL_FINFO *finfop, DbMpoolFile **mpf);
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use DbMpoolFile::open()
- // to get pointers to a DbMpoolFile,
- // and call DbMpoolFile::close() rather than delete to release them.
- //
- DbMpoolFile();
-
- // Shut g++ up.
-protected:
- ~DbMpoolFile();
-
-private:
- // no copying
- DbMpoolFile(const DbMpoolFile &);
- operator = (const DbMpoolFile &);
-
- DEFINE_DB_CLASS(DbMpoolFile);
-};
-
-class _exported DbMpool
-{
- friend class DbEnv;
-
-public:
- int close();
-
- // access to low level interface
- // Normally this would be called register to parallel
- // the C interface, but "register" is a reserved word.
- //
- int db_register(int ftype,
- int (*pgin)(db_pgno_t pgno, void *pgaddr, DBT *pgcookie),
- int (*pgout)(db_pgno_t pgno, void *pgaddr, DBT *pgcookie));
-
- int stat(DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp,
- void *(*db_malloc)(size_t));
- int sync(DbLsn *lsn);
- int trickle(int pct, int *nwrotep);
-
- // Create or remove new mpool files
- //
- static int open(const char *dir, u_int32_t flags, int mode,
- DbEnv* dbenv, DbMpool **regionp);
- static int unlink(const char *dir, int force, DbEnv* dbenv);
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use DbMpool::open() or DbEnv::get_mp_info()
- // to get pointers to a DbMpool,
- // and call DbMpool::close() rather than delete to release them.
- //
- DbMpool();
- ~DbMpool();
-
- // no copying
- DbMpool(const DbMpool &);
- DbMpool &operator = (const DbMpool &);
-
- DEFINE_DB_CLASS(DbMpool);
-};
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Transaction classes
-//
-
-class _exported DbTxnMgr
-{
- friend class DbEnv;
-
-public:
- int begin(DbTxn *pid, DbTxn **tid);
- int checkpoint(u_int32_t kbyte, u_int32_t min) const;
- int close();
- int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t));
-
- // Create or remove new txnmgr files
- //
- static int open(const char *dir, u_int32_t flags, int mode,
- DbEnv* dbenv, DbTxnMgr **regionp);
- static int unlink(const char *dir, int force, DbEnv* dbenv);
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use DbTxnMgr::open() or DbEnv::get_tx_info()
- // to get pointers to a DbTxnMgr,
- // and call DbTxnMgr::close() rather than delete to release them.
- //
- DbTxnMgr();
- ~DbTxnMgr();
-
- // no copying
- DbTxnMgr(const DbTxnMgr &);
- operator = (const DbTxnMgr &);
-
- DEFINE_DB_CLASS(DbTxnMgr);
-};
-
-class _exported DbTxn
-{
- friend class DbTxnMgr;
-
-public:
- int abort();
- int commit();
- u_int32_t id();
- int prepare();
-
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use DbTxnMgr::begin() to get pointers to a DbTxn,
- // and call DbTxn::abort() or DbTxn::commit rather than
- // delete to release them.
- //
- DbTxn();
- ~DbTxn();
-
- // no copying
- DbTxn(const DbTxn &);
- operator = (const DbTxn &);
-
- DEFINE_DB_CLASS(DbTxn);
-};
-
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Application classes
-//
-
-//
-// A set of application options - define how this application uses
-// the db library.
-//
-class _exported DbInfo : protected DB_INFO
-{
- friend class DbEnv;
- friend class Db;
-
-public:
- DbInfo();
- ~DbInfo();
-
- // Byte order.
- void set_lorder(int);
-
- // Underlying cache size.
- void set_cachesize(size_t);
-
- // Underlying page size.
- void set_pagesize(size_t);
-
- // Local heap allocation.
- typedef void *(*db_malloc_fcn)(size_t);
- void set_malloc(db_malloc_fcn);
-
- // Duplicate compare function.
- typedef int (*dup_compare_fcn)(const DBT *, const DBT *);
- void set_dup_compare(dup_compare_fcn);
-
- ////////////////////////////////////////////////////////////////
- // Btree access method.
-
- // Maximum keys per page.
- void set_bt_maxkey(int);
-
- // Minimum keys per page.
- void set_bt_minkey(int);
-
- // Comparison function.
- typedef int (*bt_compare_fcn)(const DBT *, const DBT *);
- void set_bt_compare(bt_compare_fcn);
-
- // Prefix function.
- typedef size_t (*bt_prefix_fcn)(const DBT *, const DBT *);
- void set_bt_prefix(bt_prefix_fcn);
-
- ////////////////////////////////////////////////////////////////
- // Hash access method.
-
- // Fill factor.
- void set_h_ffactor(u_int32_t);
-
- // Number of elements.
- void set_h_nelem(u_int32_t);
-
- // Hash function.
- typedef u_int32_t (*h_hash_fcn)(const void *, u_int32_t);
- void set_h_hash(h_hash_fcn);
-
- ////////////////////////////////////////////////////////////////
- // Recno access method.
-
- // Fixed-length padding byte.
- void set_re_pad(int);
-
- // Variable-length delimiting byte.
- void set_re_delim(int);
-
- // Length for fixed-length records.
- void set_re_len(u_int32_t);
-
- // Source file name.
- void set_re_source(char *);
-
- // Note: some flags are set as side effects of calling
- // above "set" methods.
- //
- void set_flags(u_int32_t);
-
-
- // (deep) copying of this object is allowed.
- //
- DbInfo(const DbInfo &);
- DbInfo &operator = (const DbInfo &);
-
-private:
- // We can add data to this class if needed
- // since parent class is not allocated by db.
- // (see comment at top)
-};
-
-//
-// Base application class. Provides functions for opening a database.
-// User of this library can use this class as a starting point for
-// developing a DB application - derive their application class from
-// this one, add application control logic.
-//
-// Note that if you use the default constructor, you must explicitly
-// call appinit() before any other db activity (e.g. opening files)
-//
-class _exported DbEnv : protected DB_ENV
-{
- friend class DbTxnMgr;
- friend class DbLog;
- friend class DbLockTab;
- friend class DbMpool;
- friend class Db;
-
-public:
-
- ~DbEnv();
-
- // This constructor can be used to immediately initialize the
- // application with these arguments. Do not use it if you
- // need to set other parameters via the access methods.
- //
- DbEnv(const char *homeDir, char *const *db_config, u_int32_t flags);
-
- // Use this constructor if you wish to *delay* the initialization
- // of the db library. This is useful if you need to set
- // any particular parameters via the access methods below.
- // Then call appinit() to complete the initialization.
- //
- DbEnv();
-
- // Used in conjunction with the default constructor to
- // complete the initialization of the db library.
- //
- int appinit(const char *homeDir, char *const *db_config, u_int32_t flags);
-
- // Called automatically when DbEnv is destroyed, or can be
- // called at any time to shut down Db.
- //
- int appexit();
-
- // Version information. A static method so it can be obtained anytime.
- //
- static char *version(int *major, int *minor, int *patch);
-
- ////////////////////////////////////////////////////////////////
- // simple get/set access methods
- //
- // If you are calling set_ methods, you need to
- // use the default constructor along with appinit().
-
- // Byte order.
- void set_lorder(int);
-
- // Panic callback.
- typedef void (*db_paniccall_fcn)(DbEnv *, int);
- void set_paniccall(db_paniccall_fcn);
-
- // Error message callback.
- typedef void (*db_errcall_fcn)(const char *, char *);
- void set_errcall(db_errcall_fcn);
-
- // Error message file stream.
- void set_errfile(FILE *);
-
- // Error message prefix.
- void set_errpfx(const char *);
-
- // Generate debugging messages.
- void set_verbose(int);
-
- ////////////////////////////////////////////////////////////////
- // Locking.
-
- // Return from lock_open().
- DbLockTab *get_lk_info() const;
-
- // Two dimensional conflict matrix.
- void set_lk_conflicts(u_int8_t *);
-
- // Number of lock modes in table.
- void set_lk_modes(int);
-
- // Maximum number of locks.
- void set_lk_max(u_int32_t);
-
- // Deadlock detect on every conflict.
- void set_lk_detect(u_int32_t);
-
-
- ////////////////////////////////////////////////////////////////
- // Logging.
-
- // Return from log_open().
- DbLog *get_lg_info() const;
-
- // Maximum file size.
- void set_lg_max(u_int32_t);
-
-
- ////////////////////////////////////////////////////////////////
- // Memory pool.
-
- // Return from memp_open().
- DbMpool *get_mp_info() const;
-
- // Maximum file size for mmap.
- void set_mp_mmapsize(size_t);
-
- // Bytes in the mpool cache.
- void set_mp_size(size_t);
-
-
- ////////////////////////////////////////////////////////////////
- // Transactions.
-
- // Return from txn_open().
- DbTxnMgr *get_tx_info() const;
-
- // Maximum number of transactions.
- void set_tx_max(u_int32_t);
-
- // Dispatch function for recovery.
- typedef int (*tx_recover_fcn)(DB_LOG *, DBT *, DB_LSN *, int, void *);
- void set_tx_recover(tx_recover_fcn);
-
- // Flags.
- void set_flags(u_int32_t);
-
- ////////////////////////////////////////////////////////////////
- // The default error model is to throw an exception whenever
- // an error occurs. This generally allows for cleaner logic
- // for transaction processing, as a try block can surround a
- // single transaction. Alternatively, since almost every method
- // returns an error code (errno), the error model can be set to
- // not throw exceptions, and instead return the appropriate code.
- //
- enum ErrorModel { Exception, ErrorReturn };
- void set_error_model(ErrorModel);
-
- // If an error is detected and the error call function
- // or stream is set, a message is dispatched or printed.
- // If a prefix is set, each message is prefixed.
- //
- // You can use set_errcall() or set_errfile() above to control
- // error functionality using a C model. Alternatively, you can
- // call set_error_stream() to force all errors to a C++ stream.
- // It is unwise to mix these approaches.
- //
- void set_error_stream(class ostream*);
-
- // used internally
- static int runtime_error(const char *caller, int err,
- int in_destructor = 0, int force_throw = 0);
-
-private:
- // We can add data to this class if needed
- // since parent class is not allocated by db.
- // (see comment at top)
-
- // no copying
- DbEnv(const DbEnv &);
- operator = (const DbEnv &);
-
- ErrorModel error_model_;
- static void stream_error_function(const char *, char *);
- static ostream *error_stream_;
-};
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-//
-// Table access classes
-//
-
-//
-// Represents a database table = a set of keys with associated values.
-//
-class _exported Db
-{
- friend class DbEnv;
-
-public:
- int close(u_int32_t flags);
- int cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags);
- int del(DbTxn *txnid, Dbt *key, u_int32_t flags);
- int fd(int *fdp);
- int get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags);
- int join(Dbc **curslist, u_int32_t flags, Dbc **dbcp);
- int put(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags);
- int stat(void *sp, void *(*db_malloc)(size_t), u_int32_t flags);
- int sync(u_int32_t flags);
-
- int get_byteswapped() const;
- DBTYPE get_type() const;
-
- static int open(const char *fname, DBTYPE type, u_int32_t flags,
- int mode, DbEnv *dbenv, DbInfo *info, Db **dbpp);
-
- static int xa_open(const char *fname, DBTYPE type, u_int32_t flags,
- int mode, DbInfo *info, Db **dbpp);
-private:
- // We can add data to this class if needed
- // since it is implemented via a pointer.
- // (see comment at top)
-
- // Note: use Db::open() to get initialize pointers to a Db,
- // and call Db::close() rather than delete to release them.
- Db();
- ~Db();
-
- // no copying
- Db(const Db &);
- Db &operator = (const Db &);
-
- DEFINE_DB_CLASS(Db);
-};
-
-//
-// A chunk of data, maybe a key or value.
-//
-class _exported Dbt : private DBT
-{
- friend class Dbc;
- friend class Db;
- friend class DbLog;
- friend class DbMpoolFile;
- friend class DbLockTab;
-
-public:
-
- // key/data
- void *get_data() const;
- void set_data(void *);
-
- // key/data length
- u_int32_t get_size() const;
- void set_size(u_int32_t);
-
- // RO: length of user buffer.
- u_int32_t get_ulen() const;
- void set_ulen(u_int32_t);
-
- // RO: get/put record length.
- u_int32_t get_dlen() const;
- void set_dlen(u_int32_t);
-
- // RO: get/put record offset.
- u_int32_t get_doff() const;
- void set_doff(u_int32_t);
-
- // flags
- u_int32_t get_flags() const;
- void set_flags(u_int32_t);
-
- Dbt(void *data, size_t size);
- Dbt();
- ~Dbt();
- Dbt(const Dbt &);
- Dbt &operator = (const Dbt &);
-
-private:
- // We can add data to this class if needed
- // since parent class is not allocated by db.
- // (see comment at top)
-};
-
-class _exported Dbc : protected DBC
-{
- friend class Db;
-
-public:
- int close();
- int del(u_int32_t flags);
- int get(Dbt* key, Dbt *data, u_int32_t flags);
- int put(Dbt* key, Dbt *data, u_int32_t flags);
-
-private:
- // No data is permitted in this class (see comment at top)
-
- // Note: use Db::cursor() to get pointers to a Dbc,
- // and call Dbc::close() rather than delete to release them.
- //
- Dbc();
- ~Dbc();
-
- // no copying
- Dbc(const Dbc &);
- Dbc &operator = (const Dbc &);
-};
-#endif /* !_DB_CXX_H_ */
diff --git a/db2/include/db_dispatch.h b/db2/include/db_dispatch.h
deleted file mode 100644
index 8f5e217..0000000
--- a/db2/include/db_dispatch.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db_dispatch.h 10.4 (Sleepycat) 5/3/98
- */
-
-#ifndef _DB_DISPATCH_H
-#define _DB_DISPATCH_H
-
-struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD;
-struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST;
-
-/*
- * Declarations and typedefs for the list of transaction IDs used during
- * recovery.
- */
-struct __db_txnhead {
- LIST_HEAD(__db_headlink, __db_txnlist) head;
- u_int32_t maxid;
- int32_t generation;
-};
-
-struct __db_txnlist {
- LIST_ENTRY(__db_txnlist) links;
- u_int32_t txnid;
- int32_t generation;
-};
-
-#define DB_log_BEGIN 0
-#define DB_txn_BEGIN 5
-#define DB_ham_BEGIN 20
-#define DB_db_BEGIN 40
-#define DB_bam_BEGIN 50
-#define DB_ram_BEGIN 100
-#define DB_user_BEGIN 150
-
-#define TXN_UNDO 0
-#define TXN_REDO 1
-#define TXN_BACKWARD_ROLL -1
-#define TXN_FORWARD_ROLL -2
-#define TXN_OPENFILES -3
-#endif
diff --git a/db2/include/db_ext.h b/db2/include/db_ext.h
deleted file mode 100644
index 1ad1643..0000000
--- a/db2/include/db_ext.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _db_ext_h_
-#define _db_ext_h_
-int __db_close __P((DB *, u_int32_t));
-int __db_init_wrapper __P((DB *));
-int __db_cprint __P((DB *));
-int __db_c_destroy __P((DBC *));
-int __db_sync __P((DB *, u_int32_t));
-int __db_addrem_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- size_t, const DBT *, const DBT *, DB_LSN *));
-int __db_addrem_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_addrem_read __P((void *, __db_addrem_args **));
-int __db_split_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, const DBT *,
- DB_LSN *));
-int __db_split_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_split_read __P((void *, __db_split_args **));
-int __db_big_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
- db_pgno_t, const DBT *, DB_LSN *, DB_LSN *,
- DB_LSN *));
-int __db_big_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_big_read __P((void *, __db_big_args **));
-int __db_ovref_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, int32_t, DB_LSN *));
-int __db_ovref_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_ovref_read __P((void *, __db_ovref_args **));
-int __db_relink_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, DB_LSN *,
- db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *));
-int __db_relink_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_relink_read __P((void *, __db_relink_args **));
-int __db_addpage_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- DB_LSN *));
-int __db_addpage_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_addpage_read __P((void *, __db_addpage_args **));
-int __db_debug_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- const DBT *, u_int32_t, const DBT *, const DBT *,
- u_int32_t));
-int __db_debug_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_debug_read __P((void *, __db_debug_args **));
-int __db_init_print __P((DB_ENV *));
-int __db_init_recover __P((DB_ENV *));
-int __db_pgin __P((db_pgno_t, size_t, void *));
-int __db_pgout __P((db_pgno_t, size_t, void *));
-int __db_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_add_recovery __P((DB_ENV *,
- int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t));
-int __db_txnlist_init __P((void *));
-int __db_txnlist_add __P((void *, u_int32_t));
-int __db_txnlist_find __P((void *, u_int32_t));
-void __db_txnlist_end __P((void *));
-void __db_txnlist_gen __P((void *, int));
-void __db_txnlist_print __P((void *));
-int __db_dput __P((DBC *, DBT *,
- PAGE **, db_indx_t *, int (*)(DBC *, u_int32_t, PAGE **)));
-int __db_drem __P((DBC *,
- PAGE **, u_int32_t, int (*)(DBC *, PAGE *)));
-int __db_dend __P((DBC *, db_pgno_t, PAGE **));
- int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
-int __db_pitem
- __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
-int __db_relink __P((DBC *, u_int32_t, PAGE *, PAGE **, int));
-int __db_ddup __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *)));
-int __db_dsearch __P((DBC *,
- int, DBT *, db_pgno_t, db_indx_t *, PAGE **, int *));
-int __db_cdelchk __P((const DB *, u_int32_t, int, int));
-int __db_cgetchk __P((const DB *, DBT *, DBT *, u_int32_t, int));
-int __db_cputchk __P((const DB *,
- const DBT *, DBT *, u_int32_t, int, int));
-int __db_closechk __P((const DB *, u_int32_t));
-int __db_delchk __P((const DB *, DBT *, u_int32_t, int));
-int __db_getchk __P((const DB *, const DBT *, DBT *, u_int32_t));
-int __db_joinchk __P((const DB *, u_int32_t));
-int __db_putchk
- __P((const DB *, DBT *, const DBT *, u_int32_t, int, int));
-int __db_statchk __P((const DB *, u_int32_t));
-int __db_syncchk __P((const DB *, u_int32_t));
-int __db_eopnotsup __P((const DB_ENV *));
-int __db_join __P((DB *, DBC **, u_int32_t, DBC **));
-int __db_goff __P((DB *, DBT *,
- u_int32_t, db_pgno_t, void **, u_int32_t *));
-int __db_poff __P((DBC *, const DBT *, db_pgno_t *,
- int (*)(DBC *, u_int32_t, PAGE **)));
-int __db_ovref __P((DBC *, db_pgno_t, int32_t));
-int __db_doff __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *)));
-int __db_moff __P((DB *, const DBT *, db_pgno_t, u_int32_t,
- int (*)(const DBT *, const DBT *), int *));
-void __db_loadme __P((void));
-FILE *__db_prinit __P((FILE *));
-int __db_dump __P((DB *, char *, int));
-int __db_prdb __P((DB *));
-int __db_prbtree __P((DB *));
-int __db_prhash __P((DB *));
-int __db_prtree __P((DB_MPOOLFILE *, int));
-int __db_prnpage __P((DB_MPOOLFILE *, db_pgno_t));
-int __db_prpage __P((PAGE *, int));
-int __db_isbad __P((PAGE *, int));
-void __db_pr __P((u_int8_t *, u_int32_t));
-int __db_prdbt __P((DBT *, int, FILE *));
-void __db_prflags __P((u_int32_t, const FN *, FILE *));
-int __db_addrem_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_split_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_big_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_ovref_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_relink_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_addpage_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_debug_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __db_ret __P((DB *,
- PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
-int __db_retcopy __P((DBT *,
- void *, u_int32_t, void **, u_int32_t *, void *(*)(size_t)));
-#endif /* _db_ext_h_ */
diff --git a/db2/include/db_join.h b/db2/include/db_join.h
deleted file mode 100644
index cb27e21..0000000
--- a/db2/include/db_join.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_join.h 10.2 (Sleepycat) 10/4/98
- */
-
-#ifndef _DB_JOIN_H
-#define _DB_JOIN_H
-/*
- * Joins use a join cursor that is similar to a regular DB cursor except
- * that it only supports c_get and c_close functionality. Also, it does
- * not support the full range of flags for get.
- */
-typedef struct __join_cursor {
- u_int32_t j_init; /* Set when cursor is initialized. */
- DBC **j_curslist; /* Array of cursors in the join. */
- DB *j_primary; /* Primary dbp. */
- DBT j_key; /* Used to do lookups. */
-} JOIN_CURSOR;
-#endif
diff --git a/db2/include/db_page.h b/db2/include/db_page.h
deleted file mode 100644
index 5c9ca67..0000000
--- a/db2/include/db_page.h
+++ /dev/null
@@ -1,512 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_page.h 10.18 (Sleepycat) 12/2/98
- */
-
-#ifndef _DB_PAGE_H_
-#define _DB_PAGE_H_
-
-/*
- * DB page formats.
- *
- * This implementation requires that values within the following structures
- * NOT be padded -- note, ANSI C permits random padding within structures.
- * If your compiler pads randomly you can just forget ever making DB run on
- * your system. In addition, no data type can require larger alignment than
- * its own size, e.g., a 4-byte data element may not require 8-byte alignment.
- *
- * Note that key/data lengths are often stored in db_indx_t's -- this is
- * not accidental, nor does it limit the key/data size. If the key/data
- * item fits on a page, it's guaranteed to be small enough to fit into a
- * db_indx_t, and storing it in one saves space.
- */
-
-#define PGNO_METADATA 0 /* Metadata page number. */
-#define PGNO_INVALID 0 /* Metadata page number, therefore illegal. */
-#define PGNO_ROOT 1 /* Root is page #1. */
-
-/*
- * When we create pages in mpool, we ask mpool to clear some number of bytes
- * in the header. This number must be at least as big as the regular page
- * headers and cover enough of the btree and hash meta-data pages to obliterate
- * the magic and version numbers.
- */
-#define DB_PAGE_CLEAR_LEN 32
-
-/************************************************************************
- BTREE METADATA PAGE LAYOUT
- ************************************************************************/
-
-/*
- * Btree metadata page layout:
- */
-typedef struct _btmeta {
- DB_LSN lsn; /* 00-07: LSN. */
- db_pgno_t pgno; /* 08-11: Current page number. */
- u_int32_t magic; /* 12-15: Magic number. */
- u_int32_t version; /* 16-19: Version. */
- u_int32_t pagesize; /* 20-23: Pagesize. */
- u_int32_t maxkey; /* 24-27: Btree: Maxkey. */
- u_int32_t minkey; /* 28-31: Btree: Minkey. */
- u_int32_t free; /* 32-35: Free list page number. */
-#define BTM_DUP 0x001 /* Duplicates. */
-#define BTM_RECNO 0x002 /* Recno tree. */
-#define BTM_RECNUM 0x004 /* Btree: maintain record count. */
-#define BTM_FIXEDLEN 0x008 /* Recno: fixed length records. */
-#define BTM_RENUMBER 0x010 /* Recno: renumber on insert/delete. */
-#define BTM_MASK 0x01f
- u_int32_t flags; /* 36-39: Flags. */
- u_int32_t re_len; /* 40-43: Recno: fixed-length record length. */
- u_int32_t re_pad; /* 44-47: Recno: fixed-length record pad. */
- /* 48-67: Unique file ID. */
- u_int8_t uid[DB_FILE_ID_LEN];
-} BTMETA;
-
-/************************************************************************
- HASH METADATA PAGE LAYOUT
- ************************************************************************/
-
-/*
- * Hash metadata page layout:
- */
-/* Hash Table Information */
-typedef struct hashhdr { /* Disk resident portion */
- DB_LSN lsn; /* 00-07: LSN of the header page */
- db_pgno_t pgno; /* 08-11: Page number (btree compatibility). */
- u_int32_t magic; /* 12-15: Magic NO for hash tables */
- u_int32_t version; /* 16-19: Version ID */
- u_int32_t pagesize; /* 20-23: Bucket/Page Size */
- u_int32_t ovfl_point; /* 24-27: Overflow page allocation location */
- u_int32_t last_freed; /* 28-31: Last freed overflow page pgno */
- u_int32_t max_bucket; /* 32-35: ID of Maximum bucket in use */
- u_int32_t high_mask; /* 36-39: Modulo mask into table */
- u_int32_t low_mask; /* 40-43: Modulo mask into table lower half */
- u_int32_t ffactor; /* 44-47: Fill factor */
- u_int32_t nelem; /* 48-51: Number of keys in hash table */
- u_int32_t h_charkey; /* 52-55: Value of hash(CHARKEY) */
-#define DB_HASH_DUP 0x01
- u_int32_t flags; /* 56-59: Allow duplicates. */
-#define NCACHED 32 /* number of spare points */
- /* 60-187: Spare pages for overflow */
- u_int32_t spares[NCACHED];
- /* 188-207: Unique file ID. */
- u_int8_t uid[DB_FILE_ID_LEN];
-
- /*
- * Minimum page size is 256.
- */
-} HASHHDR;
-
-/************************************************************************
- MAIN PAGE LAYOUT
- ************************************************************************/
-
-/*
- * +-----------------------------------+
- * | lsn | pgno | prev pgno |
- * +-----------------------------------+
- * | next pgno | entries | hf offset |
- * +-----------------------------------+
- * | level | type | index |
- * +-----------------------------------+
- * | index | free --> |
- * +-----------+-----------------------+
- * | F R E E A R E A |
- * +-----------------------------------+
- * | <-- free | item |
- * +-----------------------------------+
- * | item | item | item |
- * +-----------------------------------+
- *
- * sizeof(PAGE) == 26 bytes, and the following indices are guaranteed to be
- * two-byte aligned.
- *
- * For hash and btree leaf pages, index items are paired, e.g., inp[0] is the
- * key for inp[1]'s data. All other types of pages only contain single items.
- */
-typedef struct _db_page {
- DB_LSN lsn; /* 00-07: Log sequence number. */
- db_pgno_t pgno; /* 08-11: Current page number. */
- db_pgno_t prev_pgno; /* 12-15: Previous page number. */
- db_pgno_t next_pgno; /* 16-19: Next page number. */
- db_indx_t entries; /* 20-21: Number of item pairs on the page. */
- db_indx_t hf_offset; /* 22-23: High free byte page offset. */
-
- /*
- * The btree levels are numbered from the leaf to the root, starting
- * with 1, so the leaf is level 1, its parent is level 2, and so on.
- * We maintain this level on all btree pages, but the only place that
- * we actually need it is on the root page. It would not be difficult
- * to hide the byte on the root page once it becomes an internal page,
- * so we could get this byte back if we needed it for something else.
- */
-#define LEAFLEVEL 1
-#define MAXBTREELEVEL 255
- u_int8_t level; /* 24: Btree tree level. */
-
-#define P_INVALID 0 /* Invalid page type. */
-#define P_DUPLICATE 1 /* Duplicate. */
-#define P_HASH 2 /* Hash. */
-#define P_IBTREE 3 /* Btree internal. */
-#define P_IRECNO 4 /* Recno internal. */
-#define P_LBTREE 5 /* Btree leaf. */
-#define P_LRECNO 6 /* Recno leaf. */
-#define P_OVERFLOW 7 /* Overflow. */
- u_int8_t type; /* 25: Page type. */
- db_indx_t inp[1]; /* Variable length index of items. */
-} PAGE;
-
-/* Element macros. */
-#define LSN(p) (((PAGE *)p)->lsn)
-#define PGNO(p) (((PAGE *)p)->pgno)
-#define PREV_PGNO(p) (((PAGE *)p)->prev_pgno)
-#define NEXT_PGNO(p) (((PAGE *)p)->next_pgno)
-#define NUM_ENT(p) (((PAGE *)p)->entries)
-#define HOFFSET(p) (((PAGE *)p)->hf_offset)
-#define LEVEL(p) (((PAGE *)p)->level)
-#define TYPE(p) (((PAGE *)p)->type)
-
-/*
- * !!!
- * The next_pgno and prev_pgno fields are not maintained for btree and recno
- * internal pages. It's a minor performance improvement, and more, it's
- * hard to do when deleting internal pages, and it decreases the chance of
- * deadlock during deletes and splits.
- *
- * !!!
- * The btree/recno access method needs db_recno_t bytes of space on the root
- * page to specify how many records are stored in the tree. (The alternative
- * is to store the number of records in the meta-data page, which will create
- * a second hot spot in trees being actively modified, or recalculate it from
- * the BINTERNAL fields on each access.) Overload the prev_pgno field.
- */
-#define RE_NREC(p) \
- (TYPE(p) == P_LBTREE ? NUM_ENT(p) / 2 : \
- TYPE(p) == P_LRECNO ? NUM_ENT(p) : PREV_PGNO(p))
-#define RE_NREC_ADJ(p, adj) \
- PREV_PGNO(p) += adj;
-#define RE_NREC_SET(p, num) \
- PREV_PGNO(p) = num;
-
-/*
- * Initialize a page.
- *
- * !!!
- * Don't modify the page's LSN, code depends on it being unchanged after a
- * P_INIT call.
- */
-#define P_INIT(pg, pg_size, n, pg_prev, pg_next, btl, pg_type) do { \
- PGNO(pg) = n; \
- PREV_PGNO(pg) = pg_prev; \
- NEXT_PGNO(pg) = pg_next; \
- NUM_ENT(pg) = 0; \
- HOFFSET(pg) = pg_size; \
- LEVEL(pg) = btl; \
- TYPE(pg) = pg_type; \
-} while (0)
-
-/* Page header length (offset to first index). */
-#define P_OVERHEAD (SSZA(PAGE, inp))
-
-/* First free byte. */
-#define LOFFSET(pg) (P_OVERHEAD + NUM_ENT(pg) * sizeof(db_indx_t))
-
-/* Free space on the page. */
-#define P_FREESPACE(pg) (HOFFSET(pg) - LOFFSET(pg))
-
-/* Get a pointer to the bytes at a specific index. */
-#define P_ENTRY(pg, indx) ((u_int8_t *)pg + ((PAGE *)pg)->inp[indx])
-
-/************************************************************************
- OVERFLOW PAGE LAYOUT
- ************************************************************************/
-
-/*
- * Overflow items are referenced by HOFFPAGE and BOVERFLOW structures, which
- * store a page number (the first page of the overflow item) and a length
- * (the total length of the overflow item). The overflow item consists of
- * some number of overflow pages, linked by the next_pgno field of the page.
- * A next_pgno field of PGNO_INVALID flags the end of the overflow item.
- *
- * Overflow page overloads:
- * The amount of overflow data stored on each page is stored in the
- * hf_offset field.
- *
- * The implementation reference counts overflow items as it's possible
- * for them to be promoted onto btree internal pages. The reference
- * count is stored in the entries field.
- */
-#define OV_LEN(p) (((PAGE *)p)->hf_offset)
-#define OV_REF(p) (((PAGE *)p)->entries)
-
-/* Maximum number of bytes that you can put on an overflow page. */
-#define P_MAXSPACE(psize) ((psize) - P_OVERHEAD)
-
-/************************************************************************
- HASH PAGE LAYOUT
- ************************************************************************/
-
-/* Each index references a group of bytes on the page. */
-#define H_KEYDATA 1 /* Key/data item. */
-#define H_DUPLICATE 2 /* Duplicate key/data item. */
-#define H_OFFPAGE 3 /* Overflow key/data item. */
-#define H_OFFDUP 4 /* Overflow page of duplicates. */
-
-/*
- * !!!
- * Items on hash pages are (potentially) unaligned, so we can never cast the
- * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as
- * we do with B+tree on-page structures. Because we frequently want the type
- * field, it requires no alignment, and it's in the same location in all three
- * structures, there's a pair of macros.
- */
-#define HPAGE_PTYPE(p) (*(u_int8_t *)p)
-#define HPAGE_TYPE(pg, indx) (*P_ENTRY(pg, indx))
-
-/*
- * The first and second types are H_KEYDATA and H_DUPLICATE, represented
- * by the HKEYDATA structure:
- *
- * +-----------------------------------+
- * | type | key/data ... |
- * +-----------------------------------+
- *
- * For duplicates, the data field encodes duplicate elements in the data
- * field:
- *
- * +---------------------------------------------------------------+
- * | type | len1 | element1 | len1 | len2 | element2 | len2 |
- * +---------------------------------------------------------------+
- *
- * Thus, by keeping track of the offset in the element, we can do both
- * backward and forward traversal.
- */
-typedef struct _hkeydata {
- u_int8_t type; /* 00: Page type. */
- u_int8_t data[1]; /* Variable length key/data item. */
-} HKEYDATA;
-#define HKEYDATA_DATA(p) (((u_int8_t *)p) + SSZA(HKEYDATA, data))
-
-/*
- * The length of any HKEYDATA item. Note that indx is an element index,
- * not a PAIR index.
- */
-#define LEN_HITEM(pg, pgsize, indx) \
- (((indx) == 0 ? pgsize : pg->inp[indx - 1]) - pg->inp[indx])
-
-#define LEN_HKEYDATA(pg, psize, indx) \
- (((indx) == 0 ? psize : pg->inp[indx - 1]) - \
- pg->inp[indx] - HKEYDATA_SIZE(0))
-
-/*
- * Page space required to add a new HKEYDATA item to the page, with and
- * without the index value.
- */
-#define HKEYDATA_SIZE(len) \
- ((len) + SSZA(HKEYDATA, data))
-#define HKEYDATA_PSIZE(len) \
- (HKEYDATA_SIZE(len) + sizeof(db_indx_t))
-
-/* Put a HKEYDATA item at the location referenced by a page entry. */
-#define PUT_HKEYDATA(pe, kd, len, type) { \
- ((HKEYDATA *)pe)->type = type; \
- memcpy((u_int8_t *)pe + sizeof(u_int8_t), kd, len); \
-}
-
-/*
- * Macros the describe the page layout in terms of key-data pairs.
- * The use of "pindex" indicates that the argument is the index
- * expressed in pairs instead of individual elements.
- */
-#define H_NUMPAIRS(pg) (NUM_ENT(pg) / 2)
-#define H_KEYINDEX(pindx) (2 * (pindx))
-#define H_DATAINDEX(pindx) ((2 * (pindx)) + 1)
-#define H_PAIRKEY(pg, pindx) P_ENTRY(pg, H_KEYINDEX(pindx))
-#define H_PAIRDATA(pg, pindx) P_ENTRY(pg, H_DATAINDEX(pindx))
-#define H_PAIRSIZE(pg, psize, pindx) \
- (LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) + \
- LEN_HITEM(pg, psize, H_DATAINDEX(pindx)))
-#define LEN_HDATA(p, psize, pindx) LEN_HKEYDATA(p, psize, H_DATAINDEX(pindx))
-#define LEN_HKEY(p, psize, pindx) LEN_HKEYDATA(p, psize, H_KEYINDEX(pindx))
-
-/*
- * The third type is the H_OFFPAGE, represented by the HOFFPAGE structure:
- */
-typedef struct _hoffpage {
- u_int8_t type; /* 00: Page type and delete flag. */
- u_int8_t unused[3]; /* 01-03: Padding, unused. */
- db_pgno_t pgno; /* 04-07: Offpage page number. */
- u_int32_t tlen; /* 08-11: Total length of item. */
-} HOFFPAGE;
-
-#define HOFFPAGE_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno))
-#define HOFFPAGE_TLEN(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen))
-
-/*
- * Page space required to add a new HOFFPAGE item to the page, with and
- * without the index value.
- */
-#define HOFFPAGE_SIZE (sizeof(HOFFPAGE))
-#define HOFFPAGE_PSIZE (HOFFPAGE_SIZE + sizeof(db_indx_t))
-
-/*
- * The fourth type is H_OFFDUP represented by the HOFFDUP structure:
- */
-typedef struct _hoffdup {
- u_int8_t type; /* 00: Page type and delete flag. */
- u_int8_t unused[3]; /* 01-03: Padding, unused. */
- db_pgno_t pgno; /* 04-07: Offpage page number. */
-} HOFFDUP;
-#define HOFFDUP_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFDUP, pgno))
-
-/*
- * Page space required to add a new HOFFDUP item to the page, with and
- * without the index value.
- */
-#define HOFFDUP_SIZE (sizeof(HOFFDUP))
-#define HOFFDUP_PSIZE (HOFFDUP_SIZE + sizeof(db_indx_t))
-
-/************************************************************************
- BTREE PAGE LAYOUT
- ************************************************************************/
-
-/* Each index references a group of bytes on the page. */
-#define B_KEYDATA 1 /* Key/data item. */
-#define B_DUPLICATE 2 /* Duplicate key/data item. */
-#define B_OVERFLOW 3 /* Overflow key/data item. */
-
-/*
- * We have to store a deleted entry flag in the page. The reason is complex,
- * but the simple version is that we can't delete on-page items referenced by
- * a cursor -- the return order of subsequent insertions might be wrong. The
- * delete flag is an overload of the top bit of the type byte.
- */
-#define B_DELETE (0x80)
-#define B_DCLR(t) (t) &= ~B_DELETE
-#define B_DSET(t) (t) |= B_DELETE
-#define B_DISSET(t) ((t) & B_DELETE)
-
-#define B_TYPE(t) ((t) & ~B_DELETE)
-#define B_TSET(t, type, deleted) { \
- (t) = (type); \
- if (deleted) \
- B_DSET(t); \
-}
-
-/*
- * The first type is B_KEYDATA, represented by the BKEYDATA structure:
- */
-typedef struct _bkeydata {
- db_indx_t len; /* 00-01: Key/data item length. */
- u_int8_t type; /* 02: Page type AND DELETE FLAG. */
- u_int8_t data[1]; /* Variable length key/data item. */
-} BKEYDATA;
-
-/* Get a BKEYDATA item for a specific index. */
-#define GET_BKEYDATA(pg, indx) \
- ((BKEYDATA *)P_ENTRY(pg, indx))
-
-/*
- * Page space required to add a new BKEYDATA item to the page, with and
- * without the index value.
- */
-#define BKEYDATA_SIZE(len) \
- ALIGN((len) + SSZA(BKEYDATA, data), 4)
-#define BKEYDATA_PSIZE(len) \
- (BKEYDATA_SIZE(len) + sizeof(db_indx_t))
-
-/*
- * The second and third types are B_DUPLICATE and B_OVERFLOW, represented
- * by the BOVERFLOW structure.
- */
-typedef struct _boverflow {
- db_indx_t unused1; /* 00-01: Padding, unused. */
- u_int8_t type; /* 02: Page type AND DELETE FLAG. */
- u_int8_t unused2; /* 03: Padding, unused. */
- db_pgno_t pgno; /* 04-07: Next page number. */
- u_int32_t tlen; /* 08-11: Total length of item. */
-} BOVERFLOW;
-
-/* Get a BOVERFLOW item for a specific index. */
-#define GET_BOVERFLOW(pg, indx) \
- ((BOVERFLOW *)P_ENTRY(pg, indx))
-
-/*
- * Page space required to add a new BOVERFLOW item to the page, with and
- * without the index value.
- */
-#define BOVERFLOW_SIZE \
- ALIGN(sizeof(BOVERFLOW), 4)
-#define BOVERFLOW_PSIZE \
- (BOVERFLOW_SIZE + sizeof(db_indx_t))
-
-/*
- * Btree leaf and hash page layouts group indices in sets of two, one
- * for the key and one for the data. Everything else does it in sets
- * of one to save space. I use the following macros so that it's real
- * obvious what's going on...
- */
-#define O_INDX 1
-#define P_INDX 2
-
-/************************************************************************
- BTREE INTERNAL PAGE LAYOUT
- ************************************************************************/
-
-/*
- * Btree internal entry.
- */
-typedef struct _binternal {
- db_indx_t len; /* 00-01: Key/data item length. */
- u_int8_t type; /* 02: Page type AND DELETE FLAG. */
- u_int8_t unused; /* 03: Padding, unused. */
- db_pgno_t pgno; /* 04-07: Page number of referenced page. */
- db_recno_t nrecs; /* 08-11: Subtree record count. */
- u_int8_t data[1]; /* Variable length key item. */
-} BINTERNAL;
-
-/* Get a BINTERNAL item for a specific index. */
-#define GET_BINTERNAL(pg, indx) \
- ((BINTERNAL *)P_ENTRY(pg, indx))
-
-/*
- * Page space required to add a new BINTERNAL item to the page, with and
- * without the index value.
- */
-#define BINTERNAL_SIZE(len) \
- ALIGN((len) + SSZA(BINTERNAL, data), 4)
-#define BINTERNAL_PSIZE(len) \
- (BINTERNAL_SIZE(len) + sizeof(db_indx_t))
-
-/************************************************************************
- RECNO INTERNAL PAGE LAYOUT
- ************************************************************************/
-
-/*
- * The recno internal entry.
- *
- * XXX
- * Why not fold this into the db_indx_t structure, it's fixed length?
- */
-typedef struct _rinternal {
- db_pgno_t pgno; /* 00-03: Page number of referenced page. */
- db_recno_t nrecs; /* 04-07: Subtree record count. */
-} RINTERNAL;
-
-/* Get a RINTERNAL item for a specific index. */
-#define GET_RINTERNAL(pg, indx) \
- ((RINTERNAL *)P_ENTRY(pg, indx))
-
-/*
- * Page space required to add a new RINTERNAL item to the page, with and
- * without the index value.
- */
-#define RINTERNAL_SIZE \
- ALIGN(sizeof(RINTERNAL), 4)
-#define RINTERNAL_PSIZE \
- (RINTERNAL_SIZE + sizeof(db_indx_t))
-#endif /* _DB_PAGE_H_ */
diff --git a/db2/include/db_shash.h b/db2/include/db_shash.h
deleted file mode 100644
index 35ade39..0000000
--- a/db2/include/db_shash.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)db_shash.h 10.3 (Sleepycat) 4/10/98
- */
-
-/* Hash Headers */
-typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
-
-/*
- * HASHLOOKUP --
- *
- * Look up something in a shared memory hash table. The "elt" argument
- * should be a key, and cmp_func must know how to compare a key to whatever
- * structure it is that appears in the hash table. The comparison function
- * cmp_func is called as: cmp_func(lookup_elt, table_elt);
- * begin: address of the beginning of the hash table.
- * type: the structure type of the elements that are linked in each bucket.
- * field: the name of the field by which the "type" structures are linked.
- * elt: the item for which we are searching in the hash table.
- * result: the variable into which we'll store the element if we find it.
- * nelems: the number of buckets in the hash table.
- * hash_func: the hash function that operates on elements of the type of elt
- * cmp_func: compare elements of the type of elt with those in the table (of
- * type "type").
- *
- * If the element is not in the hash table, this macro exits with result
- * set to NULL.
- */
-#define HASHLOOKUP(begin, type, field, elt, r, n, hash, cmp) do { \
- DB_HASHTAB *__bucket; \
- u_int32_t __ndx; \
- \
- __ndx = hash(elt) % (n); \
- __bucket = &begin[__ndx]; \
- for (r = SH_TAILQ_FIRST(__bucket, type); \
- r != NULL; r = SH_TAILQ_NEXT(r, field, type)) \
- if (cmp(elt, r)) \
- break; \
-} while(0)
-
-/*
- * HASHINSERT --
- *
- * Insert a new entry into the hash table. This assumes that lookup has
- * failed; don't call it if you haven't already called HASHLOOKUP.
- * begin: the beginning address of the hash table.
- * type: the structure type of the elements that are linked in each bucket.
- * field: the name of the field by which the "type" structures are linked.
- * elt: the item to be inserted.
- * nelems: the number of buckets in the hash table.
- * hash_func: the hash function that operates on elements of the type of elt
- */
-#define HASHINSERT(begin, type, field, elt, n, hash) do { \
- u_int32_t __ndx; \
- DB_HASHTAB *__bucket; \
- \
- __ndx = hash(elt) % (n); \
- __bucket = &begin[__ndx]; \
- SH_TAILQ_INSERT_HEAD(__bucket, elt, field, type); \
-} while(0)
-
-/*
- * HASHREMOVE --
- * Remove the entry with a key == elt.
- * begin: address of the beginning of the hash table.
- * type: the structure type of the elements that are linked in each bucket.
- * field: the name of the field by which the "type" structures are linked.
- * elt: the item to be deleted.
- * nelems: the number of buckets in the hash table.
- * hash_func: the hash function that operates on elements of the type of elt
- * cmp_func: compare elements of the type of elt with those in the table (of
- * type "type").
- */
-#define HASHREMOVE(begin, type, field, elt, n, hash, cmp) { \
- u_int32_t __ndx; \
- DB_HASHTAB *__bucket; \
- SH_TAILQ_ENTRY *__entp; \
- \
- __ndx = hash(elt) % (n); \
- __bucket = &begin[__ndx]; \
- HASHLOOKUP(begin, type, field, elt, __entp, n, hash, cmp); \
- SH_TAILQ_REMOVE(__bucket, __entp, field, type); \
-}
-
-/*
- * HASHREMOVE_EL --
- * Given the object "obj" in the table, remove it.
- * begin: address of the beginning of the hash table.
- * type: the structure type of the elements that are linked in each bucket.
- * field: the name of the field by which the "type" structures are linked.
- * obj: the object in the table that we with to delete.
- * nelems: the number of buckets in the hash table.
- * hash_func: the hash function that operates on elements of the type of elt
- */
-#define HASHREMOVE_EL(begin, type, field, obj, n, hash) { \
- u_int32_t __ndx; \
- DB_HASHTAB *__bucket; \
- \
- __ndx = hash(obj) % (n); \
- __bucket = &begin[__ndx]; \
- SH_TAILQ_REMOVE(__bucket, obj, field, type); \
-}
diff --git a/db2/include/db_swap.h b/db2/include/db_swap.h
deleted file mode 100644
index 9f94ed7..0000000
--- a/db2/include/db_swap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)db_swap.h 10.5 (Sleepycat) 4/10/98
- */
-
-#ifndef _DB_SWAP_H_
-#define _DB_SWAP_H_
-
-/*
- * Little endian <==> big endian 32-bit swap macros.
- * M_32_SWAP swap a memory location
- * P_32_COPY copy potentially unaligned 4 byte quantities
- * P_32_SWAP swap a referenced memory location
- */
-#define M_32_SWAP(a) { \
- u_int32_t _tmp; \
- _tmp = a; \
- ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[3]; \
- ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[2]; \
- ((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[1]; \
- ((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[0]; \
-}
-#define P_32_COPY(a, b) { \
- ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \
- ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \
- ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \
- ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \
-}
-#define P_32_SWAP(a) { \
- u_int32_t _tmp; \
- P_32_COPY(a, &_tmp); \
- ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[3]; \
- ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[2]; \
- ((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[1]; \
- ((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[0]; \
-}
-
-/*
- * Little endian <==> big endian 16-bit swap macros.
- * M_16_SWAP swap a memory location
- * P_16_COPY copy potentially unaligned 2 byte quantities
- * P_16_SWAP swap a referenced memory location
- */
-#define M_16_SWAP(a) { \
- u_int16_t _tmp; \
- _tmp = (u_int16_t)a; \
- ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[1]; \
- ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[0]; \
-}
-#define P_16_COPY(a, b) { \
- ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \
- ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \
-}
-#define P_16_SWAP(a) { \
- u_int16_t _tmp; \
- P_16_COPY(a, &_tmp); \
- ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[1]; \
- ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[0]; \
-}
-
-#define SWAP32(p) { \
- P_32_SWAP(p); \
- (p) += sizeof(u_int32_t); \
-}
-#define SWAP16(p) { \
- P_16_SWAP(p); \
- (p) += sizeof(u_int16_t); \
-}
-#endif /* !_DB_SWAP_H_ */
diff --git a/db2/include/hash.h b/db2/include/hash.h
deleted file mode 100644
index 5d85a2a..0000000
--- a/db2/include/hash.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * Margo Seltzer. All rights reserved.
- */
-/*
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)hash.h 10.14 (Sleepycat) 10/4/98
- */
-
-/* Cursor structure definitions. */
-typedef struct cursor_t {
- DBC *dbc;
-
- /* Per-thread information */
- DB_LOCK hlock; /* Metadata page lock. */
- HASHHDR *hdr; /* Pointer to meta-data page. */
- PAGE *split_buf; /* Temporary buffer for splits. */
- struct __db_h_stat stats; /* Hash statistics. */
-
- /* Hash cursor information */
- db_pgno_t bucket; /* Bucket we are traversing. */
- db_pgno_t lbucket; /* Bucket for which we are locked. */
- DB_LOCK lock; /* Lock held on the current bucket. */
- PAGE *pagep; /* The current page. */
- db_pgno_t pgno; /* Current page number. */
- db_indx_t bndx; /* Index within the current page. */
- PAGE *dpagep; /* Duplicate page pointer. */
- db_pgno_t dpgno; /* Duplicate page number. */
- db_indx_t dndx; /* Index within a duplicate set. */
- db_indx_t dup_off; /* Offset within a duplicate set. */
- db_indx_t dup_len; /* Length of current duplicate. */
- db_indx_t dup_tlen; /* Total length of duplicate entry. */
- u_int32_t seek_size; /* Number of bytes we need for add. */
- db_pgno_t seek_found_page;/* Page on which we can insert. */
-
-#define H_DELETED 0x0001 /* Cursor item is deleted. */
-#define H_DUPONLY 0x0002 /* Dups only; do not change key. */
-#define H_EXPAND 0x0004 /* Table expanded. */
-#define H_ISDUP 0x0008 /* Cursor is within duplicate set. */
-#define H_NOMORE 0x0010 /* No more entries in bucket. */
-#define H_OK 0x0020 /* Request succeeded. */
-#define H_DIRTY 0x0040 /* Meta-data page needs to be written */
-#define H_ORIGINAL 0x0080 /* Bucket lock existed on entry. */
- u_int32_t flags;
-} HASH_CURSOR;
-
-#define IS_VALID(C) ((C)->bucket != BUCKET_INVALID)
-
-#define SAVE_CURSOR(ORIG, COPY) { \
- F_SET((ORIG), H_ORIGINAL); \
- *(COPY) = *(ORIG); \
-}
-
-#define RESTORE_CURSOR(D, ORIG, COPY, RET) { \
- if ((RET) == 0) { \
- if ((ORIG)->dbc->txn == NULL && \
- (COPY)->lock != 0 && (ORIG)->lock != (COPY)->lock) \
- (void)lock_put((D)->dbenv->lk_info, (COPY)->lock); \
- } else { \
- if ((ORIG)->dbc->txn == NULL && \
- (ORIG)->lock != 0 && (ORIG)->lock != (COPY)->lock) \
- (void)lock_put((D)->dbenv->lk_info, (ORIG)->lock); \
- *ORIG = *COPY; \
- } \
-}
-
-/*
- * More interface macros used to get/release the meta data page.
- */
-#define GET_META(D, I, R) { \
- if (F_ISSET(D, DB_AM_LOCKING) && \
- !F_ISSET((I)->dbc, DBC_RECOVER)) { \
- (I)->dbc->lock.pgno = BUCKET_INVALID; \
- (R) = lock_get((D)->dbenv->lk_info, (I)->dbc->locker, \
- 0, &(I)->dbc->lock_dbt, DB_LOCK_READ, &(I)->hlock); \
- (R) = (R) < 0 ? EAGAIN : (R); \
- } \
- if ((R) == 0 && \
- ((R) = __ham_get_page(D, 0, (PAGE **)&((I)->hdr))) != 0 && \
- (I)->hlock != LOCK_INVALID) { \
- (void)lock_put((D)->dbenv->lk_info, (I)->hlock); \
- (I)->hlock = LOCK_INVALID; \
- } \
-}
-
-#define RELEASE_META(D, I) { \
- if ((I)->hdr) \
- (void)__ham_put_page(D, (PAGE *)(I)->hdr, \
- F_ISSET(I, H_DIRTY) ? 1 : 0); \
- (I)->hdr = NULL; \
- if (!F_ISSET((I)->dbc, DBC_RECOVER) && \
- (I)->dbc->txn == NULL && (I)->hlock) \
- (void)lock_put((D)->dbenv->lk_info, (I)->hlock); \
- (I)->hlock = LOCK_INVALID; \
- F_CLR(I, H_DIRTY); \
-}
-
-#define DIRTY_META(D, I, R) { \
- if (F_ISSET(D, DB_AM_LOCKING) && \
- !F_ISSET((I)->dbc, DBC_RECOVER)) { \
- DB_LOCK _tmp; \
- (I)->dbc->lock.pgno = BUCKET_INVALID; \
- if (((R) = lock_get((D)->dbenv->lk_info, \
- (I)->dbc->locker, 0, &(I)->dbc->lock_dbt, \
- DB_LOCK_WRITE, &_tmp)) == 0) \
- (R) = lock_put((D)->dbenv->lk_info, (I)->hlock);\
- else if ((R) < 0) \
- (R) = EAGAIN; \
- (I)->hlock = _tmp; \
- } \
- F_SET((I), H_DIRTY); \
-}
-
-/* Test string. */
-#define CHARKEY "%$sniglet^&"
-
-/* Overflow management */
-/*
- * Overflow page numbers are allocated per split point. At each doubling of
- * the table, we can allocate extra pages. We keep track of how many pages
- * we've allocated at each point to calculate bucket to page number mapping.
- */
-#define BUCKET_TO_PAGE(I, B) \
- ((B) + 1 + ((B) ? (I)->hdr->spares[__db_log2((B)+1)-1] : 0))
-
-#define PGNO_OF(I, S, O) (BUCKET_TO_PAGE((I), (1 << (S)) - 1) + (O))
-
-/* Constraints about number of pages and how much data goes on a page. */
-
-#define MAX_PAGES(H) UINT32_T_MAX
-#define MINFILL 4
-#define ISBIG(I, N) (((N) > ((I)->hdr->pagesize / MINFILL)) ? 1 : 0)
-
-/* Shorthands for accessing structure */
-#define NDX_INVALID 0xFFFF
-#define BUCKET_INVALID 0xFFFFFFFF
-
-/* On page duplicates are stored as a string of size-data-size triples. */
-#define DUP_SIZE(len) ((len) + 2 * sizeof(db_indx_t))
-
-/* Log messages types (these are subtypes within a record type) */
-#define PAIR_KEYMASK 0x1
-#define PAIR_DATAMASK 0x2
-#define PAIR_ISKEYBIG(N) (N & PAIR_KEYMASK)
-#define PAIR_ISDATABIG(N) (N & PAIR_DATAMASK)
-#define OPCODE_OF(N) (N & ~(PAIR_KEYMASK | PAIR_DATAMASK))
-
-#define PUTPAIR 0x20
-#define DELPAIR 0x30
-#define PUTOVFL 0x40
-#define DELOVFL 0x50
-#define ALLOCPGNO 0x60
-#define DELPGNO 0x70
-#define SPLITOLD 0x80
-#define SPLITNEW 0x90
-
-#include "hash_auto.h"
-#include "hash_ext.h"
-#include "db_am.h"
-#include "common_ext.h"
diff --git a/db2/include/hash_auto.h b/db2/include/hash_auto.h
deleted file mode 100644
index 2b8aea8..0000000
--- a/db2/include/hash_auto.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#ifndef ham_AUTO_H
-#define ham_AUTO_H
-
-#define DB_ham_insdel (DB_ham_BEGIN + 1)
-
-typedef struct _ham_insdel_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t ndx;
- DB_LSN pagelsn;
- DBT key;
- DBT data;
-} __ham_insdel_args;
-
-
-#define DB_ham_newpage (DB_ham_BEGIN + 2)
-
-typedef struct _ham_newpage_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t prev_pgno;
- DB_LSN prevlsn;
- db_pgno_t new_pgno;
- DB_LSN pagelsn;
- db_pgno_t next_pgno;
- DB_LSN nextlsn;
-} __ham_newpage_args;
-
-
-#define DB_ham_splitmeta (DB_ham_BEGIN + 3)
-
-typedef struct _ham_splitmeta_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- u_int32_t bucket;
- u_int32_t ovflpoint;
- u_int32_t spares;
- DB_LSN metalsn;
-} __ham_splitmeta_args;
-
-
-#define DB_ham_splitdata (DB_ham_BEGIN + 4)
-
-typedef struct _ham_splitdata_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- u_int32_t opcode;
- db_pgno_t pgno;
- DBT pageimage;
- DB_LSN pagelsn;
-} __ham_splitdata_args;
-
-
-#define DB_ham_replace (DB_ham_BEGIN + 5)
-
-typedef struct _ham_replace_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- u_int32_t ndx;
- DB_LSN pagelsn;
- int32_t off;
- DBT olditem;
- DBT newitem;
- u_int32_t makedup;
-} __ham_replace_args;
-
-
-#define DB_ham_newpgno (DB_ham_BEGIN + 6)
-
-typedef struct _ham_newpgno_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t fileid;
- db_pgno_t pgno;
- db_pgno_t free_pgno;
- u_int32_t old_type;
- db_pgno_t old_pgno;
- u_int32_t new_type;
- DB_LSN pagelsn;
- DB_LSN metalsn;
-} __ham_newpgno_args;
-
-
-#define DB_ham_ovfl (DB_ham_BEGIN + 7)
-
-typedef struct _ham_ovfl_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t start_pgno;
- u_int32_t npages;
- db_pgno_t free_pgno;
- u_int32_t ovflpoint;
- DB_LSN metalsn;
-} __ham_ovfl_args;
-
-
-#define DB_ham_copypage (DB_ham_BEGIN + 8)
-
-typedef struct _ham_copypage_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t fileid;
- db_pgno_t pgno;
- DB_LSN pagelsn;
- db_pgno_t next_pgno;
- DB_LSN nextlsn;
- db_pgno_t nnext_pgno;
- DB_LSN nnextlsn;
- DBT page;
-} __ham_copypage_args;
-
-#endif
diff --git a/db2/include/hash_ext.h b/db2/include/hash_ext.h
deleted file mode 100644
index fe17dc7..0000000
--- a/db2/include/hash_ext.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _hash_ext_h_
-#define _hash_ext_h_
-int __ham_open __P((DB *, DB_INFO *));
-int __ham_close __P((DB *));
-int __ham_c_init __P((DBC *));
-u_int32_t __ham_call_hash __P((HASH_CURSOR *, u_int8_t *, int32_t));
-int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *));
-void __ham_c_update
- __P((HASH_CURSOR *, db_pgno_t, u_int32_t, int, int));
-int __ham_insdel_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, u_int32_t,
- DB_LSN *, const DBT *, const DBT *));
-int __ham_insdel_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_insdel_read __P((void *, __ham_insdel_args **));
-int __ham_newpage_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, DB_LSN *,
- db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *));
-int __ham_newpage_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_newpage_read __P((void *, __ham_newpage_args **));
-int __ham_splitmeta_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, u_int32_t, u_int32_t,
- DB_LSN *));
-int __ham_splitmeta_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_splitmeta_read __P((void *, __ham_splitmeta_args **));
-int __ham_splitdata_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, const DBT *,
- DB_LSN *));
-int __ham_splitdata_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_splitdata_read __P((void *, __ham_splitdata_args **));
-int __ham_replace_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
- int32_t, const DBT *, const DBT *, u_int32_t));
-int __ham_replace_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_replace_read __P((void *, __ham_replace_args **));
-int __ham_newpgno_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t, db_pgno_t, db_pgno_t,
- u_int32_t, db_pgno_t, u_int32_t, DB_LSN *,
- DB_LSN *));
-int __ham_newpgno_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_newpgno_read __P((void *, __ham_newpgno_args **));
-int __ham_ovfl_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, u_int32_t, db_pgno_t,
- u_int32_t, DB_LSN *));
-int __ham_ovfl_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_ovfl_read __P((void *, __ham_ovfl_args **));
-int __ham_copypage_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t,
- DB_LSN *, db_pgno_t, DB_LSN *, const DBT *));
-int __ham_copypage_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_copypage_read __P((void *, __ham_copypage_args **));
-int __ham_init_print __P((DB_ENV *));
-int __ham_init_recover __P((DB_ENV *));
-int __ham_pgin __P((db_pgno_t, void *, DBT *));
-int __ham_pgout __P((db_pgno_t, void *, DBT *));
-int __ham_mswap __P((void *));
-int __ham_add_dup __P((DBC *, DBT *, u_int32_t));
-void __ham_move_offpage __P((DBC *, PAGE *, u_int32_t, db_pgno_t));
-void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *));
-u_int32_t __ham_func2 __P((const void *, u_int32_t));
-u_int32_t __ham_func3 __P((const void *, u_int32_t));
-u_int32_t __ham_func4 __P((const void *, u_int32_t));
-u_int32_t __ham_func5 __P((const void *, u_int32_t));
-int __ham_item __P((DBC *, db_lockmode_t));
-int __ham_item_reset __P((DBC *));
-void __ham_item_init __P((HASH_CURSOR *));
-int __ham_item_done __P((DBC *, int));
-int __ham_item_last __P((DBC *, db_lockmode_t));
-int __ham_item_first __P((DBC *, db_lockmode_t));
-int __ham_item_prev __P((DBC *, db_lockmode_t));
-int __ham_item_next __P((DBC *, db_lockmode_t));
-void __ham_putitem __P((PAGE *p, const DBT *, int));
-void __ham_reputpair
- __P((PAGE *p, u_int32_t, u_int32_t, const DBT *, const DBT *));
-int __ham_del_pair __P((DBC *, int));
-int __ham_replpair __P((DBC *, DBT *, u_int32_t));
-void __ham_onpage_replace __P((PAGE *, size_t, u_int32_t, int32_t,
- int32_t, DBT *));
-int __ham_split_page __P((DBC *, u_int32_t, u_int32_t));
-int __ham_add_el __P((DBC *, const DBT *, const DBT *, int));
-void __ham_copy_item __P((size_t, PAGE *, u_int32_t, PAGE *));
-int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **));
-int __ham_new_page __P((DB *, u_int32_t, u_int32_t, PAGE **));
-int __ham_del_page __P((DBC *, PAGE *));
-int __ham_put_page __P((DB *, PAGE *, int32_t));
-int __ham_dirty_page __P((DB *, PAGE *));
-int __ham_get_page __P((DB *, db_pgno_t, PAGE **));
-int __ham_overflow_page
- __P((DBC *, u_int32_t, PAGE **));
-#ifdef DEBUG
-db_pgno_t __bucket_to_page __P((HASH_CURSOR *, db_pgno_t));
-#endif
-void __ham_init_ovflpages __P((DBC *));
-int __ham_get_cpage __P((DBC *, db_lockmode_t));
-int __ham_next_cpage __P((DBC *, db_pgno_t, int, u_int32_t));
-void __ham_dpair __P((DB *, PAGE *, u_int32_t));
-int __ham_insdel_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_newpage_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_replace_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_newpgno_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_splitmeta_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_splitdata_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_ovfl_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_copypage_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __ham_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-#endif /* _hash_ext_h_ */
diff --git a/db2/include/lock.h b/db2/include/lock.h
deleted file mode 100644
index 13364ca..0000000
--- a/db2/include/lock.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)lock.h 10.17 (Sleepycat) 1/3/99
- */
-
-typedef struct __db_lockobj DB_LOCKOBJ;
-
-#define DB_DEFAULT_LOCK_FILE "__db_lock.share"
-
-#ifndef DB_LOCK_DEFAULT_N
-#define DB_LOCK_DEFAULT_N 5000 /* Default # of locks in region. */
-#endif
-
-/*
- * The locker id space is divided between the transaction manager and the lock
- * manager. Lockid's start at 0 and go to DB_LOCK_MAXID. Txn Id's start at
- * DB_LOCK_MAXID + 1 and go up to TXN_INVALID.
- */
-#define DB_LOCK_MAXID 0x7fffffff
-
-/* Check for region catastrophic shutdown. */
-#define LOCK_PANIC_CHECK(lt) { \
- if ((lt)->region->hdr.panic) \
- return (DB_RUNRECOVERY); \
-}
-
-/*
- * The lock region consists of:
- * The DB_LOCKREGION structure (sizeof(DB_LOCKREGION)).
- * The conflict matrix of nmodes * nmodes bytes (nmodes * nmodes).
- * The hash table for object lookup (hashsize * sizeof(DB_OBJ *)).
- * The locks themselves (maxlocks * sizeof(struct __db_lock).
- * The objects being locked (maxlocks * sizeof(DB_OBJ)).
- * String space to represent the DBTs that are the objects being locked.
- */
-struct __db_lockregion {
- RLAYOUT hdr; /* Shared region header. */
- u_int32_t magic; /* lock magic number */
- u_int32_t version; /* version number */
- u_int32_t id; /* unique id generator */
- u_int32_t need_dd; /* flag for deadlock detector */
- u_int32_t detect; /* run dd on every conflict */
- SH_TAILQ_HEAD(lock_header) free_locks; /* free lock header */
- SH_TAILQ_HEAD(obj_header) free_objs; /* free obj header */
- u_int32_t maxlocks; /* maximum number of locks in table */
- u_int32_t table_size; /* size of hash table */
- u_int32_t nmodes; /* number of lock modes */
- u_int32_t numobjs; /* number of objects */
- u_int32_t nlockers; /* number of lockers */
- size_t increment; /* how much to grow region */
- size_t hash_off; /* offset of hash table */
- size_t mem_off; /* offset of memory region */
- size_t mem_bytes; /* number of bytes in memory region */
- u_int32_t nconflicts; /* number of lock conflicts */
- u_int32_t nrequests; /* number of lock gets */
- u_int32_t nreleases; /* number of lock puts */
- u_int32_t ndeadlocks; /* number of deadlocks */
-};
-
-/* Macros to lock/unlock the region. */
-#define LOCK_LOCKREGION(lt) \
- (void)__db_mutex_lock(&(lt)->region->hdr.lock, (lt)->reginfo.fd)
-#define UNLOCK_LOCKREGION(lt) \
- (void)__db_mutex_unlock(&(lt)->region->hdr.lock, (lt)->reginfo.fd)
-
-/*
- * Since we will be keeping DBTs in shared memory, we need the equivalent
- * of a DBT that will work in shared memory.
- */
-typedef struct __sh_dbt {
- u_int32_t size;
- ssize_t off;
-} SH_DBT;
-
-#define SH_DBT_PTR(p) ((void *)(((u_int8_t *)(p)) + (p)->off))
-
-struct __db_lockobj {
- SH_DBT lockobj; /* Identifies object locked. */
- SH_TAILQ_ENTRY links; /* Links for free list. */
- union {
- SH_TAILQ_HEAD(_wait) _waiters; /* List of waiting locks. */
- u_int32_t _dd_id; /* Deadlock detector id. */
- } wlinks;
- union {
- SH_LIST_HEAD(_held) _heldby; /* Locks held by this locker. */
- SH_TAILQ_HEAD(_hold) _holders; /* List of held locks. */
- } dlinks;
-#define DB_LOCK_OBJTYPE 1
-#define DB_LOCK_LOCKER 2
- /* Allocate room in the object to
- * hold typical DB lock structures
- * so that we do not have to
- * allocate them from shalloc. */
- u_int8_t objdata[sizeof(struct __db_ilock)];
- u_int8_t type; /* Real object or locker id. */
-};
-
-#define dd_id wlinks._dd_id
-#define waiters wlinks._waiters
-#define holders dlinks._holders
-#define heldby dlinks._heldby
-
-/*
- * The lock table is the per-process cookie returned from a lock_open call.
- */
-struct __db_locktab {
- DB_ENV *dbenv; /* Environment. */
- REGINFO reginfo; /* Region information. */
- DB_LOCKREGION *region; /* Address of shared memory region. */
- DB_HASHTAB *hashtab; /* Beginning of hash table. */
- void *mem; /* Beginning of string space. */
- u_int8_t *conflicts; /* Pointer to conflict matrix. */
-};
-
-/* Test for conflicts. */
-#define CONFLICTS(T, HELD, WANTED) \
- T->conflicts[HELD * T->region->nmodes + WANTED]
-
-/*
- * Resources in the lock region. Used to indicate which resource
- * is running low when we need to grow the region.
- */
-typedef enum {
- DB_LOCK_MEM, DB_LOCK_OBJ, DB_LOCK_LOCK
-} db_resource_t;
-
-struct __db_lock {
- /*
- * Wait on mutex to wait on lock. You reference your own mutex with
- * ID 0 and others reference your mutex with ID 1.
- */
- db_mutex_t mutex;
-
- u_int32_t holder; /* Who holds this lock. */
- SH_TAILQ_ENTRY links; /* Free or holder/waiter list. */
- SH_LIST_ENTRY locker_links; /* List of locks held by a locker. */
- u_int32_t refcount; /* Reference count the lock. */
- db_lockmode_t mode; /* What sort of lock. */
- ssize_t obj; /* Relative offset of object struct. */
- size_t txnoff; /* Offset of holding transaction. */
- db_status_t status; /* Status of this lock. */
-};
-
-/*
- * This is a serious layering violation. To support nested transactions, we
- * need to be able to tell that a lock is held by a transaction (as opposed to
- * some other locker) and to be able to traverse the parent/descendent chain.
- * In order to do this, each lock held by a transaction maintains a reference
- * to the shared memory transaction structure so it can be accessed during lock
- * promotion. As the structure is in shared memory, we cannot store a pointer
- * to it, so we use the offset within the region. As nothing lives at region
- * offset 0, we use that to indicate that there is no transaction associated
- * with the current lock.
- */
-#define TXN_IS_HOLDING(L) ((L)->txnoff != 0 /* INVALID_REG_OFFSET */)
-
-/*
- * We cannot return pointers to the user (else we cannot easily grow regions),
- * so we return offsets in the region. These must be converted to and from
- * regular pointers. Always use the macros below.
- */
-#define OFFSET_TO_LOCK(lt, off) \
- ((struct __db_lock *)((u_int8_t *)((lt)->region) + (off)))
-#define LOCK_TO_OFFSET(lt, lock) \
- ((size_t)((u_int8_t *)(lock) - (u_int8_t *)lt->region))
-#define OFFSET_TO_OBJ(lt, off) \
- ((DB_LOCKOBJ *)((u_int8_t *)((lt)->region) + (off)))
-#define OBJ_TO_OFFSET(lt, obj) \
- ((size_t)((u_int8_t *)(obj) - (u_int8_t *)lt->region))
-
-/*
- * The lock header contains the region structure and the conflict matrix.
- * Aligned to a large boundary because we don't know what the underlying
- * type of the hash table elements are.
- */
-#define LOCK_HASH_ALIGN 8
-#define LOCK_HEADER_SIZE(M) \
- ((size_t)(sizeof(DB_LOCKREGION) + ALIGN((M * M), LOCK_HASH_ALIGN)))
-
-/*
- * For the full region, we need to add the locks, the objects, the hash table
- * and the string space (which is 16 bytes per lock).
- */
-#define STRING_SIZE(N) (16 * N)
-
-#define LOCK_REGION_SIZE(M, N, H) \
- (ALIGN(LOCK_HEADER_SIZE(M) + \
- (H) * sizeof(DB_HASHTAB), MUTEX_ALIGNMENT) + \
- (N) * ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT) + \
- ALIGN((N) * sizeof(DB_LOCKOBJ), sizeof(size_t)) + \
- ALIGN(STRING_SIZE(N), sizeof(size_t)))
-
-#include "lock_ext.h"
diff --git a/db2/include/lock_ext.h b/db2/include/lock_ext.h
deleted file mode 100644
index ce79947..0000000
--- a/db2/include/lock_ext.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _lock_ext_h_
-#define _lock_ext_h_
-int __lock_is_locked
- __P((DB_LOCKTAB *, u_int32_t, DBT *, db_lockmode_t));
-void __lock_printlock __P((DB_LOCKTAB *, struct __db_lock *, int));
-int __lock_getobj __P((DB_LOCKTAB *,
- u_int32_t, const DBT *, u_int32_t type, DB_LOCKOBJ **));
-int __lock_downgrade __P((DB_LOCKTAB *,
- DB_LOCK, db_lockmode_t, u_int32_t));
-void __lock_panic __P((DB_ENV *));
-int __lock_validate_region __P((DB_LOCKTAB *));
-int __lock_grow_region __P((DB_LOCKTAB *, int, size_t));
-void __lock_dump_region __P((DB_LOCKTAB *, char *, FILE *));
-int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
-int __lock_locker_cmp __P((u_int32_t, DB_LOCKOBJ *));
-u_int32_t __lock_ohash __P((const DBT *));
-u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
-u_int32_t __lock_locker_hash __P((u_int32_t));
-#endif /* _lock_ext_h_ */
diff --git a/db2/include/log.h b/db2/include/log.h
deleted file mode 100644
index 5030908..0000000
--- a/db2/include/log.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)log.h 10.30 (Sleepycat) 10/11/98
- */
-
-#ifndef _LOG_H_
-#define _LOG_H_
-
-struct __fname; typedef struct __fname FNAME;
-struct __hdr; typedef struct __hdr HDR;
-struct __log; typedef struct __log LOG;
-struct __log_persist; typedef struct __log_persist LOGP;
-
-#ifndef MAXLFNAME
-#define LFPREFIX "log." /* Log file name prefix. */
-#define LFNAME "log.%010d" /* Log file name template. */
-#define LFNAME_V1 "log.%05d" /* Log file name template, rev 1. */
-#define MAXLFNAME 2000000000 /* Maximum log file name. */
-#endif
- /* Default log name. */
-#define DB_DEFAULT_LOG_FILE "__db_log.share"
-
-#define DEFAULT_MAX (10 * MEGABYTE) /* 10 Mb. */
-
-/* Macros to lock/unlock the region and threads. */
-#define LOCK_LOGTHREAD(dblp) \
- if (F_ISSET(dblp, DB_AM_THREAD)) \
- (void)__db_mutex_lock((dblp)->mutexp, -1)
-#define UNLOCK_LOGTHREAD(dblp) \
- if (F_ISSET(dblp, DB_AM_THREAD)) \
- (void)__db_mutex_unlock((dblp)->mutexp, -1);
-#define LOCK_LOGREGION(dblp) \
- (void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock, \
- (dblp)->reginfo.fd)
-#define UNLOCK_LOGREGION(dblp) \
- (void)__db_mutex_unlock(&((RLAYOUT *)(dblp)->lp)->lock, \
- (dblp)->reginfo.fd)
-
-/* Check for region catastrophic shutdown. */
-#define LOG_PANIC_CHECK(dblp) { \
- if ((dblp)->lp->rlayout.panic) \
- return (DB_RUNRECOVERY); \
-}
-
-/*
- * The per-process table that maps log file-id's to DB structures.
- */
-typedef struct __db_entry {
- DB *dbp; /* Associated DB structure. */
- u_int32_t refcount; /* Reference counted. */
- int deleted; /* File was not found during open. */
-} DB_ENTRY;
-
-/*
- * DB_LOG
- * Per-process log structure.
- */
-struct __db_log {
-/* These fields need to be protected for multi-threaded support. */
- db_mutex_t *mutexp; /* Mutex for thread protection. */
-
- DB_ENTRY *dbentry; /* Recovery file-id mapping. */
-#define DB_GROW_SIZE 64
- u_int32_t dbentry_cnt; /* Entries. Grows by DB_GROW_SIZE. */
-
-/*
- * These fields are always accessed while the region lock is held, so they do
- * not have to be protected by the thread lock as well OR, they are only used
- * when threads are not being used, i.e. most cursor operations are disallowed
- * on threaded logs.
- */
- u_int32_t lfname; /* Log file "name". */
- int lfd; /* Log file descriptor. */
-
- DB_LSN c_lsn; /* Cursor: current LSN. */
- DBT c_dbt; /* Cursor: return DBT structure. */
- int c_fd; /* Cursor: file descriptor. */
- u_int32_t c_off; /* Cursor: previous record offset. */
- u_int32_t c_len; /* Cursor: current record length. */
-
-/* These fields are not protected. */
- LOG *lp; /* Address of the shared LOG. */
-
- DB_ENV *dbenv; /* Reference to error information. */
- REGINFO reginfo; /* Region information. */
-
- void *addr; /* Address of shalloc() region. */
-
- char *dir; /* Directory argument. */
-
-/*
- * These fields are used by XA; since XA forbids threaded execution, these
- * do not have to be protected.
- */
- void *xa_info; /* Committed transaction list that
- * has to be carried between calls
- * to xa_recover. */
- DB_LSN xa_lsn; /* Position of an XA recovery scan. */
- DB_LSN xa_first; /* LSN to which we need to roll back
- for this XA recovery scan. */
-
- /*
- * !!!
- * Currently used to hold:
- * DB_AM_THREAD (a DB flag)
- * DBC_RECOVER (a DBC flag)
- * If they are ever the same bits, we're in serious trouble.
- */
-#if DB_AM_THREAD == DBC_RECOVER
- DB_AM_THREAD, DBC_RECOVER, FLAG MISMATCH
-#endif
- u_int32_t flags;
-};
-
-/*
- * HDR --
- * Log record header.
- */
-struct __hdr {
- u_int32_t prev; /* Previous offset. */
- u_int32_t cksum; /* Current checksum. */
- u_int32_t len; /* Current length. */
-};
-
-struct __log_persist {
- u_int32_t magic; /* DB_LOGMAGIC */
- u_int32_t version; /* DB_LOGVERSION */
-
- u_int32_t lg_max; /* Maximum file size. */
- int mode; /* Log file mode. */
-};
-
-/*
- * LOG --
- * Shared log region. One of these is allocated in shared memory,
- * and describes the log.
- */
-struct __log {
- RLAYOUT rlayout; /* General region information. */
-
- LOGP persist; /* Persistent information. */
-
- SH_TAILQ_HEAD(__fq) fq; /* List of file names. */
-
- /*
- * The lsn LSN is the file offset that we're about to write and which
- * we will return to the user.
- */
- DB_LSN lsn; /* LSN at current file offset. */
-
- /*
- * The s_lsn LSN is the last LSN that we know is on disk, not just
- * written, but synced.
- */
- DB_LSN s_lsn; /* LSN of the last sync. */
-
- u_int32_t len; /* Length of the last record. */
-
- u_int32_t w_off; /* Current write offset in the file. */
-
- DB_LSN chkpt_lsn; /* LSN of the last checkpoint. */
- time_t chkpt; /* Time of the last checkpoint. */
-
- DB_LOG_STAT stat; /* Log statistics. */
-
- /*
- * The f_lsn LSN is the LSN (returned to the user) that "owns" the
- * first byte of the buffer. If the record associated with the LSN
- * spans buffers, it may not reflect the physical file location of
- * the first byte of the buffer.
- */
- DB_LSN f_lsn; /* LSN of first byte in the buffer. */
- size_t b_off; /* Current offset in the buffer. */
- u_int8_t buf[4 * 1024]; /* Log buffer. */
-};
-
-/*
- * FNAME --
- * File name and id.
- */
-struct __fname {
- SH_TAILQ_ENTRY q; /* File name queue. */
-
- u_int16_t ref; /* Reference count. */
-
- u_int32_t id; /* Logging file id. */
- DBTYPE s_type; /* Saved DB type. */
-
- size_t name_off; /* Name offset. */
- u_int8_t ufid[DB_FILE_ID_LEN]; /* Unique file id. */
-};
-
-/* File open/close register log record opcodes. */
-#define LOG_CHECKPOINT 1 /* Checkpoint: file name/id dump. */
-#define LOG_CLOSE 2 /* File close. */
-#define LOG_OPEN 3 /* File open. */
-
-#include "log_auto.h"
-#include "log_ext.h"
-#endif /* _LOG_H_ */
diff --git a/db2/include/log_auto.h b/db2/include/log_auto.h
deleted file mode 100644
index 5717e14..0000000
--- a/db2/include/log_auto.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#ifndef log_AUTO_H
-#define log_AUTO_H
-
-#define DB_log_register (DB_log_BEGIN + 1)
-
-typedef struct _log_register_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- DBT name;
- DBT uid;
- u_int32_t id;
- DBTYPE ftype;
-} __log_register_args;
-
-#endif
diff --git a/db2/include/log_ext.h b/db2/include/log_ext.h
deleted file mode 100644
index 842a3f4..0000000
--- a/db2/include/log_ext.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _log_ext_h_
-#define _log_ext_h_
-void __log_panic __P((DB_ENV *));
-int __log_find __P((DB_LOG *, int, int *));
-int __log_valid __P((DB_LOG *, u_int32_t, int));
-int __log_register_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, const DBT *, const DBT *, u_int32_t,
- DBTYPE));
-int __log_register_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __log_register_read __P((void *, __log_register_args **));
-int __log_init_print __P((DB_ENV *));
-int __log_init_recover __P((DB_ENV *));
-int __log_findckp __P((DB_LOG *, DB_LSN *));
-int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
-int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, u_int32_t));
-int __log_name __P((DB_LOG *, u_int32_t, char **, int *, u_int32_t));
-int __log_register_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
-int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
-void __log_close_files __P((DB_LOG *));
-void __log_rem_logid __P((DB_LOG *, u_int32_t));
-#endif /* _log_ext_h_ */
diff --git a/db2/include/mp.h b/db2/include/mp.h
deleted file mode 100644
index 904bccf..0000000
--- a/db2/include/mp.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)mp.h 10.37 (Sleepycat) 1/1/99
- */
-
-struct __bh; typedef struct __bh BH;
-struct __db_mpreg; typedef struct __db_mpreg DB_MPREG;
-struct __mpool; typedef struct __mpool MPOOL;
-struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
-
- /* Default mpool name. */
-#define DB_DEFAULT_MPOOL_FILE "__db_mpool.share"
-
-/*
- * We default to 256K (32 8K pages) if the user doesn't specify, and
- * require a minimum of 20K.
- */
-#ifndef DB_CACHESIZE_DEF
-#define DB_CACHESIZE_DEF (256 * 1024)
-#endif
-#define DB_CACHESIZE_MIN ( 20 * 1024)
-
-#define INVALID 0 /* Invalid shared memory offset. */
-
-/*
- * There are three ways we do locking in the mpool code:
- *
- * Locking a handle mutex to provide concurrency for DB_THREAD operations.
- * Locking the region mutex to provide mutual exclusion while reading and
- * writing structures in the shared region.
- * Locking buffer header mutexes during I/O.
- *
- * The first will not be further described here. We use the shared mpool
- * region lock to provide mutual exclusion while reading/modifying all of
- * the data structures, including the buffer headers. We use a per-buffer
- * header lock to wait on buffer I/O. The order of locking is as follows:
- *
- * Searching for a buffer:
- * Acquire the region lock.
- * Find the buffer header.
- * Increment the reference count (guarantee the buffer stays).
- * While the BH_LOCKED flag is set (I/O is going on) {
- * Release the region lock.
- * Explicitly yield the processor if it's not the first pass
- * through this loop, otherwise, we can simply spin because
- * we'll be simply switching between the two locks.
- * Request the buffer lock.
- * The I/O will complete...
- * Acquire the buffer lock.
- * Release the buffer lock.
- * Acquire the region lock.
- * }
- * Return the buffer.
- *
- * Reading/writing a buffer:
- * Acquire the region lock.
- * Find/create the buffer header.
- * If reading, increment the reference count (guarantee the buffer stays).
- * Set the BH_LOCKED flag.
- * Acquire the buffer lock (guaranteed not to block).
- * Release the region lock.
- * Do the I/O and/or initialize the buffer contents.
- * Release the buffer lock.
- * At this point, the buffer lock is available, but the logical
- * operation (flagged by BH_LOCKED) is not yet completed. For
- * this reason, among others, threads checking the BH_LOCKED flag
- * must loop around their test.
- * Acquire the region lock.
- * Clear the BH_LOCKED flag.
- * Release the region lock.
- * Return/discard the buffer.
- *
- * Pointers to DB_MPOOL, MPOOL, DB_MPOOLFILE and MPOOLFILE structures are not
- * reacquired when a region lock is reacquired because they couldn't have been
- * closed/discarded and because they never move in memory.
- */
-#define LOCKINIT(dbmp, mutexp) \
- if (F_ISSET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION)) \
- (void)__db_mutex_init(mutexp, \
- MUTEX_LOCK_OFFSET((dbmp)->reginfo.addr, mutexp))
-
-#define LOCKHANDLE(dbmp, mutexp) \
- if (F_ISSET(dbmp, MP_LOCKHANDLE)) \
- (void)__db_mutex_lock(mutexp, (dbmp)->reginfo.fd)
-#define UNLOCKHANDLE(dbmp, mutexp) \
- if (F_ISSET(dbmp, MP_LOCKHANDLE)) \
- (void)__db_mutex_unlock(mutexp, (dbmp)->reginfo.fd)
-
-#define LOCKREGION(dbmp) \
- if (F_ISSET(dbmp, MP_LOCKREGION)) \
- (void)__db_mutex_lock(&((RLAYOUT *)(dbmp)->mp)->lock, \
- (dbmp)->reginfo.fd)
-#define UNLOCKREGION(dbmp) \
- if (F_ISSET(dbmp, MP_LOCKREGION)) \
- (void)__db_mutex_unlock(&((RLAYOUT *)(dbmp)->mp)->lock, \
- (dbmp)->reginfo.fd)
-
-#define LOCKBUFFER(dbmp, bhp) \
- if (F_ISSET(dbmp, MP_LOCKREGION)) \
- (void)__db_mutex_lock(&(bhp)->mutex, (dbmp)->reginfo.fd)
-#define UNLOCKBUFFER(dbmp, bhp) \
- if (F_ISSET(dbmp, MP_LOCKREGION)) \
- (void)__db_mutex_unlock(&(bhp)->mutex, (dbmp)->reginfo.fd)
-
-/* Check for region catastrophic shutdown. */
-#define MP_PANIC_CHECK(dbmp) { \
- if ((dbmp)->mp->rlayout.panic) \
- return (DB_RUNRECOVERY); \
-}
-
-/*
- * DB_MPOOL --
- * Per-process memory pool structure.
- */
-struct __db_mpool {
-/* These fields need to be protected for multi-threaded support. */
- db_mutex_t *mutexp; /* Structure lock. */
-
- /* List of pgin/pgout routines. */
- LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
-
- /* List of DB_MPOOLFILE's. */
- TAILQ_HEAD(__db_mpoolfileh, __db_mpoolfile) dbmfq;
-
-/* These fields are not protected. */
- DB_ENV *dbenv; /* Reference to error information. */
- REGINFO reginfo; /* Region information. */
-
- MPOOL *mp; /* Address of the shared MPOOL. */
-
- void *addr; /* Address of shalloc() region. */
-
- DB_HASHTAB *htab; /* Hash table of bucket headers. */
-
-#define MP_LOCKHANDLE 0x01 /* Threaded, lock handles and region. */
-#define MP_LOCKREGION 0x02 /* Concurrent access, lock region. */
- u_int32_t flags;
-};
-
-/*
- * DB_MPREG --
- * DB_MPOOL registry of pgin/pgout functions.
- */
-struct __db_mpreg {
- LIST_ENTRY(__db_mpreg) q; /* Linked list. */
-
- int ftype; /* File type. */
- /* Pgin, pgout routines. */
- int (DB_CALLBACK *pgin) __P((db_pgno_t, void *, DBT *));
- int (DB_CALLBACK *pgout) __P((db_pgno_t, void *, DBT *));
-};
-
-/*
- * DB_MPOOLFILE --
- * Per-process DB_MPOOLFILE information.
- */
-struct __db_mpoolfile {
-/* These fields need to be protected for multi-threaded support. */
- db_mutex_t *mutexp; /* Structure lock. */
-
- int fd; /* Underlying file descriptor. */
-
- u_int32_t ref; /* Reference count. */
-
- /*
- * !!!
- * This field is a special case -- it's protected by the region lock
- * NOT the thread lock. The reason for this is that we always have
- * the region lock immediately before or after we modify the field,
- * and we don't want to use the structure lock to protect it because
- * then I/O (which is done with the structure lock held because of
- * the race between the seek and write of the file descriptor) will
- * block any other put/get calls using this DB_MPOOLFILE structure.
- */
- u_int32_t pinref; /* Pinned block reference count. */
-
-/* These fields are not protected. */
- TAILQ_ENTRY(__db_mpoolfile) q; /* Linked list of DB_MPOOLFILE's. */
-
- DB_MPOOL *dbmp; /* Overlying DB_MPOOL. */
- MPOOLFILE *mfp; /* Underlying MPOOLFILE. */
-
- void *addr; /* Address of mmap'd region. */
- size_t len; /* Length of mmap'd region. */
-
-/* These fields need to be protected for multi-threaded support. */
-#define MP_READONLY 0x01 /* File is readonly. */
-#define MP_UPGRADE 0x02 /* File descriptor is readwrite. */
-#define MP_UPGRADE_FAIL 0x04 /* Upgrade wasn't possible. */
- u_int32_t flags;
-};
-
-/*
- * MPOOL --
- * Shared memory pool region. One of these is allocated in shared
- * memory, and describes the pool.
- */
-struct __mpool {
- RLAYOUT rlayout; /* General region information. */
-
- SH_TAILQ_HEAD(__bhq) bhq; /* LRU list of buckets. */
- SH_TAILQ_HEAD(__bhfq) bhfq; /* Free buckets. */
- SH_TAILQ_HEAD(__mpfq) mpfq; /* List of MPOOLFILEs. */
-
- /*
- * We make the assumption that the early pages of the file are far
- * more likely to be retrieved than the later pages, which means
- * that the top bits are more interesting for hashing since they're
- * less likely to collide. On the other hand, since 512 4K pages
- * represents a 2MB file, only the bottom 9 bits of the page number
- * are likely to be set. We XOR in the offset in the MPOOL of the
- * MPOOLFILE that backs this particular page, since that should also
- * be unique for the page.
- */
-#define BUCKET(mp, mf_offset, pgno) \
- (((pgno) ^ ((mf_offset) << 9)) % (mp)->htab_buckets)
-
- size_t htab; /* Hash table offset. */
- size_t htab_buckets; /* Number of hash table entries. */
-
- DB_LSN lsn; /* Maximum checkpoint LSN. */
- u_int32_t lsn_cnt; /* Checkpoint buffers left to write. */
-
- DB_MPOOL_STAT stat; /* Global mpool statistics. */
-
-#define MP_LSN_RETRY 0x01 /* Retry all BH_WRITE buffers. */
- u_int32_t flags;
-};
-
-/*
- * MPOOLFILE --
- * Shared DB_MPOOLFILE information.
- */
-struct __mpoolfile {
- SH_TAILQ_ENTRY q; /* List of MPOOLFILEs */
-
- u_int32_t ref; /* Reference count. */
-
- int ftype; /* File type. */
-
- int32_t lsn_off; /* Page's LSN offset. */
- u_int32_t clear_len; /* Bytes to clear on page create. */
-
- size_t path_off; /* File name location. */
- size_t fileid_off; /* File identification location. */
-
- size_t pgcookie_len; /* Pgin/pgout cookie length. */
- size_t pgcookie_off; /* Pgin/pgout cookie location. */
-
- u_int32_t lsn_cnt; /* Checkpoint buffers left to write. */
-
- db_pgno_t last_pgno; /* Last page in the file. */
- db_pgno_t orig_last_pgno; /* Original last page in the file. */
-
-#define MP_CAN_MMAP 0x01 /* If the file can be mmap'd. */
-#define MP_TEMP 0x02 /* Backing file is a temporary. */
- u_int32_t flags;
-
- DB_MPOOL_FSTAT stat; /* Per-file mpool statistics. */
-};
-
-/*
- * BH --
- * Buffer header.
- */
-struct __bh {
- db_mutex_t mutex; /* Structure lock. */
-
- u_int16_t ref; /* Reference count. */
-
-#define BH_CALLPGIN 0x001 /* Page needs to be reworked... */
-#define BH_DIRTY 0x002 /* Page was modified. */
-#define BH_DISCARD 0x004 /* Page is useless. */
-#define BH_LOCKED 0x008 /* Page is locked (I/O in progress). */
-#define BH_TRASH 0x010 /* Page is garbage. */
-#define BH_WRITE 0x020 /* Page scheduled for writing. */
- u_int16_t flags;
-
- SH_TAILQ_ENTRY q; /* LRU queue. */
- SH_TAILQ_ENTRY hq; /* MPOOL hash bucket queue. */
-
- db_pgno_t pgno; /* Underlying MPOOLFILE page number. */
- size_t mf_offset; /* Associated MPOOLFILE offset. */
-
- /*
- * !!!
- * This array must be size_t aligned -- the DB access methods put PAGE
- * and other structures into it, and expect to be able to access them
- * directly. (We guarantee size_t alignment in the db_mpool(3) manual
- * page as well.)
- */
- u_int8_t buf[1]; /* Variable length data. */
-};
-
-#include "mp_ext.h"
diff --git a/db2/include/mp_ext.h b/db2/include/mp_ext.h
deleted file mode 100644
index 8b46334..0000000
--- a/db2/include/mp_ext.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _mp_ext_h_
-#define _mp_ext_h_
-int __memp_bhwrite
- __P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
-int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
-int __memp_pgwrite __P((DB_MPOOLFILE *, BH *, int *, int *));
-int __memp_pg __P((DB_MPOOLFILE *, BH *, int));
-void __memp_bhfree __P((DB_MPOOL *, MPOOLFILE *, BH *, int));
-int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *,
- u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
-void __memp_panic __P((DB_ENV *));
-char * __memp_fn __P((DB_MPOOLFILE *));
-char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
-void __memp_dump_region __P((DB_MPOOL *, char *, FILE *));
-int __memp_reg_alloc __P((DB_MPOOL *, size_t, size_t *, void *));
-int __memp_alloc __P((DB_MPOOL *, size_t, size_t *, void *));
-int __memp_ropen
- __P((DB_MPOOL *, const char *, size_t, int, int, u_int32_t));
-int __mp_xxx_fd __P((DB_MPOOLFILE *, int *));
-#endif /* _mp_ext_h_ */
diff --git a/db2/include/mutex_ext.h b/db2/include/mutex_ext.h
deleted file mode 100644
index b48da5d..0000000
--- a/db2/include/mutex_ext.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _mutex_ext_h_
-#define _mutex_ext_h_
-int __db_mutex_init __P((db_mutex_t *, u_int32_t));
-int __db_mutex_lock __P((db_mutex_t *, int));
-int __db_mutex_unlock __P((db_mutex_t *, int));
-#endif /* _mutex_ext_h_ */
diff --git a/db2/include/os.h b/db2/include/os.h
deleted file mode 100644
index f173d1f..0000000
--- a/db2/include/os.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)os.h 10.11 (Sleepycat) 10/12/98
- */
-
-/*
- * We group seek/write calls into a single function so that we can use
- * pread(2)/pwrite(2) where they're available.
- */
-#define DB_IO_READ 1
-#define DB_IO_WRITE 2
-typedef struct __io {
- int fd_io; /* I/O file descriptor. */
- int fd_lock; /* Locking file descriptor. */
- db_mutex_t *mutexp; /* Mutex to lock. */
- size_t pagesize; /* Page size. */
- db_pgno_t pgno; /* Page number. */
- u_int8_t *buf; /* Buffer. */
- size_t bytes; /* Bytes read/written. */
-} DB_IO;
diff --git a/db2/include/os_ext.h b/db2/include/os_ext.h
deleted file mode 100644
index 3462109..0000000
--- a/db2/include/os_ext.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _os_ext_h_
-#define _os_ext_h_
-int __os_abspath __P((const char *));
-int __os_strdup __P((const char *, void *));
-int __os_calloc __P((size_t, size_t, void *));
-int __os_malloc __P((size_t, void *(*)(size_t), void *));
-int __os_realloc __P((void *, size_t));
-void __os_free __P((void *, size_t));
-void __os_freestr __P((void *));
-int __os_dirlist __P((const char *, char ***, int *));
-void __os_dirfree __P((char **, int));
-int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
-int __os_fsync __P((int));
-int __db_mapanon_ok __P((int));
-int __db_mapinit __P((void));
-int __db_mapregion __P((char *, REGINFO *));
-int __db_unmapregion __P((REGINFO *));
-int __db_unlinkregion __P((char *, REGINFO *));
-int __db_mapfile __P((char *, int, size_t, int, void **));
-int __db_unmapfile __P((void *, size_t));
-u_int32_t __db_oflags __P((int));
-int __db_omode __P((const char *));
-int __db_open __P((const char *, u_int32_t, u_int32_t, int, int *));
-int __os_open __P((const char *, int, int, int *));
-int __os_close __P((int));
-char *__db_rpath __P((const char *));
-int __os_io __P((DB_IO *, int, ssize_t *));
-int __os_read __P((int, void *, size_t, ssize_t *));
-int __os_write __P((int, const void *, size_t, ssize_t *));
-int __os_seek __P((int, size_t, db_pgno_t, u_int32_t, int, int));
-int __os_sleep __P((u_long, u_long));
-int __os_spin __P((void));
-void __os_yield __P((u_long));
-int __os_exists __P((const char *, int *));
-int __os_ioinfo
- __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *));
-int __os_tmpdir __P((DB_ENV *, u_int32_t));
-int __os_unlink __P((const char *));
-#endif /* _os_ext_h_ */
diff --git a/db2/include/os_jump.h b/db2/include/os_jump.h
deleted file mode 100644
index e2d577f..0000000
--- a/db2/include/os_jump.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)os_jump.h 10.1 (Sleepycat) 10/17/98
- */
-
-/* Calls which can be replaced by the application. */
-struct __db_jumptab {
- int (*j_close) __P((int)); /* DB_FUNC_CLOSE */
- void (*j_dirfree) __P((char **, int)); /* DB_FUNC_DIRFREE */
- int (*j_dirlist) /* DB_FUNC_DIRLIST */
- __P((const char *, char ***, int *));
- int (*j_exists) /* DB_FUNC_EXISTS */
- __P((const char *, int *));
- void (*j_free) __P((void *)); /* DB_FUNC_FREE */
- int (*j_fsync) __P((int)); /* DB_FUNC_FSYNC */
- int (*j_ioinfo) __P((const char *, /* DB_FUNC_IOINFO */
- int, u_int32_t *, u_int32_t *, u_int32_t *));
- void *(*j_malloc) __P((size_t)); /* DB_FUNC_MALLOC */
- int (*j_map) /* DB_FUNC_MAP */
- __P((char *, int, size_t, int, int, int, void **));
- int (*j_open) /* DB_FUNC_OPEN */
- __P((const char *, int, ...));
- ssize_t (*j_read) __P((int, void *, size_t)); /* DB_FUNC_READ */
- void *(*j_realloc) __P((void *, size_t)); /* DB_FUNC_REALLOC */
- int (*j_runlink) __P((char *)); /* DB_FUNC_RUNLINK */
- int (*j_seek) /* DB_FUNC_SEEK */
- __P((int, size_t, db_pgno_t, u_int32_t, int, int));
- int (*j_sleep) __P((u_long, u_long)); /* DB_FUNC_SLEEP */
- int (*j_unlink) __P((const char *)); /* DB_FUNC_UNLINK */
- int (*j_unmap) __P((void *, size_t)); /* DB_FUNC_UNMAP */
- ssize_t (*j_write) /* DB_FUNC_WRITE */
- __P((int, const void *, size_t));
- int (*j_yield) __P((void)); /* DB_FUNC_YIELD */
-};
-
-extern struct __db_jumptab __db_jump;
diff --git a/db2/include/queue.h b/db2/include/queue.h
deleted file mode 100644
index f606eb0..0000000
--- a/db2/include/queue.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/* BSDI $Id$ */
-
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines three types of data structures: lists, tail queues,
- * and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may only be traversed in the forward direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-#define LIST_END(head) NULL
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) { \
- (head)->lh_first = NULL; \
-}
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (0)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-#define TAILQ_END(head) NULL
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-#define CIRCLEQ_END(head) ((void *)(head))
-#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-} while (0)
-#endif /* !_SYS_QUEUE_H_ */
diff --git a/db2/include/shqueue.h b/db2/include/shqueue.h
deleted file mode 100644
index 00e5d76..0000000
--- a/db2/include/shqueue.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)shqueue.h 8.13 (Sleepycat) 4/10/98
- */
-#ifndef _SYS_SHQUEUE_H_
-#define _SYS_SHQUEUE_H_
-
-/*
- * This file defines three types of data structures: lists, tail queues, and
- * circular queues, similarly to the include file <sys/queue.h>.
- *
- * The difference is that this set of macros can be used for structures that
- * reside in shared memory that may be mapped at different addresses in each
- * process. In most cases, the macros for shared structures exactly mirror
- * the normal macros, although the macro calls require an additional type
- * parameter, only used by the HEAD and ENTRY macros of the standard macros.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * Shared list definitions.
- */
-#define SH_LIST_HEAD(name) \
-struct name { \
- ssize_t slh_first; /* first element */ \
-}
-
-#define SH_LIST_ENTRY \
-struct { \
- ssize_t sle_next; /* relative offset next element */ \
- ssize_t sle_prev; /* relative offset of prev element */ \
-}
-
-/*
- * Shared list functions. Since we use relative offsets for pointers,
- * 0 is a valid offset. Therefore, we use -1 to indicate end of list.
- * The macros ending in "P" return pointers without checking for end
- * of list, the others check for end of list and evaluate to either a
- * pointer or NULL.
- */
-
-#define SH_LIST_FIRSTP(head, type) \
- ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))
-
-#define SH_LIST_FIRST(head, type) \
- ((head)->slh_first == -1 ? NULL : \
- ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)))
-
-#define SH_LIST_NEXTP(elm, field, type) \
- ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))
-
-#define SH_LIST_NEXT(elm, field, type) \
- ((elm)->field.sle_next == -1 ? NULL : \
- ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)))
-
-#define SH_LIST_PREV(elm, field) \
- ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev))
-
-#define SH_PTR_TO_OFF(src, dest) \
- ((ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src))))
-
-#define SH_LIST_END(head) NULL
-
-/*
- * Take the element's next pointer and calculate what the corresponding
- * Prev pointer should be -- basically it is the negation plus the offset
- * of the next field in the structure.
- */
-#define SH_LIST_NEXT_TO_PREV(elm, field) \
- (-(elm)->field.sle_next + SH_PTR_TO_OFF(elm, &(elm)->field.sle_next))
-
-#define SH_LIST_INIT(head) (head)->slh_first = -1
-
-#define SH_LIST_INSERT_AFTER(listelm, elm, field, type) do { \
- if ((listelm)->field.sle_next != -1) { \
- (elm)->field.sle_next = SH_PTR_TO_OFF(elm, \
- SH_LIST_NEXTP(listelm, field, type)); \
- SH_LIST_NEXTP(listelm, field, type)->field.sle_prev = \
- SH_LIST_NEXT_TO_PREV(elm, field); \
- } else \
- (elm)->field.sle_next = -1; \
- (listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm); \
- (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field); \
-} while (0)
-
-#define SH_LIST_INSERT_HEAD(head, elm, field, type) do { \
- if ((head)->slh_first != -1) { \
- (elm)->field.sle_next = \
- (head)->slh_first - SH_PTR_TO_OFF(head, elm); \
- SH_LIST_FIRSTP(head, type)->field.sle_prev = \
- SH_LIST_NEXT_TO_PREV(elm, field); \
- } else \
- (elm)->field.sle_next = -1; \
- (head)->slh_first = SH_PTR_TO_OFF(head, elm); \
- (elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first); \
-} while (0)
-
-#define SH_LIST_REMOVE(elm, field, type) do { \
- if ((elm)->field.sle_next != -1) { \
- SH_LIST_NEXTP(elm, field, type)->field.sle_prev = \
- (elm)->field.sle_prev - (elm)->field.sle_next; \
- *SH_LIST_PREV(elm, field) += (elm)->field.sle_next; \
- } else \
- *SH_LIST_PREV(elm, field) = -1; \
-} while (0)
-
-/*
- * Shared tail queue definitions.
- */
-#define SH_TAILQ_HEAD(name) \
-struct name { \
- ssize_t stqh_first; /* relative offset of first element */ \
- ssize_t stqh_last; /* relative offset of last's next */ \
-}
-
-#define SH_TAILQ_ENTRY \
-struct { \
- ssize_t stqe_next; /* relative offset of next element */ \
- ssize_t stqe_prev; /* relative offset of prev's next */ \
-}
-
-/*
- * Shared tail queue functions.
- */
-#define SH_TAILQ_FIRSTP(head, type) \
- ((struct type *)((u_int8_t *)(head) + (head)->stqh_first))
-
-#define SH_TAILQ_FIRST(head, type) \
- ((head)->stqh_first == -1 ? NULL : SH_TAILQ_FIRSTP(head, type))
-
-#define SH_TAILQ_NEXTP(elm, field, type) \
- ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next))
-
-#define SH_TAILQ_NEXT(elm, field, type) \
- ((elm)->field.stqe_next == -1 ? NULL : SH_TAILQ_NEXTP(elm, field, type))
-
-#define SH_TAILQ_PREVP(elm, field) \
- ((ssize_t *)((u_int8_t *)(elm) + (elm)->field.stqe_prev))
-
-#define SH_TAILQ_LAST(head) \
- ((ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last))
-
-#define SH_TAILQ_NEXT_TO_PREV(elm, field) \
- (-(elm)->field.stqe_next + SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next))
-
-#define SH_TAILQ_END(head) NULL
-
-#define SH_TAILQ_INIT(head) { \
- (head)->stqh_first = -1; \
- (head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first); \
-}
-
-#define SH_TAILQ_INSERT_HEAD(head, elm, field, type) do { \
- if ((head)->stqh_first != -1) { \
- (elm)->field.stqe_next = \
- (head)->stqh_first - SH_PTR_TO_OFF(head, elm); \
- SH_TAILQ_FIRSTP(head, type)->field.stqe_prev = \
- SH_TAILQ_NEXT_TO_PREV(elm, field); \
- } else { \
- (elm)->field.stqe_next = -1; \
- (head)->stqh_last = \
- SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \
- } \
- (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \
- (elm)->field.stqe_prev = \
- SH_PTR_TO_OFF(elm, &(head)->stqh_first); \
-} while (0)
-
-#define SH_TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.stqe_next = -1; \
- (elm)->field.stqe_prev = \
- -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last; \
- if ((head)->stqh_last == \
- SH_PTR_TO_OFF((head), &(head)->stqh_first)) \
- (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \
- else \
- *SH_TAILQ_LAST(head) = -(head)->stqh_last + \
- SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) + \
- SH_PTR_TO_OFF(head, elm); \
- (head)->stqh_last = \
- SH_PTR_TO_OFF(head, &((elm)->field.stqe_next)); \
-} while (0)
-
-#define SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do { \
- if ((listelm)->field.stqe_next != -1) { \
- (elm)->field.stqe_next = (listelm)->field.stqe_next - \
- SH_PTR_TO_OFF(listelm, elm); \
- SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev = \
- SH_TAILQ_NEXT_TO_PREV(elm, field); \
- } else { \
- (elm)->field.stqe_next = -1; \
- (head)->stqh_last = \
- SH_PTR_TO_OFF(head, &elm->field.stqe_next); \
- } \
- (listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm); \
- (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field); \
-} while (0)
-
-#define SH_TAILQ_REMOVE(head, elm, field, type) do { \
- if ((elm)->field.stqe_next != -1) { \
- SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev = \
- (elm)->field.stqe_prev + \
- SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm, \
- field, type), elm); \
- *SH_TAILQ_PREVP(elm, field) += elm->field.stqe_next; \
- } else { \
- (head)->stqh_last = (elm)->field.stqe_prev + \
- SH_PTR_TO_OFF(head, elm); \
- *SH_TAILQ_PREVP(elm, field) = -1; \
- } \
-} while (0)
-
-/*
- * Shared circular queue definitions.
- */
-#define SH_CIRCLEQ_HEAD(name) \
-struct name { \
- ssize_t scqh_first; /* first element */ \
- ssize_t scqh_last; /* last element */ \
-}
-
-#define SH_CIRCLEQ_ENTRY \
-struct { \
- ssize_t scqe_next; /* next element */ \
- ssize_t scqe_prev; /* previous element */ \
-}
-
-/*
- * Shared circular queue functions.
- */
-#define SH_CIRCLEQ_FIRSTP(head, type) \
- ((struct type *)(((u_int8_t *)(head)) + (head)->scqh_first))
-
-#define SH_CIRCLEQ_FIRST(head, type) \
- ((head)->scqh_first == -1 ? \
- (void *)head : SH_CIRCLEQ_FIRSTP(head, type))
-
-#define SH_CIRCLEQ_LASTP(head, type) \
- ((struct type *)(((u_int8_t *)(head)) + (head)->scqh_last))
-
-#define SH_CIRCLEQ_LAST(head, type) \
- ((head)->scqh_last == -1 ? (void *)head : SH_CIRCLEQ_LASTP(head, type))
-
-#define SH_CIRCLEQ_NEXTP(elm, field, type) \
- ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.scqe_next))
-
-#define SH_CIRCLEQ_NEXT(head, elm, field, type) \
- ((elm)->field.scqe_next == SH_PTR_TO_OFF(elm, head) ? \
- (void *)head : SH_CIRCLEQ_NEXTP(elm, field, type))
-
-#define SH_CIRCLEQ_PREVP(elm, field, type) \
- ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.scqe_prev))
-
-#define SH_CIRCLEQ_PREV(head, elm, field, type) \
- ((elm)->field.scqe_prev == SH_PTR_TO_OFF(elm, head) ? \
- (void *)head : SH_CIRCLEQ_PREVP(elm, field, type))
-
-#define SH_CIRCLEQ_END(head) ((void *)(head))
-
-#define SH_CIRCLEQ_INIT(head) { \
- (head)->scqh_first = 0; \
- (head)->scqh_last = 0; \
-}
-
-#define SH_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field, type) do { \
- (elm)->field.scqe_prev = SH_PTR_TO_OFF(elm, listelm); \
- (elm)->field.scqe_next = (listelm)->field.scqe_next + \
- (elm)->field.scqe_prev; \
- if (SH_CIRCLEQ_NEXTP(listelm, field, type) == (void *)head) \
- (head)->scqh_last = SH_PTR_TO_OFF(head, elm); \
- else \
- SH_CIRCLEQ_NEXTP(listelm, \
- field, type)->field.scqe_prev = \
- SH_PTR_TO_OFF(SH_CIRCLEQ_NEXTP(listelm, \
- field, type), elm); \
- (listelm)->field.scqe_next = -(elm)->field.scqe_prev; \
-} while (0)
-
-#define SH_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field, type) do { \
- (elm)->field.scqe_next = SH_PTR_TO_OFF(elm, listelm); \
- (elm)->field.scqe_prev = (elm)->field.scqe_next - \
- SH_CIRCLEQ_PREVP(listelm, field, type)->field.scqe_next;\
- if (SH_CIRCLEQ_PREVP(listelm, field, type) == (void *)(head)) \
- (head)->scqh_first = SH_PTR_TO_OFF(head, elm); \
- else \
- SH_CIRCLEQ_PREVP(listelm, \
- field, type)->field.scqe_next = \
- SH_PTR_TO_OFF(SH_CIRCLEQ_PREVP(listelm, \
- field, type), elm); \
- (listelm)->field.scqe_prev = -(elm)->field.scqe_next; \
-} while (0)
-
-#define SH_CIRCLEQ_INSERT_HEAD(head, elm, field, type) do { \
- (elm)->field.scqe_prev = SH_PTR_TO_OFF(elm, head); \
- (elm)->field.scqe_next = (head)->scqh_first + \
- (elm)->field.scqe_prev; \
- if ((head)->scqh_last == 0) \
- (head)->scqh_last = -(elm)->field.scqe_prev; \
- else \
- SH_CIRCLEQ_FIRSTP(head, type)->field.scqe_prev = \
- SH_PTR_TO_OFF(SH_CIRCLEQ_FIRSTP(head, type), elm); \
- (head)->scqh_first = -(elm)->field.scqe_prev; \
-} while (0)
-
-#define SH_CIRCLEQ_INSERT_TAIL(head, elm, field, type) do { \
- (elm)->field.scqe_next = SH_PTR_TO_OFF(elm, head); \
- (elm)->field.scqe_prev = (head)->scqh_last + \
- (elm)->field.scqe_next; \
- if ((head)->scqh_first == 0) \
- (head)->scqh_first = -(elm)->field.scqe_next; \
- else \
- SH_CIRCLEQ_LASTP(head, type)->field.scqe_next = \
- SH_PTR_TO_OFF(SH_CIRCLEQ_LASTP(head, type), elm); \
- (head)->scqh_last = -(elm)->field.scqe_next; \
-} while (0)
-
-#define SH_CIRCLEQ_REMOVE(head, elm, field, type) do { \
- if (SH_CIRCLEQ_NEXTP(elm, field, type) == (void *)(head)) \
- (head)->scqh_last += (elm)->field.scqe_prev; \
- else \
- SH_CIRCLEQ_NEXTP(elm, field, type)->field.scqe_prev += \
- (elm)->field.scqe_prev; \
- if (SH_CIRCLEQ_PREVP(elm, field, type) == (void *)(head)) \
- (head)->scqh_first += (elm)->field.scqe_next; \
- else \
- SH_CIRCLEQ_PREVP(elm, field, type)->field.scqe_next += \
- (elm)->field.scqe_next; \
-} while (0)
-#endif /* !_SYS_SHQUEUE_H_ */
diff --git a/db2/include/txn.h b/db2/include/txn.h
deleted file mode 100644
index a6fa4db..0000000
--- a/db2/include/txn.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)txn.h 10.18 (Sleepycat) 1/3/99
- */
-#ifndef _TXN_H_
-#define _TXN_H_
-
-#include "xa.h"
-
-/*
- * The name of the transaction shared memory region is DEFAULT_TXN_FILE and
- * the region is always created group RW of the group owning the directory.
- */
-#define DEFAULT_TXN_FILE "__db_txn.share"
-/* TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. */
-#define TXN_MINIMUM 0x80000000
-#define TXN_INVALID 0xffffffff /* Maximum number of txn ids. */
-
-/*
- * Transaction type declarations.
- */
-
-/*
- * Internal data maintained in shared memory for each transaction.
- */
-typedef char DB_XID[XIDDATASIZE];
-
-typedef struct __txn_detail {
- u_int32_t txnid; /* current transaction id
- used to link free list also */
- DB_LSN last_lsn; /* last lsn written for this txn */
- DB_LSN begin_lsn; /* lsn of begin record */
- size_t last_lock; /* offset in lock region of last lock
- for this transaction. */
- size_t parent; /* Offset of transaction's parent. */
-#define TXN_UNALLOC 0
-#define TXN_RUNNING 1
-#define TXN_ABORTED 2
-#define TXN_PREPARED 3
-#define TXN_COMMITTED 4
- u_int32_t status; /* status of the transaction */
- SH_TAILQ_ENTRY links; /* free/active list */
-
-#define TXN_XA_ABORTED 1
-#define TXN_XA_DEADLOCKED 2
-#define TXN_XA_ENDED 3
-#define TXN_XA_PREPARED 4
-#define TXN_XA_STARTED 5
-#define TXN_XA_SUSPENDED 6
- u_int32_t xa_status; /* XA status */
-
- /*
- * XID (xid_t) structure: because these fields are logged, the
- * sizes have to be explicit.
- */
- DB_XID xid; /* XA global transaction id */
- u_int32_t bqual; /* bqual_length from XID */
- u_int32_t gtrid; /* gtrid_length from XID */
- int32_t format; /* XA format */
-} TXN_DETAIL;
-
-/*
- * The transaction manager encapsulates the transaction system. It contains
- * references to the log and lock managers as well as the state that keeps
- * track of the shared memory region.
- */
-struct __db_txnmgr {
-/* These fields need to be protected for multi-threaded support. */
- db_mutex_t *mutexp; /* Synchronization. */
- /* list of active transactions */
- TAILQ_HEAD(_chain, __db_txn) txn_chain;
-
-/* These fields are not protected. */
- REGINFO reginfo; /* Region information. */
- DB_ENV *dbenv; /* Environment. */
- int (*recover) /* Recovery dispatch routine */
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- u_int32_t flags; /* DB_TXN_NOSYNC, DB_THREAD */
- DB_TXNREGION *region; /* address of shared memory region */
- void *mem; /* address of the shalloc space */
-};
-
-/*
- * Layout of the shared memory region.
- * The region consists of a DB_TXNREGION structure followed by a large
- * pool of shalloc'd memory which is used to hold TXN_DETAIL structures
- * and thread mutexes (which are dynamically allocated).
- */
-struct __db_txnregion {
- RLAYOUT hdr; /* Shared memory region header. */
- u_int32_t magic; /* transaction magic number */
- u_int32_t version; /* version number */
- u_int32_t maxtxns; /* maximum number of active txns */
- u_int32_t last_txnid; /* last transaction id given out */
- DB_LSN pending_ckp; /* last checkpoint did not finish */
- DB_LSN last_ckp; /* lsn of the last checkpoint */
- time_t time_ckp; /* time of last checkpoint */
- u_int32_t logtype; /* type of logging */
- u_int32_t locktype; /* lock type */
- u_int32_t naborts; /* number of aborted transactions */
- u_int32_t ncommits; /* number of committed transactions */
- u_int32_t nbegins; /* number of begun transactions */
- SH_TAILQ_HEAD(_active) active_txn; /* active transaction list */
-};
-
-/*
- * Make the region large enough to hold N transaction detail structures
- * plus some space to hold thread handles and the beginning of the shalloc
- * region.
- */
-#define TXN_REGION_SIZE(N) \
- (sizeof(DB_TXNREGION) + N * sizeof(TXN_DETAIL) + 1000)
-
-/* Macros to lock/unlock the region and threads. */
-#define LOCK_TXNTHREAD(tmgrp) \
- if (F_ISSET(tmgrp, DB_THREAD)) \
- (void)__db_mutex_lock((tmgrp)->mutexp, -1)
-#define UNLOCK_TXNTHREAD(tmgrp) \
- if (F_ISSET(tmgrp, DB_THREAD)) \
- (void)__db_mutex_unlock((tmgrp)->mutexp, -1)
-
-#define LOCK_TXNREGION(tmgrp) \
- (void)__db_mutex_lock(&(tmgrp)->region->hdr.lock, (tmgrp)->reginfo.fd)
-#define UNLOCK_TXNREGION(tmgrp) \
- (void)__db_mutex_unlock(&(tmgrp)->region->hdr.lock, (tmgrp)->reginfo.fd)
-
-/* Check for region catastrophic shutdown. */
-#define TXN_PANIC_CHECK(tmgrp) { \
- if ((tmgrp)->region->hdr.panic) \
- return (DB_RUNRECOVERY); \
-}
-
-/*
- * Log record types.
- */
-#define TXN_COMMIT 1
-#define TXN_PREPARE 2
-#define TXN_CHECKPOINT 3
-
-#include "txn_auto.h"
-#include "txn_ext.h"
-
-#include "xa_ext.h"
-#endif /* !_TXN_H_ */
diff --git a/db2/include/txn_auto.h b/db2/include/txn_auto.h
deleted file mode 100644
index bb3de4e..0000000
--- a/db2/include/txn_auto.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#ifndef txn_AUTO_H
-#define txn_AUTO_H
-
-#define DB_txn_regop (DB_txn_BEGIN + 1)
-
-typedef struct _txn_regop_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
-} __txn_regop_args;
-
-
-#define DB_txn_ckp (DB_txn_BEGIN + 2)
-
-typedef struct _txn_ckp_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- DB_LSN ckp_lsn;
- DB_LSN last_ckp;
-} __txn_ckp_args;
-
-
-#define DB_txn_xa_regop (DB_txn_BEGIN + 3)
-
-typedef struct _txn_xa_regop_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- DBT xid;
- int32_t formatID;
- u_int32_t gtrid;
- u_int32_t bqual;
- DB_LSN begin_lsn;
-} __txn_xa_regop_args;
-
-
-#define DB_txn_child (DB_txn_BEGIN + 4)
-
-typedef struct _txn_child_args {
- u_int32_t type;
- DB_TXN *txnid;
- DB_LSN prev_lsn;
- u_int32_t opcode;
- u_int32_t parent;
-} __txn_child_args;
-
-#endif
diff --git a/db2/include/txn_ext.h b/db2/include/txn_ext.h
deleted file mode 100644
index e0d69c3..0000000
--- a/db2/include/txn_ext.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _txn_ext_h_
-#define _txn_ext_h_
-void __txn_panic __P((DB_ENV *));
-int __txn_xa_begin __P((DB_ENV *, DB_TXN *));
-int __txn_is_ancestor __P((DB_TXNMGR *, size_t, size_t));
-int __txn_regop_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t));
-int __txn_regop_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_regop_read __P((void *, __txn_regop_args **));
-int __txn_ckp_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- DB_LSN *, DB_LSN *));
-int __txn_ckp_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_ckp_read __P((void *, __txn_ckp_args **));
-int __txn_xa_regop_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, const DBT *, int32_t, u_int32_t,
- u_int32_t, DB_LSN *));
-int __txn_xa_regop_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_xa_regop_read __P((void *, __txn_xa_regop_args **));
-int __txn_child_log
- __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- u_int32_t, u_int32_t));
-int __txn_child_print
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_child_read __P((void *, __txn_child_args **));
-int __txn_init_print __P((DB_ENV *));
-int __txn_init_recover __P((DB_ENV *));
-int __txn_regop_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_xa_regop_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_ckp_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-int __txn_child_recover
- __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
-#endif /* _txn_ext_h_ */
diff --git a/db2/include/xa.h b/db2/include/xa.h
deleted file mode 100644
index ae822f3..0000000
--- a/db2/include/xa.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)xa.h 10.1 (Sleepycat) 6/22/98
- */
-/*
- * Start of xa.h header
- *
- * Define a symbol to prevent multiple inclusions of this header file
- */
-#ifndef XA_H
-#define XA_H
-
-/*
- * Transaction branch identification: XID and NULLXID:
- */
-#define XIDDATASIZE 128 /* size in bytes */
-#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */
-#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */
-
-struct xid_t {
- long formatID; /* format identifier */
- long gtrid_length; /* value from 1 through 64 */
- long bqual_length; /* value from 1 through 64 */
- char data[XIDDATASIZE];
-};
-typedef struct xid_t XID;
-/*
- * A value of -1 in formatID means that the XID is null.
- */
-
-/*
- * Declarations of routines by which RMs call TMs:
- */
-extern int ax_reg __P((int, XID *, long));
-extern int ax_unreg __P((int, long));
-
-/*
- * XA Switch Data Structure
- */
-#define RMNAMESZ 32 /* length of resource manager name, */
- /* including the null terminator */
-#define MAXINFOSIZE 256 /* maximum size in bytes of xa_info */
- /* strings, including the null
- terminator */
-struct xa_switch_t {
- char name[RMNAMESZ]; /* name of resource manager */
- long flags; /* resource manager specific options */
- long version; /* must be 0 */
- int (*xa_open_entry) /* xa_open function pointer */
- __P((char *, int, long));
- int (*xa_close_entry) /* xa_close function pointer */
- __P((char *, int, long));
- int (*xa_start_entry) /* xa_start function pointer */
- __P((XID *, int, long));
- int (*xa_end_entry) /* xa_end function pointer */
- __P((XID *, int, long));
- int (*xa_rollback_entry) /* xa_rollback function pointer */
- __P((XID *, int, long));
- int (*xa_prepare_entry) /* xa_prepare function pointer */
- __P((XID *, int, long));
- int (*xa_commit_entry) /* xa_commit function pointer */
- __P((XID *, int, long));
- int (*xa_recover_entry) /* xa_recover function pointer */
- __P((XID *, long, int, long));
- int (*xa_forget_entry) /* xa_forget function pointer */
- __P((XID *, int, long));
- int (*xa_complete_entry) /* xa_complete function pointer */
- __P((int *, int *, int, long));
-};
-
-/*
- * Flag definitions for the RM switch
- */
-#define TMNOFLAGS 0x00000000L /* no resource manager features
- selected */
-#define TMREGISTER 0x00000001L /* resource manager dynamically
- registers */
-#define TMNOMIGRATE 0x00000002L /* resource manager does not support
- association migration */
-#define TMUSEASYNC 0x00000004L /* resource manager supports
- asynchronous operations */
-/*
- * Flag definitions for xa_ and ax_ routines
- */
-/* use TMNOFLAGGS, defined above, when not specifying other flags */
-#define TMASYNC 0x80000000L /* perform routine asynchronously */
-#define TMONEPHASE 0x40000000L /* caller is using one-phase commit
- optimisation */
-#define TMFAIL 0x20000000L /* dissociates caller and marks
- transaction branch rollback-only */
-#define TMNOWAIT 0x10000000L /* return if blocking condition
- exists */
-#define TMRESUME 0x08000000L /* caller is resuming association with
- suspended transaction branch */
-#define TMSUCCESS 0x04000000L /* dissociate caller from transaction
- branch */
-#define TMSUSPEND 0x02000000L /* caller is suspending, not ending,
- association */
-#define TMSTARTRSCAN 0x01000000L /* start a recovery scan */
-#define TMENDRSCAN 0x00800000L /* end a recovery scan */
-#define TMMULTIPLE 0x00400000L /* wait for any asynchronous
- operation */
-#define TMJOIN 0x00200000L /* caller is joining existing
- transaction branch */
-#define TMMIGRATE 0x00100000L /* caller intends to perform
- migration */
-
-/*
- * ax_() return codes (transaction manager reports to resource manager)
- */
-#define TM_JOIN 2 /* caller is joining existing
- transaction branch */
-#define TM_RESUME 1 /* caller is resuming association with
- suspended transaction branch */
-#define TM_OK 0 /* normal execution */
-#define TMER_TMERR -1 /* an error occurred in the transaction
- manager */
-#define TMER_INVAL -2 /* invalid arguments were given */
-#define TMER_PROTO -3 /* routine invoked in an improper
- context */
-
-/*
- * xa_() return codes (resource manager reports to transaction manager)
- */
-#define XA_RBBASE 100 /* The inclusive lower bound of the
- rollback codes */
-#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an
- unspecified reason */
-#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a
- communication failure */
-#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */
-#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the
- integrity of the resources was
- detected */
-#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the
- transaction branch for a reason not
- on this list */
-#define XA_RBPROTO XA_RBBASE+5 /* A protocol error occurred in the
- resource manager */
-#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long */
-#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */
-#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the
- rollback codes */
-#define XA_NOMIGRATE 9 /* resumption must occur where
- suspension occurred */
-#define XA_HEURHAZ 8 /* the transaction branch may have
- been heuristically completed */
-#define XA_HEURCOM 7 /* the transaction branch has been
- heuristically committed */
-#define XA_HEURRB 6 /* the transaction branch has been
- heuristically rolled back */
-#define XA_HEURMIX 5 /* the transaction branch has been
- heuristically committed and rolled
- back */
-#define XA_RETRY 4 /* routine returned with no effect and
- may be re-issued */
-#define XA_RDONLY 3 /* the transaction branch was read-only
- and has been committed */
-#define XA_OK 0 /* normal execution */
-#define XAER_ASYNC -2 /* asynchronous operation already
- outstanding */
-#define XAER_RMERR -3 /* a resource manager error occurred in
- the transaction branch */
-#define XAER_NOTA -4 /* the XID is not valid */
-#define XAER_INVAL -5 /* invalid arguments were given */
-#define XAER_PROTO -6 /* routine invoked in an improper
- context */
-#define XAER_RMFAIL -7 /* resource manager unavailable */
-#define XAER_DUPID -8 /* the XID already exists */
-#define XAER_OUTSIDE -9 /* resource manager doing work outside
- transaction */
-#endif /* ifndef XA_H */
-/*
- * End of xa.h header
- */
diff --git a/db2/include/xa_ext.h b/db2/include/xa_ext.h
deleted file mode 100644
index 00369cc..0000000
--- a/db2/include/xa_ext.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/distrib. */
-#ifndef _xa_ext_h_
-#define _xa_ext_h_
-int __db_rmid_to_env __P((int rmid, DB_ENV **envp, int open_ok));
-int __db_xid_to_txn __P((DB_ENV *, XID *, size_t *));
-int __db_map_rmid __P((int, DB_ENV *));
-int __db_unmap_rmid __P((int));
-int __db_map_xid __P((DB_ENV *, XID *, size_t));
-void __db_unmap_xid __P((DB_ENV *, XID *, size_t));
-int __db_map_rmid_name __P((int, char *));
-int __db_rmid_to_name __P((int, char **));
- void __db_unmap_rmid_name __P((int));
-#endif /* _xa_ext_h_ */
diff --git a/db2/lock/lock.c b/db2/lock/lock.c
deleted file mode 100644
index 4cf1d9e..0000000
--- a/db2/lock/lock.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)lock.c 10.61 (Sleepycat) 1/3/99";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "db_am.h"
-#include "txn_auto.h"
-#include "txn_ext.h"
-#include "common_ext.h"
-
-static void __lock_checklocker __P((DB_LOCKTAB *, struct __db_lock *, int));
-static void __lock_freeobj __P((DB_LOCKTAB *, DB_LOCKOBJ *));
-static int __lock_get_internal __P((DB_LOCKTAB *, u_int32_t, DB_TXN *,
- u_int32_t, const DBT *, db_lockmode_t, struct __db_lock **));
-static int __lock_is_parent __P((u_int32_t, DB_TXN *));
-static int __lock_promote __P((DB_LOCKTAB *, DB_LOCKOBJ *));
-static int __lock_put_internal __P((DB_LOCKTAB *, struct __db_lock *, int));
-static void __lock_remove_waiter
- __P((DB_LOCKTAB *, DB_LOCKOBJ *, struct __db_lock *, db_status_t));
-static int __lock_vec_internal __P((DB_LOCKTAB *, u_int32_t, DB_TXN *,
- u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **elistp));
-
-int
-lock_id(lt, idp)
- DB_LOCKTAB *lt;
- u_int32_t *idp;
-{
- u_int32_t id;
-
- LOCK_PANIC_CHECK(lt);
-
- LOCK_LOCKREGION(lt);
- if (lt->region->id >= DB_LOCK_MAXID)
- lt->region->id = 0;
- id = ++lt->region->id;
- UNLOCK_LOCKREGION(lt);
-
- *idp = id;
- return (0);
-}
-
-int
-lock_vec(lt, locker, flags, list, nlist, elistp)
- DB_LOCKTAB *lt;
- u_int32_t locker, flags;
- int nlist;
- DB_LOCKREQ *list, **elistp;
-{
- return (__lock_vec_internal(lt,
- locker, NULL, flags, list, nlist, elistp));
-}
-
-int
-lock_tvec(lt, txn, flags, list, nlist, elistp)
- DB_LOCKTAB *lt;
- DB_TXN *txn;
- u_int32_t flags;
- int nlist;
- DB_LOCKREQ *list, **elistp;
-{
- return (__lock_vec_internal(lt,
- txn->txnid, txn, flags, list, nlist, elistp));
-}
-
-static int
-__lock_vec_internal(lt, locker, txn, flags, list, nlist, elistp)
- DB_LOCKTAB *lt;
- u_int32_t locker;
- DB_TXN *txn;
- u_int32_t flags;
- int nlist;
- DB_LOCKREQ *list, **elistp;
-{
- struct __db_lock *lp;
- DB_LOCKOBJ *sh_obj, *sh_locker, *sh_parent;
- int i, ret, run_dd;
-
- LOCK_PANIC_CHECK(lt);
-
- /* Validate arguments. */
- if ((ret =
- __db_fchk(lt->dbenv, "lock_vec", flags, DB_LOCK_NOWAIT)) != 0)
- return (ret);
-
- LOCK_LOCKREGION(lt);
-
- if ((ret = __lock_validate_region(lt)) != 0) {
- UNLOCK_LOCKREGION(lt);
- return (ret);
- }
-
- ret = 0;
- for (i = 0; i < nlist && ret == 0; i++) {
- switch (list[i].op) {
- case DB_LOCK_GET:
- ret = __lock_get_internal(lt, locker, txn, flags,
- list[i].obj, list[i].mode, &lp);
- if (ret == 0) {
- list[i].lock = LOCK_TO_OFFSET(lt, lp);
- lt->region->nrequests++;
- }
- break;
- case DB_LOCK_INHERIT:
- /* Find the locker. */
- if ((ret = __lock_getobj(lt, locker,
- NULL, DB_LOCK_LOCKER, &sh_locker)) != 0)
- break;
- if (txn == NULL || txn->parent == NULL) {
- ret = EINVAL;
- break;
- }
-
- if ((ret = __lock_getobj(lt, txn->parent->txnid,
- NULL, DB_LOCK_LOCKER, &sh_parent)) != 0)
- break;
-
- /*
- * Traverse all the locks held by this locker. Remove
- * the locks from the locker's list and put them on the
- * parent's list.
- */
- for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock);
- lp != NULL;
- lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock)) {
- SH_LIST_REMOVE(lp, locker_links, __db_lock);
- SH_LIST_INSERT_HEAD(&sh_parent->heldby, lp,
- locker_links, __db_lock);
- lp->holder = txn->parent->txnid;
- }
- __lock_freeobj(lt, sh_locker);
- lt->region->nlockers--;
- break;
- case DB_LOCK_PUT:
- lp = OFFSET_TO_LOCK(lt, list[i].lock);
- if (lp->holder != locker) {
- ret = DB_LOCK_NOTHELD;
- break;
- }
- list[i].mode = lp->mode;
-
- ret = __lock_put_internal(lt, lp, 0);
- __lock_checklocker(lt, lp, 0);
- break;
- case DB_LOCK_PUT_ALL:
- /* Find the locker. */
- if ((ret = __lock_getobj(lt, locker,
- NULL, DB_LOCK_LOCKER, &sh_locker)) != 0)
- break;
-
- for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock);
- lp != NULL;
- lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock)) {
- if ((ret = __lock_put_internal(lt, lp, 1)) != 0)
- break;
- }
- __lock_freeobj(lt, sh_locker);
- lt->region->nlockers--;
- break;
- case DB_LOCK_PUT_OBJ:
-
- /* Look up the object in the hash table. */
- HASHLOOKUP(lt->hashtab, __db_lockobj, links,
- list[i].obj, sh_obj, lt->region->table_size,
- __lock_ohash, __lock_cmp);
- if (sh_obj == NULL) {
- ret = EINVAL;
- break;
- }
- /*
- * Release waiters first, because they won't cause
- * anyone else to be awakened. If we release the
- * lockers first, all the waiters get awakened
- * needlessly.
- */
- for (lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock)) {
- lt->region->nreleases += lp->refcount;
- __lock_remove_waiter(lt, sh_obj, lp,
- DB_LSTAT_NOGRANT);
- __lock_checklocker(lt, lp, 1);
- }
-
- for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock)) {
-
- lt->region->nreleases += lp->refcount;
- SH_LIST_REMOVE(lp, locker_links, __db_lock);
- SH_TAILQ_REMOVE(&sh_obj->holders, lp, links,
- __db_lock);
- lp->status = DB_LSTAT_FREE;
- SH_TAILQ_INSERT_HEAD(&lt->region->free_locks,
- lp, links, __db_lock);
- }
-
- /* Now free the object. */
- __lock_freeobj(lt, sh_obj);
- break;
-#ifdef DEBUG
- case DB_LOCK_DUMP:
- /* Find the locker. */
- if ((ret = __lock_getobj(lt, locker,
- NULL, DB_LOCK_LOCKER, &sh_locker)) != 0)
- break;
-
- for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock);
- lp != NULL;
- lp = SH_LIST_NEXT(lp, locker_links, __db_lock)) {
- __lock_printlock(lt, lp, 1);
- ret = EINVAL;
- }
- if (ret == 0) {
- __lock_freeobj(lt, sh_locker);
- lt->region->nlockers--;
- }
- break;
-#endif
- default:
- ret = EINVAL;
- break;
- }
- }
-
- if (lt->region->need_dd && lt->region->detect != DB_LOCK_NORUN) {
- run_dd = 1;
- lt->region->need_dd = 0;
- } else
- run_dd = 0;
-
- UNLOCK_LOCKREGION(lt);
-
- if (ret == 0 && run_dd)
- lock_detect(lt, 0, lt->region->detect);
-
- if (elistp && ret != 0)
- *elistp = &list[i - 1];
- return (ret);
-}
-
-int
-lock_get(lt, locker, flags, obj, lock_mode, lock)
- DB_LOCKTAB *lt;
- u_int32_t locker, flags;
- const DBT *obj;
- db_lockmode_t lock_mode;
- DB_LOCK *lock;
-{
- struct __db_lock *lockp;
- int ret;
-
- LOCK_PANIC_CHECK(lt);
-
- /* Validate arguments. */
- if ((ret = __db_fchk(lt->dbenv,
- "lock_get", flags, DB_LOCK_NOWAIT | DB_LOCK_UPGRADE)) != 0)
- return (ret);
-
- LOCK_LOCKREGION(lt);
-
- if ((ret = __lock_validate_region(lt)) == 0) {
- if (LF_ISSET(DB_LOCK_UPGRADE))
- lockp = OFFSET_TO_LOCK(lt, *lock);
-
- if ((ret = __lock_get_internal(lt,
- locker, NULL, flags, obj, lock_mode, &lockp)) == 0) {
- if (!LF_ISSET(DB_LOCK_UPGRADE))
- *lock = LOCK_TO_OFFSET(lt, lockp);
- lt->region->nrequests++;
- }
- }
-
- UNLOCK_LOCKREGION(lt);
- return (ret);
-}
-
-int
-lock_tget(lt, txn, flags, obj, lock_mode, lock)
- DB_LOCKTAB *lt;
- DB_TXN *txn;
- u_int32_t flags;
- const DBT *obj;
- db_lockmode_t lock_mode;
- DB_LOCK *lock;
-{
- struct __db_lock *lockp;
- int ret;
-
- LOCK_PANIC_CHECK(lt);
-
- /* Validate arguments. */
- if ((ret = __db_fchk(lt->dbenv,
- "lock_get", flags, DB_LOCK_NOWAIT | DB_LOCK_UPGRADE)) != 0)
- return (ret);
-
- LOCK_LOCKREGION(lt);
-
- if ((ret = __lock_validate_region(lt)) == 0) {
- if (LF_ISSET(DB_LOCK_UPGRADE))
- lockp = OFFSET_TO_LOCK(lt, *lock);
-
- if ((ret = __lock_get_internal(lt,
- txn->txnid, txn, flags, obj, lock_mode, &lockp)) == 0) {
- if (!LF_ISSET(DB_LOCK_UPGRADE))
- *lock = LOCK_TO_OFFSET(lt, lockp);
- lt->region->nrequests++;
- }
- }
-
- UNLOCK_LOCKREGION(lt);
- return (ret);
-}
-int
-lock_put(lt, lock)
- DB_LOCKTAB *lt;
- DB_LOCK lock;
-{
- struct __db_lock *lockp;
- int ret, run_dd;
-
- LOCK_PANIC_CHECK(lt);
-
- LOCK_LOCKREGION(lt);
-
- if ((ret = __lock_validate_region(lt)) != 0)
- return (ret);
- else {
- lockp = OFFSET_TO_LOCK(lt, lock);
- ret = __lock_put_internal(lt, lockp, 0);
- }
-
- __lock_checklocker(lt, lockp, 0);
-
- if (lt->region->need_dd && lt->region->detect != DB_LOCK_NORUN) {
- run_dd = 1;
- lt->region->need_dd = 0;
- } else
- run_dd = 0;
-
- UNLOCK_LOCKREGION(lt);
-
- if (ret == 0 && run_dd)
- lock_detect(lt, 0, lt->region->detect);
-
- return (ret);
-}
-
-static int
-__lock_put_internal(lt, lockp, do_all)
- DB_LOCKTAB *lt;
- struct __db_lock *lockp;
- int do_all;
-{
- DB_LOCKOBJ *sh_obj;
- int state_changed;
-
- if (lockp->refcount == 0 || (lockp->status != DB_LSTAT_HELD &&
- lockp->status != DB_LSTAT_WAITING) || lockp->obj == 0) {
- __db_err(lt->dbenv, "lock_put: invalid lock %lu",
- (u_long)((u_int8_t *)lockp - (u_int8_t *)lt->region));
- return (EINVAL);
- }
-
- if (do_all)
- lt->region->nreleases += lockp->refcount;
- else
- lt->region->nreleases++;
- if (do_all == 0 && lockp->refcount > 1) {
- lockp->refcount--;
- return (0);
- }
-
- /* Get the object associated with this lock. */
- sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj);
-
- /* Remove lock from locker list. */
- SH_LIST_REMOVE(lockp, locker_links, __db_lock);
-
- /* Remove this lock from its holders/waitlist. */
- if (lockp->status != DB_LSTAT_HELD)
- __lock_remove_waiter(lt, sh_obj, lockp, DB_LSTAT_FREE);
- else
- SH_TAILQ_REMOVE(&sh_obj->holders, lockp, links, __db_lock);
-
- state_changed = __lock_promote(lt, sh_obj);
-
- /* Check if object should be reclaimed. */
- if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) {
- HASHREMOVE_EL(lt->hashtab, __db_lockobj,
- links, sh_obj, lt->region->table_size, __lock_lhash);
- if (sh_obj->lockobj.size > sizeof(sh_obj->objdata))
- __db_shalloc_free(lt->mem,
- SH_DBT_PTR(&sh_obj->lockobj));
- SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, sh_obj, links,
- __db_lockobj);
- state_changed = 1;
- }
-
- /* Free lock. */
- lockp->status = DB_LSTAT_FREE;
- SH_TAILQ_INSERT_HEAD(&lt->region->free_locks, lockp, links, __db_lock);
-
- /*
- * If we did not promote anyone; we need to run the deadlock
- * detector again.
- */
- if (state_changed == 0)
- lt->region->need_dd = 1;
-
- return (0);
-}
-
-static int
-__lock_get_internal(lt, locker, txn, flags, obj, lock_mode, lockp)
- DB_LOCKTAB *lt;
- u_int32_t locker, flags;
- DB_TXN *txn;
- const DBT *obj;
- db_lockmode_t lock_mode;
- struct __db_lock **lockp;
-{
- struct __db_lock *newl, *lp;
- DB_LOCKOBJ *sh_obj, *sh_locker;
- DB_LOCKREGION *lrp;
- size_t newl_off;
- int ihold, no_dd, ret;
-
- no_dd = ret = 0;
-
- /*
- * Check that lock mode is valid.
- */
- lrp = lt->region;
- if ((u_int32_t)lock_mode >= lrp->nmodes) {
- __db_err(lt->dbenv,
- "lock_get: invalid lock mode %lu\n", (u_long)lock_mode);
- return (EINVAL);
- }
-
- /* Allocate a new lock. Optimize for the common case of a grant. */
- if ((newl = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock)) == NULL) {
- if ((ret = __lock_grow_region(lt, DB_LOCK_LOCK, 0)) != 0)
- return (ret);
- lrp = lt->region;
- newl = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
- }
- newl_off = LOCK_TO_OFFSET(lt, newl);
-
- /* Optimize for common case of granting a lock. */
- SH_TAILQ_REMOVE(&lrp->free_locks, newl, links, __db_lock);
-
- newl->mode = lock_mode;
- newl->status = DB_LSTAT_HELD;
- newl->holder = locker;
- newl->refcount = 1;
-
- if ((ret = __lock_getobj(lt, 0, obj, DB_LOCK_OBJTYPE, &sh_obj)) != 0)
- return (ret);
-
- lrp = lt->region; /* getobj might have grown */
- newl = OFFSET_TO_LOCK(lt, newl_off);
-
- /* Now make new lock point to object */
- newl->obj = SH_PTR_TO_OFF(newl, sh_obj);
-
- /*
- * Now we have a lock and an object and we need to see if we should
- * grant the lock. We use a FIFO ordering so we can only grant a
- * new lock if it does not conflict with anyone on the holders list
- * OR anyone on the waiters list. The reason that we don't grant if
- * there's a conflict is that this can lead to starvation (a writer
- * waiting on a popularly read item will never be granted). The
- * downside of this is that a waiting reader can prevent an upgrade
- * from reader to writer, which is not uncommon.
- *
- * There is one exception to the no-conflict rule. If a lock is held
- * by the requesting locker AND the new lock does not conflict with
- * any other holders, then we grant the lock. The most common place
- * this happens is when the holder has a WRITE lock and a READ lock
- * request comes in for the same locker. If we do not grant the read
- * lock, then we guarantee deadlock.
- *
- * In case of conflict, we put the new lock on the end of the waiters
- * list, unless we are upgrading in which case the locker goes on the
- * front of the list.
- */
- ihold = 0;
- for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
- if (locker == lp->holder ||
- __lock_is_parent(lp->holder, txn)) {
- if (lp->mode == lock_mode &&
- lp->status == DB_LSTAT_HELD) {
- if (LF_ISSET(DB_LOCK_UPGRADE))
- goto upgrade;
-
- /*
- * Lock is held, so we can increment the
- * reference count and return this lock.
- */
- lp->refcount++;
- *lockp = lp;
- SH_TAILQ_INSERT_HEAD(&lrp->free_locks,
- newl, links, __db_lock);
- return (0);
- } else
- ihold = 1;
- } else if (CONFLICTS(lt, lp->mode, lock_mode))
- break;
- }
-
- /*
- * If we are upgrading, then there are two scenarios. Either
- * we had no conflicts, so we can do the upgrade. Or, there
- * is a conflict and we should wait at the HEAD of the waiters
- * list.
- */
- if (LF_ISSET(DB_LOCK_UPGRADE)) {
- if (lp == NULL)
- goto upgrade;
-
- /* There was a conflict, wait. */
- SH_TAILQ_INSERT_HEAD(&sh_obj->waiters, newl, links, __db_lock);
- goto wait;
- }
-
- if (lp == NULL && !ihold)
- for (lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
- if (CONFLICTS(lt, lp->mode, lock_mode) &&
- locker != lp->holder)
- break;
- }
- if (lp == NULL)
- SH_TAILQ_INSERT_TAIL(&sh_obj->holders, newl, links);
- else if (!(flags & DB_LOCK_NOWAIT))
- SH_TAILQ_INSERT_TAIL(&sh_obj->waiters, newl, links);
- else {
- /* Free the lock and return an error. */
- newl->status = DB_LSTAT_FREE;
- SH_TAILQ_INSERT_HEAD(&lrp->free_locks, newl, links, __db_lock);
- return (DB_LOCK_NOTGRANTED);
- }
-
- /*
- * Now, insert the lock onto its locker's list. If the locker does
- * not currently hold any locks, there's no reason to run a deadlock
- * detector, save that information.
- */
- if ((ret =
- __lock_getobj(lt, locker, NULL, DB_LOCK_LOCKER, &sh_locker)) != 0)
- return (ret);
- no_dd = SH_LIST_FIRST(&sh_locker->heldby, __db_lock) == NULL;
-
- lrp = lt->region;
- SH_LIST_INSERT_HEAD(&sh_locker->heldby, newl, locker_links, __db_lock);
-
- if (lp != NULL) {
- /*
- * This is really a blocker for the process, so initialize it
- * set. That way the current process will block when it tries
- * to get it and the waking process will release it.
- */
-wait: (void)__db_mutex_init(&newl->mutex,
- MUTEX_LOCK_OFFSET(lt->region, &newl->mutex));
- (void)__db_mutex_lock(&newl->mutex, lt->reginfo.fd);
-
- newl->status = DB_LSTAT_WAITING;
- lrp->nconflicts++;
-
- /*
- * We are about to wait; must release the region mutex. Then,
- * when we wakeup, we need to reacquire the region mutex before
- * continuing.
- */
- if (lrp->detect == DB_LOCK_NORUN)
- lt->region->need_dd = 1;
- UNLOCK_LOCKREGION(lt);
-
- /*
- * We are about to wait; before waiting, see if the deadlock
- * detector should be run.
- */
- if (lrp->detect != DB_LOCK_NORUN && !no_dd)
- (void)lock_detect(lt, 0, lrp->detect);
-
- (void)__db_mutex_lock(&newl->mutex, lt->reginfo.fd);
-
- LOCK_LOCKREGION(lt);
- if (newl->status != DB_LSTAT_PENDING) {
- /*
- * If this lock errored due to a deadlock, then
- * we have waiters that require promotion.
- */
- if (newl->status == DB_LSTAT_ABORTED)
- (void)__lock_promote(lt, sh_obj);
- /* Return to free list. */
- __lock_checklocker(lt, newl, 0);
- SH_TAILQ_INSERT_HEAD(&lrp->free_locks, newl, links,
- __db_lock);
- switch (newl->status) {
- case DB_LSTAT_ABORTED:
- ret = DB_LOCK_DEADLOCK;
- break;
- case DB_LSTAT_NOGRANT:
- ret = DB_LOCK_NOTGRANTED;
- break;
- default:
- ret = EINVAL;
- break;
- }
- newl->status = DB_LSTAT_FREE;
- newl = NULL;
- } else if (LF_ISSET(DB_LOCK_UPGRADE)) {
- /*
- * The lock that was just granted got put on the
- * holders list. Since we're upgrading some other
- * lock, we've got to remove it here.
- */
- SH_TAILQ_REMOVE(&sh_obj->holders,
- newl, links, __db_lock);
- goto upgrade;
- } else
- newl->status = DB_LSTAT_HELD;
- }
-
- *lockp = newl;
- return (ret);
-
-upgrade:
- /*
- * This was an upgrade, so return the new lock to the free list and
- * upgrade the mode.
- */
- (*lockp)->mode = lock_mode;
- newl->status = DB_LSTAT_FREE;
- SH_TAILQ_INSERT_HEAD(&lrp->free_locks, newl, links, __db_lock);
- return (0);
-}
-
-/*
- * __lock_is_locked --
- *
- * PUBLIC: int __lock_is_locked
- * PUBLIC: __P((DB_LOCKTAB *, u_int32_t, DBT *, db_lockmode_t));
- */
-int
-__lock_is_locked(lt, locker, dbt, mode)
- DB_LOCKTAB *lt;
- u_int32_t locker;
- DBT *dbt;
- db_lockmode_t mode;
-{
- struct __db_lock *lp;
- DB_LOCKOBJ *sh_obj;
- DB_LOCKREGION *lrp;
-
- lrp = lt->region;
-
- /* Look up the object in the hash table. */
- HASHLOOKUP(lt->hashtab, __db_lockobj, links,
- dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp);
- if (sh_obj == NULL)
- return (0);
-
- for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock)) {
- if (lp->holder == locker && lp->mode == mode)
- return (1);
- }
-
- return (0);
-}
-
-/*
- * __lock_printlock --
- *
- * PUBLIC: void __lock_printlock __P((DB_LOCKTAB *, struct __db_lock *, int));
- */
-void
-__lock_printlock(lt, lp, ispgno)
- DB_LOCKTAB *lt;
- struct __db_lock *lp;
- int ispgno;
-{
- DB_LOCKOBJ *lockobj;
- db_pgno_t pgno;
- size_t obj;
- u_int8_t *ptr;
- const char *mode, *status;
-
- switch (lp->mode) {
- case DB_LOCK_IREAD:
- mode = "IREAD";
- break;
- case DB_LOCK_IWR:
- mode = "IWR";
- break;
- case DB_LOCK_IWRITE:
- mode = "IWRITE";
- break;
- case DB_LOCK_NG:
- mode = "NG";
- break;
- case DB_LOCK_READ:
- mode = "READ";
- break;
- case DB_LOCK_WRITE:
- mode = "WRITE";
- break;
- default:
- mode = "UNKNOWN";
- break;
- }
- switch (lp->status) {
- case DB_LSTAT_ABORTED:
- status = "ABORT";
- break;
- case DB_LSTAT_ERR:
- status = "ERROR";
- break;
- case DB_LSTAT_FREE:
- status = "FREE";
- break;
- case DB_LSTAT_HELD:
- status = "HELD";
- break;
- case DB_LSTAT_NOGRANT:
- status = "NONE";
- break;
- case DB_LSTAT_WAITING:
- status = "WAIT";
- break;
- case DB_LSTAT_PENDING:
- status = "PENDING";
- break;
- default:
- status = "UNKNOWN";
- break;
- }
- printf("\t%lx\t%s\t%lu\t%s\t",
- (u_long)lp->holder, mode, (u_long)lp->refcount, status);
-
- lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
- ptr = SH_DBT_PTR(&lockobj->lockobj);
- if (ispgno) {
- /* Assume this is a DBT lock. */
- memcpy(&pgno, ptr, sizeof(db_pgno_t));
- printf("page %lu\n", (u_long)pgno);
- } else {
- obj = (u_int8_t *)lp + lp->obj - (u_int8_t *)lt->region;
- printf("0x%lx ", (u_long)obj);
- __db_pr(ptr, lockobj->lockobj.size);
- printf("\n");
- }
-}
-
-/*
- * PUBLIC: int __lock_getobj __P((DB_LOCKTAB *,
- * PUBLIC: u_int32_t, const DBT *, u_int32_t type, DB_LOCKOBJ **));
- */
-int
-__lock_getobj(lt, locker, dbt, type, objp)
- DB_LOCKTAB *lt;
- u_int32_t locker, type;
- const DBT *dbt;
- DB_LOCKOBJ **objp;
-{
- DB_LOCKREGION *lrp;
- DB_LOCKOBJ *sh_obj;
- u_int32_t obj_size;
- int ret;
- void *p, *src;
-
- lrp = lt->region;
-
- /* Look up the object in the hash table. */
- if (type == DB_LOCK_OBJTYPE) {
- HASHLOOKUP(lt->hashtab, __db_lockobj, links, dbt, sh_obj,
- lrp->table_size, __lock_ohash, __lock_cmp);
- obj_size = dbt->size;
- } else {
- HASHLOOKUP(lt->hashtab, __db_lockobj, links, locker,
- sh_obj, lrp->table_size, __lock_locker_hash,
- __lock_locker_cmp);
- obj_size = sizeof(locker);
- }
-
- /*
- * If we found the object, then we can just return it. If
- * we didn't find the object, then we need to create it.
- */
- if (sh_obj == NULL) {
- /* Create new object and then insert it into hash table. */
- if ((sh_obj =
- SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj)) == NULL) {
- if ((ret = __lock_grow_region(lt, DB_LOCK_OBJ, 0)) != 0)
- return (ret);
- lrp = lt->region;
- sh_obj = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
- }
-
- /*
- * If we can fit this object in the structure, do so instead
- * of shalloc-ing space for it.
- */
- if (obj_size <= sizeof(sh_obj->objdata))
- p = sh_obj->objdata;
- else
- if ((ret =
- __db_shalloc(lt->mem, obj_size, 0, &p)) != 0) {
- if ((ret = __lock_grow_region(lt,
- DB_LOCK_MEM, obj_size)) != 0)
- return (ret);
- lrp = lt->region;
- /* Reacquire the head of the list. */
- sh_obj = SH_TAILQ_FIRST(&lrp->free_objs,
- __db_lockobj);
- (void)__db_shalloc(lt->mem, obj_size, 0, &p);
- }
-
- src = type == DB_LOCK_OBJTYPE ? dbt->data : (void *)&locker;
- memcpy(p, src, obj_size);
-
- sh_obj->type = type;
- SH_TAILQ_REMOVE(&lrp->free_objs, sh_obj, links, __db_lockobj);
-
- SH_TAILQ_INIT(&sh_obj->waiters);
- if (type == DB_LOCK_LOCKER)
- SH_LIST_INIT(&sh_obj->heldby);
- else
- SH_TAILQ_INIT(&sh_obj->holders);
- sh_obj->lockobj.size = obj_size;
- sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p);
-
- HASHINSERT(lt->hashtab,
- __db_lockobj, links, sh_obj, lrp->table_size, __lock_lhash);
-
- if (type == DB_LOCK_LOCKER)
- lrp->nlockers++;
- }
-
- *objp = sh_obj;
- return (0);
-}
-
-/*
- * Any lock on the waitlist has a process waiting for it. Therefore, we
- * can't return the lock to the freelist immediately. Instead, we can
- * remove the lock from the list of waiters, set the status field of the
- * lock, and then let the process waking up return the lock to the
- * free list.
- */
-static void
-__lock_remove_waiter(lt, sh_obj, lockp, status)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *sh_obj;
- struct __db_lock *lockp;
- db_status_t status;
-{
- SH_TAILQ_REMOVE(&sh_obj->waiters, lockp, links, __db_lock);
- lockp->status = status;
-
- /* Wake whoever is waiting on this lock. */
- (void)__db_mutex_unlock(&lockp->mutex, lt->reginfo.fd);
-}
-
-static void
-__lock_checklocker(lt, lockp, do_remove)
- DB_LOCKTAB *lt;
- struct __db_lock *lockp;
- int do_remove;
-{
- DB_LOCKOBJ *sh_locker;
-
- if (do_remove)
- SH_LIST_REMOVE(lockp, locker_links, __db_lock);
-
- /* if the locker list is NULL, free up the object. */
- if (__lock_getobj(lt, lockp->holder, NULL, DB_LOCK_LOCKER, &sh_locker)
- == 0 && SH_LIST_FIRST(&sh_locker->heldby, __db_lock) == NULL) {
- __lock_freeobj(lt, sh_locker);
- lt->region->nlockers--;
- }
-}
-
-static void
-__lock_freeobj(lt, obj)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *obj;
-{
- HASHREMOVE_EL(lt->hashtab,
- __db_lockobj, links, obj, lt->region->table_size, __lock_lhash);
- if (obj->lockobj.size > sizeof(obj->objdata))
- __db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj));
- SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, obj, links, __db_lockobj);
-}
-
-/*
- * __lock_downgrade --
- * Used by the concurrent access product to downgrade write locks
- * back to iwrite locks.
- *
- * PUBLIC: int __lock_downgrade __P((DB_LOCKTAB *,
- * PUBLIC: DB_LOCK, db_lockmode_t, u_int32_t));
- */
-int
-__lock_downgrade(lt, lock, new_mode, flags)
- DB_LOCKTAB *lt;
- DB_LOCK lock;
- db_lockmode_t new_mode;
- u_int32_t flags;
-{
- struct __db_lock *lockp;
- DB_LOCKOBJ *obj;
- int ret;
-
- COMPQUIET(flags, 0);
- LOCK_PANIC_CHECK(lt);
- LOCK_LOCKREGION(lt);
-
- if ((ret = __lock_validate_region(lt)) == 0) {
- lockp = OFFSET_TO_LOCK(lt, lock);
- lockp->mode = new_mode;
-
- /* Get the object associated with this lock. */
- obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj);
- (void)__lock_promote(lt, obj);
- ++lt->region->nreleases;
- }
-
- UNLOCK_LOCKREGION(lt);
-
- return (ret);
-}
-
-/*
- * __lock_promote --
- *
- * Look through the waiters and holders lists and decide which (if any)
- * locks can be promoted. Promote any that are eligible.
- */
-static int
-__lock_promote(lt, obj)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *obj;
-{
- struct __db_lock *lp_w, *lp_h, *next_waiter;
- int state_changed, waiter_is_txn;
-
- /*
- * We need to do lock promotion. We also need to determine if
- * we're going to need to run the deadlock detector again. If
- * we release locks, and there are waiters, but no one gets promoted,
- * then we haven't fundamentally changed the lockmgr state, so
- * we may still have a deadlock and we have to run again. However,
- * if there were no waiters, or we actually promoted someone, then
- * we are OK and we don't have to run it immediately.
- *
- * During promotion, we look for state changes so we can return
- * this information to the caller.
- */
- for (lp_w = SH_TAILQ_FIRST(&obj->waiters, __db_lock),
- state_changed = lp_w == NULL;
- lp_w != NULL;
- lp_w = next_waiter) {
- waiter_is_txn = TXN_IS_HOLDING(lp_w);
- next_waiter = SH_TAILQ_NEXT(lp_w, links, __db_lock);
- for (lp_h = SH_TAILQ_FIRST(&obj->holders, __db_lock);
- lp_h != NULL;
- lp_h = SH_TAILQ_NEXT(lp_h, links, __db_lock)) {
- if (CONFLICTS(lt, lp_h->mode, lp_w->mode) &&
- lp_h->holder != lp_w->holder &&
- !(waiter_is_txn &&
- TXN_IS_HOLDING(lp_h) &&
- __txn_is_ancestor(lt->dbenv->tx_info,
- lp_h->txnoff, lp_w->txnoff)))
- break;
- }
- if (lp_h != NULL) /* Found a conflict. */
- break;
-
- /* No conflict, promote the waiting lock. */
- SH_TAILQ_REMOVE(&obj->waiters, lp_w, links, __db_lock);
- lp_w->status = DB_LSTAT_PENDING;
- SH_TAILQ_INSERT_TAIL(&obj->holders, lp_w, links);
-
- /* Wake up waiter. */
- (void)__db_mutex_unlock(&lp_w->mutex, lt->reginfo.fd);
- state_changed = 1;
- }
-
- return (state_changed);
-}
-
-static int
-__lock_is_parent(locker, txn)
- u_int32_t locker;
- DB_TXN *txn;
-{
- DB_TXN *t;
-
- if (txn == NULL)
- return (0);
-
- for (t = txn->parent; t != NULL; t = t->parent)
- if (t->txnid == locker)
- return (1);
-
- return (0);
-}
diff --git a/db2/lock/lock_conflict.c b/db2/lock/lock_conflict.c
deleted file mode 100644
index 4be858a..0000000
--- a/db2/lock/lock_conflict.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)lock_conflict.c 10.4 (Sleepycat) 11/20/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * The conflict arrays are set up such that the row is the lock you
- * are holding and the column is the lock that is desired.
- */
-const u_int8_t db_rw_conflicts[] = {
- /* N R W */
- /* N */ 0, 0, 0,
- /* R */ 0, 0, 1,
- /* W */ 0, 1, 1
-};
-
-const u_int8_t db_riw_conflicts[] = {
- /* N S X IX IS SIX */
- /* N */ 0, 0, 0, 0, 0, 0,
- /* S */ 0, 0, 1, 1, 0, 1,
- /* X */ 1, 1, 1, 1, 1, 1,
- /* IX */ 0, 1, 1, 0, 0, 0,
- /* IS */ 0, 0, 1, 0, 0, 0,
- /* SIX */ 0, 1, 1, 0, 0, 0
-};
diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c
deleted file mode 100644
index 8b2f91b..0000000
--- a/db2/lock/lock_deadlock.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)lock_deadlock.c 10.37 (Sleepycat) 10/4/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "common_ext.h"
-
-#define ISSET_MAP(M, N) (M[(N) / 32] & (1 << (N) % 32))
-
-#define CLEAR_MAP(M, N) { \
- u_int32_t __i; \
- for (__i = 0; __i < (N); __i++) \
- M[__i] = 0; \
-}
-
-#define SET_MAP(M, B) (M[(B) / 32] |= (1 << ((B) % 32)))
-#define CLR_MAP(M, B) (M[(B) / 32] &= ~(1 << ((B) % 32)))
-
-#define OR_MAP(D, S, N) { \
- u_int32_t __i; \
- for (__i = 0; __i < (N); __i++) \
- D[__i] |= S[__i]; \
-}
-#define BAD_KILLID 0xffffffff
-
-typedef struct {
- int valid;
- u_int32_t id;
- DB_LOCK last_lock;
- db_pgno_t pgno;
-} locker_info;
-
-static int __dd_abort __P((DB_ENV *, locker_info *));
-static int __dd_build
- __P((DB_ENV *, u_int32_t **, u_int32_t *, locker_info **));
-static u_int32_t
- *__dd_find __P((u_int32_t *, locker_info *, u_int32_t));
-
-#ifdef DIAGNOSTIC
-static void __dd_debug __P((DB_ENV *, locker_info *, u_int32_t *, u_int32_t));
-#endif
-
-int
-lock_detect(lt, flags, atype)
- DB_LOCKTAB *lt;
- u_int32_t flags, atype;
-{
- DB_ENV *dbenv;
- locker_info *idmap;
- u_int32_t *bitmap, *deadlock, i, killid, nentries, nlockers;
- int do_pass, ret;
-
- LOCK_PANIC_CHECK(lt);
-
- /* Validate arguments. */
- if ((ret =
- __db_fchk(lt->dbenv, "lock_detect", flags, DB_LOCK_CONFLICT)) != 0)
- return (ret);
-
- /* Check if a detector run is necessary. */
- dbenv = lt->dbenv;
- if (LF_ISSET(DB_LOCK_CONFLICT)) {
- /* Make a pass every time a lock waits. */
- LOCK_LOCKREGION(lt);
- do_pass = dbenv->lk_info->region->need_dd != 0;
- UNLOCK_LOCKREGION(lt);
-
- if (!do_pass)
- return (0);
- }
-
- /* Build the waits-for bitmap. */
- if ((ret = __dd_build(dbenv, &bitmap, &nlockers, &idmap)) != 0)
- return (ret);
-
- if (nlockers == 0)
- return (0);
-#ifdef DIAGNOSTIC
- if (dbenv->db_verbose != 0)
- __dd_debug(dbenv, idmap, bitmap, nlockers);
-#endif
- /* Find a deadlock. */
- deadlock = __dd_find(bitmap, idmap, nlockers);
- nentries = ALIGN(nlockers, 32) / 32;
- killid = BAD_KILLID;
- if (deadlock != NULL) {
- /* Kill someone. */
- switch (atype) {
- case DB_LOCK_OLDEST:
- /*
- * Find the first bit set in the current
- * array and then look for a lower tid in
- * the array.
- */
- for (i = 0; i < nlockers; i++)
- if (ISSET_MAP(deadlock, i))
- killid = i;
-
- if (killid == BAD_KILLID) {
- __db_err(dbenv,
- "warning: could not find locker to abort");
- break;
- }
-
- /*
- * The oldest transaction has the lowest
- * transaction id.
- */
- for (i = killid + 1; i < nlockers; i++)
- if (ISSET_MAP(deadlock, i) &&
- idmap[i].id < idmap[killid].id)
- killid = i;
- break;
- case DB_LOCK_DEFAULT:
- case DB_LOCK_RANDOM:
- /*
- * We are trying to calculate the id of the
- * locker whose entry is indicated by deadlock.
- */
- killid = (deadlock - bitmap) / nentries;
- break;
- case DB_LOCK_YOUNGEST:
- /*
- * Find the first bit set in the current
- * array and then look for a lower tid in
- * the array.
- */
- for (i = 0; i < nlockers; i++)
- if (ISSET_MAP(deadlock, i))
- killid = i;
-
- if (killid == BAD_KILLID) {
- __db_err(dbenv,
- "warning: could not find locker to abort");
- break;
- }
- /*
- * The youngest transaction has the highest
- * transaction id.
- */
- for (i = killid + 1; i < nlockers; i++)
- if (ISSET_MAP(deadlock, i) &&
- idmap[i].id > idmap[killid].id)
- killid = i;
- break;
- default:
- killid = BAD_KILLID;
- ret = EINVAL;
- }
-
- /* Kill the locker with lockid idmap[killid]. */
- if (dbenv->db_verbose != 0 && killid != BAD_KILLID)
- __db_err(dbenv, "Aborting locker %lx",
- (u_long)idmap[killid].id);
-
- if (killid != BAD_KILLID &&
- (ret = __dd_abort(dbenv, &idmap[killid])) != 0)
- __db_err(dbenv,
- "warning: unable to abort locker %lx",
- (u_long)idmap[killid].id);
- }
- __os_free(bitmap, 0);
- __os_free(idmap, 0);
-
- return (ret);
-}
-
-/*
- * ========================================================================
- * Utilities
- */
-static int
-__dd_build(dbenv, bmp, nlockers, idmap)
- DB_ENV *dbenv;
- u_int32_t **bmp, *nlockers;
- locker_info **idmap;
-{
- struct __db_lock *lp;
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *op, *lo, *lockerp;
- u_int8_t *pptr;
- locker_info *id_array;
- u_int32_t *bitmap, count, *entryp, i, id, nentries, *tmpmap;
- int is_first, ret;
-
- lt = dbenv->lk_info;
-
- /*
- * We'll check how many lockers there are, add a few more in for
- * good measure and then allocate all the structures. Then we'll
- * verify that we have enough room when we go back in and get the
- * mutex the second time.
- */
- LOCK_LOCKREGION(lt);
-retry: count = lt->region->nlockers;
- lt->region->need_dd = 0;
- UNLOCK_LOCKREGION(lt);
-
- if (count == 0) {
- *nlockers = 0;
- return (0);
- }
-
- if (dbenv->db_verbose)
- __db_err(dbenv, "%lu lockers", (u_long)count);
-
- count += 10;
- nentries = ALIGN(count, 32) / 32;
- /*
- * Allocate enough space for a count by count bitmap matrix.
- *
- * XXX
- * We can probably save the malloc's between iterations just
- * reallocing if necessary because count grew by too much.
- */
- if ((ret = __os_calloc((size_t)count,
- sizeof(u_int32_t) * nentries, &bitmap)) != 0)
- return (ret);
-
- if ((ret = __os_calloc(sizeof(u_int32_t), nentries, &tmpmap)) != 0) {
- __os_free(bitmap, sizeof(u_int32_t) * nentries);
- return (ret);
- }
-
- if ((ret =
- __os_calloc((size_t)count, sizeof(locker_info), &id_array)) != 0) {
- __os_free(bitmap, count * sizeof(u_int32_t) * nentries);
- __os_free(tmpmap, sizeof(u_int32_t) * nentries);
- return (ret);
- }
-
- /*
- * Now go back in and actually fill in the matrix.
- */
- LOCK_LOCKREGION(lt);
- if (lt->region->nlockers > count) {
- __os_free(bitmap, count * sizeof(u_int32_t) * nentries);
- __os_free(tmpmap, sizeof(u_int32_t) * nentries);
- __os_free(id_array, count * sizeof(locker_info));
- goto retry;
- }
-
- /*
- * First we go through and assign each locker a deadlock detector id.
- * Note that we fill in the idmap in the next loop since that's the
- * only place where we conveniently have both the deadlock id and the
- * actual locker.
- */
- for (id = 0, i = 0; i < lt->region->table_size; i++)
- for (op = SH_TAILQ_FIRST(&lt->hashtab[i], __db_lockobj);
- op != NULL; op = SH_TAILQ_NEXT(op, links, __db_lockobj))
- if (op->type == DB_LOCK_LOCKER)
- op->dd_id = id++;
- /*
- * We go through the hash table and find each object. For each object,
- * we traverse the waiters list and add an entry in the waitsfor matrix
- * for each waiter/holder combination.
- */
- for (i = 0; i < lt->region->table_size; i++) {
- for (op = SH_TAILQ_FIRST(&lt->hashtab[i], __db_lockobj);
- op != NULL; op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {
- if (op->type != DB_LOCK_OBJTYPE)
- continue;
- CLEAR_MAP(tmpmap, nentries);
-
- /*
- * First we go through and create a bit map that
- * represents all the holders of this object.
- */
- for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
- if (__lock_getobj(lt, lp->holder,
- NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
- __db_err(dbenv,
- "warning unable to find object");
- continue;
- }
- id_array[lockerp->dd_id].id = lp->holder;
- id_array[lockerp->dd_id].valid = 1;
-
- /*
- * If the holder has already been aborted, then
- * we should ignore it for now.
- */
- if (lp->status == DB_LSTAT_HELD)
- SET_MAP(tmpmap, lockerp->dd_id);
- }
-
- /*
- * Next, for each waiter, we set its row in the matrix
- * equal to the map of holders we set up above.
- */
- for (is_first = 1,
- lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);
- lp != NULL;
- is_first = 0,
- lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
- if (__lock_getobj(lt, lp->holder,
- NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
- __db_err(dbenv,
- "warning unable to find object");
- continue;
- }
- id_array[lockerp->dd_id].id = lp->holder;
- id_array[lockerp->dd_id].valid = 1;
-
- /*
- * If the transaction is pending abortion, then
- * ignore it on this iteration.
- */
- if (lp->status != DB_LSTAT_WAITING)
- continue;
-
- entryp = bitmap + (nentries * lockerp->dd_id);
- OR_MAP(entryp, tmpmap, nentries);
- /*
- * If this is the first waiter on the queue,
- * then we remove the waitsfor relationship
- * with oneself. However, if it's anywhere
- * else on the queue, then we have to keep
- * it and we have an automatic deadlock.
- */
- if (is_first)
- CLR_MAP(entryp, lockerp->dd_id);
- }
- }
- }
-
- /* Now for each locker; record its last lock. */
- for (id = 0; id < count; id++) {
- if (!id_array[id].valid)
- continue;
- if (__lock_getobj(lt,
- id_array[id].id, NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
- __db_err(dbenv,
- "No locks for locker %lu", (u_long)id_array[id].id);
- continue;
- }
- lp = SH_LIST_FIRST(&lockerp->heldby, __db_lock);
- if (lp != NULL) {
- id_array[id].last_lock = LOCK_TO_OFFSET(lt, lp);
- lo = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
- pptr = SH_DBT_PTR(&lo->lockobj);
- if (lo->lockobj.size >= sizeof(db_pgno_t))
- memcpy(&id_array[id].pgno, pptr,
- sizeof(db_pgno_t));
- else
- id_array[id].pgno = 0;
- }
- }
-
- /* Pass complete, reset the deadlock detector bit. */
- lt->region->need_dd = 0;
- UNLOCK_LOCKREGION(lt);
-
- /*
- * Now we can release everything except the bitmap matrix that we
- * created.
- */
- *nlockers = id;
- *idmap = id_array;
- *bmp = bitmap;
- __os_free(tmpmap, sizeof(u_int32_t) * nentries);
- return (0);
-}
-
-static u_int32_t *
-__dd_find(bmp, idmap, nlockers)
- u_int32_t *bmp, nlockers;
- locker_info *idmap;
-{
- u_int32_t i, j, nentries, *mymap, *tmpmap;
-
- /*
- * For each locker, OR in the bits from the lockers on which that
- * locker is waiting.
- */
- nentries = ALIGN(nlockers, 32) / 32;
- for (mymap = bmp, i = 0; i < nlockers; i++, mymap += nentries) {
- if (!idmap[i].valid)
- continue;
- for (j = 0; j < nlockers; j++) {
- if (ISSET_MAP(mymap, j)) {
- /* Find the map for this bit. */
- tmpmap = bmp + (nentries * j);
- OR_MAP(mymap, tmpmap, nentries);
- if (ISSET_MAP(mymap, i))
- return (mymap);
- }
- }
- }
- return (NULL);
-}
-
-static int
-__dd_abort(dbenv, info)
- DB_ENV *dbenv;
- locker_info *info;
-{
- struct __db_lock *lockp;
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *lockerp, *sh_obj;
- int ret;
-
- lt = dbenv->lk_info;
- LOCK_LOCKREGION(lt);
-
- /* Find the locker's last lock. */
- if ((ret =
- __lock_getobj(lt, info->id, NULL, DB_LOCK_LOCKER, &lockerp)) != 0)
- goto out;
-
- lockp = SH_LIST_FIRST(&lockerp->heldby, __db_lock);
-
- /*
- * It's possible that this locker was already aborted.
- * If that's the case, make sure that we remove its
- * locker from the hash table.
- */
- if (lockp == NULL) {
- HASHREMOVE_EL(lt->hashtab, __db_lockobj,
- links, lockerp, lt->region->table_size, __lock_lhash);
- SH_TAILQ_INSERT_HEAD(&lt->region->free_objs,
- lockerp, links, __db_lockobj);
- lt->region->nlockers--;
- goto out;
- } else if (LOCK_TO_OFFSET(lt, lockp) != info->last_lock ||
- lockp->status != DB_LSTAT_WAITING)
- goto out;
-
- /* Abort lock, take it off list, and wake up this lock. */
- lockp->status = DB_LSTAT_ABORTED;
- lt->region->ndeadlocks++;
- SH_LIST_REMOVE(lockp, locker_links, __db_lock);
- sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj);
- SH_TAILQ_REMOVE(&sh_obj->waiters, lockp, links, __db_lock);
- (void)__db_mutex_unlock(&lockp->mutex, lt->reginfo.fd);
-
- ret = 0;
-
-out: UNLOCK_LOCKREGION(lt);
- return (ret);
-}
-
-#ifdef DIAGNOSTIC
-static void
-__dd_debug(dbenv, idmap, bitmap, nlockers)
- DB_ENV *dbenv;
- locker_info *idmap;
- u_int32_t *bitmap, nlockers;
-{
- u_int32_t i, j, *mymap, nentries;
- int ret;
- char *msgbuf;
-
- __db_err(dbenv, "Waitsfor array");
- __db_err(dbenv, "waiter\twaiting on");
-
- /* Allocate space to print 10 bytes per item waited on. */
-#undef MSGBUF_LEN
-#define MSGBUF_LEN ((nlockers + 1) * 10 + 64)
- if ((ret = __os_malloc(MSGBUF_LEN, NULL, &msgbuf)) != 0)
- return;
-
- nentries = ALIGN(nlockers, 32) / 32;
- for (mymap = bitmap, i = 0; i < nlockers; i++, mymap += nentries) {
- if (!idmap[i].valid)
- continue;
- sprintf(msgbuf, /* Waiter. */
- "%lx/%lu:\t", (u_long)idmap[i].id, (u_long)idmap[i].pgno);
- for (j = 0; j < nlockers; j++)
- if (ISSET_MAP(mymap, j))
- sprintf(msgbuf, "%s %lx", msgbuf,
- (u_long)idmap[j].id);
- (void)sprintf(msgbuf,
- "%s %lu", msgbuf, (u_long)idmap[i].last_lock);
- __db_err(dbenv, msgbuf);
- }
-
- __os_free(msgbuf, MSGBUF_LEN);
-}
-#endif
diff --git a/db2/lock/lock_region.c b/db2/lock/lock_region.c
deleted file mode 100644
index 613a6ce..0000000
--- a/db2/lock/lock_region.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)lock_region.c 10.21 (Sleepycat) 10/19/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "common_ext.h"
-
-static u_int32_t __lock_count_locks __P((DB_LOCKREGION *));
-static u_int32_t __lock_count_objs __P((DB_LOCKREGION *));
-static void __lock_dump_locker __P((DB_LOCKTAB *, DB_LOCKOBJ *, FILE *));
-static void __lock_dump_object __P((DB_LOCKTAB *, DB_LOCKOBJ *, FILE *));
-static const char *
- __lock_dump_status __P((db_status_t));
-static void __lock_reset_region __P((DB_LOCKTAB *));
-static int __lock_tabinit __P((DB_ENV *, DB_LOCKREGION *));
-
-int
-lock_open(path, flags, mode, dbenv, ltp)
- const char *path;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_LOCKTAB **ltp;
-{
- DB_LOCKTAB *lt;
- u_int32_t lock_modes, maxlocks, regflags;
- int ret;
-
- /* Validate arguments. */
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_THREAD)
-#else
-#define OKFLAGS (DB_CREATE)
-#endif
- if ((ret = __db_fchk(dbenv, "lock_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- /* Create the lock table structure. */
- if ((ret = __os_calloc(1, sizeof(DB_LOCKTAB), &lt)) != 0)
- return (ret);
- lt->dbenv = dbenv;
-
- /* Grab the values that we need to compute the region size. */
- lock_modes = DB_LOCK_RW_N;
- maxlocks = DB_LOCK_DEFAULT_N;
- regflags = REGION_SIZEDEF;
- if (dbenv != NULL) {
- if (dbenv->lk_modes != 0) {
- lock_modes = dbenv->lk_modes;
- regflags = 0;
- }
- if (dbenv->lk_max != 0) {
- maxlocks = dbenv->lk_max;
- regflags = 0;
- }
- }
-
- /* Join/create the lock region. */
- lt->reginfo.dbenv = dbenv;
- lt->reginfo.appname = DB_APP_NONE;
- if (path == NULL)
- lt->reginfo.path = NULL;
- else
- if ((ret = __os_strdup(path, &lt->reginfo.path)) != 0)
- goto err;
- lt->reginfo.file = DB_DEFAULT_LOCK_FILE;
- lt->reginfo.mode = mode;
- lt->reginfo.size =
- LOCK_REGION_SIZE(lock_modes, maxlocks, __db_tablesize(maxlocks));
- lt->reginfo.dbflags = flags;
- lt->reginfo.addr = NULL;
- lt->reginfo.fd = -1;
- lt->reginfo.flags = regflags;
-
- if ((ret = __db_rattach(&lt->reginfo)) != 0)
- goto err;
-
- /* Now set up the pointer to the region. */
- lt->region = lt->reginfo.addr;
-
- /* Initialize the region if we created it. */
- if (F_ISSET(&lt->reginfo, REGION_CREATED)) {
- lt->region->maxlocks = maxlocks;
- lt->region->nmodes = lock_modes;
- if ((ret = __lock_tabinit(dbenv, lt->region)) != 0)
- goto err;
- } else {
- /* Check for an unexpected region. */
- if (lt->region->magic != DB_LOCKMAGIC) {
- __db_err(dbenv,
- "lock_open: %s: bad magic number", path);
- ret = EINVAL;
- goto err;
- }
- }
-
- /* Check for automatic deadlock detection. */
- if (dbenv != NULL && dbenv->lk_detect != DB_LOCK_NORUN) {
- if (lt->region->detect != DB_LOCK_NORUN &&
- dbenv->lk_detect != DB_LOCK_DEFAULT &&
- lt->region->detect != dbenv->lk_detect) {
- __db_err(dbenv,
- "lock_open: incompatible deadlock detector mode");
- ret = EINVAL;
- goto err;
- }
- if (lt->region->detect == DB_LOCK_NORUN)
- lt->region->detect = dbenv->lk_detect;
- }
-
- /* Set up remaining pointers into region. */
- lt->conflicts = (u_int8_t *)lt->region + sizeof(DB_LOCKREGION);
- lt->hashtab =
- (DB_HASHTAB *)((u_int8_t *)lt->region + lt->region->hash_off);
- lt->mem = (void *)((u_int8_t *)lt->region + lt->region->mem_off);
-
- UNLOCK_LOCKREGION(lt);
- *ltp = lt;
- return (0);
-
-err: if (lt->reginfo.addr != NULL) {
- UNLOCK_LOCKREGION(lt);
- (void)__db_rdetach(&lt->reginfo);
- if (F_ISSET(&lt->reginfo, REGION_CREATED))
- (void)lock_unlink(path, 1, dbenv);
- }
-
- if (lt->reginfo.path != NULL)
- __os_freestr(lt->reginfo.path);
- __os_free(lt, sizeof(*lt));
- return (ret);
-}
-
-/*
- * __lock_panic --
- * Panic a lock region.
- *
- * PUBLIC: void __lock_panic __P((DB_ENV *));
- */
-void
-__lock_panic(dbenv)
- DB_ENV *dbenv;
-{
- if (dbenv->lk_info != NULL)
- dbenv->lk_info->region->hdr.panic = 1;
-}
-
-
-/*
- * __lock_tabinit --
- * Initialize the lock region.
- */
-static int
-__lock_tabinit(dbenv, lrp)
- DB_ENV *dbenv;
- DB_LOCKREGION *lrp;
-{
- struct __db_lock *lp;
- struct lock_header *tq_head;
- struct obj_header *obj_head;
- DB_LOCKOBJ *op;
- u_int32_t i, nelements;
- const u_int8_t *conflicts;
- u_int8_t *curaddr;
-
- conflicts = dbenv == NULL || dbenv->lk_conflicts == NULL ?
- db_rw_conflicts : dbenv->lk_conflicts;
-
- lrp->table_size = __db_tablesize(lrp->maxlocks);
- lrp->magic = DB_LOCKMAGIC;
- lrp->version = DB_LOCKVERSION;
- lrp->id = 0;
- /*
- * These fields (lrp->maxlocks, lrp->nmodes) are initialized
- * in the caller, since we had to grab those values to size
- * the region.
- */
- lrp->need_dd = 0;
- lrp->detect = DB_LOCK_NORUN;
- lrp->numobjs = lrp->maxlocks;
- lrp->nlockers = 0;
- lrp->mem_bytes = ALIGN(STRING_SIZE(lrp->maxlocks), sizeof(size_t));
- lrp->increment = lrp->hdr.size / 2;
- lrp->nconflicts = 0;
- lrp->nrequests = 0;
- lrp->nreleases = 0;
- lrp->ndeadlocks = 0;
-
- /*
- * As we write the region, we've got to maintain the alignment
- * for the structures that follow each chunk. This information
- * ends up being encapsulated both in here as well as in the
- * lock.h file for the XXX_SIZE macros.
- */
- /* Initialize conflict matrix. */
- curaddr = (u_int8_t *)lrp + sizeof(DB_LOCKREGION);
- memcpy(curaddr, conflicts, lrp->nmodes * lrp->nmodes);
- curaddr += lrp->nmodes * lrp->nmodes;
-
- /*
- * Initialize hash table.
- */
- curaddr = (u_int8_t *)ALIGNP(curaddr, LOCK_HASH_ALIGN);
- lrp->hash_off = curaddr - (u_int8_t *)lrp;
- nelements = lrp->table_size;
- __db_hashinit(curaddr, nelements);
- curaddr += nelements * sizeof(DB_HASHTAB);
-
- /*
- * Initialize locks onto a free list. Since locks contains mutexes,
- * we need to make sure that each lock is aligned on a MUTEX_ALIGNMENT
- * boundary.
- */
- curaddr = (u_int8_t *)ALIGNP(curaddr, MUTEX_ALIGNMENT);
- tq_head = &lrp->free_locks;
- SH_TAILQ_INIT(tq_head);
-
- for (i = 0; i++ < lrp->maxlocks;
- curaddr += ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT)) {
- lp = (struct __db_lock *)curaddr;
- lp->status = DB_LSTAT_FREE;
- SH_TAILQ_INSERT_HEAD(tq_head, lp, links, __db_lock);
- }
-
- /* Initialize objects onto a free list. */
- obj_head = &lrp->free_objs;
- SH_TAILQ_INIT(obj_head);
-
- for (i = 0; i++ < lrp->maxlocks; curaddr += sizeof(DB_LOCKOBJ)) {
- op = (DB_LOCKOBJ *)curaddr;
- SH_TAILQ_INSERT_HEAD(obj_head, op, links, __db_lockobj);
- }
-
- /*
- * Initialize the string space; as for all shared memory allocation
- * regions, this requires size_t alignment, since we store the
- * lengths of malloc'd areas in the area.
- */
- curaddr = (u_int8_t *)ALIGNP(curaddr, sizeof(size_t));
- lrp->mem_off = curaddr - (u_int8_t *)lrp;
- __db_shalloc_init(curaddr, lrp->mem_bytes);
- return (0);
-}
-
-int
-lock_close(lt)
- DB_LOCKTAB *lt;
-{
- int ret;
-
- LOCK_PANIC_CHECK(lt);
-
- if ((ret = __db_rdetach(&lt->reginfo)) != 0)
- return (ret);
-
- if (lt->reginfo.path != NULL)
- __os_freestr(lt->reginfo.path);
- __os_free(lt, sizeof(*lt));
-
- return (0);
-}
-
-int
-lock_unlink(path, force, dbenv)
- const char *path;
- int force;
- DB_ENV *dbenv;
-{
- REGINFO reginfo;
- int ret;
-
- memset(&reginfo, 0, sizeof(reginfo));
- reginfo.dbenv = dbenv;
- reginfo.appname = DB_APP_NONE;
- if (path != NULL && (ret = __os_strdup(path, &reginfo.path)) != 0)
- return (ret);
- reginfo.file = DB_DEFAULT_LOCK_FILE;
- ret = __db_runlink(&reginfo, force);
- if (reginfo.path != NULL)
- __os_freestr(reginfo.path);
- return (ret);
-}
-
-/*
- * __lock_validate_region --
- * Called at every interface to verify if the region has changed size,
- * and if so, to remap the region in and reset the process' pointers.
- *
- * PUBLIC: int __lock_validate_region __P((DB_LOCKTAB *));
- */
-int
-__lock_validate_region(lt)
- DB_LOCKTAB *lt;
-{
- int ret;
-
- if (lt->reginfo.size == lt->region->hdr.size)
- return (0);
-
- /* Detach/reattach the region. */
- if ((ret = __db_rreattach(&lt->reginfo, lt->region->hdr.size)) != 0)
- return (ret);
-
- /* Reset region information. */
- lt->region = lt->reginfo.addr;
- __lock_reset_region(lt);
-
- return (0);
-}
-
-/*
- * __lock_grow_region --
- * We have run out of space; time to grow the region.
- *
- * PUBLIC: int __lock_grow_region __P((DB_LOCKTAB *, int, size_t));
- */
-int
-__lock_grow_region(lt, which, howmuch)
- DB_LOCKTAB *lt;
- int which;
- size_t howmuch;
-{
- struct __db_lock *newl;
- struct lock_header *lock_head;
- struct obj_header *obj_head;
- DB_LOCKOBJ *op;
- DB_LOCKREGION *lrp;
- float lock_ratio, obj_ratio;
- size_t incr, oldsize, used, usedmem;
- u_int32_t i, newlocks, newmem, newobjs, usedlocks, usedobjs;
- u_int8_t *curaddr;
- int ret;
-
- lrp = lt->region;
- oldsize = lrp->hdr.size;
- incr = lrp->increment;
-
- /* Figure out how much of each sort of space we have. */
- usedmem = lrp->mem_bytes - __db_shalloc_count(lt->mem);
- usedobjs = lrp->numobjs - __lock_count_objs(lrp);
- usedlocks = lrp->maxlocks - __lock_count_locks(lrp);
-
- /*
- * Figure out what fraction of the used space belongs to each
- * different type of "thing" in the region. Then partition the
- * new space up according to this ratio.
- */
- used = usedmem +
- usedlocks * ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT) +
- usedobjs * sizeof(DB_LOCKOBJ);
-
- lock_ratio = usedlocks *
- ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT) / (float)used;
- obj_ratio = usedobjs * sizeof(DB_LOCKOBJ) / (float)used;
-
- newlocks = (u_int32_t)(lock_ratio *
- incr / ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT));
- newobjs = (u_int32_t)(obj_ratio * incr / sizeof(DB_LOCKOBJ));
- newmem = incr -
- (newobjs * sizeof(DB_LOCKOBJ) +
- newlocks * ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT));
-
- /*
- * Make sure we allocate enough memory for the object being
- * requested.
- */
- switch (which) {
- case DB_LOCK_LOCK:
- if (newlocks == 0) {
- newlocks = 10;
- incr += newlocks * sizeof(struct __db_lock);
- }
- break;
- case DB_LOCK_OBJ:
- if (newobjs == 0) {
- newobjs = 10;
- incr += newobjs * sizeof(DB_LOCKOBJ);
- }
- break;
- case DB_LOCK_MEM:
- if (newmem < howmuch * 2) {
- incr += howmuch * 2 - newmem;
- newmem = howmuch * 2;
- }
- break;
- }
-
- newmem += ALIGN(incr, sizeof(size_t)) - incr;
- incr = ALIGN(incr, sizeof(size_t));
-
- /*
- * Since we are going to be allocating locks at the beginning of the
- * new chunk, we need to make sure that the chunk is MUTEX_ALIGNMENT
- * aligned. We did not guarantee this when we created the region, so
- * we may need to pad the old region by extra bytes to ensure this
- * alignment.
- */
- incr += ALIGN(oldsize, MUTEX_ALIGNMENT) - oldsize;
-
- __db_err(lt->dbenv,
- "Growing lock region: %lu locks %lu objs %lu bytes",
- (u_long)newlocks, (u_long)newobjs, (u_long)newmem);
-
- if ((ret = __db_rgrow(&lt->reginfo, oldsize + incr)) != 0)
- return (ret);
- lt->region = lt->reginfo.addr;
- __lock_reset_region(lt);
-
- /* Update region parameters. */
- lrp = lt->region;
- lrp->increment = incr << 1;
- lrp->maxlocks += newlocks;
- lrp->numobjs += newobjs;
- lrp->mem_bytes += newmem;
-
- curaddr = (u_int8_t *)lrp + oldsize;
- curaddr = (u_int8_t *)ALIGNP(curaddr, MUTEX_ALIGNMENT);
-
- /* Put new locks onto the free list. */
- lock_head = &lrp->free_locks;
- for (i = 0; i++ < newlocks;
- curaddr += ALIGN(sizeof(struct __db_lock), MUTEX_ALIGNMENT)) {
- newl = (struct __db_lock *)curaddr;
- SH_TAILQ_INSERT_HEAD(lock_head, newl, links, __db_lock);
- }
-
- /* Put new objects onto the free list. */
- obj_head = &lrp->free_objs;
- for (i = 0; i++ < newobjs; curaddr += sizeof(DB_LOCKOBJ)) {
- op = (DB_LOCKOBJ *)curaddr;
- SH_TAILQ_INSERT_HEAD(obj_head, op, links, __db_lockobj);
- }
-
- *((size_t *)curaddr) = newmem - sizeof(size_t);
- curaddr += sizeof(size_t);
- __db_shalloc_free(lt->mem, curaddr);
-
- return (0);
-}
-
-static void
-__lock_reset_region(lt)
- DB_LOCKTAB *lt;
-{
- lt->conflicts = (u_int8_t *)lt->region + sizeof(DB_LOCKREGION);
- lt->hashtab =
- (DB_HASHTAB *)((u_int8_t *)lt->region + lt->region->hash_off);
- lt->mem = (void *)((u_int8_t *)lt->region + lt->region->mem_off);
-}
-
-/*
- * lock_stat --
- * Return LOCK statistics.
- */
-int
-lock_stat(lt, gspp, db_malloc)
- DB_LOCKTAB *lt;
- DB_LOCK_STAT **gspp;
- void *(*db_malloc) __P((size_t));
-{
- DB_LOCKREGION *rp;
- int ret;
-
- *gspp = NULL;
-
- LOCK_PANIC_CHECK(lt);
-
- if ((ret = __os_malloc(sizeof(**gspp), db_malloc, gspp)) != 0)
- return (ret);
-
- /* Copy out the global statistics. */
- LOCK_LOCKREGION(lt);
-
- rp = lt->region;
- (*gspp)->st_magic = rp->magic;
- (*gspp)->st_version = rp->version;
- (*gspp)->st_maxlocks = rp->maxlocks;
- (*gspp)->st_nmodes = rp->nmodes;
- (*gspp)->st_numobjs = rp->numobjs;
- (*gspp)->st_nlockers = rp->nlockers;
- (*gspp)->st_nconflicts = rp->nconflicts;
- (*gspp)->st_nrequests = rp->nrequests;
- (*gspp)->st_nreleases = rp->nreleases;
- (*gspp)->st_ndeadlocks = rp->ndeadlocks;
- (*gspp)->st_region_nowait = rp->hdr.lock.mutex_set_nowait;
- (*gspp)->st_region_wait = rp->hdr.lock.mutex_set_wait;
- (*gspp)->st_refcnt = rp->hdr.refcnt;
- (*gspp)->st_regsize = rp->hdr.size;
-
- UNLOCK_LOCKREGION(lt);
-
- return (0);
-}
-
-static u_int32_t
-__lock_count_locks(lrp)
- DB_LOCKREGION *lrp;
-{
- struct __db_lock *newl;
- u_int32_t count;
-
- count = 0;
- for (newl = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
- newl != NULL;
- newl = SH_TAILQ_NEXT(newl, links, __db_lock))
- count++;
-
- return (count);
-}
-
-static u_int32_t
-__lock_count_objs(lrp)
- DB_LOCKREGION *lrp;
-{
- DB_LOCKOBJ *obj;
- u_int32_t count;
-
- count = 0;
- for (obj = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
- obj != NULL;
- obj = SH_TAILQ_NEXT(obj, links, __db_lockobj))
- count++;
-
- return (count);
-}
-
-#define LOCK_DUMP_CONF 0x001 /* Conflict matrix. */
-#define LOCK_DUMP_FREE 0x002 /* Display lock free list. */
-#define LOCK_DUMP_LOCKERS 0x004 /* Display lockers. */
-#define LOCK_DUMP_MEM 0x008 /* Display region memory. */
-#define LOCK_DUMP_OBJECTS 0x010 /* Display objects. */
-#define LOCK_DUMP_ALL 0x01f /* Display all. */
-
-/*
- * __lock_dump_region --
- *
- * PUBLIC: void __lock_dump_region __P((DB_LOCKTAB *, char *, FILE *));
- */
-void
-__lock_dump_region(lt, area, fp)
- DB_LOCKTAB *lt;
- char *area;
- FILE *fp;
-{
- struct __db_lock *lp;
- DB_LOCKOBJ *op;
- DB_LOCKREGION *lrp;
- u_int32_t flags, i, j;
- int label;
-
- /* Make it easy to call from the debugger. */
- if (fp == NULL)
- fp = stderr;
-
- for (flags = 0; *area != '\0'; ++area)
- switch (*area) {
- case 'A':
- LF_SET(LOCK_DUMP_ALL);
- break;
- case 'c':
- LF_SET(LOCK_DUMP_CONF);
- break;
- case 'f':
- LF_SET(LOCK_DUMP_FREE);
- break;
- case 'l':
- LF_SET(LOCK_DUMP_LOCKERS);
- break;
- case 'm':
- LF_SET(LOCK_DUMP_MEM);
- break;
- case 'o':
- LF_SET(LOCK_DUMP_OBJECTS);
- break;
- }
-
- lrp = lt->region;
-
- fprintf(fp, "%s\nLock region parameters\n", DB_LINE);
- fprintf(fp, "%s: %lu, %s: %lu, %s: %lu, %s: %lu\n%s: %lu, %s: %lu\n",
- "table size", (u_long)lrp->table_size,
- "hash_off", (u_long)lrp->hash_off,
- "increment", (u_long)lrp->increment,
- "mem_off", (u_long)lrp->mem_off,
- "mem_bytes", (u_long)lrp->mem_bytes,
- "need_dd", (u_long)lrp->need_dd);
-
- if (LF_ISSET(LOCK_DUMP_CONF)) {
- fprintf(fp, "\n%s\nConflict matrix\n", DB_LINE);
- for (i = 0; i < lrp->nmodes; i++) {
- for (j = 0; j < lrp->nmodes; j++)
- fprintf(fp, "%lu\t",
- (u_long)lt->conflicts[i * lrp->nmodes + j]);
- fprintf(fp, "\n");
- }
- }
-
- if (LF_ISSET(LOCK_DUMP_LOCKERS | LOCK_DUMP_OBJECTS)) {
- fprintf(fp, "%s\nLock hash buckets\n", DB_LINE);
- for (i = 0; i < lrp->table_size; i++) {
- label = 1;
- for (op = SH_TAILQ_FIRST(&lt->hashtab[i], __db_lockobj);
- op != NULL;
- op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {
- if (LF_ISSET(LOCK_DUMP_LOCKERS) &&
- op->type == DB_LOCK_LOCKER) {
- if (label) {
- fprintf(fp,
- "Bucket %lu:\n", (u_long)i);
- label = 0;
- }
- __lock_dump_locker(lt, op, fp);
- }
- if (LF_ISSET(LOCK_DUMP_OBJECTS) &&
- op->type == DB_LOCK_OBJTYPE) {
- if (label) {
- fprintf(fp,
- "Bucket %lu:\n", (u_long)i);
- label = 0;
- }
- __lock_dump_object(lt, op, fp);
- }
- }
- }
- }
-
- if (LF_ISSET(LOCK_DUMP_FREE)) {
- fprintf(fp, "%s\nLock free list\n", DB_LINE);
- for (lp = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- fprintf(fp, "0x%lx: %lu\t%lu\t%s\t0x%lx\n", (u_long)lp,
- (u_long)lp->holder, (u_long)lp->mode,
- __lock_dump_status(lp->status), (u_long)lp->obj);
-
- fprintf(fp, "%s\nObject free list\n", DB_LINE);
- for (op = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
- op != NULL;
- op = SH_TAILQ_NEXT(op, links, __db_lockobj))
- fprintf(fp, "0x%lx\n", (u_long)op);
- }
-
- if (LF_ISSET(LOCK_DUMP_MEM))
- __db_shalloc_dump(lt->mem, fp);
-}
-
-static void
-__lock_dump_locker(lt, op, fp)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *op;
- FILE *fp;
-{
- struct __db_lock *lp;
- u_int32_t locker;
- void *ptr;
-
- ptr = SH_DBT_PTR(&op->lockobj);
- memcpy(&locker, ptr, sizeof(u_int32_t));
- fprintf(fp, "L %lx", (u_long)locker);
-
- lp = SH_LIST_FIRST(&op->heldby, __db_lock);
- if (lp == NULL) {
- fprintf(fp, "\n");
- return;
- }
- for (; lp != NULL; lp = SH_LIST_NEXT(lp, locker_links, __db_lock))
- __lock_printlock(lt, lp, 0);
-}
-
-static void
-__lock_dump_object(lt, op, fp)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *op;
- FILE *fp;
-{
- struct __db_lock *lp;
- u_int32_t j;
- u_int8_t *ptr;
- u_int ch;
-
- ptr = SH_DBT_PTR(&op->lockobj);
- for (j = 0; j < op->lockobj.size; ptr++, j++) {
- ch = *ptr;
- fprintf(fp, isprint(ch) ? "%c" : "\\%o", ch);
- }
- fprintf(fp, "\n");
-
- fprintf(fp, "H:");
- for (lp =
- SH_TAILQ_FIRST(&op->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- __lock_printlock(lt, lp, 0);
- lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);
- if (lp != NULL) {
- fprintf(fp, "\nW:");
- for (; lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- __lock_printlock(lt, lp, 0);
- }
-}
-
-static const char *
-__lock_dump_status(status)
- db_status_t status;
-{
- switch (status) {
- case DB_LSTAT_ABORTED:
- return ("aborted");
- case DB_LSTAT_ERR:
- return ("err");
- case DB_LSTAT_FREE:
- return ("free");
- case DB_LSTAT_HELD:
- return ("held");
- case DB_LSTAT_NOGRANT:
- return ("nogrant");
- case DB_LSTAT_PENDING:
- return ("pending");
- case DB_LSTAT_WAITING:
- return ("waiting");
- }
- return ("unknown status");
-}
diff --git a/db2/lock/lock_util.c b/db2/lock/lock_util.c
deleted file mode 100644
index 29da75b..0000000
--- a/db2/lock/lock_util.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)lock_util.c 10.10 (Sleepycat) 9/20/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_shash.h"
-#include "hash.h"
-#include "lock.h"
-
-/*
- * __lock_cmp --
- * This function is used to compare a DBT that is about to be entered
- * into a hash table with an object already in the hash table. Note
- * that it just returns true on equal and 0 on not-equal. Therefore
- * this function cannot be used as a sort function; its purpose is to
- * be used as a hash comparison function.
- *
- * PUBLIC: int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
- */
-int
-__lock_cmp(dbt, lock_obj)
- const DBT *dbt;
- DB_LOCKOBJ *lock_obj;
-{
- void *obj_data;
-
- if (lock_obj->type != DB_LOCK_OBJTYPE)
- return (0);
-
- obj_data = SH_DBT_PTR(&lock_obj->lockobj);
- return (dbt->size == lock_obj->lockobj.size &&
- memcmp(dbt->data, obj_data, dbt->size) == 0);
-}
-
-/*
- * PUBLIC: int __lock_locker_cmp __P((u_int32_t, DB_LOCKOBJ *));
- */
-int
-__lock_locker_cmp(locker, lock_obj)
- u_int32_t locker;
- DB_LOCKOBJ *lock_obj;
-{
- void *obj_data;
-
- if (lock_obj->type != DB_LOCK_LOCKER)
- return (0);
-
- obj_data = SH_DBT_PTR(&lock_obj->lockobj);
- return (memcmp(&locker, obj_data, sizeof(u_int32_t)) == 0);
-}
-
-/*
- * The next two functions are the hash functions used to store objects in the
- * lock hash table. They are hashing the same items, but one (__lock_ohash)
- * takes a DBT (used for hashing a parameter passed from the user) and the
- * other (__lock_lhash) takes a DB_LOCKOBJ (used for hashing something that is
- * already in the lock manager). In both cases, we have a special check to
- * fast path the case where we think we are doing a hash on a DB page/fileid
- * pair. If the size is right, then we do the fast hash.
- *
- * We know that DB uses DB_LOCK_ILOCK types for its lock objects. The first
- * four bytes are the 4-byte page number and the next DB_FILE_ID_LEN bytes
- * are a unique file id, where the first 4 bytes on UNIX systems are the file
- * inode number, and the first 4 bytes on Windows systems are the FileIndexLow
- * bytes. So, we use the XOR of the page number and the first four bytes of
- * the file id to produce a 32-bit hash value.
- *
- * We have no particular reason to believe that this algorithm will produce
- * a good hash, but we want a fast hash more than we want a good one, when
- * we're coming through this code path.
- */
-#define FAST_HASH(P) { \
- u_int32_t __h; \
- u_int8_t *__cp, *__hp; \
- __hp = (u_int8_t *)&__h; \
- __cp = (u_int8_t *)(P); \
- __hp[0] = __cp[0] ^ __cp[4]; \
- __hp[1] = __cp[1] ^ __cp[5]; \
- __hp[2] = __cp[2] ^ __cp[6]; \
- __hp[3] = __cp[3] ^ __cp[7]; \
- return (__h); \
-}
-
-/*
- * __lock_ohash --
- *
- * PUBLIC: u_int32_t __lock_ohash __P((const DBT *));
- */
-u_int32_t
-__lock_ohash(dbt)
- const DBT *dbt;
-{
- if (dbt->size == sizeof(DB_LOCK_ILOCK))
- FAST_HASH(dbt->data);
-
- return (__ham_func5(dbt->data, dbt->size));
-}
-
-/*
- * __lock_lhash --
- *
- * PUBLIC: u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
- */
-u_int32_t
-__lock_lhash(lock_obj)
- DB_LOCKOBJ *lock_obj;
-{
- u_int32_t tmp;
- void *obj_data;
-
- obj_data = SH_DBT_PTR(&lock_obj->lockobj);
- if (lock_obj->type == DB_LOCK_LOCKER) {
- memcpy(&tmp, obj_data, sizeof(u_int32_t));
- return (tmp);
- }
-
- if (lock_obj->lockobj.size == sizeof(DB_LOCK_ILOCK))
- FAST_HASH(obj_data);
-
- return (__ham_func5(obj_data, lock_obj->lockobj.size));
-}
-
-/*
- * __lock_locker_hash --
- * Hash function for entering lockers into the hash table. Since these
- * are simply 32-bit unsigned integers, just return the locker value.
- *
- * PUBLIC: u_int32_t __lock_locker_hash __P((u_int32_t));
- */
-u_int32_t
-__lock_locker_hash(locker)
- u_int32_t locker;
-{
- return (locker);
-}
diff --git a/db2/log/log.c b/db2/log/log.c
deleted file mode 100644
index ad15f16..0000000
--- a/db2/log/log.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log.c 10.63 (Sleepycat) 10/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <shqueue.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "db_dispatch.h"
-#include "txn.h"
-#include "txn_auto.h"
-#include "common_ext.h"
-
-static int __log_recover __P((DB_LOG *));
-
-/*
- * log_open --
- * Initialize and/or join a log.
- */
-int
-log_open(path, flags, mode, dbenv, lpp)
- const char *path;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_LOG **lpp;
-{
- DB_LOG *dblp;
- LOG *lp;
- int ret;
-
- /* Validate arguments. */
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_THREAD)
-#else
-#define OKFLAGS (DB_CREATE)
-#endif
- if ((ret = __db_fchk(dbenv, "log_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- /* Create and initialize the DB_LOG structure. */
- if ((ret = __os_calloc(1, sizeof(DB_LOG), &dblp)) != 0)
- return (ret);
-
- if (path != NULL && (ret = __os_strdup(path, &dblp->dir)) != 0)
- goto err;
-
- dblp->dbenv = dbenv;
- dblp->lfd = -1;
- ZERO_LSN(dblp->c_lsn);
- dblp->c_fd = -1;
-
- /*
- * The log region isn't fixed size because we store the registered
- * file names there. Make it fairly large so that we don't have to
- * grow it.
- */
-#define DEF_LOG_SIZE (30 * 1024)
-
- /* Map in the region. */
- dblp->reginfo.dbenv = dbenv;
- dblp->reginfo.appname = DB_APP_LOG;
- if (path == NULL)
- dblp->reginfo.path = NULL;
- else
- if ((ret = __os_strdup(path, &dblp->reginfo.path)) != 0)
- goto err;
- dblp->reginfo.file = DB_DEFAULT_LOG_FILE;
- dblp->reginfo.mode = mode;
- dblp->reginfo.size = DEF_LOG_SIZE;
- dblp->reginfo.dbflags = flags;
- dblp->reginfo.flags = REGION_SIZEDEF;
- if ((ret = __db_rattach(&dblp->reginfo)) != 0)
- goto err;
-
- /*
- * The LOG structure is first in the region, the rest of the region
- * is free space.
- */
- dblp->lp = dblp->reginfo.addr;
- dblp->addr = (u_int8_t *)dblp->lp + sizeof(LOG);
-
- /* Initialize a created region. */
- if (F_ISSET(&dblp->reginfo, REGION_CREATED)) {
- __db_shalloc_init(dblp->addr, DEF_LOG_SIZE - sizeof(LOG));
-
- /* Initialize the LOG structure. */
- lp = dblp->lp;
- lp->persist.lg_max = dbenv == NULL ? 0 : dbenv->lg_max;
- if (lp->persist.lg_max == 0)
- lp->persist.lg_max = DEFAULT_MAX;
- lp->persist.magic = DB_LOGMAGIC;
- lp->persist.version = DB_LOGVERSION;
- lp->persist.mode = mode;
- SH_TAILQ_INIT(&lp->fq);
-
- /* Initialize LOG LSNs. */
- lp->lsn.file = 1;
- lp->lsn.offset = 0;
- }
-
- /* Initialize thread information, mutex. */
- if (LF_ISSET(DB_THREAD)) {
- F_SET(dblp, DB_AM_THREAD);
- if ((ret = __db_shalloc(dblp->addr,
- sizeof(db_mutex_t), MUTEX_ALIGNMENT, &dblp->mutexp)) != 0)
- goto err;
- (void)__db_mutex_init(dblp->mutexp, 0);
- }
-
- /*
- * If doing recovery, try and recover any previous log files before
- * releasing the lock.
- */
- if (F_ISSET(&dblp->reginfo, REGION_CREATED) &&
- (ret = __log_recover(dblp)) != 0)
- goto err;
-
- UNLOCK_LOGREGION(dblp);
- *lpp = dblp;
- return (0);
-
-err: if (dblp->reginfo.addr != NULL) {
- if (dblp->mutexp != NULL)
- __db_shalloc_free(dblp->addr, dblp->mutexp);
-
- UNLOCK_LOGREGION(dblp);
- (void)__db_rdetach(&dblp->reginfo);
- if (F_ISSET(&dblp->reginfo, REGION_CREATED))
- (void)log_unlink(path, 1, dbenv);
- }
-
- if (dblp->reginfo.path != NULL)
- __os_freestr(dblp->reginfo.path);
- if (dblp->dir != NULL)
- __os_freestr(dblp->dir);
- __os_free(dblp, sizeof(*dblp));
- return (ret);
-}
-
-/*
- * __log_panic --
- * Panic a log.
- *
- * PUBLIC: void __log_panic __P((DB_ENV *));
- */
-void
-__log_panic(dbenv)
- DB_ENV *dbenv;
-{
- if (dbenv->lg_info != NULL)
- dbenv->lg_info->lp->rlayout.panic = 1;
-}
-
-/*
- * __log_recover --
- * Recover a log.
- */
-static int
-__log_recover(dblp)
- DB_LOG *dblp;
-{
- DBT dbt;
- DB_LSN lsn;
- LOG *lp;
- u_int32_t chk;
- int cnt, found_checkpoint, ret;
-
- lp = dblp->lp;
-
- /*
- * Find a log file. If none exist, we simply return, leaving
- * everything initialized to a new log.
- */
- if ((ret = __log_find(dblp, 0, &cnt)) != 0)
- return (ret);
- if (cnt == 0)
- return (0);
-
- /*
- * We have the last useful log file and we've loaded any persistent
- * information. Pretend that the log is larger than it can possibly
- * be, and read the last file, looking for the last checkpoint and
- * the log's end.
- */
- lp->lsn.file = cnt + 1;
- lp->lsn.offset = 0;
- lsn.file = cnt;
- lsn.offset = 0;
-
- /* Set the cursor. Shouldn't fail, leave error messages on. */
- memset(&dbt, 0, sizeof(dbt));
- if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
- return (ret);
-
- /*
- * Read to the end of the file, saving checkpoints. This will fail
- * at some point, so turn off error messages.
- */
- found_checkpoint = 0;
- while (__log_get(dblp, &lsn, &dbt, DB_NEXT, 1) == 0) {
- if (dbt.size < sizeof(u_int32_t))
- continue;
- memcpy(&chk, dbt.data, sizeof(u_int32_t));
- if (chk == DB_txn_ckp) {
- lp->chkpt_lsn = lsn;
- found_checkpoint = 1;
- }
- }
-
- /*
- * We now know where the end of the log is. Set the first LSN that
- * we want to return to an application and the LSN of the last known
- * record on disk.
- */
- lp->lsn = lp->s_lsn = lsn;
- lp->lsn.offset += dblp->c_len;
-
- /* Set up the current buffer information, too. */
- lp->len = dblp->c_len;
- lp->b_off = 0;
- lp->w_off = lp->lsn.offset;
-
- /*
- * It's possible that we didn't find a checkpoint because there wasn't
- * one in the last log file. Start searching.
- */
- while (!found_checkpoint && cnt > 1) {
- lsn.file = --cnt;
- lsn.offset = 0;
-
- /* Set the cursor. Shouldn't fail, leave error messages on. */
- if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
- return (ret);
-
- /*
- * Read to the end of the file, saving checkpoints. Shouldn't
- * fail, leave error messages on.
- */
- while (__log_get(dblp, &lsn, &dbt, DB_NEXT, 0) == 0) {
- if (dbt.size < sizeof(u_int32_t))
- continue;
- memcpy(&chk, dbt.data, sizeof(u_int32_t));
- if (chk == DB_txn_ckp) {
- lp->chkpt_lsn = lsn;
- found_checkpoint = 1;
- }
- }
- }
- /*
- * Reset the cursor lsn to the beginning of the log, so that an
- * initial call to DB_NEXT does the right thing.
- */
- ZERO_LSN(dblp->c_lsn);
-
- /* If we never find a checkpoint, that's okay, just 0 it out. */
- if (!found_checkpoint)
- ZERO_LSN(lp->chkpt_lsn);
-
- /*
- * !!!
- * The test suite explicitly looks for this string -- don't change
- * it here unless you also change it there.
- */
- __db_err(dblp->dbenv,
- "Finding last valid log LSN: file: %lu offset %lu",
- (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
-
- return (0);
-}
-
-/*
- * __log_find --
- * Try to find a log file. If find_first is set, valp will contain
- * the number of the first log file, else it will contain the number of
- * the last log file.
- *
- * PUBLIC: int __log_find __P((DB_LOG *, int, int *));
- */
-int
-__log_find(dblp, find_first, valp)
- DB_LOG *dblp;
- int find_first, *valp;
-{
- u_int32_t clv, logval;
- int cnt, fcnt, ret;
- const char *dir;
- char **names, *p, *q;
-
- *valp = 0;
-
- /* Find the directory name. */
- if ((ret = __log_name(dblp, 1, &p, NULL, 0)) != 0)
- return (ret);
- if ((q = __db_rpath(p)) == NULL)
- dir = PATH_DOT;
- else {
- *q = '\0';
- dir = p;
- }
-
- /* Get the list of file names. */
- ret = __os_dirlist(dir, &names, &fcnt);
- __os_freestr(p);
- if (ret != 0) {
- __db_err(dblp->dbenv, "%s: %s", dir, strerror(ret));
- return (ret);
- }
-
- /*
- * Search for a valid log file name, return a value of 0 on
- * failure.
- *
- * XXX
- * Assumes that atoi(3) returns a 32-bit number.
- */
- for (cnt = fcnt, clv = logval = 0; --cnt >= 0;) {
- if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1) != 0)
- continue;
-
- clv = atoi(names[cnt] + (sizeof(LFPREFIX) - 1));
- if (find_first) {
- if (logval != 0 && clv > logval)
- continue;
- } else
- if (logval != 0 && clv < logval)
- continue;
-
- if (__log_valid(dblp, clv, 1) == 0)
- logval = clv;
- }
-
- *valp = logval;
-
- /* Discard the list. */
- __os_dirfree(names, fcnt);
-
- return (0);
-}
-
-/*
- * log_valid --
- * Validate a log file.
- *
- * PUBLIC: int __log_valid __P((DB_LOG *, u_int32_t, int));
- */
-int
-__log_valid(dblp, number, set_persist)
- DB_LOG *dblp;
- u_int32_t number;
- int set_persist;
-{
- LOGP persist;
- ssize_t nw;
- char *fname;
- int fd, ret;
-
- /* Try to open the log file. */
- if ((ret = __log_name(dblp,
- number, &fname, &fd, DB_RDONLY | DB_SEQUENTIAL)) != 0) {
- __os_freestr(fname);
- return (ret);
- }
-
- /* Try to read the header. */
- if ((ret = __os_seek(fd, 0, 0, sizeof(HDR), 0, SEEK_SET)) != 0 ||
- (ret = __os_read(fd, &persist, sizeof(LOGP), &nw)) != 0 ||
- nw != sizeof(LOGP)) {
- if (ret == 0)
- ret = EIO;
-
- (void)__os_close(fd);
-
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: %s", fname, strerror(ret));
- goto err;
- }
- (void)__os_close(fd);
-
- /* Validate the header. */
- if (persist.magic != DB_LOGMAGIC) {
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: magic number %lx, not %lx",
- fname, (u_long)persist.magic, (u_long)DB_LOGMAGIC);
- ret = EINVAL;
- goto err;
- }
- if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) {
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: unsupported log version %lu",
- fname, (u_long)persist.version);
- ret = EINVAL;
- goto err;
- }
-
- /*
- * If we're going to use this log file, set the region's persistent
- * information based on the headers.
- */
- if (set_persist) {
- dblp->lp->persist.lg_max = persist.lg_max;
- dblp->lp->persist.mode = persist.mode;
- }
- ret = 0;
-
-err: __os_freestr(fname);
- return (ret);
-}
-
-/*
- * log_close --
- * Close a log.
- */
-int
-log_close(dblp)
- DB_LOG *dblp;
-{
- int ret, t_ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* We may have opened files as part of XA; if so, close them. */
- __log_close_files(dblp);
-
- /* Discard the per-thread pointer. */
- if (dblp->mutexp != NULL) {
- LOCK_LOGREGION(dblp);
- __db_shalloc_free(dblp->addr, dblp->mutexp);
- UNLOCK_LOGREGION(dblp);
- }
-
- /* Close the region. */
- ret = __db_rdetach(&dblp->reginfo);
-
- /* Close open files, release allocated memory. */
- if (dblp->lfd != -1 && (t_ret = __os_close(dblp->lfd)) != 0 && ret == 0)
- ret = t_ret;
- if (dblp->c_dbt.data != NULL)
- __os_free(dblp->c_dbt.data, dblp->c_dbt.ulen);
- if (dblp->c_fd != -1 &&
- (t_ret = __os_close(dblp->c_fd)) != 0 && ret == 0)
- ret = t_ret;
- if (dblp->dbentry != NULL)
- __os_free(dblp->dbentry,
- (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
- if (dblp->dir != NULL)
- __os_freestr(dblp->dir);
-
- if (dblp->reginfo.path != NULL)
- __os_freestr(dblp->reginfo.path);
- __os_free(dblp, sizeof(*dblp));
-
- return (ret);
-}
-
-/*
- * log_unlink --
- * Exit a log.
- */
-int
-log_unlink(path, force, dbenv)
- const char *path;
- int force;
- DB_ENV *dbenv;
-{
- REGINFO reginfo;
- int ret;
-
- memset(&reginfo, 0, sizeof(reginfo));
- reginfo.dbenv = dbenv;
- reginfo.appname = DB_APP_LOG;
- if (path != NULL && (ret = __os_strdup(path, &reginfo.path)) != 0)
- return (ret);
- reginfo.file = DB_DEFAULT_LOG_FILE;
- ret = __db_runlink(&reginfo, force);
- if (reginfo.path != NULL)
- __os_freestr(reginfo.path);
- return (ret);
-}
-
-/*
- * log_stat --
- * Return LOG statistics.
- */
-int
-log_stat(dblp, gspp, db_malloc)
- DB_LOG *dblp;
- DB_LOG_STAT **gspp;
- void *(*db_malloc) __P((size_t));
-{
- LOG *lp;
- int ret;
-
- *gspp = NULL;
- lp = dblp->lp;
-
- LOG_PANIC_CHECK(dblp);
-
- if ((ret = __os_malloc(sizeof(**gspp), db_malloc, gspp)) != 0)
- return (ret);
-
- /* Copy out the global statistics. */
- LOCK_LOGREGION(dblp);
- **gspp = lp->stat;
-
- (*gspp)->st_magic = lp->persist.magic;
- (*gspp)->st_version = lp->persist.version;
- (*gspp)->st_mode = lp->persist.mode;
- (*gspp)->st_lg_max = lp->persist.lg_max;
-
- (*gspp)->st_region_nowait = lp->rlayout.lock.mutex_set_nowait;
- (*gspp)->st_region_wait = lp->rlayout.lock.mutex_set_wait;
-
- (*gspp)->st_cur_file = lp->lsn.file;
- (*gspp)->st_cur_offset = lp->lsn.offset;
-
- (*gspp)->st_refcnt = lp->rlayout.refcnt;
- (*gspp)->st_regsize = lp->rlayout.size;
-
- UNLOCK_LOGREGION(dblp);
-
- return (0);
-}
diff --git a/db2/log/log.src b/db2/log/log.src
deleted file mode 100644
index 12883bd..0000000
--- a/db2/log/log.src
+++ /dev/null
@@ -1,19 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)log.src 10.5 (Sleepycat) 4/10/98
- */
-
-PREFIX log
-
-/* Used for registering name/id translations at open or close. */
-BEGIN register
-ARG opcode u_int32_t lu
-DBT name DBT s
-DBT uid DBT s
-ARG id u_int32_t lu
-ARG ftype DBTYPE lx
-END
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
deleted file mode 100644
index 9f3b24d..0000000
--- a/db2/log/log_archive.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_archive.c 10.44 (Sleepycat) 10/9/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db_dispatch.h"
-#include "shqueue.h"
-#include "log.h"
-#include "common_ext.h"
-#include "clib_ext.h" /* XXX: needed for getcwd. */
-
-static int __absname __P((char *, char *, char **));
-static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
-static int __cmpfunc __P((const void *, const void *));
-static int __usermem __P((char ***, void *(*)(size_t)));
-
-/*
- * log_archive --
- * Supporting function for db_archive(1).
- */
-int
-log_archive(dblp, listp, flags, db_malloc)
- DB_LOG *dblp;
- char ***listp;
- u_int32_t flags;
- void *(*db_malloc) __P((size_t));
-{
- DBT rec;
- DB_LSN stable_lsn;
- u_int32_t fnum;
- int array_size, n, ret;
- char **array, **arrayp, *name, *p, *pref, buf[MAXPATHLEN];
-
- name = NULL;
- COMPQUIET(fnum, 0);
-
- LOG_PANIC_CHECK(dblp);
-
-#define OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
- if (flags != 0) {
- if ((ret =
- __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
- return (ret);
- if ((ret =
- __db_fcchk(dblp->dbenv,
- "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0)
- return (ret);
- }
-
- /*
- * Get the absolute pathname of the current directory. It would
- * be nice to get the shortest pathname of the database directory,
- * but that's just not possible.
- */
- if (LF_ISSET(DB_ARCH_ABS)) {
- errno = 0;
- if ((pref = getcwd(buf, sizeof(buf))) == NULL)
- return (errno == 0 ? ENOMEM : errno);
- } else
- pref = NULL;
-
- switch (LF_ISSET(~DB_ARCH_ABS)) {
- case DB_ARCH_DATA:
- return (__build_data(dblp, pref, listp, db_malloc));
- case DB_ARCH_LOG:
- memset(&rec, 0, sizeof(rec));
- if (F_ISSET(dblp, DB_AM_THREAD))
- F_SET(&rec, DB_DBT_MALLOC);
- if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0)
- return (ret);
- if (F_ISSET(dblp, DB_AM_THREAD))
- __os_free(rec.data, rec.size);
- fnum = stable_lsn.file;
- break;
- case 0:
- if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) {
- /*
- * A return of DB_NOTFOUND means that we didn't find
- * any records in the log (so we are not going to be
- * deleting any log files).
- */
- if (ret != DB_NOTFOUND)
- return (ret);
- *listp = NULL;
- return (0);
- }
- /* Remove any log files before the last stable LSN. */
- fnum = stable_lsn.file - 1;
- break;
- }
-
-#define LIST_INCREMENT 64
- /* Get some initial space. */
- array_size = 10;
- if ((ret = __os_malloc(sizeof(char *) * array_size, NULL, &array)) != 0)
- return (ret);
- array[0] = NULL;
-
- /* Build an array of the file names. */
- for (n = 0; fnum > 0; --fnum) {
- if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0)
- goto err;
- if (__os_exists(name, NULL) != 0) {
- __os_freestr(name);
- name = NULL;
- break;
- }
-
- if (n >= array_size - 1) {
- array_size += LIST_INCREMENT;
- if ((ret = __os_realloc(&array,
- sizeof(char *) * array_size)) != 0)
- goto err;
- }
-
- if (LF_ISSET(DB_ARCH_ABS)) {
- if ((ret = __absname(pref, name, &array[n])) != 0)
- goto err;
- __os_freestr(name);
- } else if ((p = __db_rpath(name)) != NULL) {
- if ((ret = __os_strdup(p + 1, &array[n])) != 0)
- goto err;
- __os_freestr(name);
- } else
- array[n] = name;
-
- name = NULL;
- array[++n] = NULL;
- }
-
- /* If there's nothing to return, we're done. */
- if (n == 0) {
- *listp = NULL;
- ret = 0;
- goto err;
- }
-
- /* Sort the list. */
- qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
-
- /* Rework the memory. */
- if ((ret = __usermem(&array, db_malloc)) != 0)
- goto err;
-
- *listp = array;
- return (0);
-
-err: if (array != NULL) {
- for (arrayp = array; *arrayp != NULL; ++arrayp)
- __os_freestr(*arrayp);
- __os_free(array, sizeof(char *) * array_size);
- }
- if (name != NULL)
- __os_freestr(name);
- return (ret);
-}
-
-/*
- * __build_data --
- * Build a list of datafiles for return.
- */
-static int
-__build_data(dblp, pref, listp, db_malloc)
- DB_LOG *dblp;
- char *pref, ***listp;
- void *(*db_malloc) __P((size_t));
-{
- DBT rec;
- DB_LSN lsn;
- __log_register_args *argp;
- u_int32_t rectype;
- int array_size, last, n, nxt, ret;
- char **array, **arrayp, *p, *real_name;
-
- /* Get some initial space. */
- array_size = 10;
- if ((ret = __os_malloc(sizeof(char *) * array_size, NULL, &array)) != 0)
- return (ret);
- array[0] = NULL;
-
- memset(&rec, 0, sizeof(rec));
- if (F_ISSET(dblp, DB_AM_THREAD))
- F_SET(&rec, DB_DBT_MALLOC);
- for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST);
- ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) {
- if (rec.size < sizeof(rectype)) {
- ret = EINVAL;
- __db_err(dblp->dbenv, "log_archive: bad log record");
- goto lg_free;
- }
-
- memcpy(&rectype, rec.data, sizeof(rectype));
- if (rectype != DB_log_register) {
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- __os_free(rec.data, rec.size);
- rec.data = NULL;
- }
- continue;
- }
- if ((ret = __log_register_read(rec.data, &argp)) != 0) {
- ret = EINVAL;
- __db_err(dblp->dbenv,
- "log_archive: unable to read log record");
- goto lg_free;
- }
-
- if (n >= array_size - 1) {
- array_size += LIST_INCREMENT;
- if ((ret = __os_realloc(&array,
- sizeof(char *) * array_size)) != 0)
- goto lg_free;
- }
-
- if ((ret = __os_strdup(argp->name.data, &array[n])) != 0) {
-lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
- __os_free(rec.data, rec.size);
- goto err1;
- }
-
- array[++n] = NULL;
- __os_free(argp, 0);
-
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- __os_free(rec.data, rec.size);
- rec.data = NULL;
- }
- }
-
- /* If there's nothing to return, we're done. */
- if (n == 0) {
- ret = 0;
- *listp = NULL;
- goto err1;
- }
-
- /* Sort the list. */
- qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
-
- /*
- * Build the real pathnames, discarding nonexistent files and
- * duplicates.
- */
- for (last = nxt = 0; nxt < n;) {
- /*
- * Discard duplicates. Last is the next slot we're going
- * to return to the user, nxt is the next slot that we're
- * going to consider.
- */
- if (last != nxt) {
- array[last] = array[nxt];
- array[nxt] = NULL;
- }
- for (++nxt; nxt < n &&
- strcmp(array[last], array[nxt]) == 0; ++nxt) {
- __os_freestr(array[nxt]);
- array[nxt] = NULL;
- }
-
- /* Get the real name. */
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_DATA, NULL, array[last], 0, NULL, &real_name)) != 0)
- goto err2;
-
- /* If the file doesn't exist, ignore it. */
- if (__os_exists(real_name, NULL) != 0) {
- __os_freestr(real_name);
- __os_freestr(array[last]);
- array[last] = NULL;
- continue;
- }
-
- /* Rework the name as requested by the user. */
- __os_freestr(array[last]);
- array[last] = NULL;
- if (pref != NULL) {
- ret = __absname(pref, real_name, &array[last]);
- __os_freestr(real_name);
- if (ret != 0)
- goto err2;
- } else if ((p = __db_rpath(real_name)) != NULL) {
- ret = __os_strdup(p + 1, &array[last]);
- __os_freestr(real_name);
- if (ret != 0)
- goto err2;
- } else
- array[last] = real_name;
- ++last;
- }
-
- /* NULL-terminate the list. */
- array[last] = NULL;
-
- /* Rework the memory. */
- if ((ret = __usermem(&array, db_malloc)) != 0)
- goto err1;
-
- *listp = array;
- return (0);
-
-err2: /*
- * XXX
- * We've possibly inserted NULLs into the array list, so clean up a
- * bit so that the other error processing works.
- */
- if (array != NULL)
- for (; nxt < n; ++nxt)
- __os_freestr(array[nxt]);
- /* FALLTHROUGH */
-
-err1: if (array != NULL) {
- for (arrayp = array; *arrayp != NULL; ++arrayp)
- __os_freestr(*arrayp);
- __os_free(array, array_size * sizeof(char *));
- }
- return (ret);
-}
-
-/*
- * __absname --
- * Return an absolute path name for the file.
- */
-static int
-__absname(pref, name, newnamep)
- char *pref, *name, **newnamep;
-{
- size_t l_pref, l_name;
- int isabspath, ret;
- char *newname;
-
- l_name = strlen(name);
- isabspath = __os_abspath(name);
- l_pref = isabspath ? 0 : strlen(pref);
-
- /* Malloc space for concatenating the two. */
- if ((ret = __os_malloc(l_pref + l_name + 2, NULL, &newname)) != 0)
- return (ret);
- *newnamep = newname;
-
- /* Build the name. If `name' is an absolute path, ignore any prefix. */
- if (!isabspath) {
- memcpy(newname, pref, l_pref);
- if (strchr(PATH_SEPARATOR, newname[l_pref - 1]) == NULL)
- newname[l_pref++] = PATH_SEPARATOR[0];
- }
- memcpy(newname + l_pref, name, l_name + 1);
-
- return (0);
-}
-
-/*
- * __usermem --
- * Create a single chunk of memory that holds the returned information.
- * If the user has their own malloc routine, use it.
- */
-static int
-__usermem(listp, db_malloc)
- char ***listp;
- void *(*db_malloc) __P((size_t));
-{
- size_t len;
- int ret;
- char **array, **arrayp, **orig, *strp;
-
- /* Find out how much space we need. */
- for (len = 0, orig = *listp; *orig != NULL; ++orig)
- len += sizeof(char *) + strlen(*orig) + 1;
- len += sizeof(char *);
-
- /* Allocate it and set up the pointers. */
- if ((ret = __os_malloc(len, db_malloc, &array)) != 0)
- return (ret);
-
- strp = (char *)(array + (orig - *listp) + 1);
-
- /* Copy the original information into the new memory. */
- for (orig = *listp, arrayp = array; *orig != NULL; ++orig, ++arrayp) {
- len = strlen(*orig);
- memcpy(strp, *orig, len + 1);
- *arrayp = strp;
- strp += len + 1;
-
- __os_freestr(*orig);
- }
-
- /* NULL-terminate the list. */
- *arrayp = NULL;
-
- __os_free(*listp, 0);
- *listp = array;
-
- return (0);
-}
-
-static int
-__cmpfunc(p1, p2)
- const void *p1, *p2;
-{
- return (strcmp(*((char * const *)p1), *((char * const *)p2)));
-}
diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c
deleted file mode 100644
index 92e6826..0000000
--- a/db2/log/log_auto.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "log.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __log_register_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, const DBT *, const DBT *, u_int32_t,
- * PUBLIC: DBTYPE));
- */
-int __log_register_log(logp, txnid, ret_lsnp, flags,
- opcode, name, uid, id, ftype)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- const DBT *name;
- const DBT *uid;
- u_int32_t id;
- DBTYPE ftype;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_log_register;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(u_int32_t) + (name == NULL ? 0 : name->size)
- + sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size)
- + sizeof(id)
- + sizeof(ftype);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- if (name == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &name->size, sizeof(name->size));
- bp += sizeof(name->size);
- memcpy(bp, name->data, name->size);
- bp += name->size;
- }
- if (uid == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &uid->size, sizeof(uid->size));
- bp += sizeof(uid->size);
- memcpy(bp, uid->data, uid->size);
- bp += uid->size;
- }
- memcpy(bp, &id, sizeof(id));
- bp += sizeof(id);
- memcpy(bp, &ftype, sizeof(ftype));
- bp += sizeof(ftype);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = __log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __log_register_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_register_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __log_register_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]log_register: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tname: ");
- for (i = 0; i < argp->name.size; i++) {
- ch = ((u_int8_t *)argp->name.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tuid: ");
- for (i = 0; i < argp->uid.size; i++) {
- ch = ((u_int8_t *)argp->uid.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tid: %lu\n", (u_long)argp->id);
- printf("\tftype: 0x%lx\n", (u_long)argp->ftype);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __log_register_read __P((void *, __log_register_args **));
- */
-int
-__log_register_read(recbuf, argpp)
- void *recbuf;
- __log_register_args **argpp;
-{
- __log_register_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__log_register_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->name.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->name.data = bp;
- bp += argp->name.size;
- memcpy(&argp->uid.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->uid.data = bp;
- bp += argp->uid.size;
- memcpy(&argp->id, bp, sizeof(argp->id));
- bp += sizeof(argp->id);
- memcpy(&argp->ftype, bp, sizeof(argp->ftype));
- bp += sizeof(argp->ftype);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __log_init_print __P((DB_ENV *));
- */
-int
-__log_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __log_register_print, DB_log_register)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __log_init_recover __P((DB_ENV *));
- */
-int
-__log_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __log_register_recover, DB_log_register)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/log/log_compare.c b/db2/log/log_compare.c
deleted file mode 100644
index 320b34a..0000000
--- a/db2/log/log_compare.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_compare.c 10.3 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * log_compare --
- * Compare two LSN's.
- */
-int
-log_compare(lsn0, lsn1)
- const DB_LSN *lsn0, *lsn1;
-{
- if (lsn0->file != lsn1->file)
- return (lsn0->file < lsn1->file ? -1 : 1);
-
- if (lsn0->offset != lsn1->offset)
- return (lsn0->offset < lsn1->offset ? -1 : 1);
-
- return (0);
-}
diff --git a/db2/log/log_findckp.c b/db2/log/log_findckp.c
deleted file mode 100644
index ab13c83..0000000
--- a/db2/log/log_findckp.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_findckp.c 10.17 (Sleepycat) 9/17/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "txn.h"
-#include "common_ext.h"
-
-/*
- * __log_findckp --
- *
- * Looks for the most recent checkpoint that occurs before the most recent
- * checkpoint LSN, subject to the constraint that there must be at least two
- * checkpoints. The reason you need two checkpoints is that you might have
- * crashed during the most recent one and may not have a copy of all the
- * open files. This is the point from which recovery can start and the
- * point up to which archival/truncation can take place. Checkpoints in
- * the log look like:
- *
- * -------------------------------------------------------------------
- * | ckp A, ckplsn 100 | .... record .... | ckp B, ckplsn 600 | ...
- * -------------------------------------------------------------------
- * LSN 500 LSN 1000
- *
- * If we read what log returns from using the DB_CKP parameter to logput,
- * we'll get the record at LSN 1000. The checkpoint LSN there is 600.
- * Now we have to scan backwards looking for a checkpoint before LSN 600.
- * We find one at 500. This means that we can truncate the log before
- * 500 or run recovery beginning at 500.
- *
- * Returns 0 if we find a suitable checkpoint or we retrieved the
- * first record in the log from which to start.
- * Returns DB_NOTFOUND if there are no log records.
- * Returns errno on error.
- *
- * PUBLIC: int __log_findckp __P((DB_LOG *, DB_LSN *));
- */
-int
-__log_findckp(lp, lsnp)
- DB_LOG *lp;
- DB_LSN *lsnp;
-{
- DBT data;
- DB_LSN ckp_lsn, final_ckp, last_ckp, next_lsn;
- __txn_ckp_args *ckp_args;
- int ret, verbose;
-
- verbose = lp->dbenv != NULL && lp->dbenv->db_verbose != 0;
-
- /*
- * Need to find the appropriate point from which to begin
- * recovery.
- */
- memset(&data, 0, sizeof(data));
- if (F_ISSET(lp, DB_AM_THREAD))
- F_SET(&data, DB_DBT_MALLOC);
- ZERO_LSN(ckp_lsn);
- if ((ret = log_get(lp, &last_ckp, &data, DB_CHECKPOINT)) != 0) {
- if (ret == ENOENT)
- goto get_first;
- else
- return (ret);
- }
-
- final_ckp = last_ckp;
- next_lsn = last_ckp;
- do {
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
-
- if ((ret = log_get(lp, &next_lsn, &data, DB_SET)) != 0)
- return (ret);
- if ((ret = __txn_ckp_read(data.data, &ckp_args)) != 0) {
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
- return (ret);
- }
- if (IS_ZERO_LSN(ckp_lsn))
- ckp_lsn = ckp_args->ckp_lsn;
- if (verbose) {
- __db_err(lp->dbenv, "Checkpoint at: [%lu][%lu]",
- (u_long)last_ckp.file, (u_long)last_ckp.offset);
- __db_err(lp->dbenv, "Checkpoint LSN: [%lu][%lu]",
- (u_long)ckp_args->ckp_lsn.file,
- (u_long)ckp_args->ckp_lsn.offset);
- __db_err(lp->dbenv, "Previous checkpoint: [%lu][%lu]",
- (u_long)ckp_args->last_ckp.file,
- (u_long)ckp_args->last_ckp.offset);
- }
- last_ckp = next_lsn;
- next_lsn = ckp_args->last_ckp;
- __os_free(ckp_args, sizeof(*ckp_args));
-
- /*
- * Keep looping until either you 1) run out of checkpoints,
- * 2) you've found a checkpoint before the most recent
- * checkpoint's LSN and you have at least 2 checkpoints.
- */
- } while (!IS_ZERO_LSN(next_lsn) &&
- (log_compare(&last_ckp, &ckp_lsn) > 0 ||
- log_compare(&final_ckp, &last_ckp) == 0));
-
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
-
- /*
- * At this point, either, next_lsn is ZERO or ckp_lsn is the
- * checkpoint lsn and last_ckp is the LSN of the last checkpoint
- * before ckp_lsn. If the compare in the loop is still true, then
- * next_lsn must be 0 and we need to roll forward from the
- * beginning of the log.
- */
- if (log_compare(&last_ckp, &ckp_lsn) > 0 ||
- log_compare(&final_ckp, &last_ckp) == 0) {
-get_first: if ((ret = log_get(lp, &last_ckp, &data, DB_FIRST)) != 0)
- return (ret);
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
- }
- *lsnp = last_ckp;
-
- return (IS_ZERO_LSN(last_ckp) ? DB_NOTFOUND : 0);
-}
diff --git a/db2/log/log_get.c b/db2/log/log_get.c
deleted file mode 100644
index de81519..0000000
--- a/db2/log/log_get.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_get.c 10.38 (Sleepycat) 10/3/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "hash.h"
-#include "common_ext.h"
-
-/*
- * log_get --
- * Get a log record.
- */
-int
-log_get(dblp, alsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *alsn;
- DBT *dbt;
- u_int32_t flags;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Validate arguments. */
- if (flags != DB_CHECKPOINT && flags != DB_CURRENT &&
- flags != DB_FIRST && flags != DB_LAST &&
- flags != DB_NEXT && flags != DB_PREV && flags != DB_SET)
- return (__db_ferr(dblp->dbenv, "log_get", 1));
-
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- if (flags == DB_NEXT || flags == DB_PREV || flags == DB_CURRENT)
- return (__db_ferr(dblp->dbenv, "log_get", 1));
- if (!F_ISSET(dbt, DB_DBT_USERMEM | DB_DBT_MALLOC))
- return (__db_ferr(dblp->dbenv, "threaded data", 1));
- }
-
- LOCK_LOGREGION(dblp);
-
- /*
- * If we get one of the log's header records, repeat the operation.
- * This assumes that applications don't ever request the log header
- * records by LSN, but that seems reasonable to me.
- */
- ret = __log_get(dblp, alsn, dbt, flags, 0);
- if (ret == 0 && alsn->offset == 0) {
- switch (flags) {
- case DB_FIRST:
- flags = DB_NEXT;
- break;
- case DB_LAST:
- flags = DB_PREV;
- break;
- }
- ret = __log_get(dblp, alsn, dbt, flags, 0);
- }
-
- UNLOCK_LOGREGION(dblp);
-
- return (ret);
-}
-
-/*
- * __log_get --
- * Get a log record; internal version.
- *
- * PUBLIC: int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
- */
-int
-__log_get(dblp, alsn, dbt, flags, silent)
- DB_LOG *dblp;
- DB_LSN *alsn;
- DBT *dbt;
- u_int32_t flags;
- int silent;
-{
- DB_LSN nlsn;
- HDR hdr;
- LOG *lp;
- size_t len;
- ssize_t nr;
- int cnt, ret;
- char *np, *tbuf;
- const char *fail;
- void *p, *shortp;
-
- lp = dblp->lp;
- fail = np = tbuf = NULL;
-
- nlsn = dblp->c_lsn;
- switch (flags) {
- case DB_CHECKPOINT:
- nlsn = lp->chkpt_lsn;
- if (IS_ZERO_LSN(nlsn)) {
- __db_err(dblp->dbenv,
- "log_get: unable to find checkpoint record: no checkpoint set.");
- ret = ENOENT;
- goto err2;
- }
- break;
- case DB_NEXT: /* Next log record. */
- if (!IS_ZERO_LSN(nlsn)) {
- /* Increment the cursor by the cursor record size. */
- nlsn.offset += dblp->c_len;
- break;
- }
- /* FALLTHROUGH */
- case DB_FIRST: /* Find the first log record. */
- /* Find the first log file. */
- if ((ret = __log_find(dblp, 1, &cnt)) != 0)
- goto err2;
-
- /*
- * We may have only entered records in the buffer, and not
- * yet written a log file. If no log files were found and
- * there's anything in the buffer, it belongs to file 1.
- */
- if (cnt == 0)
- cnt = 1;
-
- nlsn.file = cnt;
- nlsn.offset = 0;
- break;
- case DB_CURRENT: /* Current log record. */
- break;
- case DB_PREV: /* Previous log record. */
- if (!IS_ZERO_LSN(nlsn)) {
- /* If at start-of-file, move to the previous file. */
- if (nlsn.offset == 0) {
- if (nlsn.file == 1 ||
- __log_valid(dblp, nlsn.file - 1, 0) != 0)
- return (DB_NOTFOUND);
-
- --nlsn.file;
- nlsn.offset = dblp->c_off;
- } else
- nlsn.offset = dblp->c_off;
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST: /* Last log record. */
- nlsn.file = lp->lsn.file;
- nlsn.offset = lp->lsn.offset - lp->len;
- break;
- case DB_SET: /* Set log record. */
- nlsn = *alsn;
- break;
- }
-
-retry:
- /* Return 1 if the request is past end-of-file. */
- if (nlsn.file > lp->lsn.file ||
- (nlsn.file == lp->lsn.file && nlsn.offset >= lp->lsn.offset))
- return (DB_NOTFOUND);
-
- /* If we've switched files, discard the current fd. */
- if (dblp->c_lsn.file != nlsn.file && dblp->c_fd != -1) {
- (void)__os_close(dblp->c_fd);
- dblp->c_fd = -1;
- }
-
- /* If the entire record is in the in-memory buffer, copy it out. */
- if (nlsn.file == lp->lsn.file && nlsn.offset >= lp->w_off) {
- /* Copy the header. */
- p = lp->buf + (nlsn.offset - lp->w_off);
- memcpy(&hdr, p, sizeof(HDR));
-
- /* Copy the record. */
- len = hdr.len - sizeof(HDR);
- if ((ret = __db_retcopy(dbt, (u_int8_t *)p + sizeof(HDR),
- len, &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- goto cksum;
- }
-
- /* Acquire a file descriptor. */
- if (dblp->c_fd == -1) {
- if ((ret = __log_name(dblp, nlsn.file,
- &np, &dblp->c_fd, DB_RDONLY | DB_SEQUENTIAL)) != 0) {
- fail = np;
- goto err1;
- }
- __os_freestr(np);
- np = NULL;
- }
-
- /* Seek to the header offset and read the header. */
- if ((ret =
- __os_seek(dblp->c_fd, 0, 0, nlsn.offset, 0, SEEK_SET)) != 0) {
- fail = "seek";
- goto err1;
- }
- if ((ret = __os_read(dblp->c_fd, &hdr, sizeof(HDR), &nr)) != 0) {
- fail = "read";
- goto err1;
- }
- if (nr == sizeof(HDR))
- shortp = NULL;
- else {
- /* If read returns EOF, try the next file. */
- if (nr == 0) {
- if (flags != DB_NEXT || nlsn.file == lp->lsn.file)
- goto corrupt;
-
- /* Move to the next file. */
- ++nlsn.file;
- nlsn.offset = 0;
- goto retry;
- }
-
- /*
- * If read returns a short count the rest of the record has
- * to be in the in-memory buffer.
- */
- if (lp->b_off < sizeof(HDR) - nr)
- goto corrupt;
-
- /* Get the rest of the header from the in-memory buffer. */
- memcpy((u_int8_t *)&hdr + nr, lp->buf, sizeof(HDR) - nr);
- shortp = lp->buf + (sizeof(HDR) - nr);
- }
-
- /*
- * Check for buffers of 0's, that's what we usually see during
- * recovery, although it's certainly not something on which we
- * can depend.
- */
- if (hdr.len <= sizeof(HDR))
- goto corrupt;
- len = hdr.len - sizeof(HDR);
-
- /* If we've already moved to the in-memory buffer, fill from there. */
- if (shortp != NULL) {
- if (lp->b_off < ((u_int8_t *)shortp - lp->buf) + len)
- goto corrupt;
- if ((ret = __db_retcopy(dbt, shortp, len,
- &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- goto cksum;
- }
-
- /*
- * Allocate temporary memory to hold the record.
- *
- * XXX
- * We're calling malloc(3) with a region locked. This isn't
- * a good idea.
- */
- if ((ret = __os_malloc(len, NULL, &tbuf)) != 0)
- goto err1;
-
- /*
- * Read the record into the buffer. If read returns a short count,
- * there was an error or the rest of the record is in the in-memory
- * buffer. Note, the information may be garbage if we're in recovery,
- * so don't read past the end of the buffer's memory.
- */
- if ((ret = __os_read(dblp->c_fd, tbuf, len, &nr)) != 0) {
- fail = "read";
- goto err1;
- }
- if (len - nr > sizeof(lp->buf))
- goto corrupt;
- if (nr != (ssize_t)len) {
- if (lp->b_off < len - nr)
- goto corrupt;
-
- /* Get the rest of the record from the in-memory buffer. */
- memcpy((u_int8_t *)tbuf + nr, lp->buf, len - nr);
- }
-
- /* Copy the record into the user's DBT. */
- if ((ret = __db_retcopy(dbt, tbuf, len,
- &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- __os_free(tbuf, 0);
- tbuf = NULL;
-
-cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
- if (!silent)
- __db_err(dblp->dbenv, "log_get: checksum mismatch");
- goto corrupt;
- }
-
- /* Update the cursor and the return lsn. */
- dblp->c_off = hdr.prev;
- dblp->c_len = hdr.len;
- dblp->c_lsn = *alsn = nlsn;
-
- return (0);
-
-corrupt:/*
- * This is the catchall -- for some reason we didn't find enough
- * information or it wasn't reasonable information, and it wasn't
- * because a system call failed.
- */
- ret = EIO;
- fail = "read";
-
-err1: if (!silent) {
- if (fail == NULL)
- __db_err(dblp->dbenv, "log_get: %s", strerror(ret));
- else
- __db_err(dblp->dbenv,
- "log_get: %s: %s", fail, strerror(ret));
- }
-err2: if (np != NULL)
- __os_freestr(np);
- if (tbuf != NULL)
- __os_free(tbuf, 0);
- return (ret);
-}
diff --git a/db2/log/log_put.c b/db2/log/log_put.c
deleted file mode 100644
index 86de6b0..0000000
--- a/db2/log/log_put.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_put.c 10.44 (Sleepycat) 11/3/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "hash.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-static int __log_fill __P((DB_LOG *, DB_LSN *, void *, u_int32_t));
-static int __log_flush __P((DB_LOG *, const DB_LSN *));
-static int __log_newfd __P((DB_LOG *));
-static int __log_putr __P((DB_LOG *, DB_LSN *, const DBT *, u_int32_t));
-static int __log_write __P((DB_LOG *, void *, u_int32_t));
-
-/*
- * log_put --
- * Write a log record.
- */
-int
-log_put(dblp, lsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t flags;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Validate arguments. */
- if (flags != 0 && flags != DB_CHECKPOINT &&
- flags != DB_CURLSN && flags != DB_FLUSH)
- return (__db_ferr(dblp->dbenv, "log_put", 0));
-
- LOCK_LOGREGION(dblp);
- ret = __log_put(dblp, lsn, dbt, flags);
- UNLOCK_LOGREGION(dblp);
- return (ret);
-}
-
-/*
- * __log_put --
- * Write a log record; internal version.
- *
- * PUBLIC: int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, u_int32_t));
- */
-int
-__log_put(dblp, lsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t flags;
-{
- DBT fid_dbt, t;
- DB_LSN r_unused;
- FNAME *fnp;
- LOG *lp;
- u_int32_t lastoff;
- int ret;
-
- lp = dblp->lp;
-
- /*
- * If the application just wants to know where we are, fill in
- * the information. Currently used by the transaction manager
- * to avoid writing TXN_begin records.
- */
- if (flags == DB_CURLSN) {
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
- return (0);
- }
-
- /* If this information won't fit in the file, swap files. */
- if (lp->lsn.offset + sizeof(HDR) + dbt->size > lp->persist.lg_max) {
- if (sizeof(HDR) +
- sizeof(LOGP) + dbt->size > lp->persist.lg_max) {
- __db_err(dblp->dbenv,
- "log_put: record larger than maximum file size");
- return (EINVAL);
- }
-
- /* Flush the log. */
- if ((ret = __log_flush(dblp, NULL)) != 0)
- return (ret);
-
- /*
- * Save the last known offset from the previous file, we'll
- * need it to initialize the persistent header information.
- */
- lastoff = lp->lsn.offset;
-
- /* Point the current LSN to the new file. */
- ++lp->lsn.file;
- lp->lsn.offset = 0;
-
- /* Reset the file write offset. */
- lp->w_off = 0;
- } else
- lastoff = 0;
-
- /* Initialize the LSN information returned to the user. */
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
-
- /*
- * Insert persistent information as the first record in every file.
- * Note that the previous length is wrong for the very first record
- * of the log, but that's okay, we check for it during retrieval.
- */
- if (lp->lsn.offset == 0) {
- t.data = &lp->persist;
- t.size = sizeof(LOGP);
- if ((ret = __log_putr(dblp, lsn,
- &t, lastoff == 0 ? 0 : lastoff - lp->len)) != 0)
- return (ret);
-
- /* Update the LSN information returned to the user. */
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
- }
-
- /* Write the application's log record. */
- if ((ret = __log_putr(dblp, lsn, dbt, lp->lsn.offset - lp->len)) != 0)
- return (ret);
-
- /*
- * On a checkpoint, we:
- * Put out the checkpoint record (above).
- * Save the LSN of the checkpoint in the shared region.
- * Append the set of file name information into the log.
- */
- if (flags == DB_CHECKPOINT) {
- lp->chkpt_lsn = *lsn;
-
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) /* Entry not in use. */
- continue;
- memset(&t, 0, sizeof(t));
- t.data = R_ADDR(dblp, fnp->name_off);
- t.size = strlen(t.data) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = fnp->ufid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused, 0,
- LOG_CHECKPOINT, &t, &fid_dbt, fnp->id, fnp->s_type))
- != 0)
- return (ret);
- }
- }
-
- /*
- * On a checkpoint or when flush is requested, we:
- * Flush the current buffer contents to disk.
- * Sync the log to disk.
- */
- if (flags == DB_FLUSH || flags == DB_CHECKPOINT)
- if ((ret = __log_flush(dblp, NULL)) != 0)
- return (ret);
-
- /*
- * On a checkpoint, we:
- * Save the time the checkpoint was written.
- * Reset the bytes written since the last checkpoint.
- */
- if (flags == DB_CHECKPOINT) {
- (void)time(&lp->chkpt);
- lp->stat.st_wc_bytes = lp->stat.st_wc_mbytes = 0;
- }
- return (0);
-}
-
-/*
- * __log_putr --
- * Actually put a record into the log.
- */
-static int
-__log_putr(dblp, lsn, dbt, prev)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t prev;
-{
- HDR hdr;
- LOG *lp;
- int ret;
-
- lp = dblp->lp;
-
- /*
- * Initialize the header. If we just switched files, lsn.offset will
- * be 0, and what we really want is the offset of the previous record
- * in the previous file. Fortunately, prev holds the value we want.
- */
- hdr.prev = prev;
- hdr.len = sizeof(HDR) + dbt->size;
- hdr.cksum = __ham_func4(dbt->data, dbt->size);
-
- if ((ret = __log_fill(dblp, lsn, &hdr, sizeof(HDR))) != 0)
- return (ret);
- lp->len = sizeof(HDR);
- lp->lsn.offset += sizeof(HDR);
-
- if ((ret = __log_fill(dblp, lsn, dbt->data, dbt->size)) != 0)
- return (ret);
- lp->len += dbt->size;
- lp->lsn.offset += dbt->size;
- return (0);
-}
-
-/*
- * log_flush --
- * Write all records less than or equal to the specified LSN.
- */
-int
-log_flush(dblp, lsn)
- DB_LOG *dblp;
- const DB_LSN *lsn;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- LOCK_LOGREGION(dblp);
- ret = __log_flush(dblp, lsn);
- UNLOCK_LOGREGION(dblp);
- return (ret);
-}
-
-/*
- * __log_flush --
- * Write all records less than or equal to the specified LSN; internal
- * version.
- */
-static int
-__log_flush(dblp, lsn)
- DB_LOG *dblp;
- const DB_LSN *lsn;
-{
- DB_LSN t_lsn;
- LOG *lp;
- int current, ret;
-
- ret = 0;
- lp = dblp->lp;
-
- /*
- * If no LSN specified, flush the entire log by setting the flush LSN
- * to the last LSN written in the log. Otherwise, check that the LSN
- * isn't a non-existent record for the log.
- */
- if (lsn == NULL) {
- t_lsn.file = lp->lsn.file;
- t_lsn.offset = lp->lsn.offset - lp->len;
- lsn = &t_lsn;
- } else
- if (lsn->file > lp->lsn.file ||
- (lsn->file == lp->lsn.file &&
- lsn->offset > lp->lsn.offset - lp->len)) {
- __db_err(dblp->dbenv,
- "log_flush: LSN past current end-of-log");
- return (EINVAL);
- }
-
- /*
- * If the LSN is less than the last-sync'd LSN, we're done. Note,
- * the last-sync LSN saved in s_lsn is the LSN of the first byte
- * we absolutely know has been written to disk, so the test is <=.
- */
- if (lsn->file < lp->s_lsn.file ||
- (lsn->file == lp->s_lsn.file && lsn->offset <= lp->s_lsn.offset))
- return (0);
-
- /*
- * We may need to write the current buffer. We have to write the
- * current buffer if the flush LSN is greater than or equal to the
- * buffer's starting LSN.
- */
- current = 0;
- if (lp->b_off != 0 && log_compare(lsn, &lp->f_lsn) >= 0) {
- if ((ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
- return (ret);
-
- lp->b_off = 0;
- current = 1;
- }
-
- /*
- * It's possible that this thread may never have written to this log
- * file. Acquire a file descriptor if we don't already have one.
- */
- if (dblp->lfname != dblp->lp->lsn.file)
- if ((ret = __log_newfd(dblp)) != 0)
- return (ret);
-
- /* Sync all writes to disk. */
- if ((ret = __os_fsync(dblp->lfd)) != 0) {
- __db_panic(dblp->dbenv, ret);
- return (ret);
- }
- ++lp->stat.st_scount;
-
- /*
- * Set the last-synced LSN, using the LSN of the current buffer. If
- * the current buffer was flushed, we know the LSN of the first byte
- * of the buffer is on disk, otherwise, we only know that the LSN of
- * the record before the one beginning the current buffer is on disk.
- *
- * XXX
- * Check to make sure that the saved lsn isn't 0 before we go making
- * this change. If DB_CHECKPOINT was called before we actually wrote
- * something, you can end up here without ever having written anything
- * to a log file, and decrementing either s_lsn.file or s_lsn.offset
- * will cause much sadness later on.
- */
- lp->s_lsn = lp->f_lsn;
- if (!current && lp->s_lsn.file != 0) {
- if (lp->s_lsn.offset == 0) {
- --lp->s_lsn.file;
- lp->s_lsn.offset = lp->persist.lg_max;
- } else
- --lp->s_lsn.offset;
- }
-
- return (0);
-}
-
-/*
- * __log_fill --
- * Write information into the log.
- */
-static int
-__log_fill(dblp, lsn, addr, len)
- DB_LOG *dblp;
- DB_LSN *lsn;
- void *addr;
- u_int32_t len;
-{
- LOG *lp;
- u_int32_t nrec;
- size_t nw, remain;
- int ret;
-
- /* Copy out the data. */
- for (lp = dblp->lp; len > 0;) {
- /*
- * If we're beginning a new buffer, note the user LSN to which
- * the first byte of the buffer belongs. We have to know this
- * when flushing the buffer so that we know if the in-memory
- * buffer needs to be flushed.
- */
- if (lp->b_off == 0)
- lp->f_lsn = *lsn;
-
- /*
- * If we're on a buffer boundary and the data is big enough,
- * copy as many records as we can directly from the data.
- */
- if (lp->b_off == 0 && len >= sizeof(lp->buf)) {
- nrec = len / sizeof(lp->buf);
- if ((ret = __log_write(dblp,
- addr, nrec * sizeof(lp->buf))) != 0)
- return (ret);
- addr = (u_int8_t *)addr + nrec * sizeof(lp->buf);
- len -= nrec * sizeof(lp->buf);
- continue;
- }
-
- /* Figure out how many bytes we can copy this time. */
- remain = sizeof(lp->buf) - lp->b_off;
- nw = remain > len ? len : remain;
- memcpy(lp->buf + lp->b_off, addr, nw);
- addr = (u_int8_t *)addr + nw;
- len -= nw;
- lp->b_off += nw;
-
- /* If we fill the buffer, flush it. */
- if (lp->b_off == sizeof(lp->buf)) {
- if ((ret =
- __log_write(dblp, lp->buf, sizeof(lp->buf))) != 0)
- return (ret);
- lp->b_off = 0;
- }
- }
- return (0);
-}
-
-/*
- * __log_write --
- * Write the log buffer to disk.
- */
-static int
-__log_write(dblp, addr, len)
- DB_LOG *dblp;
- void *addr;
- u_int32_t len;
-{
- LOG *lp;
- ssize_t nw;
- int ret;
-
- /*
- * If we haven't opened the log file yet or the current one
- * has changed, acquire a new log file.
- */
- lp = dblp->lp;
- if (dblp->lfd == -1 || dblp->lfname != lp->lsn.file)
- if ((ret = __log_newfd(dblp)) != 0)
- return (ret);
-
- /*
- * Seek to the offset in the file (someone may have written it
- * since we last did).
- */
- if ((ret = __os_seek(dblp->lfd, 0, 0, lp->w_off, 0, SEEK_SET)) != 0 ||
- (ret = __os_write(dblp->lfd, addr, len, &nw)) != 0) {
- __db_panic(dblp->dbenv, ret);
- return (ret);
- }
- if (nw != (int32_t)len)
- return (EIO);
-
- /* Reset the buffer offset and update the seek offset. */
- lp->w_off += len;
-
- /* Update written statistics. */
- if ((lp->stat.st_w_bytes += len) >= MEGABYTE) {
- lp->stat.st_w_bytes -= MEGABYTE;
- ++lp->stat.st_w_mbytes;
- }
- if ((lp->stat.st_wc_bytes += len) >= MEGABYTE) {
- lp->stat.st_wc_bytes -= MEGABYTE;
- ++lp->stat.st_wc_mbytes;
- }
- ++lp->stat.st_wcount;
-
- return (0);
-}
-
-/*
- * log_file --
- * Map a DB_LSN to a file name.
- */
-int
-log_file(dblp, lsn, namep, len)
- DB_LOG *dblp;
- const DB_LSN *lsn;
- char *namep;
- size_t len;
-{
- int ret;
- char *name;
-
- LOG_PANIC_CHECK(dblp);
-
- LOCK_LOGREGION(dblp);
- ret = __log_name(dblp, lsn->file, &name, NULL, 0);
- UNLOCK_LOGREGION(dblp);
- if (ret != 0)
- return (ret);
-
- /* Check to make sure there's enough room and copy the name. */
- if (len < strlen(name) + 1) {
- *namep = '\0';
- return (ENOMEM);
- }
- (void)strcpy(namep, name);
- __os_freestr(name);
-
- return (0);
-}
-
-/*
- * __log_newfd --
- * Acquire a file descriptor for the current log file.
- */
-static int
-__log_newfd(dblp)
- DB_LOG *dblp;
-{
- int ret;
- char *name;
-
- /* Close any previous file descriptor. */
- if (dblp->lfd != -1) {
- (void)__os_close(dblp->lfd);
- dblp->lfd = -1;
- }
-
- /* Get the path of the new file and open it. */
- dblp->lfname = dblp->lp->lsn.file;
- if ((ret = __log_name(dblp,
- dblp->lfname, &name, &dblp->lfd, DB_CREATE | DB_SEQUENTIAL)) != 0)
- __db_err(dblp->dbenv, "log_put: %s: %s", name, strerror(ret));
-
- __os_freestr(name);
- return (ret);
-}
-
-/*
- * __log_name --
- * Return the log name for a particular file, and optionally open it.
- *
- * PUBLIC: int __log_name __P((DB_LOG *, u_int32_t, char **, int *, u_int32_t));
- */
-int
-__log_name(dblp, filenumber, namep, fdp, flags)
- DB_LOG *dblp;
- u_int32_t filenumber, flags;
- char **namep;
- int *fdp;
-{
- int ret;
- char *oname;
- char old[sizeof(LFPREFIX) + 5 + 20], new[sizeof(LFPREFIX) + 10 + 20];
-
- /*
- * !!!
- * The semantics of this routine are bizarre.
- *
- * The reason for all of this is that we need a place where we can
- * intercept requests for log files, and, if appropriate, check for
- * both the old-style and new-style log file names. The trick is
- * that all callers of this routine that are opening the log file
- * read-only want to use an old-style file name if they can't find
- * a match using a new-style name. The only down-side is that some
- * callers may check for the old-style when they really don't need
- * to, but that shouldn't mess up anything, and we only check for
- * the old-style name when we've already failed to find a new-style
- * one.
- *
- * Create a new-style file name, and if we're not going to open the
- * file, return regardless.
- */
- (void)snprintf(new, sizeof(new), LFNAME, filenumber);
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_LOG, dblp->dir, new, 0, NULL, namep)) != 0 || fdp == NULL)
- return (ret);
-
- /* Open the new-style file -- if we succeed, we're done. */
- if ((ret = __db_open(*namep,
- flags, flags, dblp->lp->persist.mode, fdp)) == 0)
- return (0);
-
- /*
- * The open failed... if the DB_RDONLY flag isn't set, we're done,
- * the caller isn't interested in old-style files.
- */
- if (!LF_ISSET(DB_RDONLY))
- return (ret);
-
- /* Create an old-style file name. */
- (void)snprintf(old, sizeof(old), LFNAME_V1, filenumber);
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_LOG, dblp->dir, old, 0, NULL, &oname)) != 0)
- goto err;
-
- /*
- * Open the old-style file -- if we succeed, we're done. Free the
- * space allocated for the new-style name and return the old-style
- * name to the caller.
- */
- if ((ret = __db_open(oname,
- flags, flags, dblp->lp->persist.mode, fdp)) == 0) {
- __os_freestr(*namep);
- *namep = oname;
- return (0);
- }
-
- /*
- * Couldn't find either style of name -- return the new-style name
- * for the caller's error message. If it's an old-style name that's
- * actually missing we're going to confuse the user with the error
- * message, but that implies that not only were we looking for an
- * old-style name, but we expected it to exist and we weren't just
- * looking for any log file. That's not a likely error.
- */
-err: __os_freestr(oname);
- return (ret);
-}
diff --git a/db2/log/log_rec.c b/db2/log/log_rec.c
deleted file mode 100644
index 8895150..0000000
--- a/db2/log/log_rec.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_rec.c 10.26 (Sleepycat) 10/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "db_dispatch.h"
-#include "common_ext.h"
-
-static int __log_do_open __P((DB_LOG *,
- u_int8_t *, char *, DBTYPE, u_int32_t));
-static int __log_lid_to_fname __P((DB_LOG *, u_int32_t, FNAME **));
-static int __log_open_file __P((DB_LOG *, __log_register_args *));
-
-/*
- * PUBLIC: int __log_register_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_register_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __log_register_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- __log_register_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(info, NULL);
- COMPQUIET(lsnp, NULL);
-
- F_SET(logp, DBC_RECOVER);
-
- if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
- goto out;
-
- if ((argp->opcode == LOG_CHECKPOINT && redo == TXN_OPENFILES) ||
- (argp->opcode == LOG_OPEN &&
- (redo == TXN_REDO || redo == TXN_OPENFILES ||
- redo == TXN_FORWARD_ROLL)) ||
- (argp->opcode == LOG_CLOSE &&
- (redo == TXN_UNDO || redo == TXN_BACKWARD_ROLL))) {
- /*
- * If we are redoing an open or undoing a close, then we need
- * to open a file.
- */
- ret = __log_open_file(logp, argp);
- if (ret == ENOENT) {
- if (redo == TXN_OPENFILES)
- __db_err(logp->dbenv, "warning: %s: %s",
- argp->name.data, strerror(ENOENT));
- ret = 0;
- }
- } else if (argp->opcode != LOG_CHECKPOINT) {
- /*
- * If we are redoing a close or undoing an open, then we need
- * to close the file.
- *
- * If the file is deleted, then we can just ignore this close.
- * Otherwise, we should usually have a valid dbp we should
- * close or whose reference count should be decremented.
- * However, if we shut down without closing a file, we
- * may, in fact, not have the file open, and that's OK.
- */
- LOCK_LOGTHREAD(logp);
- if (logp->dbentry[argp->id].dbp != NULL &&
- --logp->dbentry[argp->id].refcount == 0) {
- ret = logp->dbentry[argp->id].dbp->close(
- logp->dbentry[argp->id].dbp, 0);
- logp->dbentry[argp->id].dbp = NULL;
- }
- UNLOCK_LOGTHREAD(logp);
- } else if (redo == TXN_UNDO &&
- (argp->id >= logp->dbentry_cnt ||
- (!logp->dbentry[argp->id].deleted &&
- logp->dbentry[argp->id].dbp == NULL))) {
- /*
- * It's a checkpoint and we are rolling backward. It
- * is possible that the system was shut down and thus
- * ended with a stable checkpoint; this file was never
- * closed and has therefore not been reopened yet. If
- * so, we need to try to open it.
- */
- ret = __log_open_file(logp, argp);
- if (ret == ENOENT) {
- __db_err(logp->dbenv, "warning: %s: %s",
- argp->name.data, strerror(ENOENT));
- ret = 0;
- }
- }
-
-out: F_CLR(logp, DBC_RECOVER);
- if (argp != NULL)
- __os_free(argp, 0);
- return (ret);
-}
-
-/* Hand coded routines. */
-
-/*
- * Called during log_register recovery. Make sure that we have an
- * entry in the dbentry table for this ndx.
- * Returns 0 on success, non-zero on error.
- */
-static int
-__log_open_file(lp, argp)
- DB_LOG *lp;
- __log_register_args *argp;
-{
- LOCK_LOGTHREAD(lp);
- if (argp->id < lp->dbentry_cnt &&
- (lp->dbentry[argp->id].deleted == 1 ||
- lp->dbentry[argp->id].dbp != NULL)) {
- if (argp->opcode != LOG_CHECKPOINT)
- lp->dbentry[argp->id].refcount++;
-
- UNLOCK_LOGTHREAD(lp);
- return (0);
- }
- UNLOCK_LOGTHREAD(lp);
- return (__log_do_open(lp,
- argp->uid.data, argp->name.data, argp->ftype, argp->id));
-}
-
-/*
- * __log_do_open --
- * Open files referenced in the log. This is the part of the open that
- * is not protected by the thread mutex.
- */
-
-static int
-__log_do_open(lp, uid, name, ftype, ndx)
- DB_LOG *lp;
- u_int8_t *uid;
- char *name;
- DBTYPE ftype;
- u_int32_t ndx;
-{
- DB *dbp;
- int ret;
-
- dbp = NULL;
- if ((ret = db_open(name, ftype, 0, 0, lp->dbenv, NULL, &dbp)) == 0) {
- /*
- * Verify that we are opening the same file that we were
- * referring to when we wrote this log record.
- */
- if (memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) {
- (void)dbp->close(dbp, 0);
- dbp = NULL;
- ret = ENOENT;
- }
- }
-
- if (ret == 0 || ret == ENOENT)
- (void)__log_add_logid(lp, dbp, ndx);
-
- return (ret);
-}
-
-/*
- * __log_add_logid --
- * Adds a DB entry to the log's DB entry table.
- *
- * PUBLIC: int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
- */
-int
-__log_add_logid(logp, dbp, ndx)
- DB_LOG *logp;
- DB *dbp;
- u_int32_t ndx;
-{
- u_int32_t i;
- int ret;
-
- ret = 0;
-
- LOCK_LOGTHREAD(logp);
-
- /*
- * Check if we need to grow the table. Note, ndx is 0-based (the
- * index into the DB entry table) an dbentry_cnt is 1-based, the
- * number of available slots.
- */
- if (logp->dbentry_cnt <= ndx) {
- if ((ret = __os_realloc(&logp->dbentry,
- (ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY))) != 0)
- goto err;
-
- /* Initialize the new entries. */
- for (i = logp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) {
- logp->dbentry[i].dbp = NULL;
- logp->dbentry[i].deleted = 0;
- }
-
- logp->dbentry_cnt = i;
- }
-
- if (logp->dbentry[ndx].deleted == 0 && logp->dbentry[ndx].dbp == NULL) {
- logp->dbentry[ndx].dbp = dbp;
- logp->dbentry[ndx].refcount = 1;
- logp->dbentry[ndx].deleted = dbp == NULL;
- } else
- logp->dbentry[ndx].refcount++;
-
-err: UNLOCK_LOGTHREAD(logp);
- return (ret);
-}
-
-
-/*
- * __db_fileid_to_db --
- * Return the DB corresponding to the specified fileid.
- *
- * PUBLIC: int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
- */
-int
-__db_fileid_to_db(logp, dbpp, ndx)
- DB_LOG *logp;
- DB **dbpp;
- u_int32_t ndx;
-{
- int ret;
- char *name;
- FNAME *fname;
-
- ret = 0;
- LOCK_LOGTHREAD(logp);
-
- /*
- * Under XA, a process different than the one issuing DB
- * operations may abort a transaction. In this case,
- * recovery routines are run by a process that does not
- * necessarily have the file open. In this case, we must
- * open the file explicitly.
- */
- if (ndx >= logp->dbentry_cnt ||
- (!logp->dbentry[ndx].deleted && logp->dbentry[ndx].dbp == NULL)) {
- if (__log_lid_to_fname(logp, ndx, &fname) != 0) {
- /* Couldn't find entry; this is a fatal error. */
- ret = EINVAL;
- goto err;
- }
- name = R_ADDR(logp, fname->name_off);
- /*
- * __log_do_open is called without protection of the
- * log thread lock.
- */
- UNLOCK_LOGTHREAD(logp);
- /*
- * At this point, we are not holding the thread lock, so
- * exit directly instead of going through the exit code
- * at the bottom. If the __log_do_open succeeded, then
- * we don't need to do any of the remaining error checking
- * at the end of this routine.
- */
- if ((ret = __log_do_open(logp,
- fname->ufid, name, fname->s_type, ndx)) != 0)
- return (ret);
- *dbpp = logp->dbentry[ndx].dbp;
- return (0);
- }
-
- /*
- * Return DB_DELETED if the file has been deleted
- * (it's not an error).
- */
- if (logp->dbentry[ndx].deleted) {
- ret = DB_DELETED;
- goto err;
- }
-
- /*
- * Otherwise return 0, but if we don't have a corresponding DB,
- * it's an error.
- */
- if ((*dbpp = logp->dbentry[ndx].dbp) == NULL)
- ret = ENOENT;
-
-err: UNLOCK_LOGTHREAD(logp);
- return (ret);
-}
-
-/*
- * Close files that were opened by the recovery daemon.
- *
- * PUBLIC: void __log_close_files __P((DB_LOG *));
- */
-void
-__log_close_files(logp)
- DB_LOG *logp;
-{
- u_int32_t i;
-
- LOCK_LOGTHREAD(logp);
- for (i = 0; i < logp->dbentry_cnt; i++)
- if (logp->dbentry[i].dbp) {
- logp->dbentry[i].dbp->close(logp->dbentry[i].dbp, 0);
- logp->dbentry[i].dbp = NULL;
- logp->dbentry[i].deleted = 0;
- }
- F_CLR(logp, DBC_RECOVER);
- UNLOCK_LOGTHREAD(logp);
-}
-
-/*
- * PUBLIC: void __log_rem_logid __P((DB_LOG *, u_int32_t));
- */
-void
-__log_rem_logid(logp, ndx)
- DB_LOG *logp;
- u_int32_t ndx;
-{
- LOCK_LOGTHREAD(logp);
- if (--logp->dbentry[ndx].refcount == 0) {
- logp->dbentry[ndx].dbp = NULL;
- logp->dbentry[ndx].deleted = 0;
- }
- UNLOCK_LOGTHREAD(logp);
-}
-
-/*
- * __log_lid_to_fname --
- * Traverse the shared-memory region looking for the entry that
- * matches the passed log fileid. Returns 0 on success; -1 on error.
- */
-static int
-__log_lid_to_fname(dblp, lid, fnamep)
- DB_LOG *dblp;
- u_int32_t lid;
- FNAME **fnamep;
-{
- FNAME *fnp;
-
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) /* Entry not in use. */
- continue;
- if (fnp->id == lid) {
- *fnamep = fnp;
- return (0);
- }
- }
- return (-1);
-}
diff --git a/db2/log/log_register.c b/db2/log/log_register.c
deleted file mode 100644
index 22264e3..0000000
--- a/db2/log/log_register.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_register.c 10.22 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "common_ext.h"
-
-/*
- * log_register --
- * Register a file name.
- */
-int
-log_register(dblp, dbp, name, type, idp)
- DB_LOG *dblp;
- DB *dbp;
- const char *name;
- DBTYPE type;
- u_int32_t *idp;
-{
- DBT fid_dbt, r_name;
- DB_LSN r_unused;
- FNAME *fnp, *reuse_fnp;
- size_t len;
- u_int32_t maxid;
- int inserted, ret;
- char *fullname;
- void *namep;
-
- inserted = 0;
- fullname = NULL;
- fnp = namep = reuse_fnp = NULL;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Check the arguments. */
- if (type != DB_BTREE && type != DB_HASH && type != DB_RECNO) {
- __db_err(dblp->dbenv, "log_register: unknown DB file type");
- return (EINVAL);
- }
-
- /* Get the log file id. */
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_DATA, NULL, name, 0, NULL, &fullname)) != 0)
- return (ret);
-
- LOCK_LOGREGION(dblp);
-
- /*
- * See if we've already got this file in the log, finding the
- * (maximum+1) in-use file id and some available file id (if we
- * find an available fid, we'll use it, else we'll have to allocate
- * one after the maximum that we found).
- */
- for (maxid = 0, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) { /* Entry is not in use. */
- if (reuse_fnp == NULL)
- reuse_fnp = fnp;
- continue;
- }
- if (!memcmp(dbp->fileid, fnp->ufid, DB_FILE_ID_LEN)) {
- ++fnp->ref;
- goto found;
- }
- if (maxid <= fnp->id)
- maxid = fnp->id + 1;
- }
-
- /* Fill in fnp structure. */
-
- if (reuse_fnp != NULL) /* Reuse existing one. */
- fnp = reuse_fnp;
- else if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0)
- goto err;
- else /* Allocate a new one. */
- fnp->id = maxid;
-
- fnp->ref = 1;
- fnp->s_type = type;
- memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN);
-
- len = strlen(name) + 1;
- if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0)
- goto err;
- fnp->name_off = R_OFFSET(dblp, namep);
- memcpy(namep, name, len);
-
- /* Only do the insert if we allocated a new fnp. */
- if (reuse_fnp == NULL)
- SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
- inserted = 1;
-
-found: /* Log the registry. */
- if (!F_ISSET(dblp, DBC_RECOVER)) {
- r_name.data = (void *)name; /* XXX: Yuck! */
- r_name.size = strlen(name) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = dbp->fileid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused,
- 0, LOG_OPEN, &r_name, &fid_dbt, fnp->id, type)) != 0)
- goto err;
- if ((ret = __log_add_logid(dblp, dbp, fnp->id)) != 0)
- goto err;
- }
-
- if (0) {
-err: /*
- * XXX
- * We should grow the region.
- */
- if (inserted)
- SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
- if (namep != NULL)
- __db_shalloc_free(dblp->addr, namep);
- if (fnp != NULL)
- __db_shalloc_free(dblp->addr, fnp);
- }
-
- if (idp != NULL)
- *idp = fnp->id;
- UNLOCK_LOGREGION(dblp);
-
- if (fullname != NULL)
- __os_freestr(fullname);
-
- return (ret);
-}
-
-/*
- * log_unregister --
- * Discard a registered file name.
- */
-int
-log_unregister(dblp, fid)
- DB_LOG *dblp;
- u_int32_t fid;
-{
- DBT fid_dbt, r_name;
- DB_LSN r_unused;
- FNAME *fnp;
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- ret = 0;
- LOCK_LOGREGION(dblp);
-
- /* Find the entry in the log. */
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname))
- if (fid == fnp->id)
- break;
- if (fnp == NULL) {
- __db_err(dblp->dbenv, "log_unregister: non-existent file id");
- ret = EINVAL;
- goto ret1;
- }
-
- /* Unlog the registry. */
- if (!F_ISSET(dblp, DBC_RECOVER)) {
- memset(&r_name, 0, sizeof(r_name));
- r_name.data = R_ADDR(dblp, fnp->name_off);
- r_name.size = strlen(r_name.data) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = fnp->ufid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused,
- 0, LOG_CLOSE, &r_name, &fid_dbt, fid, fnp->s_type)) != 0)
- goto ret1;
- }
-
- /*
- * If more than 1 reference, just decrement the reference and return.
- * Otherwise, free the name.
- */
- --fnp->ref;
- if (fnp->ref == 0)
- __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
-
- /*
- * Remove from the process local table. If this operation is taking
- * place during recovery, then the logid was never added to the table,
- * so do not remove it.
- */
- if (!F_ISSET(dblp, DBC_RECOVER))
- __log_rem_logid(dblp, fid);
-
-ret1: UNLOCK_LOGREGION(dblp);
- return (ret);
-}
diff --git a/db2/makedb.c b/db2/makedb.c
deleted file mode 100644
index edc2c5f..0000000
--- a/db2/makedb.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* Create simple DB database from textual input.
- Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <argp.h>
-#include <ctype.h>
-#include <db.h>
-#include <errno.h>
-#include <error.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-/* Get libc version number. */
-#include "../version.h"
-
-#define PACKAGE _libc_intl_domainname
-
-/* If non-zero convert key to lower case. */
-static int to_lowercase;
-
-/* If non-zero print content of input file, one entry per line. */
-static int do_undo;
-
-/* If non-zero do not print informational messages. */
-static int be_quiet;
-
-/* Name of output file. */
-static const char *output_name;
-
-/* Name and version of program. */
-static void print_version (FILE *stream, struct argp_state *state);
-void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
-
-/* Definitions of arguments for argp functions. */
-static const struct argp_option options[] =
-{
- { "fold-case", 'f', NULL, 0, N_("Convert key to lower case") },
- { "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") },
- { "quiet", 'q', NULL, 0,
- N_("Do not print messages while building database") },
- { "undo", 'u', NULL, 0,
- N_("Print content of database file, one entry a line") },
- { NULL, 0, NULL, 0, NULL }
-};
-
-/* Short description of program. */
-static const char doc[] = N_("Create simple DB database from textual input.");
-
-/* Strings for arguments in help texts. */
-static const char args_doc[] = N_("\
-INPUT-FILE OUTPUT-FILE\n-o OUTPUT-FILE INPUT-FILE\n-u INPUT-FILE");
-
-/* Prototype for option handler. */
-static error_t parse_opt __P ((int key, char *arg, struct argp_state *state));
-
-/* Function to print some extra text in the help message. */
-static char *more_help __P ((int key, const char *text, void *input));
-
-/* Data structure to communicate with argp functions. */
-static struct argp argp =
-{
- options, parse_opt, args_doc, doc, NULL, more_help
-};
-
-
-/* Prototypes for local functions. */
-static int process_input __P ((FILE *input, const char *inname, DB *output,
- int to_lowercase, int be_quiet));
-static int print_database __P ((DB *db));
-int main __P ((int argc, char *argv[]));
-
-
-int
-main (argc, argv)
- int argc;
- char *argv[];
-{
- const char *input_name;
- FILE *input_file;
- DB *db_file;
- int status;
- int remaining;
- int mode = 0666;
-
- /* Set locale via LC_ALL. */
- setlocale (LC_ALL, "");
-
- /* Set the text message domain. */
- textdomain (_libc_intl_domainname);
-
- /* Initialize local variables. */
- input_name = NULL;
-
- /* Parse and process arguments. */
- argp_parse (&argp, argc, argv, 0, &remaining, NULL);
-
- /* Determine file names. */
- if (do_undo || output_name != NULL)
- {
- if (remaining + 1 != argc)
- {
- wrong_arguments:
- error (0, 0, gettext ("wrong number of arguments"));
- argp_help (&argp, stdout, ARGP_HELP_SEE,
- program_invocation_short_name);
- exit (1);
- }
- input_name = argv[remaining];
- }
- else
- {
- if (remaining + 2 != argc)
- goto wrong_arguments;
-
- input_name = argv[remaining++];
- output_name = argv[remaining];
- }
-
- /* Special handling if we are asked to print the database. */
- if (do_undo)
- {
- status = db_open (input_name, DB_BTREE, DB_RDONLY, 0666, NULL, NULL,
- &db_file);
- if (status != 0)
- error (EXIT_FAILURE, 0, gettext ("cannot open database file `%s': %s"),
- input_name,
- (status == EINVAL ? gettext ("incorrectly formatted file")
- : strerror (status)));
-
- status = print_database (db_file);
-
- db_file->close (db_file, 0);
-
- return status;
- }
-
- /* Open input file. */
- if (strcmp (input_name, "-") == 0 || strcmp (input_name, "/dev/stdin") == 0)
- input_file = stdin;
- else
- {
- struct stat st;
-
- input_file = fopen (input_name, "r");
- if (input_file == NULL)
- error (EXIT_FAILURE, errno, gettext ("cannot open input file `%s'"),
- input_name);
-
- /* Get the access rights from the source file. The output file should
- have the same. */
- if (fstat (fileno (input_file), &st) >= 0)
- mode = st.st_mode & ACCESSPERMS;
- }
-
- /* Open output file. This must not be standard output so we don't
- handle "-" and "/dev/stdout" special. */
- status = db_open (output_name, DB_BTREE, DB_CREATE | DB_TRUNCATE, mode,
- NULL, NULL, &db_file);
- if (status != 0)
- error (EXIT_FAILURE, status, gettext ("cannot open output file `%s'"),
- output_name);
-
- /* Start the real work. */
- status = process_input (input_file, input_name, db_file, to_lowercase,
- be_quiet);
-
- /* Close files. */
- if (input_file != stdin)
- fclose (input_file);
- db_file->close (db_file, 0);
-
- return status;
-}
-
-
-/* Handle program arguments. */
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
-{
- switch (key)
- {
- case 'f':
- to_lowercase = 1;
- break;
- case 'o':
- output_name = arg;
- break;
- case 'q':
- be_quiet = 1;
- break;
- case 'u':
- do_undo = 1;
- break;
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
-}
-
-
-static char *
-more_help (int key, const char *text, void *input)
-{
- switch (key)
- {
- case ARGP_KEY_HELP_EXTRA:
- /* We print some extra information. */
- return strdup (gettext ("\
-Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"));
- default:
- break;
- }
- return (char *) text;
-}
-
-/* Print the version information. */
-static void
-print_version (FILE *stream, struct argp_state *state)
-{
- fprintf (stream, "makedb (GNU %s) %s\n", PACKAGE, VERSION);
- fprintf (stream, gettext ("\
-Copyright (C) %s Free Software Foundation, Inc.\n\
-This is free software; see the source for copying conditions. There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1999");
- fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
-}
-
-
-static int
-process_input (input, inname, output, to_lowercase, be_quiet)
- FILE *input;
- const char *inname;
- DB *output;
- int to_lowercase;
- int be_quiet;
-{
- char *line;
- size_t linelen;
- int status;
- size_t linenr;
-
- line = NULL;
- linelen = 0;
- status = EXIT_SUCCESS;
- linenr = 0;
-
- while (!feof (input))
- {
- DBT key;
- DBT val;
- char *cp;
- int n;
-
- n = getline (&line, &linelen, input);
- if (n < 0)
- /* This means end of file or some bug. */
- break;
- if (n == 0)
- /* Short read. Probably interrupted system call. */
- continue;
-
- ++linenr;
-
- if (line[n - 1] == '\n')
- /* Remove trailing newline. */
- line[--n] = '\0';
-
- cp = line;
- while (isspace (*cp))
- ++cp;
-
- if (*cp == '#')
- /* First non-space character in line '#': it's a comment. */
- continue;
-
- key.data = cp;
- while (*cp != '\0' && !isspace (*cp))
- {
- if (to_lowercase)
- *cp = tolower (*cp);
- ++cp;
- }
-
- if (key.data == cp)
- /* It's an empty line. */
- continue;
-
- key.size = cp - (char *) key.data;
- key.flags = 0;
-
- while (isspace (*cp))
- ++cp;
-
- val.data = cp;
- val.size = (&line[n] - cp) + 1;
- val.flags = 0;
-
- /* Store the value. */
- status = output->put (output, NULL, &key, &val, DB_NOOVERWRITE);
- if (status != 0)
- {
- if (status == DB_KEYEXIST)
- {
- if (!be_quiet)
- error_at_line (0, 0, inname, linenr,
- gettext ("duplicate key"));
- /* This is no real error. Just give a warning. */
- status = 0;
- continue;
- }
- else
- error (0, status, gettext ("while writing database file"));
-
- status = EXIT_FAILURE;
-
- clearerr (input);
- break;
- }
- }
-
- if (ferror (input))
- {
- error (0, 0, gettext ("problems while reading `%s'"), inname);
- status = EXIT_FAILURE;
- }
-
- return status;
-}
-
-
-static int
-print_database (db)
- DB *db;
-{
- DBT key;
- DBT val;
- DBC *cursor;
- int status;
-
- status = db->cursor (db, NULL, &cursor, 0);
- if (status != 0)
- {
- error (0, status, gettext ("while reading database"));
- return EXIT_FAILURE;
- }
-
- key.flags = 0;
- val.flags = 0;
- status = cursor->c_get (cursor, &key, &val, DB_FIRST);
- while (status == 0)
- {
- printf ("%.*s %s\n", (int) key.size, (char *) key.data,
- (char *) val.data);
-
- status = cursor->c_get (cursor, &key, &val, DB_NEXT);
- }
-
- if (status != DB_NOTFOUND)
- {
- error (0, status, gettext ("while reading database"));
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
deleted file mode 100644
index 12c5341..0000000
--- a/db2/mp/mp_bh.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_bh.c 10.45 (Sleepycat) 11/25/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-static int __memp_upgrade __P((DB_MPOOL *, DB_MPOOLFILE *, MPOOLFILE *));
-
-/*
- * __memp_bhwrite --
- * Write the page associated with a given bucket header.
- *
- * PUBLIC: int __memp_bhwrite
- * PUBLIC: __P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
- */
-int
-__memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
- DB_MPOOL *dbmp;
- MPOOLFILE *mfp;
- BH *bhp;
- int *restartp, *wrotep;
-{
- DB_MPOOLFILE *dbmfp;
- DB_MPREG *mpreg;
- int incremented, ret;
-
- if (restartp != NULL)
- *restartp = 0;
- if (wrotep != NULL)
- *wrotep = 0;
- incremented = 0;
-
- /*
- * Walk the process' DB_MPOOLFILE list and find a file descriptor for
- * the file. We also check that the descriptor is open for writing.
- * If we find a descriptor on the file that's not open for writing, we
- * try and upgrade it to make it writeable. If that fails, we're done.
- */
- LOCKHANDLE(dbmp, dbmp->mutexp);
- for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
- dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))
- if (dbmfp->mfp == mfp) {
- if (F_ISSET(dbmfp, MP_READONLY) &&
- __memp_upgrade(dbmp, dbmfp, mfp)) {
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
- return (0);
- }
-
- /*
- * Increment the reference count -- see the comment in
- * memp_fclose().
- */
- ++dbmfp->ref;
- incremented = 1;
- break;
- }
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
- if (dbmfp != NULL)
- goto found;
-
- /*
- * It's not a page from a file we've opened. If the file requires
- * input/output processing, see if this process has ever registered
- * information as to how to write this type of file. If not, there's
- * nothing we can do.
- */
- if (mfp->ftype != 0) {
- LOCKHANDLE(dbmp, dbmp->mutexp);
- for (mpreg = LIST_FIRST(&dbmp->dbregq);
- mpreg != NULL; mpreg = LIST_NEXT(mpreg, q))
- if (mpreg->ftype == mfp->ftype)
- break;
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
- if (mpreg == NULL)
- return (0);
- }
-
- /*
- * Try and open the file, attaching to the underlying shared area.
- *
- * XXX
- * Don't try to attach to temporary files. There are two problems in
- * trying to do that. First, if we have different privileges than the
- * process that "owns" the temporary file, we might create the backing
- * disk file such that the owning process couldn't read/write its own
- * buffers, e.g., memp_trickle() running as root creating a file owned
- * as root, mode 600. Second, if the temporary file has already been
- * created, we don't have any way of finding out what its real name is,
- * and, even if we did, it was already unlinked (so that it won't be
- * left if the process dies horribly). This decision causes a problem,
- * however: if the temporary file consumes the entire buffer cache,
- * and the owner doesn't flush the buffers to disk, we could end up
- * with resource starvation, and the memp_trickle() thread couldn't do
- * anything about it. That's a pretty unlikely scenario, though.
- *
- * XXX
- * There's no negative cache, so we may repeatedly try and open files
- * that we have previously tried (and failed) to open.
- *
- * Ignore any error, assume it's a permissions problem.
- */
- if (F_ISSET(mfp, MP_TEMP))
- return (0);
-
- if (__memp_fopen(dbmp, mfp, R_ADDR(dbmp, mfp->path_off),
- 0, 0, mfp->stat.st_pagesize, 0, NULL, &dbmfp) != 0)
- return (0);
-
-found: ret = __memp_pgwrite(dbmfp, bhp, restartp, wrotep);
-
- if (incremented) {
- LOCKHANDLE(dbmp, dbmp->mutexp);
- --dbmfp->ref;
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
- }
-
- return (ret);
-}
-
-/*
- * __memp_pgread --
- * Read a page from a file.
- *
- * PUBLIC: int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
- */
-int
-__memp_pgread(dbmfp, bhp, can_create)
- DB_MPOOLFILE *dbmfp;
- BH *bhp;
- int can_create;
-{
- DB_IO db_io;
- DB_MPOOL *dbmp;
- MPOOLFILE *mfp;
- size_t len, pagesize;
- ssize_t nr;
- int created, ret;
-
- dbmp = dbmfp->dbmp;
- mfp = dbmfp->mfp;
- pagesize = mfp->stat.st_pagesize;
-
- F_SET(bhp, BH_LOCKED | BH_TRASH);
- LOCKBUFFER(dbmp, bhp);
- UNLOCKREGION(dbmp);
-
- /*
- * Temporary files may not yet have been created. We don't create
- * them now, we create them when the pages have to be flushed.
- */
- nr = 0;
- if (dbmfp->fd == -1)
- ret = 0;
- else {
- /*
- * Ignore read errors if we have permission to create the page.
- * Assume that the page doesn't exist, and that we'll create it
- * when we write it out.
- */
- db_io.fd_io = dbmfp->fd;
- db_io.fd_lock = dbmp->reginfo.fd;
- db_io.mutexp =
- F_ISSET(dbmp, MP_LOCKHANDLE) ? dbmfp->mutexp : NULL;
- db_io.pagesize = db_io.bytes = pagesize;
- db_io.pgno = bhp->pgno;
- db_io.buf = bhp->buf;
-
- ret = __os_io(&db_io, DB_IO_READ, &nr);
- }
-
- created = 0;
- if (nr < (ssize_t)pagesize) {
- if (can_create)
- created = 1;
- else {
- /* If we had a short read, ret may be 0. */
- if (ret == 0)
- ret = EIO;
- __db_err(dbmp->dbenv,
- "%s: page %lu doesn't exist, create flag not set",
- __memp_fn(dbmfp), (u_long)bhp->pgno);
- goto err;
- }
- }
-
- /*
- * Clear any bytes we didn't read that need to be cleared. If we're
- * running in diagnostic mode, smash any bytes on the page that are
- * unknown quantities for the caller.
- */
- if (nr != (ssize_t)pagesize) {
- len = mfp->clear_len == 0 ? pagesize : mfp->clear_len;
- if (nr < (ssize_t)len)
- memset(bhp->buf + nr, 0, len - nr);
-#ifdef DIAGNOSTIC
- if (nr > (ssize_t)len)
- len = nr;
- if (len < pagesize)
- memset(bhp->buf + len, 0xdb, pagesize - len);
-#endif
- }
-
- /* Call any pgin function. */
- ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1);
-
- /* Unlock the buffer and reacquire the region lock. */
-err: UNLOCKBUFFER(dbmp, bhp);
- LOCKREGION(dbmp);
-
- /*
- * If no errors occurred, the data is now valid, clear the BH_TRASH
- * flag; regardless, clear the lock bit and let other threads proceed.
- */
- F_CLR(bhp, BH_LOCKED);
- if (ret == 0) {
- F_CLR(bhp, BH_TRASH);
-
- /* Update the statistics. */
- if (created) {
- ++dbmp->mp->stat.st_page_create;
- ++mfp->stat.st_page_create;
- } else {
- ++dbmp->mp->stat.st_page_in;
- ++mfp->stat.st_page_in;
- }
- }
-
- return (ret);
-}
-
-/*
- * __memp_pgwrite --
- * Write a page to a file.
- *
- * PUBLIC: int __memp_pgwrite __P((DB_MPOOLFILE *, BH *, int *, int *));
- */
-int
-__memp_pgwrite(dbmfp, bhp, restartp, wrotep)
- DB_MPOOLFILE *dbmfp;
- BH *bhp;
- int *restartp, *wrotep;
-{
- DB_ENV *dbenv;
- DB_IO db_io;
- DB_LOG *lg_info;
- DB_LSN lsn;
- DB_MPOOL *dbmp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- ssize_t nw;
- int callpgin, ret, syncfail;
- const char *fail;
-
- dbmp = dbmfp->dbmp;
- dbenv = dbmp->dbenv;
- mp = dbmp->mp;
- mfp = dbmfp->mfp;
-
- if (restartp != NULL)
- *restartp = 0;
- if (wrotep != NULL)
- *wrotep = 0;
- callpgin = 0;
-
- /*
- * Check the dirty bit -- this buffer may have been written since we
- * decided to write it.
- */
- if (!F_ISSET(bhp, BH_DIRTY)) {
- if (wrotep != NULL)
- *wrotep = 1;
- return (0);
- }
-
- LOCKBUFFER(dbmp, bhp);
-
- /*
- * If there were two writers, we may have just been waiting while the
- * other writer completed I/O on this buffer. Check the dirty bit one
- * more time.
- */
- if (!F_ISSET(bhp, BH_DIRTY)) {
- UNLOCKBUFFER(dbmp, bhp);
-
- if (wrotep != NULL)
- *wrotep = 1;
- return (0);
- }
-
- F_SET(bhp, BH_LOCKED);
- UNLOCKREGION(dbmp);
-
- if (restartp != NULL)
- *restartp = 1;
-
- /* Copy the LSN off the page if we're going to need it. */
- lg_info = dbenv->lg_info;
- if (lg_info != NULL || F_ISSET(bhp, BH_WRITE))
- memcpy(&lsn, bhp->buf + mfp->lsn_off, sizeof(DB_LSN));
-
- /* Ensure the appropriate log records are on disk. */
- if (lg_info != NULL && (ret = log_flush(lg_info, &lsn)) != 0)
- goto err;
-
- /*
- * Call any pgout function. We set the callpgin flag so that we flag
- * that the contents of the buffer will need to be passed through pgin
- * before they are reused.
- */
- if (mfp->ftype == 0)
- ret = 0;
- else {
- callpgin = 1;
- if ((ret = __memp_pg(dbmfp, bhp, 0)) != 0)
- goto err;
- }
-
- /* Temporary files may not yet have been created. */
- if (dbmfp->fd == -1) {
- LOCKHANDLE(dbmp, dbmfp->mutexp);
- if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv,
- DB_APP_TMP, NULL, NULL, DB_CREATE | DB_EXCL | DB_TEMPORARY,
- &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) {
- UNLOCKHANDLE(dbmp, dbmfp->mutexp);
- __db_err(dbenv,
- "unable to create temporary backing file");
- goto err;
- }
- UNLOCKHANDLE(dbmp, dbmfp->mutexp);
- }
-
- /* Write the page. */
- db_io.fd_io = dbmfp->fd;
- db_io.fd_lock = dbmp->reginfo.fd;
- db_io.mutexp = F_ISSET(dbmp, MP_LOCKHANDLE) ? dbmfp->mutexp : NULL;
- db_io.pagesize = db_io.bytes = mfp->stat.st_pagesize;
- db_io.pgno = bhp->pgno;
- db_io.buf = bhp->buf;
- if ((ret = __os_io(&db_io, DB_IO_WRITE, &nw)) != 0) {
- __db_panic(dbenv, ret);
- fail = "write";
- goto syserr;
- }
- if (nw != (ssize_t)mfp->stat.st_pagesize) {
- ret = EIO;
- fail = "write";
- goto syserr;
- }
-
- if (wrotep != NULL)
- *wrotep = 1;
-
- /* Unlock the buffer and reacquire the region lock. */
- UNLOCKBUFFER(dbmp, bhp);
- LOCKREGION(dbmp);
-
- /*
- * Clean up the flags based on a successful write.
- *
- * If we rewrote the page, it will need processing by the pgin
- * routine before reuse.
- */
- if (callpgin)
- F_SET(bhp, BH_CALLPGIN);
- F_CLR(bhp, BH_DIRTY | BH_LOCKED);
-
- /*
- * If we write a buffer for which a checkpoint is waiting, update
- * the count of pending buffers (both in the mpool as a whole and
- * for this file). If the count for this file goes to zero, flush
- * the writes.
- *
- * XXX:
- * Don't lock the region around the sync, fsync(2) has no atomicity
- * issues.
- *
- * XXX:
- * We ignore errors from the sync -- it makes no sense to return an
- * error to the calling process, so set a flag causing the checkpoint
- * to be retried later.
- */
- if (F_ISSET(bhp, BH_WRITE)) {
- if (mfp->lsn_cnt == 1) {
- UNLOCKREGION(dbmp);
- syncfail = __os_fsync(dbmfp->fd) != 0;
- LOCKREGION(dbmp);
- if (syncfail)
- F_SET(mp, MP_LSN_RETRY);
-
- }
-
- F_CLR(bhp, BH_WRITE);
-
- /*
- * If the buffer just written has a larger LSN than the current
- * max LSN written for this checkpoint, update the saved value.
- */
- if (log_compare(&lsn, &mp->lsn) > 0)
- mp->lsn = lsn;
-
- --mp->lsn_cnt;
- --mfp->lsn_cnt;
- }
-
- /* Update the page clean/dirty statistics. */
- ++mp->stat.st_page_clean;
- --mp->stat.st_page_dirty;
-
- /* Update I/O statistics. */
- ++mp->stat.st_page_out;
- ++mfp->stat.st_page_out;
-
- return (0);
-
-syserr: __db_err(dbenv, "%s: %s failed for page %lu",
- __memp_fn(dbmfp), fail, (u_long)bhp->pgno);
-
-err: /* Unlock the buffer and reacquire the region lock. */
- UNLOCKBUFFER(dbmp, bhp);
- LOCKREGION(dbmp);
-
- /*
- * Clean up the flags based on a failure.
- *
- * The page remains dirty but we remove our lock. If we rewrote the
- * page, it will need processing by the pgin routine before reuse.
- */
- if (callpgin)
- F_SET(bhp, BH_CALLPGIN);
- F_CLR(bhp, BH_LOCKED);
-
- return (ret);
-}
-
-/*
- * __memp_pg --
- * Call the pgin/pgout routine.
- *
- * PUBLIC: int __memp_pg __P((DB_MPOOLFILE *, BH *, int));
- */
-int
-__memp_pg(dbmfp, bhp, is_pgin)
- DB_MPOOLFILE *dbmfp;
- BH *bhp;
- int is_pgin;
-{
- DBT dbt, *dbtp;
- DB_MPOOL *dbmp;
- DB_MPREG *mpreg;
- MPOOLFILE *mfp;
- int ftype, ret;
-
- dbmp = dbmfp->dbmp;
- mfp = dbmfp->mfp;
-
- LOCKHANDLE(dbmp, dbmp->mutexp);
-
- ftype = mfp->ftype;
- for (mpreg = LIST_FIRST(&dbmp->dbregq);
- mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) {
- if (ftype != mpreg->ftype)
- continue;
- if (mfp->pgcookie_len == 0)
- dbtp = NULL;
- else {
- dbt.size = mfp->pgcookie_len;
- dbt.data = R_ADDR(dbmp, mfp->pgcookie_off);
- dbtp = &dbt;
- }
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- if (is_pgin) {
- if (mpreg->pgin != NULL && (ret =
- mpreg->pgin(bhp->pgno, bhp->buf, dbtp)) != 0)
- goto err;
- } else
- if (mpreg->pgout != NULL && (ret =
- mpreg->pgout(bhp->pgno, bhp->buf, dbtp)) != 0)
- goto err;
- break;
- }
-
- if (mpreg == NULL)
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- return (0);
-
-err: UNLOCKHANDLE(dbmp, dbmp->mutexp);
- __db_err(dbmp->dbenv, "%s: %s failed for page %lu",
- __memp_fn(dbmfp), is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno);
- return (ret);
-}
-
-/*
- * __memp_bhfree --
- * Free a bucket header and its referenced data.
- *
- * PUBLIC: void __memp_bhfree __P((DB_MPOOL *, MPOOLFILE *, BH *, int));
- */
-void
-__memp_bhfree(dbmp, mfp, bhp, free_mem)
- DB_MPOOL *dbmp;
- MPOOLFILE *mfp;
- BH *bhp;
- int free_mem;
-{
- size_t off;
-
- /* Delete the buffer header from the hash bucket queue. */
- off = BUCKET(dbmp->mp, R_OFFSET(dbmp, mfp), bhp->pgno);
- SH_TAILQ_REMOVE(&dbmp->htab[off], bhp, hq, __bh);
-
- /* Delete the buffer header from the LRU queue. */
- SH_TAILQ_REMOVE(&dbmp->mp->bhq, bhp, q, __bh);
-
- /*
- * If we're not reusing it immediately, free the buffer header
- * and data for real.
- */
- if (free_mem) {
- __db_shalloc_free(dbmp->addr, bhp);
- --dbmp->mp->stat.st_page_clean;
- }
-}
-
-/*
- * __memp_upgrade --
- * Upgrade a file descriptor from readonly to readwrite.
- */
-static int
-__memp_upgrade(dbmp, dbmfp, mfp)
- DB_MPOOL *dbmp;
- DB_MPOOLFILE *dbmfp;
- MPOOLFILE *mfp;
-{
- int fd, ret;
- char *rpath;
-
- /*
- * !!!
- * We expect the handle to already be locked.
- */
-
- /* Check to see if we've already upgraded. */
- if (F_ISSET(dbmfp, MP_UPGRADE))
- return (0);
-
- /* Check to see if we've already failed. */
- if (F_ISSET(dbmfp, MP_UPGRADE_FAIL))
- return (1);
-
- /*
- * Calculate the real name for this file and try to open it read/write.
- * We know we have a valid pathname for the file because it's the only
- * way we could have gotten a file descriptor of any kind.
- */
- if ((ret = __db_appname(dbmp->dbenv, DB_APP_DATA,
- NULL, R_ADDR(dbmp, mfp->path_off), 0, NULL, &rpath)) != 0)
- return (ret);
- if (__db_open(rpath, 0, 0, 0, &fd) != 0) {
- F_SET(dbmfp, MP_UPGRADE_FAIL);
- ret = 1;
- } else {
- /* Swap the descriptors and set the upgrade flag. */
- (void)__os_close(dbmfp->fd);
- dbmfp->fd = fd;
- F_SET(dbmfp, MP_UPGRADE);
- ret = 0;
- }
- __os_freestr(rpath);
- return (ret);
-}
diff --git a/db2/mp/mp_fget.c b/db2/mp/mp_fget.c
deleted file mode 100644
index f159dc2..0000000
--- a/db2/mp/mp_fget.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_fget.c 10.53 (Sleepycat) 11/16/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-/*
- * memp_fget --
- * Get a page from the file.
- */
-int
-memp_fget(dbmfp, pgnoaddr, flags, addrp)
- DB_MPOOLFILE *dbmfp;
- db_pgno_t *pgnoaddr;
- u_int32_t flags;
- void *addrp;
-{
- BH *bhp;
- DB_MPOOL *dbmp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- size_t bucket, mf_offset;
- u_int32_t st_hsearch;
- int b_incr, first, ret;
-
- dbmp = dbmfp->dbmp;
- mp = dbmp->mp;
- mfp = dbmfp->mfp;
-
- MP_PANIC_CHECK(dbmp);
-
- /*
- * Validate arguments.
- *
- * !!!
- * Don't test for DB_MPOOL_CREATE and DB_MPOOL_NEW flags for readonly
- * files here, and create non-existent pages in readonly files if the
- * flags are set, later. The reason is that the hash access method
- * wants to get empty pages that don't really exist in readonly files.
- * The only alternative is for hash to write the last "bucket" all the
- * time, which we don't want to do because one of our big goals in life
- * is to keep database files small. It's sleazy as hell, but we catch
- * any attempt to actually write the file in memp_fput().
- */
-#define OKFLAGS (DB_MPOOL_CREATE | DB_MPOOL_LAST | DB_MPOOL_NEW)
- if (flags != 0) {
- if ((ret =
- __db_fchk(dbmp->dbenv, "memp_fget", flags, OKFLAGS)) != 0)
- return (ret);
-
- switch (flags) {
- case DB_MPOOL_CREATE:
- case DB_MPOOL_LAST:
- case DB_MPOOL_NEW:
- case 0:
- break;
- default:
- return (__db_ferr(dbmp->dbenv, "memp_fget", 1));
- }
- }
-
-#ifdef DIAGNOSTIC
- /*
- * XXX
- * We want to switch threads as often as possible. Yield every time
- * we get a new page to ensure contention.
- */
- if (DB_GLOBAL(db_pageyield))
- __os_yield(1);
-#endif
-
- /* Initialize remaining local variables. */
- mf_offset = R_OFFSET(dbmp, mfp);
- bhp = NULL;
- st_hsearch = 0;
- b_incr = ret = 0;
-
- /* Determine the hash bucket where this page will live. */
- bucket = BUCKET(mp, mf_offset, *pgnoaddr);
-
- LOCKREGION(dbmp);
-
- /*
- * Check for the last or last + 1 page requests.
- *
- * Examine and update the file's last_pgno value. We don't care if
- * the last_pgno value immediately changes due to another thread --
- * at this instant in time, the value is correct. We do increment the
- * current last_pgno value if the thread is asking for a new page,
- * however, to ensure that two threads creating pages don't get the
- * same one.
- */
- if (LF_ISSET(DB_MPOOL_LAST | DB_MPOOL_NEW)) {
- if (LF_ISSET(DB_MPOOL_NEW))
- ++mfp->last_pgno;
- *pgnoaddr = mfp->last_pgno;
- bucket = BUCKET(mp, mf_offset, mfp->last_pgno);
-
- if (LF_ISSET(DB_MPOOL_NEW))
- goto alloc;
- }
-
- /*
- * If mmap'ing the file and the page is not past the end of the file,
- * just return a pointer.
- *
- * The page may be past the end of the file, so check the page number
- * argument against the original length of the file. If we previously
- * returned pages past the original end of the file, last_pgno will
- * have been updated to match the "new" end of the file, and checking
- * against it would return pointers past the end of the mmap'd region.
- *
- * If another process has opened the file for writing since we mmap'd
- * it, we will start playing the game by their rules, i.e. everything
- * goes through the cache. All pages previously returned will be safe,
- * as long as the correct locking protocol was observed.
- *
- * XXX
- * We don't discard the map because we don't know when all of the
- * pages will have been discarded from the process' address space.
- * It would be possible to do so by reference counting the open
- * pages from the mmap, but it's unclear to me that it's worth it.
- */
- if (dbmfp->addr != NULL && F_ISSET(mfp, MP_CAN_MMAP)) {
- if (*pgnoaddr > mfp->orig_last_pgno) {
- /*
- * !!!
- * See the comment above about non-existent pages and
- * the hash access method.
- */
- if (!LF_ISSET(DB_MPOOL_CREATE)) {
- __db_err(dbmp->dbenv,
- "%s: page %lu doesn't exist",
- __memp_fn(dbmfp), (u_long)*pgnoaddr);
- ret = EINVAL;
- goto err;
- }
- } else {
- *(void **)addrp =
- R_ADDR(dbmfp, *pgnoaddr * mfp->stat.st_pagesize);
- ++mp->stat.st_map;
- ++mfp->stat.st_map;
- goto done;
- }
- }
-
- /* Search the hash chain for the page. */
- for (bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) {
- ++st_hsearch;
- if (bhp->pgno != *pgnoaddr || bhp->mf_offset != mf_offset)
- continue;
-
- /* Increment the reference count. */
- if (bhp->ref == UINT16_T_MAX) {
- __db_err(dbmp->dbenv,
- "%s: page %lu: reference count overflow",
- __memp_fn(dbmfp), (u_long)bhp->pgno);
- ret = EINVAL;
- goto err;
- }
-
- /*
- * Increment the reference count. We may discard the region
- * lock as we evaluate and/or read the buffer, so we need to
- * ensure that it doesn't move and that its contents remain
- * unchanged.
- */
- ++bhp->ref;
- b_incr = 1;
-
- /*
- * Any buffer we find might be trouble.
- *
- * BH_LOCKED --
- * I/O is in progress. Because we've incremented the buffer
- * reference count, we know the buffer can't move. Unlock
- * the region lock, wait for the I/O to complete, and reacquire
- * the region.
- */
- for (first = 1; F_ISSET(bhp, BH_LOCKED); first = 0) {
- UNLOCKREGION(dbmp);
-
- /*
- * Explicitly yield the processor if it's not the first
- * pass through this loop -- if we don't, we might end
- * up running to the end of our CPU quantum as we will
- * simply be swapping between the two locks.
- */
- if (!first)
- __os_yield(1);
-
- LOCKBUFFER(dbmp, bhp);
- /* Wait for I/O to finish... */
- UNLOCKBUFFER(dbmp, bhp);
- LOCKREGION(dbmp);
- }
-
- /*
- * BH_TRASH --
- * The contents of the buffer are garbage. Shouldn't happen,
- * and this read is likely to fail, but might as well try.
- */
- if (F_ISSET(bhp, BH_TRASH))
- goto reread;
-
- /*
- * BH_CALLPGIN --
- * The buffer was converted so it could be written, and the
- * contents need to be converted again.
- */
- if (F_ISSET(bhp, BH_CALLPGIN)) {
- if ((ret = __memp_pg(dbmfp, bhp, 1)) != 0)
- goto err;
- F_CLR(bhp, BH_CALLPGIN);
- }
-
- ++mp->stat.st_cache_hit;
- ++mfp->stat.st_cache_hit;
- *(void **)addrp = bhp->buf;
- goto done;
- }
-
-alloc: /* Allocate new buffer header and data space. */
- if ((ret = __memp_alloc(dbmp, sizeof(BH) -
- sizeof(u_int8_t) + mfp->stat.st_pagesize, NULL, &bhp)) != 0)
- goto err;
-
-#ifdef DIAGNOSTIC
- if ((ALIGNTYPE)bhp->buf & (sizeof(size_t) - 1)) {
- __db_err(dbmp->dbenv,
- "Internal error: BH data NOT size_t aligned.");
- ret = EINVAL;
- goto err;
- }
-#endif
- /* Initialize the BH fields. */
- memset(bhp, 0, sizeof(BH));
- LOCKINIT(dbmp, &bhp->mutex);
- bhp->ref = 1;
- bhp->pgno = *pgnoaddr;
- bhp->mf_offset = mf_offset;
-
- /*
- * Prepend the bucket header to the head of the appropriate MPOOL
- * bucket hash list. Append the bucket header to the tail of the
- * MPOOL LRU chain.
- */
- SH_TAILQ_INSERT_HEAD(&dbmp->htab[bucket], bhp, hq, __bh);
- SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
-
- /*
- * If we created the page, zero it out and continue.
- *
- * !!!
- * Note: DB_MPOOL_NEW specifically doesn't call the pgin function.
- * If DB_MPOOL_CREATE is used, then the application's pgin function
- * has to be able to handle pages of 0's -- if it uses DB_MPOOL_NEW,
- * it can detect all of its page creates, and not bother.
- *
- * Otherwise, read the page into memory, optionally creating it if
- * DB_MPOOL_CREATE is set.
- */
- if (LF_ISSET(DB_MPOOL_NEW)) {
- if (mfp->clear_len == 0)
- memset(bhp->buf, 0, mfp->stat.st_pagesize);
- else {
- memset(bhp->buf, 0, mfp->clear_len);
-#ifdef DIAGNOSTIC
- memset(bhp->buf + mfp->clear_len, 0xdb,
- mfp->stat.st_pagesize - mfp->clear_len);
-#endif
- }
-
- ++mp->stat.st_page_create;
- ++mfp->stat.st_page_create;
- } else {
- /*
- * It's possible for the read function to fail, which means
- * that we fail as well. Note, the __memp_pgread() function
- * discards the region lock, so the buffer must be pinned
- * down so that it cannot move and its contents are unchanged.
- */
-reread: if ((ret = __memp_pgread(dbmfp,
- bhp, LF_ISSET(DB_MPOOL_CREATE))) != 0) {
- /*
- * !!!
- * Discard the buffer unless another thread is waiting
- * on our I/O to complete. Regardless, the header has
- * the BH_TRASH flag set.
- */
- if (bhp->ref == 1)
- __memp_bhfree(dbmp, mfp, bhp, 1);
- goto err;
- }
-
- ++mp->stat.st_cache_miss;
- ++mfp->stat.st_cache_miss;
- }
-
- /*
- * If we're returning a page after our current notion of the last-page,
- * update our information. Note, there's no way to un-instantiate this
- * page, it's going to exist whether it's returned to us dirty or not.
- */
- if (bhp->pgno > mfp->last_pgno)
- mfp->last_pgno = bhp->pgno;
-
- ++mp->stat.st_page_clean;
- *(void **)addrp = bhp->buf;
-
-done: /* Update the chain search statistics. */
- if (st_hsearch) {
- ++mp->stat.st_hash_searches;
- if (st_hsearch > mp->stat.st_hash_longest)
- mp->stat.st_hash_longest = st_hsearch;
- mp->stat.st_hash_examined += st_hsearch;
- }
-
- ++dbmfp->pinref;
-
- UNLOCKREGION(dbmp);
-
- return (0);
-
-err: /* Discard our reference. */
- if (b_incr)
- --bhp->ref;
- UNLOCKREGION(dbmp);
-
- *(void **)addrp = NULL;
- return (ret);
-}
diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c
deleted file mode 100644
index dd02662..0000000
--- a/db2/mp/mp_fopen.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_fopen.c 10.60 (Sleepycat) 1/1/99";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *));
-static int __memp_mf_open __P((DB_MPOOL *,
- const char *, size_t, db_pgno_t, DB_MPOOL_FINFO *, MPOOLFILE **));
-
-/*
- * memp_fopen --
- * Open a backing file for the memory pool.
- */
-int
-memp_fopen(dbmp, path, flags, mode, pagesize, finfop, retp)
- DB_MPOOL *dbmp;
- const char *path;
- u_int32_t flags;
- int mode;
- size_t pagesize;
- DB_MPOOL_FINFO *finfop;
- DB_MPOOLFILE **retp;
-{
- int ret;
-
- MP_PANIC_CHECK(dbmp);
-
- /* Validate arguments. */
- if ((ret = __db_fchk(dbmp->dbenv,
- "memp_fopen", flags, DB_CREATE | DB_NOMMAP | DB_RDONLY)) != 0)
- return (ret);
-
- /* Require a non-zero pagesize. */
- if (pagesize == 0) {
- __db_err(dbmp->dbenv, "memp_fopen: pagesize not specified");
- return (EINVAL);
- }
- if (finfop != NULL && finfop->clear_len > pagesize)
- return (EINVAL);
-
- return (__memp_fopen(dbmp,
- NULL, path, flags, mode, pagesize, 1, finfop, retp));
-}
-
-/*
- * __memp_fopen --
- * Open a backing file for the memory pool; internal version.
- *
- * PUBLIC: int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *,
- * PUBLIC: u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
- */
-int
-__memp_fopen(dbmp, mfp, path, flags, mode, pagesize, needlock, finfop, retp)
- DB_MPOOL *dbmp;
- MPOOLFILE *mfp;
- const char *path;
- u_int32_t flags;
- int mode, needlock;
- size_t pagesize;
- DB_MPOOL_FINFO *finfop;
- DB_MPOOLFILE **retp;
-{
- DB_ENV *dbenv;
- DB_MPOOLFILE *dbmfp;
- DB_MPOOL_FINFO finfo;
- db_pgno_t last_pgno;
- size_t maxmap;
- u_int32_t mbytes, bytes;
- int ret;
- u_int8_t idbuf[DB_FILE_ID_LEN];
- char *rpath;
-
- dbenv = dbmp->dbenv;
- ret = 0;
- rpath = NULL;
-
- /*
- * If mfp is provided, we take the DB_MPOOL_FINFO information from
- * the mfp. We don't bother initializing everything, because some
- * of them are expensive to acquire. If no mfp is provided and the
- * finfop argument is NULL, we default the values.
- */
- if (finfop == NULL) {
- memset(&finfo, 0, sizeof(finfo));
- if (mfp != NULL) {
- finfo.ftype = mfp->ftype;
- finfo.pgcookie = NULL;
- finfo.fileid = NULL;
- finfo.lsn_offset = mfp->lsn_off;
- finfo.clear_len = mfp->clear_len;
- } else {
- finfo.ftype = 0;
- finfo.pgcookie = NULL;
- finfo.fileid = NULL;
- finfo.lsn_offset = -1;
- finfo.clear_len = 0;
- }
- finfop = &finfo;
- }
-
- /* Allocate and initialize the per-process structure. */
- if ((ret = __os_calloc(1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0)
- return (ret);
- dbmfp->dbmp = dbmp;
- dbmfp->fd = -1;
- dbmfp->ref = 1;
- if (LF_ISSET(DB_RDONLY))
- F_SET(dbmfp, MP_READONLY);
-
- if (path == NULL) {
- if (LF_ISSET(DB_RDONLY)) {
- __db_err(dbenv,
- "memp_fopen: temporary files can't be readonly");
- ret = EINVAL;
- goto err;
- }
- last_pgno = 0;
- } else {
- /* Get the real name for this file and open it. */
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, NULL, path, 0, NULL, &rpath)) != 0)
- goto err;
- if ((ret = __db_open(rpath,
- LF_ISSET(DB_CREATE | DB_RDONLY),
- DB_CREATE | DB_RDONLY, mode, &dbmfp->fd)) != 0) {
- __db_err(dbenv, "%s: %s", rpath, strerror(ret));
- goto err;
- }
-
- /*
- * Don't permit files that aren't a multiple of the pagesize,
- * and find the number of the last page in the file, all the
- * time being careful not to overflow 32 bits.
- *
- * !!!
- * We can't use off_t's here, or in any code in the mainline
- * library for that matter. (We have to use them in the os
- * stubs, of course, as there are system calls that take them
- * as arguments.) The reason is that some customers build in
- * environments where an off_t is 32-bits, but still run where
- * offsets are 64-bits, and they pay us a lot of money.
- */
- if ((ret = __os_ioinfo(rpath,
- dbmfp->fd, &mbytes, &bytes, NULL)) != 0) {
- __db_err(dbenv, "%s: %s", rpath, strerror(ret));
- goto err;
- }
-
- /* Page sizes have to be a power-of-two, ignore mbytes. */
- if (bytes % pagesize != 0) {
- __db_err(dbenv,
- "%s: file size not a multiple of the pagesize",
- rpath);
- ret = EINVAL;
- goto err;
- }
-
- last_pgno = mbytes * (MEGABYTE / pagesize);
- last_pgno += bytes / pagesize;
-
- /* Correction: page numbers are zero-based, not 1-based. */
- if (last_pgno != 0)
- --last_pgno;
-
- /*
- * Get the file id if we weren't given one. Generated file id's
- * don't use timestamps, otherwise there'd be no chance of any
- * other process joining the party.
- */
- if (finfop->fileid == NULL) {
- if ((ret = __os_fileid(dbenv, rpath, 0, idbuf)) != 0)
- goto err;
- finfop->fileid = idbuf;
- }
- }
-
- /*
- * If we weren't provided an underlying shared object to join with,
- * find/allocate the shared file objects. Also allocate space for
- * for the per-process thread lock.
- */
- if (needlock)
- LOCKREGION(dbmp);
-
- if (mfp == NULL)
- ret = __memp_mf_open(dbmp,
- path, pagesize, last_pgno, finfop, &mfp);
- else {
- ++mfp->ref;
- ret = 0;
- }
- if (ret == 0 &&
- F_ISSET(dbmp, MP_LOCKHANDLE) && (ret =
- __memp_alloc(dbmp, sizeof(db_mutex_t), NULL, &dbmfp->mutexp)) == 0)
- LOCKINIT(dbmp, dbmfp->mutexp);
-
- if (needlock)
- UNLOCKREGION(dbmp);
- if (ret != 0)
- goto err;
-
- dbmfp->mfp = mfp;
-
- /*
- * If a file:
- * + is read-only
- * + isn't temporary
- * + doesn't require any pgin/pgout support
- * + the DB_NOMMAP flag wasn't set
- * + and is less than mp_mmapsize bytes in size
- *
- * we can mmap it instead of reading/writing buffers. Don't do error
- * checking based on the mmap call failure. We want to do normal I/O
- * on the file if the reason we failed was because the file was on an
- * NFS mounted partition, and we can fail in buffer I/O just as easily
- * as here.
- *
- * XXX
- * We'd like to test to see if the file is too big to mmap. Since we
- * don't know what size or type off_t's or size_t's are, or the largest
- * unsigned integral type is, or what random insanity the local C
- * compiler will perpetrate, doing the comparison in a portable way is
- * flatly impossible. Hope that mmap fails if the file is too large.
- */
-#define DB_MAXMMAPSIZE (10 * 1024 * 1024) /* 10 Mb. */
- if (F_ISSET(mfp, MP_CAN_MMAP)) {
- if (!F_ISSET(dbmfp, MP_READONLY))
- F_CLR(mfp, MP_CAN_MMAP);
- if (path == NULL)
- F_CLR(mfp, MP_CAN_MMAP);
- if (finfop->ftype != 0)
- F_CLR(mfp, MP_CAN_MMAP);
- if (LF_ISSET(DB_NOMMAP))
- F_CLR(mfp, MP_CAN_MMAP);
- maxmap = dbenv == NULL || dbenv->mp_mmapsize == 0 ?
- DB_MAXMMAPSIZE : dbenv->mp_mmapsize;
- if (mbytes > maxmap / MEGABYTE ||
- (mbytes == maxmap / MEGABYTE && bytes >= maxmap % MEGABYTE))
- F_CLR(mfp, MP_CAN_MMAP);
- }
- dbmfp->addr = NULL;
- if (F_ISSET(mfp, MP_CAN_MMAP)) {
- dbmfp->len = (size_t)mbytes * MEGABYTE + bytes;
- if (__db_mapfile(rpath,
- dbmfp->fd, dbmfp->len, 1, &dbmfp->addr) != 0) {
- dbmfp->addr = NULL;
- F_CLR(mfp, MP_CAN_MMAP);
- }
- }
- if (rpath != NULL)
- __os_freestr(rpath);
-
- LOCKHANDLE(dbmp, dbmp->mutexp);
- TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- *retp = dbmfp;
- return (0);
-
-err: /*
- * Note that we do not have to free the thread mutex, because we
- * never get to here after we have successfully allocated it.
- */
- if (rpath != NULL)
- __os_freestr(rpath);
- if (dbmfp->fd != -1)
- (void)__os_close(dbmfp->fd);
- if (dbmfp != NULL)
- __os_free(dbmfp, sizeof(DB_MPOOLFILE));
- return (ret);
-}
-
-/*
- * __memp_mf_open --
- * Open an MPOOLFILE.
- */
-static int
-__memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, retp)
- DB_MPOOL *dbmp;
- const char *path;
- size_t pagesize;
- db_pgno_t last_pgno;
- DB_MPOOL_FINFO *finfop;
- MPOOLFILE **retp;
-{
- MPOOLFILE *mfp;
- int ret;
- void *p;
-
-#define ISTEMPORARY (path == NULL)
-
- /*
- * Walk the list of MPOOLFILE's, looking for a matching file.
- * Temporary files can't match previous files.
- */
- if (!ISTEMPORARY)
- for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
- if (F_ISSET(mfp, MP_TEMP))
- continue;
- if (!memcmp(finfop->fileid,
- R_ADDR(dbmp, mfp->fileid_off), DB_FILE_ID_LEN)) {
- if (finfop->clear_len != mfp->clear_len ||
- finfop->ftype != mfp->ftype ||
- pagesize != mfp->stat.st_pagesize) {
- __db_err(dbmp->dbenv,
- "%s: ftype, clear length or pagesize changed",
- path);
- return (EINVAL);
- }
-
- /* Found it: increment the reference count. */
- ++mfp->ref;
- *retp = mfp;
- return (0);
- }
- }
-
- /* Allocate a new MPOOLFILE. */
- if ((ret = __memp_alloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
- return (ret);
- *retp = mfp;
-
- /* Initialize the structure. */
- memset(mfp, 0, sizeof(MPOOLFILE));
- mfp->ref = 1;
- mfp->ftype = finfop->ftype;
- mfp->lsn_off = finfop->lsn_offset;
- mfp->clear_len = finfop->clear_len;
-
- /*
- * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a memp_fget,
- * we have to know the last page in the file. Figure it out and save
- * it away.
- */
- mfp->stat.st_pagesize = pagesize;
- mfp->orig_last_pgno = mfp->last_pgno = last_pgno;
-
- if (ISTEMPORARY)
- F_SET(mfp, MP_TEMP);
- else {
- /* Copy the file path into shared memory. */
- if ((ret = __memp_alloc(dbmp,
- strlen(path) + 1, &mfp->path_off, &p)) != 0)
- goto err;
- memcpy(p, path, strlen(path) + 1);
-
- /* Copy the file identification string into shared memory. */
- if ((ret = __memp_alloc(dbmp,
- DB_FILE_ID_LEN, &mfp->fileid_off, &p)) != 0)
- goto err;
- memcpy(p, finfop->fileid, DB_FILE_ID_LEN);
-
- F_SET(mfp, MP_CAN_MMAP);
- }
-
- /* Copy the page cookie into shared memory. */
- if (finfop->pgcookie == NULL || finfop->pgcookie->size == 0) {
- mfp->pgcookie_len = 0;
- mfp->pgcookie_off = 0;
- } else {
- if ((ret = __memp_alloc(dbmp,
- finfop->pgcookie->size, &mfp->pgcookie_off, &p)) != 0)
- goto err;
- memcpy(p, finfop->pgcookie->data, finfop->pgcookie->size);
- mfp->pgcookie_len = finfop->pgcookie->size;
- }
-
- /* Prepend the MPOOLFILE to the list of MPOOLFILE's. */
- SH_TAILQ_INSERT_HEAD(&dbmp->mp->mpfq, mfp, q, __mpoolfile);
-
- if (0) {
-err: if (mfp->path_off != 0)
- __db_shalloc_free(dbmp->addr,
- R_ADDR(dbmp, mfp->path_off));
- if (mfp->fileid_off != 0)
- __db_shalloc_free(dbmp->addr,
- R_ADDR(dbmp, mfp->fileid_off));
- if (mfp != NULL)
- __db_shalloc_free(dbmp->addr, mfp);
- mfp = NULL;
- }
- return (0);
-}
-
-/*
- * memp_fclose --
- * Close a backing file for the memory pool.
- */
-int
-memp_fclose(dbmfp)
- DB_MPOOLFILE *dbmfp;
-{
- DB_MPOOL *dbmp;
- int ret, t_ret;
-
- dbmp = dbmfp->dbmp;
- ret = 0;
-
- MP_PANIC_CHECK(dbmp);
-
- for (;;) {
- LOCKHANDLE(dbmp, dbmp->mutexp);
-
- /*
- * We have to reference count DB_MPOOLFILE structures as other
- * threads may be using them. The problem only happens if the
- * application makes a bad design choice. Here's the path:
- *
- * Thread A opens a database.
- * Thread B uses thread A's DB_MPOOLFILE to write a buffer
- * in order to free up memory in the mpool cache.
- * Thread A closes the database while thread B is using the
- * DB_MPOOLFILE structure.
- *
- * By opening all databases before creating the threads, and
- * closing them after the threads have exited, applications
- * get better performance and avoid the problem path entirely.
- *
- * Regardless, holding the DB_MPOOLFILE to flush a dirty buffer
- * is a short-term lock, even in worst case, since we better be
- * the only thread of control using the DB_MPOOLFILE structure
- * to read pages *into* the cache. Wait until we're the only
- * reference holder and remove the DB_MPOOLFILE structure from
- * the list, so nobody else can even find it.
- */
- if (dbmfp->ref == 1) {
- TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);
- break;
- }
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- (void)__os_sleep(1, 0);
- }
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- /* Complain if pinned blocks never returned. */
- if (dbmfp->pinref != 0)
- __db_err(dbmp->dbenv, "%s: close: %lu blocks left pinned",
- __memp_fn(dbmfp), (u_long)dbmfp->pinref);
-
- /* Close the underlying MPOOLFILE. */
- (void)__memp_mf_close(dbmp, dbmfp);
-
- /* Discard any mmap information. */
- if (dbmfp->addr != NULL &&
- (ret = __db_unmapfile(dbmfp->addr, dbmfp->len)) != 0)
- __db_err(dbmp->dbenv,
- "%s: %s", __memp_fn(dbmfp), strerror(ret));
-
- /* Close the file; temporary files may not yet have been created. */
- if (dbmfp->fd != -1 && (t_ret = __os_close(dbmfp->fd)) != 0) {
- __db_err(dbmp->dbenv,
- "%s: %s", __memp_fn(dbmfp), strerror(t_ret));
- if (ret != 0)
- t_ret = ret;
- }
-
- /* Free memory. */
- if (dbmfp->mutexp != NULL) {
- LOCKREGION(dbmp);
- __db_shalloc_free(dbmp->addr, dbmfp->mutexp);
- UNLOCKREGION(dbmp);
- }
-
- /* Discard the DB_MPOOLFILE structure. */
- __os_free(dbmfp, sizeof(DB_MPOOLFILE));
-
- return (ret);
-}
-
-/*
- * __memp_mf_close --
- * Close down an MPOOLFILE.
- */
-static int
-__memp_mf_close(dbmp, dbmfp)
- DB_MPOOL *dbmp;
- DB_MPOOLFILE *dbmfp;
-{
- BH *bhp, *nbhp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- size_t mf_offset;
-
- mp = dbmp->mp;
- mfp = dbmfp->mfp;
-
- LOCKREGION(dbmp);
-
- /* If more than a single reference, simply decrement. */
- if (mfp->ref > 1) {
- --mfp->ref;
- goto ret1;
- }
-
- /*
- * Move any BH's held by the file to the free list. We don't free the
- * memory itself because we may be discarding the memory pool, and it's
- * fairly expensive to reintegrate the buffers back into the region for
- * no purpose.
- */
- mf_offset = R_OFFSET(dbmp, mfp);
- for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh); bhp != NULL; bhp = nbhp) {
- nbhp = SH_TAILQ_NEXT(bhp, q, __bh);
-
-#ifdef DEBUG_NO_DIRTY
- /* Complain if we find any blocks that were left dirty. */
- if (F_ISSET(bhp, BH_DIRTY))
- __db_err(dbmp->dbenv,
- "%s: close: pgno %lu left dirty; ref %lu",
- __memp_fn(dbmfp),
- (u_long)bhp->pgno, (u_long)bhp->ref);
-#endif
-
- if (bhp->mf_offset == mf_offset) {
- if (F_ISSET(bhp, BH_DIRTY)) {
- ++mp->stat.st_page_clean;
- --mp->stat.st_page_dirty;
- }
- __memp_bhfree(dbmp, mfp, bhp, 0);
- SH_TAILQ_INSERT_HEAD(&mp->bhfq, bhp, q, __bh);
- }
- }
-
- /* Delete from the list of MPOOLFILEs. */
- SH_TAILQ_REMOVE(&mp->mpfq, mfp, q, __mpoolfile);
-
- /* Free the space. */
- if (mfp->path_off != 0)
- __db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->path_off));
- if (mfp->fileid_off != 0)
- __db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->fileid_off));
- if (mfp->pgcookie_off != 0)
- __db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->pgcookie_off));
- __db_shalloc_free(dbmp->addr, mfp);
-
-ret1: UNLOCKREGION(dbmp);
- return (0);
-}
diff --git a/db2/mp/mp_fput.c b/db2/mp/mp_fput.c
deleted file mode 100644
index c551f97..0000000
--- a/db2/mp/mp_fput.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_fput.c 10.24 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-/*
- * memp_fput --
- * Mpool file put function.
- */
-int
-memp_fput(dbmfp, pgaddr, flags)
- DB_MPOOLFILE *dbmfp;
- void *pgaddr;
- u_int32_t flags;
-{
- BH *bhp;
- DB_MPOOL *dbmp;
- MPOOL *mp;
- int wrote, ret;
-
- dbmp = dbmfp->dbmp;
- mp = dbmp->mp;
-
- MP_PANIC_CHECK(dbmp);
-
- /* Validate arguments. */
- if (flags) {
- if ((ret = __db_fchk(dbmp->dbenv, "memp_fput", flags,
- DB_MPOOL_CLEAN | DB_MPOOL_DIRTY | DB_MPOOL_DISCARD)) != 0)
- return (ret);
- if ((ret = __db_fcchk(dbmp->dbenv, "memp_fput",
- flags, DB_MPOOL_CLEAN, DB_MPOOL_DIRTY)) != 0)
- return (ret);
-
- if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) {
- __db_err(dbmp->dbenv,
- "%s: dirty flag set for readonly file page",
- __memp_fn(dbmfp));
- return (EACCES);
- }
- }
-
- LOCKREGION(dbmp);
-
- /* Decrement the pinned reference count. */
- if (dbmfp->pinref == 0)
- __db_err(dbmp->dbenv,
- "%s: put: more blocks returned than retrieved",
- __memp_fn(dbmfp));
- else
- --dbmfp->pinref;
-
- /*
- * If we're mapping the file, there's nothing to do. Because we can
- * stop mapping the file at any time, we have to check on each buffer
- * to see if the address we gave the application was part of the map
- * region.
- */
- if (dbmfp->addr != NULL && pgaddr >= dbmfp->addr &&
- (u_int8_t *)pgaddr <= (u_int8_t *)dbmfp->addr + dbmfp->len) {
- UNLOCKREGION(dbmp);
- return (0);
- }
-
- /* Convert the page address to a buffer header. */
- bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
-
- /* Set/clear the page bits. */
- if (LF_ISSET(DB_MPOOL_CLEAN) && F_ISSET(bhp, BH_DIRTY)) {
- ++mp->stat.st_page_clean;
- --mp->stat.st_page_dirty;
- F_CLR(bhp, BH_DIRTY);
- }
- if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) {
- --mp->stat.st_page_clean;
- ++mp->stat.st_page_dirty;
- F_SET(bhp, BH_DIRTY);
- }
- if (LF_ISSET(DB_MPOOL_DISCARD))
- F_SET(bhp, BH_DISCARD);
-
- /*
- * Check for a reference count going to zero. This can happen if the
- * application returns a page twice.
- */
- if (bhp->ref == 0) {
- __db_err(dbmp->dbenv, "%s: page %lu: unpinned page returned",
- __memp_fn(dbmfp), (u_long)bhp->pgno);
- UNLOCKREGION(dbmp);
- return (EINVAL);
- }
-
- /*
- * If more than one reference to the page, we're done. Ignore the
- * discard flags (for now) and leave it at its position in the LRU
- * chain. The rest gets done at last reference close.
- */
- if (--bhp->ref > 0) {
- UNLOCKREGION(dbmp);
- return (0);
- }
-
- /*
- * If this buffer is scheduled for writing because of a checkpoint, we
- * need to write it (if we marked it dirty), or update the checkpoint
- * counters (if we didn't mark it dirty). If we try to write it and
- * can't, that's not necessarily an error, but set a flag so that the
- * next time the memp_sync function runs we try writing it there, as
- * the checkpoint application better be able to write all of the files.
- */
- if (F_ISSET(bhp, BH_WRITE)) {
- if (F_ISSET(bhp, BH_DIRTY)) {
- if (__memp_bhwrite(dbmp,
- dbmfp->mfp, bhp, NULL, &wrote) != 0 || !wrote)
- F_SET(mp, MP_LSN_RETRY);
- } else {
- F_CLR(bhp, BH_WRITE);
-
- --dbmfp->mfp->lsn_cnt;
- --mp->lsn_cnt;
- }
- }
-
- /* Move the buffer to the head/tail of the LRU chain. */
- SH_TAILQ_REMOVE(&mp->bhq, bhp, q, __bh);
- if (F_ISSET(bhp, BH_DISCARD))
- SH_TAILQ_INSERT_HEAD(&mp->bhq, bhp, q, __bh);
- else
- SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
-
-
- UNLOCKREGION(dbmp);
- return (0);
-}
diff --git a/db2/mp/mp_fset.c b/db2/mp/mp_fset.c
deleted file mode 100644
index 1940d3b..0000000
--- a/db2/mp/mp_fset.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_fset.c 10.16 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-/*
- * memp_fset --
- * Mpool page set-flag routine.
- */
-int
-memp_fset(dbmfp, pgaddr, flags)
- DB_MPOOLFILE *dbmfp;
- void *pgaddr;
- u_int32_t flags;
-{
- BH *bhp;
- DB_MPOOL *dbmp;
- MPOOL *mp;
- int ret;
-
- dbmp = dbmfp->dbmp;
- mp = dbmp->mp;
-
- MP_PANIC_CHECK(dbmp);
-
- /* Validate arguments. */
- if (flags == 0)
- return (__db_ferr(dbmp->dbenv, "memp_fset", 1));
-
- if ((ret = __db_fchk(dbmp->dbenv, "memp_fset", flags,
- DB_MPOOL_DIRTY | DB_MPOOL_CLEAN | DB_MPOOL_DISCARD)) != 0)
- return (ret);
- if ((ret = __db_fcchk(dbmp->dbenv, "memp_fset",
- flags, DB_MPOOL_CLEAN, DB_MPOOL_DIRTY)) != 0)
- return (ret);
-
- if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) {
- __db_err(dbmp->dbenv,
- "%s: dirty flag set for readonly file page",
- __memp_fn(dbmfp));
- return (EACCES);
- }
-
- /* Convert the page address to a buffer header. */
- bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
-
- LOCKREGION(dbmp);
-
- if (LF_ISSET(DB_MPOOL_CLEAN) && F_ISSET(bhp, BH_DIRTY)) {
- ++mp->stat.st_page_clean;
- --mp->stat.st_page_dirty;
- F_CLR(bhp, BH_DIRTY);
- }
- if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) {
- --mp->stat.st_page_clean;
- ++mp->stat.st_page_dirty;
- F_SET(bhp, BH_DIRTY);
- }
- if (LF_ISSET(DB_MPOOL_DISCARD))
- F_SET(bhp, BH_DISCARD);
-
- UNLOCKREGION(dbmp);
- return (0);
-}
diff --git a/db2/mp/mp_open.c b/db2/mp/mp_open.c
deleted file mode 100644
index 4c90fc4..0000000
--- a/db2/mp/mp_open.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_open.c 10.27 (Sleepycat) 10/1/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-/*
- * memp_open --
- * Initialize and/or join a memory pool.
- */
-int
-memp_open(path, flags, mode, dbenv, retp)
- const char *path;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_MPOOL **retp;
-{
- DB_MPOOL *dbmp;
- size_t cachesize;
- int is_private, ret;
-
- /* Validate arguments. */
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP | DB_THREAD)
-#else
-#define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP)
-#endif
- if ((ret = __db_fchk(dbenv, "memp_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- /* Extract fields from DB_ENV structure. */
- cachesize = dbenv == NULL ? 0 : dbenv->mp_size;
-
- /* Create and initialize the DB_MPOOL structure. */
- if ((ret = __os_calloc(1, sizeof(DB_MPOOL), &dbmp)) != 0)
- return (ret);
- LIST_INIT(&dbmp->dbregq);
- TAILQ_INIT(&dbmp->dbmfq);
-
- dbmp->dbenv = dbenv;
-
- /* Decide if it's possible for anyone else to access the pool. */
- is_private =
- (dbenv == NULL && path == NULL) || LF_ISSET(DB_MPOOL_PRIVATE);
-
- /*
- * Map in the region. We do locking regardless, as portions of it are
- * implemented in common code (if we put the region in a file, that is).
- */
- F_SET(dbmp, MP_LOCKREGION);
- if ((ret = __memp_ropen(dbmp,
- path, cachesize, mode, is_private, LF_ISSET(DB_CREATE))) != 0)
- goto err;
- F_CLR(dbmp, MP_LOCKREGION);
-
- /*
- * If there's concurrent access, then we have to lock the region.
- * If it's threaded, then we have to lock both the handles and the
- * region, and we need to allocate a mutex for that purpose.
- */
- if (!is_private)
- F_SET(dbmp, MP_LOCKREGION);
- if (LF_ISSET(DB_THREAD)) {
- F_SET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION);
- LOCKREGION(dbmp);
- ret = __memp_alloc(dbmp,
- sizeof(db_mutex_t), NULL, &dbmp->mutexp);
- UNLOCKREGION(dbmp);
- if (ret != 0) {
- (void)memp_close(dbmp);
- goto err;
- }
- LOCKINIT(dbmp, dbmp->mutexp);
- }
-
- *retp = dbmp;
- return (0);
-
-err: if (dbmp != NULL)
- __os_free(dbmp, sizeof(DB_MPOOL));
- return (ret);
-}
-
-/*
- * memp_close --
- * Close a memory pool.
- */
-int
-memp_close(dbmp)
- DB_MPOOL *dbmp;
-{
- DB_MPOOLFILE *dbmfp;
- DB_MPREG *mpreg;
- int ret, t_ret;
-
- ret = 0;
-
- MP_PANIC_CHECK(dbmp);
-
- /* Discard DB_MPREGs. */
- while ((mpreg = LIST_FIRST(&dbmp->dbregq)) != NULL) {
- LIST_REMOVE(mpreg, q);
- __os_free(mpreg, sizeof(DB_MPREG));
- }
-
- /* Discard DB_MPOOLFILEs. */
- while ((dbmfp = TAILQ_FIRST(&dbmp->dbmfq)) != NULL)
- if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard thread mutex. */
- if (F_ISSET(dbmp, MP_LOCKHANDLE)) {
- LOCKREGION(dbmp);
- __db_shalloc_free(dbmp->addr, dbmp->mutexp);
- UNLOCKREGION(dbmp);
- }
-
- /* Close the region. */
- if ((t_ret = __db_rdetach(&dbmp->reginfo)) != 0 && ret == 0)
- ret = t_ret;
-
- if (dbmp->reginfo.path != NULL)
- __os_freestr(dbmp->reginfo.path);
- __os_free(dbmp, sizeof(DB_MPOOL));
-
- return (ret);
-}
-
-/*
- * __memp_panic --
- * Panic a memory pool.
- *
- * PUBLIC: void __memp_panic __P((DB_ENV *));
- */
-void
-__memp_panic(dbenv)
- DB_ENV *dbenv;
-{
- if (dbenv->mp_info != NULL)
- dbenv->mp_info->mp->rlayout.panic = 1;
-}
-
-/*
- * memp_unlink --
- * Exit a memory pool.
- */
-int
-memp_unlink(path, force, dbenv)
- const char *path;
- int force;
- DB_ENV *dbenv;
-{
- REGINFO reginfo;
- int ret;
-
- memset(&reginfo, 0, sizeof(reginfo));
- reginfo.dbenv = dbenv;
- reginfo.appname = DB_APP_NONE;
- if (path != NULL && (ret = __os_strdup(path, &reginfo.path)) != 0)
- return (ret);
- reginfo.file = DB_DEFAULT_MPOOL_FILE;
- ret = __db_runlink(&reginfo, force);
- if (reginfo.path != NULL)
- __os_freestr(reginfo.path);
- return (ret);
-}
-
-/*
- * memp_register --
- * Register a file type's pgin, pgout routines.
- */
-int
-memp_register(dbmp, ftype, pgin, pgout)
- DB_MPOOL *dbmp;
- int ftype;
- int (*pgin) __P((db_pgno_t, void *, DBT *));
- int (*pgout) __P((db_pgno_t, void *, DBT *));
-{
- DB_MPREG *mpr;
- int ret;
-
- MP_PANIC_CHECK(dbmp);
-
- if ((ret = __os_malloc(sizeof(DB_MPREG), NULL, &mpr)) != 0)
- return (ret);
-
- mpr->ftype = ftype;
- mpr->pgin = pgin;
- mpr->pgout = pgout;
-
- /*
- * Insert at the head. Because we do a linear walk, we'll find
- * the most recent registry in the case of multiple entries, so
- * we don't have to check for multiple registries.
- */
- LOCKHANDLE(dbmp, dbmp->mutexp);
- LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q);
- UNLOCKHANDLE(dbmp, dbmp->mutexp);
-
- return (0);
-}
diff --git a/db2/mp/mp_pr.c b/db2/mp/mp_pr.c
deleted file mode 100644
index 84c782e..0000000
--- a/db2/mp/mp_pr.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_pr.c 10.30 (Sleepycat) 10/1/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "db_auto.h"
-#include "db_ext.h"
-#include "common_ext.h"
-
-static void __memp_pbh __P((DB_MPOOL *, BH *, size_t *, FILE *));
-
-/*
- * memp_stat --
- * Display MPOOL statistics.
- */
-int
-memp_stat(dbmp, gspp, fspp, db_malloc)
- DB_MPOOL *dbmp;
- DB_MPOOL_STAT **gspp;
- DB_MPOOL_FSTAT ***fspp;
- void *(*db_malloc) __P((size_t));
-{
- DB_MPOOL_FSTAT **tfsp;
- MPOOLFILE *mfp;
- size_t len, nlen;
- int ret;
- char *name;
-
- MP_PANIC_CHECK(dbmp);
-
- /* Allocate space for the global statistics. */
- if (gspp != NULL) {
- *gspp = NULL;
-
- if ((ret = __os_malloc(sizeof(**gspp), db_malloc, gspp)) != 0)
- return (ret);
-
- LOCKREGION(dbmp);
-
- /* Copy out the global statistics. */
- **gspp = dbmp->mp->stat;
- (*gspp)->st_hash_buckets = dbmp->mp->htab_buckets;
- (*gspp)->st_region_wait =
- dbmp->mp->rlayout.lock.mutex_set_wait;
- (*gspp)->st_region_nowait =
- dbmp->mp->rlayout.lock.mutex_set_nowait;
- (*gspp)->st_refcnt = dbmp->mp->rlayout.refcnt;
- (*gspp)->st_regsize = dbmp->mp->rlayout.size;
-
- UNLOCKREGION(dbmp);
- }
-
- if (fspp != NULL) {
- *fspp = NULL;
-
- LOCKREGION(dbmp);
-
- /* Count the MPOOLFILE structures. */
- for (len = 0,
- mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL;
- ++len, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
- ;
-
- UNLOCKREGION(dbmp);
-
- if (len == 0)
- return (0);
-
- /* Allocate space for the pointers. */
- len = (len + 1) * sizeof(DB_MPOOL_FSTAT *);
- if ((ret = __os_malloc(len, db_malloc, fspp)) != 0)
- return (ret);
-
- LOCKREGION(dbmp);
-
- /* Build each individual entry. */
- for (tfsp = *fspp,
- mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL;
- ++tfsp, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
- name = __memp_fns(dbmp, mfp);
- nlen = strlen(name);
- len = sizeof(DB_MPOOL_FSTAT) + nlen + 1;
- if ((ret = __os_malloc(len, db_malloc, tfsp)) != 0)
- return (ret);
- **tfsp = mfp->stat;
- (*tfsp)->file_name = (char *)
- (u_int8_t *)*tfsp + sizeof(DB_MPOOL_FSTAT);
- memcpy((*tfsp)->file_name, name, nlen + 1);
- }
- *tfsp = NULL;
-
- UNLOCKREGION(dbmp);
- }
- return (0);
-}
-
-/*
- * __memp_fn --
- * On errors we print whatever is available as the file name.
- *
- * PUBLIC: char * __memp_fn __P((DB_MPOOLFILE *));
- */
-char *
-__memp_fn(dbmfp)
- DB_MPOOLFILE *dbmfp;
-{
- return (__memp_fns(dbmfp->dbmp, dbmfp->mfp));
-}
-
-/*
- * __memp_fns --
- * On errors we print whatever is available as the file name.
- *
- * PUBLIC: char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
- *
- */
-char *
-__memp_fns(dbmp, mfp)
- DB_MPOOL *dbmp;
- MPOOLFILE *mfp;
-{
- if (mfp->path_off == 0)
- return ((char *)"temporary");
-
- return ((char *)R_ADDR(dbmp, mfp->path_off));
-}
-
-#define FMAP_ENTRIES 200 /* Files we map. */
-
-#define MPOOL_DUMP_HASH 0x01 /* Debug hash chains. */
-#define MPOOL_DUMP_LRU 0x02 /* Debug LRU chains. */
-#define MPOOL_DUMP_MEM 0x04 /* Debug region memory. */
-#define MPOOL_DUMP_ALL 0x07 /* Debug all. */
-
-
-/*
- * __memp_dump_region --
- * Display MPOOL structures.
- *
- * PUBLIC: void __memp_dump_region __P((DB_MPOOL *, char *, FILE *));
- */
-void
-__memp_dump_region(dbmp, area, fp)
- DB_MPOOL *dbmp;
- char *area;
- FILE *fp;
-{
- BH *bhp;
- DB_HASHTAB *htabp;
- DB_MPOOLFILE *dbmfp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- size_t bucket, fmap[FMAP_ENTRIES + 1];
- u_int32_t flags;
- int cnt;
-
- /* Make it easy to call from the debugger. */
- if (fp == NULL)
- fp = stderr;
-
- for (flags = 0; *area != '\0'; ++area)
- switch (*area) {
- case 'A':
- LF_SET(MPOOL_DUMP_ALL);
- break;
- case 'h':
- LF_SET(MPOOL_DUMP_HASH);
- break;
- case 'l':
- LF_SET(MPOOL_DUMP_LRU);
- break;
- case 'm':
- LF_SET(MPOOL_DUMP_MEM);
- break;
- }
-
- LOCKREGION(dbmp);
-
- mp = dbmp->mp;
-
- /* Display MPOOL structures. */
- (void)fprintf(fp, "%s\nPool (region addr 0x%lx, alloc addr 0x%lx)\n",
- DB_LINE, (u_long)dbmp->reginfo.addr, (u_long)dbmp->addr);
-
- /* Display the MPOOLFILE structures. */
- cnt = 0;
- for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile), ++cnt) {
- (void)fprintf(fp, "file #%d: %s: refs %lu, type %ld, %s\n",
- cnt + 1, __memp_fns(dbmp, mfp), (u_long)mfp->ref,
- (long)mfp->ftype,
- F_ISSET(mfp, MP_CAN_MMAP) ? "mmap" : "read/write");
- if (cnt < FMAP_ENTRIES)
- fmap[cnt] = R_OFFSET(dbmp, mfp);
- }
-
- for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
- dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q), ++cnt) {
- (void)fprintf(fp, "file #%d: %s: fd: %d: per-process, %s\n",
- cnt + 1, __memp_fn(dbmfp), dbmfp->fd,
- F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
- if (cnt < FMAP_ENTRIES)
- fmap[cnt] = R_OFFSET(dbmp, mfp);
- }
- if (cnt < FMAP_ENTRIES)
- fmap[cnt] = INVALID;
- else
- fmap[FMAP_ENTRIES] = INVALID;
-
- /* Display the hash table list of BH's. */
- if (LF_ISSET(MPOOL_DUMP_HASH)) {
- (void)fprintf(fp,
- "%s\nBH hash table (%lu hash slots)\npageno, file, ref, address\n",
- DB_LINE, (u_long)mp->htab_buckets);
- for (htabp = dbmp->htab,
- bucket = 0; bucket < mp->htab_buckets; ++htabp, ++bucket) {
- if (SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh) != NULL)
- (void)fprintf(fp, "%lu:\n", (u_long)bucket);
- for (bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
- __memp_pbh(dbmp, bhp, fmap, fp);
- }
- }
-
- /* Display the LRU list of BH's. */
- if (LF_ISSET(MPOOL_DUMP_LRU)) {
- (void)fprintf(fp, "%s\nBH LRU list\n", DB_LINE);
- (void)fprintf(fp, "pageno, file, ref, address\n");
- for (bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh))
- __memp_pbh(dbmp, bhp, fmap, fp);
- }
-
- if (LF_ISSET(MPOOL_DUMP_MEM))
- __db_shalloc_dump(dbmp->addr, fp);
-
- UNLOCKREGION(dbmp);
-
- /* Flush in case we're debugging. */
- (void)fflush(fp);
-}
-
-/*
- * __memp_pbh --
- * Display a BH structure.
- */
-static void
-__memp_pbh(dbmp, bhp, fmap, fp)
- DB_MPOOL *dbmp;
- BH *bhp;
- size_t *fmap;
- FILE *fp;
-{
- static const FN fn[] = {
- { BH_CALLPGIN, "callpgin" },
- { BH_DIRTY, "dirty" },
- { BH_DISCARD, "discard" },
- { BH_LOCKED, "locked" },
- { BH_TRASH, "trash" },
- { BH_WRITE, "write" },
- { 0 },
- };
- int i;
-
- for (i = 0; i < FMAP_ENTRIES; ++i)
- if (fmap[i] == INVALID || fmap[i] == bhp->mf_offset)
- break;
-
- if (fmap[i] == INVALID)
- (void)fprintf(fp, " %4lu, %lu, %2lu, %lu",
- (u_long)bhp->pgno, (u_long)bhp->mf_offset,
- (u_long)bhp->ref, (u_long)R_OFFSET(dbmp, bhp));
- else
- (void)fprintf(fp, " %4lu, #%d, %2lu, %lu",
- (u_long)bhp->pgno, i + 1,
- (u_long)bhp->ref, (u_long)R_OFFSET(dbmp, bhp));
-
- __db_prflags(bhp->flags, fn, fp);
-
- (void)fprintf(fp, "\n");
-}
diff --git a/db2/mp/mp_region.c b/db2/mp/mp_region.c
deleted file mode 100644
index b9c92f2..0000000
--- a/db2/mp/mp_region.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_region.c 10.35 (Sleepycat) 12/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-/*
- * __memp_reg_alloc --
- * Allocate some space in the mpool region, with locking.
- *
- * PUBLIC: int __memp_reg_alloc __P((DB_MPOOL *, size_t, size_t *, void *));
- */
-int
-__memp_reg_alloc(dbmp, len, offsetp, retp)
- DB_MPOOL *dbmp;
- size_t len, *offsetp;
- void *retp;
-{
- int ret;
-
- LOCKREGION(dbmp);
- ret = __memp_alloc(dbmp, len, offsetp, retp);
- UNLOCKREGION(dbmp);
- return (ret);
-}
-
-/*
- * __memp_alloc --
- * Allocate some space in the mpool region.
- *
- * PUBLIC: int __memp_alloc __P((DB_MPOOL *, size_t, size_t *, void *));
- */
-int
-__memp_alloc(dbmp, len, offsetp, retp)
- DB_MPOOL *dbmp;
- size_t len, *offsetp;
- void *retp;
-{
- BH *bhp, *nbhp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- size_t fsize, total;
- int nomore, restart, ret, wrote;
- void *p;
-
- mp = dbmp->mp;
-
- nomore = 0;
-alloc: if ((ret = __db_shalloc(dbmp->addr, len, MUTEX_ALIGNMENT, &p)) == 0) {
- if (offsetp != NULL)
- *offsetp = R_OFFSET(dbmp, p);
- *(void **)retp = p;
- return (0);
- }
- if (nomore) {
- __db_err(dbmp->dbenv,
- "Unable to allocate %lu bytes from mpool shared region: %s\n",
- (u_long)len, strerror(ret));
- return (ret);
- }
-
- /* Look for a buffer on the free list that's the right size. */
- for (bhp =
- SH_TAILQ_FIRST(&mp->bhfq, __bh); bhp != NULL; bhp = nbhp) {
- nbhp = SH_TAILQ_NEXT(bhp, q, __bh);
-
- if (__db_shsizeof(bhp) == len) {
- SH_TAILQ_REMOVE(&mp->bhfq, bhp, q, __bh);
- if (offsetp != NULL)
- *offsetp = R_OFFSET(dbmp, bhp);
- *(void **)retp = bhp;
- return (0);
- }
- }
-
- /* Discard from the free list until we've freed enough memory. */
- total = 0;
- for (bhp =
- SH_TAILQ_FIRST(&mp->bhfq, __bh); bhp != NULL; bhp = nbhp) {
- nbhp = SH_TAILQ_NEXT(bhp, q, __bh);
-
- SH_TAILQ_REMOVE(&mp->bhfq, bhp, q, __bh);
- __db_shalloc_free(dbmp->addr, bhp);
- --mp->stat.st_page_clean;
-
- /*
- * Retry as soon as we've freed up sufficient space. If we
- * will have to coalesce memory to satisfy the request, don't
- * try until it's likely (possible?) that we'll succeed.
- */
- total += fsize = __db_shsizeof(bhp);
- if (fsize >= len || total >= 3 * len)
- goto alloc;
- }
-
-retry: /* Find a buffer we can flush; pure LRU. */
- restart = total = 0;
- for (bhp =
- SH_TAILQ_FIRST(&mp->bhq, __bh); bhp != NULL; bhp = nbhp) {
- nbhp = SH_TAILQ_NEXT(bhp, q, __bh);
-
- /* Ignore pinned or locked (I/O in progress) buffers. */
- if (bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED))
- continue;
-
- /* Find the associated MPOOLFILE. */
- mfp = R_ADDR(dbmp, bhp->mf_offset);
-
- /*
- * Write the page if it's dirty.
- *
- * If we wrote the page, fall through and free the buffer. We
- * don't have to rewalk the list to acquire the buffer because
- * it was never available for any other process to modify it.
- * If we didn't write the page, but we discarded and reacquired
- * the region lock, restart the buffer list walk. If we neither
- * wrote the buffer nor discarded the region lock, continue down
- * the buffer list.
- */
- if (F_ISSET(bhp, BH_DIRTY)) {
- if ((ret = __memp_bhwrite(dbmp,
- mfp, bhp, &restart, &wrote)) != 0)
- return (ret);
-
- /*
- * It's possible that another process wants this buffer
- * and incremented the ref count while we were writing
- * it.
- */
- if (bhp->ref != 0)
- goto retry;
-
- if (wrote)
- ++mp->stat.st_rw_evict;
- else {
- if (restart)
- goto retry;
- continue;
- }
- } else
- ++mp->stat.st_ro_evict;
-
- /*
- * Check to see if the buffer is the size we're looking for.
- * If it is, simply reuse it.
- */
- total += fsize = __db_shsizeof(bhp);
- if (fsize == len) {
- __memp_bhfree(dbmp, mfp, bhp, 0);
-
- if (offsetp != NULL)
- *offsetp = R_OFFSET(dbmp, bhp);
- *(void **)retp = bhp;
- return (0);
- }
-
- /* Free the buffer. */
- __memp_bhfree(dbmp, mfp, bhp, 1);
-
- /*
- * Retry as soon as we've freed up sufficient space. If we
- * have to coalesce of memory to satisfy the request, don't
- * try until it's likely (possible?) that we'll succeed.
- */
- if (fsize >= len || total >= 3 * len)
- goto alloc;
-
- /* Restart the walk if we discarded the region lock. */
- if (restart)
- goto retry;
- }
- nomore = 1;
- goto alloc;
-}
-
-/*
- * __memp_ropen --
- * Attach to, and optionally create, the mpool region.
- *
- * PUBLIC: int __memp_ropen
- * PUBLIC: __P((DB_MPOOL *, const char *, size_t, int, int, u_int32_t));
- */
-int
-__memp_ropen(dbmp, path, cachesize, mode, is_private, flags)
- DB_MPOOL *dbmp;
- const char *path;
- size_t cachesize;
- int mode, is_private;
- u_int32_t flags;
-{
- MPOOL *mp;
- size_t rlen;
- int defcache, ret;
-
- /*
- * Unlike other DB subsystems, mpool can't simply grow the region
- * because it returns pointers into the region to its clients. To
- * "grow" the region, we'd have to allocate a new region and then
- * store a region number in the structures that reference regional
- * objects. It's reasonable that we fail regardless, as clients
- * shouldn't have every page in the region pinned, so the only
- * "failure" mode should be a performance penalty because we don't
- * find a page in the cache that we'd like to have found.
- *
- * Up the user's cachesize by 25% to account for our overhead.
- */
- defcache = 0;
- if (cachesize < DB_CACHESIZE_MIN) {
- if (cachesize == 0) {
- defcache = 1;
- cachesize = DB_CACHESIZE_DEF;
- } else
- cachesize = DB_CACHESIZE_MIN;
- }
- rlen = cachesize + cachesize / 4;
-
- /*
- * Map in the region.
- *
- * If it's a private mpool, use malloc, it's a lot faster than
- * instantiating a region.
- */
- dbmp->reginfo.dbenv = dbmp->dbenv;
- dbmp->reginfo.appname = DB_APP_NONE;
- if (path == NULL)
- dbmp->reginfo.path = NULL;
- else
- if ((ret = __os_strdup(path, &dbmp->reginfo.path)) != 0)
- return (ret);
- dbmp->reginfo.file = DB_DEFAULT_MPOOL_FILE;
- dbmp->reginfo.mode = mode;
- dbmp->reginfo.size = rlen;
- dbmp->reginfo.dbflags = flags;
- dbmp->reginfo.flags = 0;
- if (defcache)
- F_SET(&dbmp->reginfo, REGION_SIZEDEF);
-
- /*
- * If we're creating a temporary region, don't use any standard
- * naming.
- */
- if (is_private) {
- dbmp->reginfo.appname = DB_APP_TMP;
- dbmp->reginfo.file = NULL;
- F_SET(&dbmp->reginfo, REGION_PRIVATE);
- }
-
- if ((ret = __db_rattach(&dbmp->reginfo)) != 0) {
- if (dbmp->reginfo.path != NULL)
- __os_freestr(dbmp->reginfo.path);
- return (ret);
- }
-
- /*
- * The MPOOL structure is first in the region, the rest of the region
- * is free space.
- */
- dbmp->mp = dbmp->reginfo.addr;
- dbmp->addr = (u_int8_t *)dbmp->mp + sizeof(MPOOL);
-
- /* Initialize a created region. */
- if (F_ISSET(&dbmp->reginfo, REGION_CREATED)) {
- mp = dbmp->mp;
- SH_TAILQ_INIT(&mp->bhq);
- SH_TAILQ_INIT(&mp->bhfq);
- SH_TAILQ_INIT(&mp->mpfq);
-
- __db_shalloc_init(dbmp->addr, rlen - sizeof(MPOOL));
-
- /*
- * Assume we want to keep the hash chains with under 10 pages
- * on each chain. We don't know the pagesize in advance, and
- * it may differ for different files. Use a pagesize of 1K for
- * the calculation -- we walk these chains a lot, they should
- * be short.
- */
- mp->htab_buckets =
- __db_tablesize((cachesize / (1 * 1024)) / 10);
-
- /* Allocate hash table space and initialize it. */
- if ((ret = __db_shalloc(dbmp->addr,
- mp->htab_buckets * sizeof(DB_HASHTAB),
- 0, &dbmp->htab)) != 0)
- goto err;
- __db_hashinit(dbmp->htab, mp->htab_buckets);
- mp->htab = R_OFFSET(dbmp, dbmp->htab);
-
- ZERO_LSN(mp->lsn);
- mp->lsn_cnt = 0;
-
- memset(&mp->stat, 0, sizeof(mp->stat));
- mp->stat.st_cachesize = cachesize;
-
- mp->flags = 0;
- }
-
- /* Get the local hash table address. */
- dbmp->htab = R_ADDR(dbmp, dbmp->mp->htab);
-
- UNLOCKREGION(dbmp);
- return (0);
-
-err: UNLOCKREGION(dbmp);
- (void)__db_rdetach(&dbmp->reginfo);
- if (F_ISSET(&dbmp->reginfo, REGION_CREATED))
- (void)memp_unlink(path, 1, dbmp->dbenv);
-
- if (dbmp->reginfo.path != NULL)
- __os_freestr(dbmp->reginfo.path);
- return (ret);
-}
diff --git a/db2/mp/mp_sync.c b/db2/mp/mp_sync.c
deleted file mode 100644
index 5353485..0000000
--- a/db2/mp/mp_sync.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mp_sync.c 10.31 (Sleepycat) 12/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "mp.h"
-#include "common_ext.h"
-
-static int __bhcmp __P((const void *, const void *));
-static int __memp_fsync __P((DB_MPOOLFILE *));
-
-/*
- * memp_sync --
- * Mpool sync function.
- */
-int
-memp_sync(dbmp, lsnp)
- DB_MPOOL *dbmp;
- DB_LSN *lsnp;
-{
- BH *bhp, **bharray;
- DB_ENV *dbenv;
- MPOOL *mp;
- MPOOLFILE *mfp;
- int ar_cnt, nalloc, next, maxpin, ret, wrote;
-
- MP_PANIC_CHECK(dbmp);
-
- dbenv = dbmp->dbenv;
- mp = dbmp->mp;
-
- if (dbenv->lg_info == NULL) {
- __db_err(dbenv, "memp_sync: requires logging");
- return (EINVAL);
- }
-
- /*
- * We try and write the buffers in page order: it should reduce seeks
- * by the underlying filesystem and possibly reduce the actual number
- * of writes. We don't want to hold the region lock while we write
- * the buffers, so only hold it lock while we create a list. Get a
- * good-size block of memory to hold buffer pointers, we don't want
- * to run out.
- */
- LOCKREGION(dbmp);
- nalloc = mp->stat.st_page_dirty + mp->stat.st_page_dirty / 2 + 10;
- UNLOCKREGION(dbmp);
-
- if ((ret = __os_malloc(nalloc * sizeof(BH *), NULL, &bharray)) != 0)
- return (ret);
-
- LOCKREGION(dbmp);
-
- /*
- * If the application is asking about a previous call to memp_sync(),
- * and we haven't found any buffers that the application holding the
- * pin couldn't write, return yes or no based on the current count.
- * Note, if the application is asking about a LSN *smaller* than one
- * we've already handled or are currently handling, then we return a
- * result based on the count for the larger LSN.
- */
- if (!F_ISSET(mp, MP_LSN_RETRY) && log_compare(lsnp, &mp->lsn) <= 0) {
- if (mp->lsn_cnt == 0) {
- *lsnp = mp->lsn;
- ret = 0;
- } else
- ret = DB_INCOMPLETE;
- goto done;
- }
-
- /* Else, it's a new checkpoint. */
- F_CLR(mp, MP_LSN_RETRY);
-
- /*
- * Save the LSN. We know that it's a new LSN or larger than the one
- * for which we were already doing a checkpoint. (BTW, I don't expect
- * to see multiple LSN's from the same or multiple processes, but You
- * Just Never Know. Responding as if they all called with the largest
- * of the LSNs specified makes everything work.)
- *
- * We don't currently use the LSN we save. We could potentially save
- * the last-written LSN in each buffer header and use it to determine
- * what buffers need to be written. The problem with this is that it's
- * sizeof(LSN) more bytes of buffer header. We currently write all the
- * dirty buffers instead.
- *
- * Walk the list of shared memory segments clearing the count of
- * buffers waiting to be written.
- */
- mp->lsn = *lsnp;
- mp->lsn_cnt = 0;
- for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
- mfp->lsn_cnt = 0;
-
- /*
- * Walk the list of buffers and mark all dirty buffers to be written
- * and all pinned buffers to be potentially written (we can't know if
- * we'll need to write them until the holding process returns them to
- * the cache). We do this in one pass while holding the region locked
- * so that processes can't make new buffers dirty, causing us to never
- * finish. Since the application may have restarted the sync, clear
- * any BH_WRITE flags that appear to be left over from previous calls.
- *
- * We don't want to pin down the entire buffer cache, otherwise we'll
- * starve threads needing new pages. Don't pin down more than 80% of
- * the cache.
- *
- * Keep a count of the total number of buffers we need to write in
- * MPOOL->lsn_cnt, and for each file, in MPOOLFILE->lsn_count.
- */
- ar_cnt = 0;
- maxpin = ((mp->stat.st_page_dirty + mp->stat.st_page_clean) * 8) / 10;
- for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh))
- if (F_ISSET(bhp, BH_DIRTY) || bhp->ref != 0) {
- F_SET(bhp, BH_WRITE);
-
- ++mp->lsn_cnt;
-
- mfp = R_ADDR(dbmp, bhp->mf_offset);
- ++mfp->lsn_cnt;
-
- /*
- * If the buffer isn't in use, we should be able to
- * write it immediately, so increment the reference
- * count to lock it and its contents down, and then
- * save a reference to it.
- *
- * If we've run out space to store buffer references,
- * we're screwed. We don't want to realloc the array
- * while holding a region lock, so we set the flag to
- * force the checkpoint to be done again, from scratch,
- * later.
- *
- * If we've pinned down too much of the cache stop, and
- * set a flag to force the checkpoint to be tried again
- * later.
- */
- if (bhp->ref == 0) {
- ++bhp->ref;
- bharray[ar_cnt] = bhp;
- if (++ar_cnt >= nalloc || ar_cnt >= maxpin) {
- F_SET(mp, MP_LSN_RETRY);
- break;
- }
- }
- } else
- if (F_ISSET(bhp, BH_WRITE))
- F_CLR(bhp, BH_WRITE);
-
- /* If there no buffers we can write immediately, we're done. */
- if (ar_cnt == 0) {
- ret = mp->lsn_cnt ? DB_INCOMPLETE : 0;
- goto done;
- }
-
- UNLOCKREGION(dbmp);
-
- /* Sort the buffers we're going to write. */
- qsort(bharray, ar_cnt, sizeof(BH *), __bhcmp);
-
- LOCKREGION(dbmp);
-
- /* Walk the array, writing buffers. */
- for (next = 0; next < ar_cnt; ++next) {
- /*
- * It's possible for a thread to have gotten the buffer since
- * we listed it for writing. If the reference count is still
- * 1, we're the only ones using the buffer, go ahead and write.
- * If it's >1, then skip the buffer and assume that it will be
- * written when it's returned to the cache.
- */
- if (bharray[next]->ref > 1) {
- --bharray[next]->ref;
- continue;
- }
-
- /* Write the buffer. */
- mfp = R_ADDR(dbmp, bharray[next]->mf_offset);
- ret = __memp_bhwrite(dbmp, mfp, bharray[next], NULL, &wrote);
-
- /* Release the buffer. */
- --bharray[next]->ref;
-
- /* If there's an error, release the rest of the buffers. */
- if (ret != 0 || !wrote) {
- /*
- * Any process syncing the shared memory buffer pool
- * had better be able to write to any underlying file.
- * Be understanding, but firm, on this point.
- */
- if (ret == 0) {
- __db_err(dbenv, "%s: unable to flush page: %lu",
- __memp_fns(dbmp, mfp),
- (u_long)bharray[next]->pgno);
- ret = EPERM;
- }
-
- while (++next < ar_cnt)
- --bharray[next]->ref;
- goto err;
- }
- }
- ret = mp->lsn_cnt != 0 ||
- F_ISSET(mp, MP_LSN_RETRY) ? DB_INCOMPLETE : 0;
-
-done:
- if (0) {
-err: /*
- * On error, clear:
- * MPOOL->lsn_cnt (the total sync count)
- * MPOOLFILE->lsn_cnt (the per-file sync count)
- * BH_WRITE flag (the scheduled for writing flag)
- */
- mp->lsn_cnt = 0;
- for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
- mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
- mfp->lsn_cnt = 0;
- for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh))
- F_CLR(bhp, BH_WRITE);
- }
- UNLOCKREGION(dbmp);
- __os_free(bharray, nalloc * sizeof(BH *));
- return (ret);
-}
-
-/*
- * memp_fsync --
- * Mpool file sync function.
- */
-int
-memp_fsync(dbmfp)
- DB_MPOOLFILE *dbmfp;
-{
- DB_MPOOL *dbmp;
- int is_tmp;
-
- dbmp = dbmfp->dbmp;
-
- MP_PANIC_CHECK(dbmp);
-
- /*
- * If this handle doesn't have a file descriptor that's open for
- * writing, or if the file is a temporary, there's no reason to
- * proceed further.
- */
- if (F_ISSET(dbmfp, MP_READONLY))
- return (0);
-
- LOCKREGION(dbmp);
- is_tmp = F_ISSET(dbmfp->mfp, MP_TEMP);
- UNLOCKREGION(dbmp);
- if (is_tmp)
- return (0);
-
- return (__memp_fsync(dbmfp));
-}
-
-/*
- * __mp_xxx_fd --
- * Return a file descriptor for DB 1.85 compatibility locking.
- *
- * PUBLIC: int __mp_xxx_fd __P((DB_MPOOLFILE *, int *));
- */
-int
-__mp_xxx_fd(dbmfp, fdp)
- DB_MPOOLFILE *dbmfp;
- int *fdp;
-{
- int ret;
-
- /*
- * This is a truly spectacular layering violation, intended ONLY to
- * support compatibility for the DB 1.85 DB->fd call.
- *
- * Sync the database file to disk, creating the file as necessary.
- *
- * We skip the MP_READONLY and MP_TEMP tests done by memp_fsync(3).
- * The MP_READONLY test isn't interesting because we will either
- * already have a file descriptor (we opened the database file for
- * reading) or we aren't readonly (we created the database which
- * requires write privileges). The MP_TEMP test isn't interesting
- * because we want to write to the backing file regardless so that
- * we get a file descriptor to return.
- */
- ret = dbmfp->fd == -1 ? __memp_fsync(dbmfp) : 0;
-
- return ((*fdp = dbmfp->fd) == -1 ? ENOENT : ret);
-}
-
-/*
- * __memp_fsync --
- * Mpool file internal sync function.
- */
-static int
-__memp_fsync(dbmfp)
- DB_MPOOLFILE *dbmfp;
-{
- BH *bhp, **bharray;
- DB_MPOOL *dbmp;
- MPOOL *mp;
- size_t mf_offset;
- int ar_cnt, incomplete, nalloc, next, ret, wrote;
-
- ret = 0;
- dbmp = dbmfp->dbmp;
- mp = dbmp->mp;
- mf_offset = R_OFFSET(dbmp, dbmfp->mfp);
-
- /*
- * We try and write the buffers in page order: it should reduce seeks
- * by the underlying filesystem and possibly reduce the actual number
- * of writes. We don't want to hold the region lock while we write
- * the buffers, so only hold it lock while we create a list. Get a
- * good-size block of memory to hold buffer pointers, we don't want
- * to run out.
- */
- LOCKREGION(dbmp);
- nalloc = mp->stat.st_page_dirty + mp->stat.st_page_dirty / 2 + 10;
- UNLOCKREGION(dbmp);
-
- if ((ret = __os_malloc(nalloc * sizeof(BH *), NULL, &bharray)) != 0)
- return (ret);
-
- LOCKREGION(dbmp);
-
- /*
- * Walk the LRU list of buffer headers, and get a list of buffers to
- * write for this MPOOLFILE.
- */
- ar_cnt = incomplete = 0;
- for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {
- if (!F_ISSET(bhp, BH_DIRTY) || bhp->mf_offset != mf_offset)
- continue;
- if (bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED)) {
- incomplete = 1;
- continue;
- }
-
- ++bhp->ref;
- bharray[ar_cnt] = bhp;
-
- /*
- * If we've run out space to store buffer references, we're
- * screwed, as we don't want to realloc the array holding a
- * region lock. Set the incomplete flag -- the only way we
- * can get here is if the file is active in the buffer cache,
- * which is the same thing as finding pinned buffers.
- */
- if (++ar_cnt >= nalloc) {
- incomplete = 1;
- break;
- }
- }
-
- UNLOCKREGION(dbmp);
-
- /* Sort the buffers we're going to write. */
- if (ar_cnt != 0)
- qsort(bharray, ar_cnt, sizeof(BH *), __bhcmp);
-
- LOCKREGION(dbmp);
-
- /* Walk the array, writing buffers. */
- for (next = 0; next < ar_cnt; ++next) {
- /*
- * It's possible for a thread to have gotten the buffer since
- * we listed it for writing. If the reference count is still
- * 1, we're the only ones using the buffer, go ahead and write.
- * If it's >1, then skip the buffer.
- */
- if (bharray[next]->ref > 1) {
- incomplete = 1;
-
- --bharray[next]->ref;
- continue;
- }
-
- /* Write the buffer. */
- ret = __memp_pgwrite(dbmfp, bharray[next], NULL, &wrote);
-
- /* Release the buffer. */
- --bharray[next]->ref;
-
- /* If there's an error, release the rest of the buffers. */
- if (ret != 0) {
- while (++next < ar_cnt)
- --bharray[next]->ref;
- goto err;
- }
-
- /*
- * If we didn't write the buffer for some reason, don't return
- * success.
- */
- if (!wrote)
- incomplete = 1;
- }
-
-err: UNLOCKREGION(dbmp);
-
- __os_free(bharray, nalloc * sizeof(BH *));
-
- /*
- * Sync the underlying file as the last thing we do, so that the OS
- * has maximal opportunity to flush buffers before we request it.
- *
- * XXX:
- * Don't lock the region around the sync, fsync(2) has no atomicity
- * issues.
- */
- if (ret == 0)
- return (incomplete ? DB_INCOMPLETE : __os_fsync(dbmfp->fd));
- return (ret);
-}
-
-/*
- * memp_trickle --
- * Keep a specified percentage of the buffers clean.
- */
-int
-memp_trickle(dbmp, pct, nwrotep)
- DB_MPOOL *dbmp;
- int pct, *nwrotep;
-{
- BH *bhp;
- MPOOL *mp;
- MPOOLFILE *mfp;
- u_long total;
- int ret, wrote;
-
- MP_PANIC_CHECK(dbmp);
-
- mp = dbmp->mp;
- if (nwrotep != NULL)
- *nwrotep = 0;
-
- if (pct < 1 || pct > 100)
- return (EINVAL);
-
- LOCKREGION(dbmp);
-
- /*
- * If there are sufficient clean buffers, or no buffers or no dirty
- * buffers, we're done.
- *
- * XXX
- * Using st_page_clean and st_page_dirty is our only choice at the
- * moment, but it's not as correct as we might like in the presence
- * of pools with more than one buffer size, as a free 512-byte buffer
- * isn't the same as a free 8K buffer.
- */
-loop: total = mp->stat.st_page_clean + mp->stat.st_page_dirty;
- if (total == 0 || mp->stat.st_page_dirty == 0 ||
- (mp->stat.st_page_clean * 100) / total >= (u_long)pct) {
- UNLOCKREGION(dbmp);
- return (0);
- }
-
- /* Loop until we write a buffer. */
- for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
- bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {
- if (bhp->ref != 0 ||
- !F_ISSET(bhp, BH_DIRTY) || F_ISSET(bhp, BH_LOCKED))
- continue;
-
- mfp = R_ADDR(dbmp, bhp->mf_offset);
-
- /*
- * We can't write to temporary files -- see the comment in
- * mp_bh.c:__memp_bhwrite().
- */
- if (F_ISSET(mfp, MP_TEMP))
- continue;
-
- if ((ret = __memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0)
- goto err;
-
- /*
- * Any process syncing the shared memory buffer pool had better
- * be able to write to any underlying file. Be understanding,
- * but firm, on this point.
- */
- if (!wrote) {
- __db_err(dbmp->dbenv, "%s: unable to flush page: %lu",
- __memp_fns(dbmp, mfp), (u_long)bhp->pgno);
- ret = EPERM;
- goto err;
- }
-
- ++mp->stat.st_page_trickle;
- if (nwrotep != NULL)
- ++*nwrotep;
- goto loop;
- }
-
- /* No more buffers to write. */
- ret = 0;
-
-err: UNLOCKREGION(dbmp);
- return (ret);
-}
-
-static int
-__bhcmp(p1, p2)
- const void *p1, *p2;
-{
- BH *bhp1, *bhp2;
-
- bhp1 = *(BH * const *)p1;
- bhp2 = *(BH * const *)p2;
-
- /* Sort by file (shared memory pool offset). */
- if (bhp1->mf_offset < bhp2->mf_offset)
- return (-1);
- if (bhp1->mf_offset > bhp2->mf_offset)
- return (1);
-
- /*
- * !!!
- * Defend against badly written quicksort code calling the comparison
- * function with two identical pointers (e.g., WATCOM C++ (Power++)).
- */
- if (bhp1->pgno < bhp2->pgno)
- return (-1);
- if (bhp1->pgno > bhp2->pgno)
- return (1);
- return (0);
-}
diff --git a/db2/mutex/68020.gcc b/db2/mutex/68020.gcc
deleted file mode 100644
index 21410e6..0000000
--- a/db2/mutex/68020.gcc
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * @(#)68020.gcc 10.2 (Sleepycat) 2/15/98
- *
- * For gcc/68K, 0 is clear, 1 is set.
- */
-#define TSL_SET(tsl) ({ \
- register tsl_t *__l = (tsl); \
- int __r; \
- asm volatile("tas %1; \n \
- seq %0" \
- : "=dm" (__r), "=m" (*__l) \
- : "1" (*__l) \
- ); \
- __r & 1; \
-})
-
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/mutex/README b/db2/mutex/README
deleted file mode 100644
index fceeef7..0000000
--- a/db2/mutex/README
+++ /dev/null
@@ -1,105 +0,0 @@
-# @(#)README 10.2 (Sleepycat) 11/25/97
-
-Resource locking routines: lock based on a db_mutex_t. All this gunk
-(including trying to make assembly code portable), is necessary because
-System V semaphores require system calls for uncontested locks and we
-don't want to make two system calls per resource lock.
-
-First, this is how it works. The db_mutex_t structure contains a resource
-test-and-set lock (tsl), a file offset, a pid for debugging and statistics
-information.
-
-If HAVE_SPINLOCKS is defined (i.e. we know how to do test-and-sets for
-this compiler/architecture combination), we try and lock the resource tsl
-__db_tsl_spins times. If we can't acquire the lock that way, we use a
-system call to sleep for 10ms, 20ms, 40ms, etc. (The time is bounded at
-1 second, just in case.) Using the timer backoff means that there are
-two assumptions: that locks are held for brief periods (never over system
-calls or I/O) and that locks are not hotly contested.
-
-If HAVE_SPINLOCKS is not defined, i.e. we can't do test-and-sets, we use
-a file descriptor to do byte locking on a file at a specified offset. In
-this case, ALL of the locking is done in the kernel. Because file
-descriptors are allocated per process, we have to provide the file
-descriptor as part of the lock/unlock call. We still have to do timer
-backoff because we need to be able to block ourselves, i.e. the lock
-manager causes processes to wait by having the process acquire a mutex
-and then attempting to re-acquire the mutex. There's no way to use kernel
-locking to block yourself, i.e. if you hold a lock and attempt to
-re-acquire it, the attempt will succeed.
-
-Next, let's talk about why it doesn't work the way a reasonable person
-would think it should work.
-
-Ideally, we'd have the ability to try to lock the resource tsl, and if
-that fails, increment a counter of waiting processes, then block in the
-kernel until the tsl is released. The process holding the resource tsl
-would see the wait counter when it went to release the resource tsl, and
-would wake any waiting processes up after releasing the lock. This would
-actually require both another tsl (call it the mutex tsl) and
-synchronization between the call that blocks in the kernel and the actual
-resource tsl. The mutex tsl would be used to protect accesses to the
-db_mutex_t itself. Locking the mutex tsl would be done by a busy loop,
-which is safe because processes would never block holding that tsl (all
-they would do is try to obtain the resource tsl and set/check the wait
-count). The problem in this model is that the blocking call into the
-kernel requires a blocking semaphore, i.e. one whose normal state is
-locked.
-
-The only portable forms of locking under UNIX are fcntl(2) on a file
-descriptor/offset, and System V semaphores. Neither of these locking
-methods are sufficient to solve the problem.
-
-The problem with fcntl locking is that only the process that obtained the
-lock can release it. Remember, we want the normal state of the kernel
-semaphore to be locked. So, if the creator of the db_mutex_t were to
-initialize the lock to "locked", then a second process locks the resource
-tsl, and then a third process needs to block, waiting for the resource
-tsl, when the second process wants to wake up the third process, it can't
-because it's not the holder of the lock! For the second process to be
-the holder of the lock, we would have to make a system call per
-uncontested lock, which is what we were trying to get away from in the
-first place.
-
-There are some hybrid schemes, such as signaling the holder of the lock,
-or using a different blocking offset depending on which process is
-holding the lock, but it gets complicated fairly quickly. I'm open to
-suggestions, but I'm not holding my breath.
-
-Regardless, we use this form of locking when HAVE_SPINLOCKS is not
-defined, (i.e. we're locking in the kernel) because it doesn't have the
-limitations found in System V semaphores, and because the normal state of
-the kernel object in that case is unlocked, so the process releasing the
-lock is also the holder of the lock.
-
-The System V semaphore design has a number of other limitations that make
-it inappropriate for this task. Namely:
-
-First, the semaphore key name space is separate from the file system name
-space (although there exist methods for using file names to create
-semaphore keys). If we use a well-known key, there's no reason to believe
-that any particular key will not already be in use, either by another
-instance of the DB application or some other application, in which case
-the DB application will fail. If we create a key, then we have to use a
-file system name to rendezvous and pass around the key.
-
-Second, System V semaphores traditionally have compile-time, system-wide
-limits on the number of semaphore keys that you can have. Typically, that
-number is far too low for any practical purpose. Since the semaphores
-permit more than a single slot per semaphore key, we could try and get
-around that limit by using multiple slots, but that means that the file
-that we're using for rendezvous is going to have to contain slot
-information as well as semaphore key information, and we're going to be
-reading/writing it on every db_mutex_t init or destroy operation. Anyhow,
-similar compile-time, system-wide limits on the numbers of slots per
-semaphore key kick in, and you're right back where you started.
-
-My fantasy is that once POSIX.1 standard mutexes are in wide-spread use,
-we can switch to them. My guess is that it won't happen, because the
-POSIX semaphores are only required to work for threads within a process,
-and not independent processes.
-
-Note: there are races in the statistics code, but since it's just that,
-I didn't bother fixing them. (The fix requires a mutex tsl, so, when/if
-this code is fixed to do rational locking (see above), then change the
-statistics update code to acquire/release the mutex tsl.
diff --git a/db2/mutex/alpha.h b/db2/mutex/alpha.h
deleted file mode 100644
index ad3afc4..0000000
--- a/db2/mutex/alpha.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* For alpha, 0 is clear, 1 is set. */
-
-#ifdef __GNUC__
-#define TSL_SET(tsl) ({ \
- register tsl_t *__l = (tsl); \
- int __r; \
- asm volatile( \
- "1: ldl_l %0,%1\n" \
- " blbs %0,2f\n" \
- " mov 1,%0\n" \
- " stl_c %0,%1\n" \
- " bne %0,1b\n" \
- " mb\n" \
- "2:" \
- : "=&r"(__r), "=m"(*__l) : "m"(*__l) : "memory"); \
- __r; \
-})
-#endif
-
-#ifdef __DECC
-#include <alpha/builtins.h>
-#define TSL_SET(tsl) (__LOCK_LONG_RETRY((tsl), 1) != 0)
-#endif
-
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/mutex/mutex.c b/db2/mutex/mutex.c
deleted file mode 100644
index 2fac14c..0000000
--- a/db2/mutex/mutex.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)mutex.c 10.52 (Sleepycat) 11/8/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-
-#ifdef HAVE_SPINLOCKS
-
-#ifdef HAVE_FUNC_AIX
-#define TSL_INIT(x)
-#define TSL_SET(x) (!_check_lock(x, 0, 1))
-#define TSL_UNSET(x) _clear_lock(x, 0)
-#endif
-
-#ifdef HAVE_ASSEM_MC68020_GCC
-#include "68020.gcc"
-#endif
-
-#if defined(HAVE_FUNC_MSEM)
-/*
- * !!!
- * Do not remove the MSEM_IF_NOWAIT flag. The problem is that if a single
- * process makes two msem_lock() calls in a row, the second one returns an
- * error. We depend on the fact that we can lock against ourselves in the
- * locking subsystem, where we set up a mutex so that we can block ourselves.
- * Tested on OSF1 v4.0.
- */
-#define TSL_INIT(x) (msem_init(x, MSEM_UNLOCKED) == NULL)
-#define TSL_INIT_ERROR 1
-#define TSL_SET(x) (!msem_lock(x, MSEM_IF_NOWAIT))
-#define TSL_UNSET(x) msem_unlock(x, 0)
-#endif
-
-#ifdef HAVE_FUNC_RELIANT
-#define TSL_INIT(x) initspin(x, 1)
-#define TSL_SET(x) (cspinlock(x) == 0)
-#define TSL_UNSET(x) spinunlock(x)
-#endif
-
-#ifdef HAVE_FUNC_SGI
-#define TSL_INIT(x) (init_lock(x) != 0)
-#define TSL_INIT_ERROR 1
-#define TSL_SET(x) (!acquire_lock(x))
-#define TSL_UNSET(x) release_lock(x)
-#endif
-
-#ifdef HAVE_FUNC_SOLARIS
-/*
- * Semaphore calls don't work on Solaris 5.5.
- *
- * #define TSL_INIT(x) (sema_init(x, 1, USYNC_PROCESS, NULL) != 0)
- * #define TSL_INIT_ERROR 1
- * #define TSL_SET(x) (sema_wait(x) == 0)
- * #define TSL_UNSET(x) sema_post(x)
- */
-#define TSL_INIT(x)
-#define TSL_SET(x) (_lock_try(x))
-#define TSL_UNSET(x) _lock_clear(x)
-#endif
-
-#ifdef HAVE_FUNC_VMS
-#include <builtins.h>
-#ifdef __ALPHA
-#define TSL_SET(tsl) (!__TESTBITSSI(tsl, 0))
-#else /* __VAX */
-#define TSL_SET(tsl) (!(int)_BBSSI(0, tsl))
-#endif
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
-#endif
-
-#ifdef HAVE_ASSEM_PARISC_GCC
-#include "parisc.gcc"
-#endif
-
-#ifdef HAVE_ASSEM_SCO_CC
-#include "sco.cc"
-#endif
-
-#ifdef HAVE_ASSEM_SPARC_GCC
-#include "sparc.gcc"
-#endif
-
-#ifdef HAVE_ASSEM_UTS4_CC
-#define TSL_INIT(x)
-#define TSL_SET(x) (!uts_lock(x, 1))
-#define TSL_UNSET(x) (*(x) = 0)
-#endif
-
-#ifdef HAVE_ASSEM_X86_GCC
-#include "x86.gcc"
-#endif
-
-#ifdef HAVE_ASSEM_ALPHA
-#include "alpha.h"
-#endif
-
-#ifdef WIN16
-/* Win16 spinlocks are simple because we cannot possibly be preempted. */
-#define TSL_INIT(tsl)
-#define TSL_SET(tsl) (*(tsl) = 1)
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#endif
-
-#if defined(_WIN32)
-/*
- * XXX
- * DBDB this needs to be byte-aligned!!
- */
-#define TSL_INIT(tsl)
-#define TSL_SET(tsl) (!InterlockedExchange((PLONG)tsl, 1))
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#endif
-
-#endif /* HAVE_SPINLOCKS */
-
-/*
- * __db_mutex_init --
- * Initialize a DB mutex structure.
- *
- * PUBLIC: int __db_mutex_init __P((db_mutex_t *, u_int32_t));
- */
-int
-__db_mutex_init(mp, off)
- db_mutex_t *mp;
- u_int32_t off;
-{
-#ifdef DIAGNOSTIC
- if ((ALIGNTYPE)mp & (MUTEX_ALIGNMENT - 1)) {
- (void)fprintf(stderr,
- "MUTEX ERROR: mutex NOT %d-byte aligned!\n",
- MUTEX_ALIGNMENT);
- abort();
- }
-#endif
- memset(mp, 0, sizeof(db_mutex_t));
-
-#ifdef HAVE_SPINLOCKS
- COMPQUIET(off, 0);
-
-#ifdef TSL_INIT_ERROR
- if (TSL_INIT(&mp->tsl_resource))
- return (errno);
-#else
- TSL_INIT(&mp->tsl_resource);
-#endif
- mp->spins = __os_spin();
-#else
- mp->off = off;
-#endif
- return (0);
-}
-
-#define MS(n) ((n) * 1000) /* Milliseconds to micro-seconds. */
-#define SECOND (MS(1000)) /* A second's worth of micro-seconds. */
-
-/*
- * __db_mutex_lock
- * Lock on a mutex, logically blocking if necessary.
- *
- * PUBLIC: int __db_mutex_lock __P((db_mutex_t *, int));
- */
-int
-__db_mutex_lock(mp, fd)
- db_mutex_t *mp;
- int fd;
-{
- u_long usecs;
-#ifdef HAVE_SPINLOCKS
- int nspins;
-#else
- struct flock k_lock;
- pid_t mypid;
- int locked;
-#endif
-
- if (!DB_GLOBAL(db_mutexlocks))
- return (0);
-
-#ifdef HAVE_SPINLOCKS
- COMPQUIET(fd, 0);
-
- for (usecs = MS(1);;) {
- /* Try and acquire the uncontested resource lock for N spins. */
- for (nspins = mp->spins; nspins > 0; --nspins)
- if (TSL_SET(&mp->tsl_resource)) {
-#ifdef DIAGNOSTIC
- if (mp->pid != 0) {
- (void)fprintf(stderr,
- "MUTEX ERROR: __db_mutex_lock: lock currently locked\n");
- abort();
- }
- mp->pid = getpid();
-#endif
- if (usecs == MS(1))
- ++mp->mutex_set_nowait;
- else
- ++mp->mutex_set_wait;
- return (0);
- }
-
- /* Yield the processor; wait 1ms initially, up to 1 second. */
- __os_yield(usecs);
- if ((usecs <<= 1) > SECOND)
- usecs = SECOND;
- }
- /* NOTREACHED */
-
-#else /* !HAVE_SPINLOCKS */
-
- /* Initialize the lock. */
- k_lock.l_whence = SEEK_SET;
- k_lock.l_start = mp->off;
- k_lock.l_len = 1;
-
- for (locked = 0, mypid = getpid();;) {
- /*
- * Wait for the lock to become available; wait 1ms initially,
- * up to 1 second.
- */
- for (usecs = MS(1); mp->pid != 0;) {
- __os_yield(usecs);
- if ((usecs <<= 1) > SECOND)
- usecs = SECOND;
- }
-
- /* Acquire an exclusive kernel lock. */
- k_lock.l_type = F_WRLCK;
- if (fcntl(fd, F_SETLKW, &k_lock))
- return (errno);
-
- /* If the resource tsl is still available, it's ours. */
- if (mp->pid == 0) {
- locked = 1;
- mp->pid = mypid;
- }
-
- /* Release the kernel lock. */
- k_lock.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &k_lock))
- return (errno);
-
- /*
- * If we got the resource tsl we're done.
- *
- * !!!
- * We can't check to see if the lock is ours, because we may
- * be trying to block ourselves in the lock manager, and so
- * the holder of the lock that's preventing us from getting
- * the lock may be us! (Seriously.)
- */
- if (locked)
- break;
- }
- return (0);
-#endif /* !HAVE_SPINLOCKS */
-}
-
-/*
- * __db_mutex_unlock --
- * Release a lock.
- *
- * PUBLIC: int __db_mutex_unlock __P((db_mutex_t *, int));
- */
-int
-__db_mutex_unlock(mp, fd)
- db_mutex_t *mp;
- int fd;
-{
- if (!DB_GLOBAL(db_mutexlocks))
- return (0);
-
-#ifdef DIAGNOSTIC
- if (mp->pid == 0) {
- (void)fprintf(stderr,
- "MUTEX ERROR: __db_mutex_unlock: lock already unlocked\n");
- abort();
- }
-#endif
-
-#ifdef HAVE_SPINLOCKS
- COMPQUIET(fd, 0);
-
-#ifdef DIAGNOSTIC
- mp->pid = 0;
-#endif
-
- /* Release the resource tsl. */
- TSL_UNSET(&mp->tsl_resource);
-#else
- /*
- * Release the resource tsl. We don't have to acquire any locks
- * because processes trying to acquire the lock are checking for
- * a pid of 0, not a specific value.
- */
- mp->pid = 0;
-#endif
- return (0);
-}
diff --git a/db2/mutex/parisc.gcc b/db2/mutex/parisc.gcc
deleted file mode 100644
index 2e4540f..0000000
--- a/db2/mutex/parisc.gcc
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * @(#)parisc.gcc 8.8 (Sleepycat) 6/2/98
- *
- * Copyright (c) 1996-1997, The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL). All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the Computer
- * Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- */
-
-/*
- * The PA-RISC has a "load and clear" instead of a "test and set" instruction.
- * The 32-bit word used by that instruction must be 16-byte aligned. We could
- * use the "aligned" attribute in GCC but that doesn't work for stack variables.
- */
-#define TSL_SET(tsl) ({ \
- register tsl_t *__l = (tsl); \
- int __r; \
- asm volatile("ldcws 0(%1),%0" : "=r" (__r) : "r" (__l)); \
- __r & 1; \
-})
-
-#define TSL_UNSET(tsl) (*(tsl) = -1)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/mutex/sco.cc b/db2/mutex/sco.cc
deleted file mode 100644
index 7c165a2..0000000
--- a/db2/mutex/sco.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * @(#)x86.uslc
- *
- * UnixWare has threads in libthread, but OpenServer doesn't (yet).
- *
- * For cc/x86, 0 is clear, 1 is set.
- */
-
-#if defined(__USLC__)
-asm int
-_tsl_set(void *tsl)
-{
-%mem tsl
- movl tsl, %ecx
- movl $1, %eax
- lock
- xchgb (%ecx),%al
- xorl $1,%eax
-}
-#endif
-
-#define TSL_SET(tsl) _tsl_set(tsl)
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/mutex/sparc.gcc b/db2/mutex/sparc.gcc
deleted file mode 100644
index 5eff176..0000000
--- a/db2/mutex/sparc.gcc
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * @(#)sparc.gcc 10.1 (Sleepycat) 4/12/97
- *
- * The ldstub instruction takes the location specified by its first argument
- * (a register containing a memory address) and loads its contents into its
- * second argument (a register) and atomically sets the contents the location
- * specified by its first argument to a byte of 1s. (The value in the second
- * argument is never read, but only overwritten.)
- *
- * The membar instructions are needed to ensure that writes to the lock are
- * correctly ordered with writes that occur later in the instruction stream.
- *
- * For gcc/sparc, 0 is clear, 1 is set.
- */
-
-/* The stbar is needed for v8, and is implemented as membar #sync on v9,
- so is functional there as well. For v7, stbar may generate an illegal
- instruction and we have no way to tell what we're running on. Some
- operating systems notice and skip this instruction in the fault handler. */
-
-#define TSL_SET(tsl) ({ \
- register tsl_t *__l = (tsl); \
- register tsl_t __r; \
- __asm__ volatile \
- ("ldstub [%1],%0; stbar" \
- : "=r"( __r) : "r" (__l)); \
- !__r; \
-})
-
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/mutex/tsl_parisc.s b/db2/mutex/tsl_parisc.s
deleted file mode 100644
index e605494..0000000
--- a/db2/mutex/tsl_parisc.s
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1996-1997 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL). All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the Computer
- * Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- * @(#)tsl_parisc.s 8.4 (Sleepycat) 1/18/97
- */
-
-/*
- * Spin locks for the PA-RISC. Based on Bob Wheeler's Mach implementation.
- */
- .SPACE $TEXT$
- .SUBSPA $CODE$
-
-/*
- * int tsl_set(tsl_t *tsl)
- *
- * Try to acquire a lock, return 1 if successful, 0 if not.
- */
- .EXPORT tsl_set,ENTRY
-tsl_set
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- ldo 15(%r26),%r26
- depi 0,31,4,%r26
- ldcws 0(%r26),%r28
- subi,= 0,%r28,%r0
- ldi 1,%r28
- bv,n 0(%r2)
- .EXIT
- .PROCEND
-
-
-/*
- * void tsl_unset(tsl_t *tsl)
- *
- * Release a lock.
- */
- .EXPORT tsl_unset,ENTRY
-tsl_unset
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- ldo 15(%r26),%r26
- ldi -1,%r19
- depi 0,31,4,%r26
- bv 0(%r2)
- stw %r19,0(%r26)
- .EXIT
- .PROCEND
diff --git a/db2/mutex/uts4_cc.s b/db2/mutex/uts4_cc.s
deleted file mode 100644
index ee5f414..0000000
--- a/db2/mutex/uts4_cc.s
+++ /dev/null
@@ -1,21 +0,0 @@
- /
- / int uts_lock ( int *p, int i );
- / Update the lock word pointed to by p with the
- / value i, using compare-and-swap.
- / Returns 0 if update was successful.
- / Returns 1 if update failed.
- /
- entry uts_lock
- uts_lock:
- using .,r15
- st r2,8(sp) / Save R2
- l r2,64+0(sp) / R2 -> word to update
- slr r0, r0 / R0 = current lock value must be 0
- l r1,64+4(sp) / R1 = new lock value
- cs r0,r1,0(r2) / Try the update ...
- be x / ... Success. Return 0
- la r0,1 / ... Failure. Return 1
- x: /
- l r2,8(sp) / Restore R2
- b 2(,r14) / Return to caller
- drop r15
diff --git a/db2/mutex/x86.gcc b/db2/mutex/x86.gcc
deleted file mode 100644
index 566b9c4..0000000
--- a/db2/mutex/x86.gcc
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * @(#)x86.gcc 10.3 (Sleepycat) 8/27/97
- *
- * For gcc/x86, 0 is clear, 1 is set.
- */
-#define TSL_SET(tsl) ({ \
- register tsl_t *__l = (tsl); \
- int __r; \
- asm volatile("movl $1,%%eax; lock; xchgb %1,%%al; xorl $1,%%eax"\
- : "=&a" (__r), "=m" (*__l) \
- : "1" (*__l) \
- ); \
- __r & 1; \
-})
-
-#define TSL_UNSET(tsl) (*(tsl) = 0)
-#define TSL_INIT(tsl) TSL_UNSET(tsl)
diff --git a/db2/os/os_abs.c b/db2/os/os_abs.c
deleted file mode 100644
index 547a680..0000000
--- a/db2/os/os_abs.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_abs.c 10.9 (Sleepycat) 7/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * __os_abspath --
- * Return if a path is an absolute path.
- *
- * PUBLIC: int __os_abspath __P((const char *));
- */
-int
-__os_abspath(path)
- const char *path;
-{
- return (path[0] == '/');
-}
diff --git a/db2/os/os_alloc.c b/db2/os/os_alloc.c
deleted file mode 100644
index 0090eb1..0000000
--- a/db2/os/os_alloc.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_alloc.c 10.10 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * !!!
- * Correct for systems that return NULL when you allocate 0 bytes of memory.
- * There are several places in DB where we allocate the number of bytes held
- * by the key/data item, and it can be 0. Correct here so that malloc never
- * returns a NULL for that reason (which behavior is permitted by ANSI). We
- * could make these calls macros on non-Alpha architectures (that's where we
- * saw the problem), but it's probably not worth the autoconf complexity.
- *
- * !!!
- * Correct for systems that don't set errno when malloc and friends fail.
- *
- * Out of memory.
- * We wish to hold the whole sky,
- * But we never will.
- */
-
-/*
- * __os_strdup --
- * The strdup(3) function for DB.
- *
- * PUBLIC: int __os_strdup __P((const char *, void *));
- */
-int
-__os_strdup(str, storep)
- const char *str;
- void *storep;
-{
- size_t size;
- int ret;
- void *p;
-
- *(void **)storep = NULL;
-
- size = strlen(str) + 1;
- if ((ret = __os_malloc(size, NULL, &p)) != 0)
- return (ret);
-
- memcpy(p, str, size);
-
- *(void **)storep = p;
- return (0);
-}
-
-/*
- * __os_calloc --
- * The calloc(3) function for DB.
- *
- * PUBLIC: int __os_calloc __P((size_t, size_t, void *));
- */
-int
-__os_calloc(num, size, storep)
- size_t num, size;
- void *storep;
-{
- void *p;
- int ret;
-
- size *= num;
- if ((ret = __os_malloc(size, NULL, &p)) != 0)
- return (ret);
-
- memset(p, 0, size);
- *(void **)storep = p;
-
- return (0);
-}
-
-/*
- * __os_malloc --
- * The malloc(3) function for DB.
- *
- * PUBLIC: int __os_malloc __P((size_t, void *(*)(size_t), void *));
- */
-int
-__os_malloc(size, db_malloc, storep)
- size_t size;
- void *(*db_malloc) __P((size_t)), *storep;
-{
- void *p;
-
- *(void **)storep = NULL;
-
- /* Never allocate 0 bytes -- some C libraries don't like it. */
- if (size == 0)
- ++size;
-
- /* Some C libraries don't correctly set errno when malloc(3) fails. */
- errno = 0;
- if (db_malloc != NULL)
- p = db_malloc(size);
- else if (__db_jump.j_malloc != NULL)
- p = __db_jump.j_malloc(size);
- else
- p = malloc(size);
- if (p == NULL) {
- if (errno == 0)
- errno = ENOMEM;
- return (errno);
- }
-
-#ifdef DIAGNOSTIC
- memset(p, 0xdb, size);
-#endif
- *(void **)storep = p;
-
- return (0);
-}
-
-/*
- * __os_realloc --
- * The realloc(3) function for DB.
- *
- * PUBLIC: int __os_realloc __P((void *, size_t));
- */
-int
-__os_realloc(storep, size)
- void *storep;
- size_t size;
-{
- void *p, *ptr;
-
- ptr = *(void **)storep;
-
- /* If we haven't yet allocated anything yet, simply call malloc. */
- if (ptr == NULL)
- return (__os_malloc(size, NULL, storep));
-
- /* Never allocate 0 bytes -- some C libraries don't like it. */
- if (size == 0)
- ++size;
-
- /*
- * Some C libraries don't correctly set errno when realloc(3) fails.
- *
- * Don't overwrite the original pointer, there are places in DB we
- * try to continue after realloc fails.
- */
- errno = 0;
- if (__db_jump.j_realloc != NULL)
- p = __db_jump.j_realloc(ptr, size);
- else
- p = realloc(ptr, size);
- if (p == NULL) {
- if (errno == 0)
- errno = ENOMEM;
- return (errno);
- }
-
- *(void **)storep = p;
-
- return (0);
-}
-
-/*
- * __os_free --
- * The free(3) function for DB.
- *
- * PUBLIC: void __os_free __P((void *, size_t));
- */
-void
-__os_free(ptr, size)
- void *ptr;
- size_t size;
-{
-#ifdef DIAGNOSTIC
- if (size != 0)
- memset(ptr, 0xdb, size);
-#endif
-
- if (__db_jump.j_free != NULL)
- __db_jump.j_free(ptr);
- else
- free(ptr);
-}
-
-/*
- * __os_freestr --
- * The free(3) function for DB, freeing a string.
- *
- * PUBLIC: void __os_freestr __P((void *));
- */
-void
-__os_freestr(ptr)
- void *ptr;
-{
-#ifdef DIAGNOSTIC
- memset(ptr, 0xdb, strlen(ptr) + 1);
-#endif
-
- if (__db_jump.j_free != NULL)
- __db_jump.j_free(ptr);
- else
- free(ptr);
-}
diff --git a/db2/os/os_config.c b/db2/os/os_config.c
deleted file mode 100644
index 71d379a..0000000
--- a/db2/os/os_config.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_config.c 10.30 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-struct __db_jumptab __db_jump;
-
-DB_GLOBALS __db_global_values = {
- 1, /* DB_MUTEXLOCKS */
- 0, /* DB_PAGEYIELD */
- 0, /* DB_REGION_ANON, DB_REGION_NAME */
- 0, /* DB_REGION_INIT */
- 0, /* DB_TSL_SPINS */
- {NULL, &__db_global_values.db_envq.tqh_first}, /* Environemnt queue */
- {NULL, &__db_global_values.db_nameq.tqh_first} /* Name queue */
-};
-
-/*
- * db_jump_set --
- * Replace functions for the DB package.
- */
-int
-db_jump_set(func, which)
- void *func;
- int which;
-{
- switch (which) {
- case DB_FUNC_CLOSE:
- __db_jump.j_close = (int (*) __P((int)))func;
- break;
- case DB_FUNC_DIRFREE:
- __db_jump.j_dirfree = (void (*) __P((char **, int)))func;
- break;
- case DB_FUNC_DIRLIST:
- __db_jump.j_dirlist =
- (int (*) __P((const char *, char ***, int *)))func;
- break;
- case DB_FUNC_EXISTS:
- __db_jump.j_exists = (int (*) __P((const char *, int *)))func;
- break;
- case DB_FUNC_FREE:
- __db_jump.j_free = (void (*) __P((void *)))func;
- break;
- case DB_FUNC_FSYNC:
- __db_jump.j_fsync = (int (*) __P((int)))func;
- break;
- case DB_FUNC_IOINFO:
- __db_jump.j_ioinfo = (int (*) __P((const char *,
- int, u_int32_t *, u_int32_t *, u_int32_t *)))func;
- break;
- case DB_FUNC_MALLOC:
- __db_jump.j_malloc = (void *(*) __P((size_t)))func;
- break;
- case DB_FUNC_MAP:
- __db_jump.j_map = (int (*)
- __P((char *, int, size_t, int, int, int, void **)))func;
- break;
- case DB_FUNC_OPEN:
- __db_jump.j_open = (int (*) __P((const char *, int, ...)))func;
- break;
- case DB_FUNC_READ:
- __db_jump.j_read =
- (ssize_t (*) __P((int, void *, size_t)))func;
- break;
- case DB_FUNC_REALLOC:
- __db_jump.j_realloc = (void *(*) __P((void *, size_t)))func;
- break;
- case DB_FUNC_RUNLINK:
- __db_jump.j_runlink = (int (*) __P((char *)))func;
- break;
- case DB_FUNC_SEEK:
- __db_jump.j_seek = (int (*)
- __P((int, size_t, db_pgno_t, u_int32_t, int, int)))func;
- break;
- case DB_FUNC_SLEEP:
- __db_jump.j_sleep = (int (*) __P((u_long, u_long)))func;
- break;
- case DB_FUNC_UNLINK:
- __db_jump.j_unlink = (int (*) __P((const char *)))func;
- break;
- case DB_FUNC_UNMAP:
- __db_jump.j_unmap = (int (*) __P((void *, size_t)))func;
- break;
- case DB_FUNC_WRITE:
- __db_jump.j_write =
- (ssize_t (*) __P((int, const void *, size_t)))func;
- break;
- case DB_FUNC_YIELD:
- __db_jump.j_yield = (int (*) __P((void)))func;
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * db_value_set --
- * Replace values for the DB package.
- */
-int
-db_value_set(value, which)
- int value, which;
-{
- int ret;
-
- switch (which) {
- case DB_MUTEXLOCKS:
- DB_GLOBAL(db_mutexlocks) = value;
- break;
- case DB_PAGEYIELD:
- DB_GLOBAL(db_pageyield) = value;
- break;
- case DB_REGION_ANON:
- if (value != 0 && (ret = __db_mapanon_ok(0)) != 0)
- return (ret);
- DB_GLOBAL(db_region_anon) = value;
- break;
- case DB_REGION_INIT:
- DB_GLOBAL(db_region_init) = value;
- break;
- case DB_REGION_NAME:
- if (value != 0 && (ret = __db_mapanon_ok(1)) != 0)
- return (ret);
- DB_GLOBAL(db_region_anon) = value;
- break;
- case DB_TSL_SPINS:
- if (value <= 0)
- return (EINVAL);
- DB_GLOBAL(db_tsl_spins) = value;
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
diff --git a/db2/os/os_dir.c b/db2/os/os_dir.c
deleted file mode 100644
index f2ee128..0000000
--- a/db2/os/os_dir.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_dir.c 10.19 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_dirlist --
- * Return a list of the files in a directory.
- *
- * PUBLIC: int __os_dirlist __P((const char *, char ***, int *));
- */
-int
-__os_dirlist(dir, namesp, cntp)
- const char *dir;
- char ***namesp;
- int *cntp;
-{
- struct dirent *dp;
- DIR *dirp;
- int arraysz, cnt, ret;
- char **names;
-
- if (__db_jump.j_dirlist != NULL)
- return (__db_jump.j_dirlist(dir, namesp, cntp));
-
- if ((dirp = opendir(dir)) == NULL)
- return (errno);
- names = NULL;
- for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL; ++cnt) {
- if (cnt >= arraysz) {
- arraysz += 100;
- if ((ret = __os_realloc(&names,
- arraysz * sizeof(names[0]))) != 0)
- goto nomem;
- }
- if ((ret = __os_strdup(dp->d_name, &names[cnt])) != 0)
- goto nomem;
- }
- (void)closedir(dirp);
-
- *namesp = names;
- *cntp = cnt;
- return (0);
-
-nomem: if (names != NULL)
- __os_dirfree(names, cnt);
- return (ret);
-}
-
-/*
- * __os_dirfree --
- * Free the list of files.
- *
- * PUBLIC: void __os_dirfree __P((char **, int));
- */
-void
-__os_dirfree(names, cnt)
- char **names;
- int cnt;
-{
- if (__db_jump.j_dirfree != NULL)
- __db_jump.j_dirfree(names, cnt);
-
- while (cnt > 0)
- __os_free(names[--cnt], 0);
- __os_free(names, 0);
-}
diff --git a/db2/os/os_fid.c b/db2/os/os_fid.c
deleted file mode 100644
index 62da590..0000000
--- a/db2/os/os_fid.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_fid.c 10.12 (Sleepycat) 7/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#endif
-
-#include "db_int.h"
-#include "common_ext.h"
-
-/*
- * __os_fileid --
- * Return a unique identifier for a file.
- *
- * PUBLIC: int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
- */
-int
-__os_fileid(dbenv, fname, timestamp, fidp)
- DB_ENV *dbenv;
- const char *fname;
- int timestamp;
- u_int8_t *fidp;
-{
- struct stat sb;
- size_t i;
- time_t now;
- u_int8_t *p;
-
- /* Clear the buffer. */
- memset(fidp, 0, DB_FILE_ID_LEN);
-
- /* Check for the unthinkable. */
- if (sizeof(sb.st_ino) +
- sizeof(sb.st_dev) + sizeof(time_t) > DB_FILE_ID_LEN)
- return (EINVAL);
-
- /* On UNIX, use a dev/inode pair. */
- if (stat(fname, &sb)) {
- __db_err(dbenv, "%s: %s", fname, strerror(errno));
- return (errno);
- }
-
- /*
- * Use the inode first and in reverse order, hopefully putting the
- * distinguishing information early in the string.
- */
- for (p = (u_int8_t *)&sb.st_ino +
- sizeof(sb.st_ino), i = 0; i < sizeof(sb.st_ino); ++i)
- *fidp++ = *--p;
- for (p = (u_int8_t *)&sb.st_dev +
- sizeof(sb.st_dev), i = 0; i < sizeof(sb.st_dev); ++i)
- *fidp++ = *--p;
-
- if (timestamp) {
- (void)time(&now);
- for (p = (u_int8_t *)&now +
- sizeof(now), i = 0; i < sizeof(now); ++i)
- *fidp++ = *--p;
- }
- return (0);
-}
diff --git a/db2/os/os_fsync.c b/db2/os/os_fsync.c
deleted file mode 100644
index 61a504f..0000000
--- a/db2/os/os_fsync.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_fsync.c 10.7 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h> /* XXX: Required by __hp3000s900 */
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-#ifdef __hp3000s900
-int
-__mpe_fsync(fd)
- int fd;
-{
- extern FCONTROL(short, short, void *);
-
- FCONTROL(_MPE_FILENO(fd), 2, NULL); /* Flush the buffers */
- FCONTROL(_MPE_FILENO(fd), 6, NULL); /* Write the EOF */
- return (0);
-}
-#endif
-
-#ifdef __hp3000s900
-#define fsync(fd) __mpe_fsync(fd);
-#endif
-#ifdef _WIN32
-#define fsync(fd) _commit(fd);
-#endif
-
-/*
- * __os_fsync --
- * Flush a file descriptor.
- *
- * PUBLIC: int __os_fsync __P((int));
- */
-int
-__os_fsync(fd)
- int fd;
-{
- int ret;
-
- ret = __db_jump.j_fsync != NULL ? __db_jump.j_fsync(fd) : fsync(fd);
- return (ret == 0 ? 0 : errno);
-}
diff --git a/db2/os/os_map.c b/db2/os/os_map.c
deleted file mode 100644
index 5664a2e..0000000
--- a/db2/os/os_map.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_map.c 10.24 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-
-#ifdef HAVE_SHMGET
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-#include "common_ext.h"
-
-#ifdef HAVE_MMAP
-static int __os_map __P((char *, int, size_t, int, int, int, void **));
-#endif
-#ifdef HAVE_SHMGET
-static int __os_shmget __P((REGINFO *));
-#endif
-
-/*
- * __db_mapanon_ok --
- * Return if this OS can support anonymous memory regions.
- *
- * PUBLIC: int __db_mapanon_ok __P((int));
- */
-int
-__db_mapanon_ok(need_names)
- int need_names;
-{
- int ret;
-
- ret = EINVAL;
-
- /*
- * If we don't have spinlocks, we have to have a file descriptor
- * for fcntl(2) locking, which implies using mmap(2) to map in a
- * regular file. Theoretically, we could probably find ways to
- * get a file descriptor to lock other types of shared regions,
- * but I don't see any reason to do so.
- *
- * If need_names is set, the application wants to share anonymous
- * memory among multiple processes, so we have to have a way to
- * name it. This requires shmget(2), on UNIX systems.
- */
-#ifdef HAVE_SPINLOCKS
-#ifdef HAVE_SHMGET
- ret = 0;
-#endif
-#ifdef HAVE_MMAP
-#ifdef MAP_ANON
- if (!need_names)
- ret = 0;
-#endif
-#ifdef MAP_ANONYMOUS
- if (!need_names)
- ret = 0;
-#endif
-#else
- COMPQUIET(need_names, 0);
-#endif /* HAVE_MMAP */
-#endif /* HAVE_SPINLOCKS */
-
- return (ret);
-}
-
-/*
- * __db_mapinit --
- * Return if shared regions need to be initialized.
- *
- * PUBLIC: int __db_mapinit __P((void));
- */
-int
-__db_mapinit()
-{
- /*
- * Historically, some systems required that all of the bytes of the
- * region be written before it could be mmapped and accessed randomly.
- * We have the option of setting REGION_INIT_NEEDED at configuration
- * time if we're running on one of those systems.
- */
-#ifdef REGION_INIT_NEEDED
- return (1);
-#else
- return (0);
-#endif
-}
-
-/*
- * __db_mapregion --
- * Attach to a shared memory region.
- *
- * PUBLIC: int __db_mapregion __P((char *, REGINFO *));
- */
-int
-__db_mapregion(path, infop)
- char *path;
- REGINFO *infop;
-{
- int called, ret;
-
- called = 0;
- ret = EINVAL;
-
- /* If the user replaces the map call, call through their interface. */
- if (__db_jump.j_map != NULL) {
- F_SET(infop, REGION_HOLDINGSYS);
- return (__db_jump.j_map(path, infop->fd, infop->size,
- 1, F_ISSET(infop, REGION_ANONYMOUS), 0, &infop->addr));
- }
-
- if (F_ISSET(infop, REGION_ANONYMOUS)) {
- /*
- * !!!
- * If we're creating anonymous regions:
- *
- * If it's private, we use mmap(2). The problem with using
- * shmget(2) is that we may be creating a region of which the
- * application isn't aware, and if the application crashes
- * we'll have no way to remove the system resources for the
- * region.
- *
- * If it's not private, we use the shmget(2) interface if it's
- * available, because it allows us to name anonymous memory.
- * If shmget(2) isn't available, use the mmap(2) calls.
- *
- * In the case of anonymous memory, using mmap(2) means the
- * memory isn't named and only the single process and its
- * threads can access the region.
- */
-#ifdef HAVE_MMAP
-#ifdef MAP_ANON
-#define HAVE_MMAP_ANONYMOUS 1
-#else
-#ifdef MAP_ANONYMOUS
-#define HAVE_MMAP_ANONYMOUS 1
-#endif
-#endif
-#endif
-#ifdef HAVE_MMAP_ANONYMOUS
- if (!called && F_ISSET(infop, REGION_PRIVATE)) {
- called = 1;
- ret = __os_map(path,
- infop->fd, infop->size, 1, 1, 0, &infop->addr);
- }
-#endif
-#ifdef HAVE_SHMGET
- if (!called) {
- called = 1;
- ret = __os_shmget(infop);
- }
-#endif
-#ifdef HAVE_MMAP
- /*
- * If we're trying to join an unnamed anonymous region, fail --
- * that's not possible.
- */
- if (!called) {
- called = 1;
-
- if (!F_ISSET(infop, REGION_CREATED)) {
- __db_err(infop->dbenv,
- "cannot join region in unnamed anonymous memory");
- return (EINVAL);
- }
-
- ret = __os_map(path,
- infop->fd, infop->size, 1, 1, 0, &infop->addr);
- }
-#endif
- } else {
- /*
- * !!!
- * If we're creating normal regions, we use the mmap(2)
- * interface if it's available because it's POSIX 1003.1
- * standard and we trust it more than we do shmget(2).
- */
-#ifdef HAVE_MMAP
- if (!called) {
- called = 1;
-
- /* Mmap(2) regions that aren't anonymous can grow. */
- F_SET(infop, REGION_CANGROW);
-
- ret = __os_map(path,
- infop->fd, infop->size, 1, 0, 0, &infop->addr);
- }
-#endif
-#ifdef HAVE_SHMGET
- if (!called) {
- called = 1;
- ret = __os_shmget(infop);
- }
-#endif
- }
- return (ret);
-}
-
-/*
- * __db_unmapregion --
- * Detach from the shared memory region.
- *
- * PUBLIC: int __db_unmapregion __P((REGINFO *));
- */
-int
-__db_unmapregion(infop)
- REGINFO *infop;
-{
- int called, ret;
-
- called = 0;
- ret = EINVAL;
-
- if (__db_jump.j_unmap != NULL)
- return (__db_jump.j_unmap(infop->addr, infop->size));
-
-#ifdef HAVE_SHMGET
- if (infop->segid != INVALID_SEGID) {
- called = 1;
- ret = shmdt(infop->addr) ? errno : 0;
- }
-#endif
-#ifdef HAVE_MMAP
- if (!called) {
- called = 1;
- ret = munmap(infop->addr, infop->size) ? errno : 0;
- }
-#endif
- return (ret);
-}
-
-/*
- * __db_unlinkregion --
- * Remove the shared memory region.
- *
- * PUBLIC: int __db_unlinkregion __P((char *, REGINFO *));
- */
-int
-__db_unlinkregion(name, infop)
- char *name;
- REGINFO *infop;
-{
- int called, ret;
-
- called = 0;
- ret = EINVAL;
-
- if (__db_jump.j_runlink != NULL)
- return (__db_jump.j_runlink(name));
-
-#ifdef HAVE_SHMGET
- if (infop->segid != INVALID_SEGID) {
- called = 1;
- ret = shmctl(infop->segid, IPC_RMID, NULL) ? errno : 0;
- }
-#endif
-#ifdef HAVE_MMAP
- COMPQUIET(infop, NULL);
- if (!called) {
- called = 1;
- ret = 0;
- }
-#endif
- return (ret);
-}
-
-/*
- * __db_mapfile --
- * Map in a shared memory file.
- *
- * PUBLIC: int __db_mapfile __P((char *, int, size_t, int, void **));
- */
-int
-__db_mapfile(path, fd, len, is_rdonly, addr)
- char *path;
- int fd, is_rdonly;
- size_t len;
- void **addr;
-{
- if (__db_jump.j_map != NULL)
- return (__db_jump.j_map(path, fd, len, 0, 0, is_rdonly, addr));
-
-#ifdef HAVE_MMAP
- return (__os_map(path, fd, len, 0, 0, is_rdonly, addr));
-#else
- return (EINVAL);
-#endif
-}
-
-/*
- * __db_unmapfile --
- * Unmap the shared memory file.
- *
- * PUBLIC: int __db_unmapfile __P((void *, size_t));
- */
-int
-__db_unmapfile(addr, len)
- void *addr;
- size_t len;
-{
- if (__db_jump.j_unmap != NULL)
- return (__db_jump.j_unmap(addr, len));
-
-#ifdef HAVE_MMAP
- return (munmap(addr, len) ? errno : 0);
-#else
- return (EINVAL);
-#endif
-}
-
-#ifdef HAVE_MMAP
-/*
- * __os_map --
- * Call the mmap(2) function.
- */
-static int
-__os_map(path, fd, len, is_region, is_anonymous, is_rdonly, addr)
- char *path;
- int fd, is_region, is_anonymous, is_rdonly;
- size_t len;
- void **addr;
-{
- void *p;
- int flags, prot;
-
- COMPQUIET(path, NULL);
-
- /*
- * If it's read-only, it's private, and if it's not, it's shared.
- * Don't bother with an additional parameter.
- */
- flags = is_rdonly ? MAP_PRIVATE : MAP_SHARED;
-
- if (is_region && is_anonymous) {
- /*
- * BSD derived systems use MAP_ANON; Digital Unix and HP/UX
- * use MAP_ANONYMOUS.
- */
-#ifdef MAP_ANON
- flags |= MAP_ANON;
-#endif
-#ifdef MAP_ANONYMOUS
- flags |= MAP_ANONYMOUS;
-#endif
- fd = -1;
- }
-#ifdef MAP_FILE
- if (!is_region || !is_anonymous) {
- /*
- * Historically, MAP_FILE was required for mapping regular
- * files, even though it was the default. Some systems have
- * it, some don't, some that have it set it to 0.
- */
- flags |= MAP_FILE;
- }
-#endif
-
- /*
- * I know of no systems that implement the flag to tell the system
- * that the region contains semaphores, but it's not an unreasonable
- * thing to do, and has been part of the design since forever. I
- * don't think anyone will object, but don't set it for read-only
- * files, it doesn't make sense.
- */
-#ifdef MAP_HASSEMAPHORE
- if (!is_rdonly)
- flags |= MAP_HASSEMAPHORE;
-#endif
-
- prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);
-
-/*
- * XXX
- * Work around a bug in the VMS V7.1 mmap() implementation. To map a file
- * into memory on VMS it needs to be opened in a certain way, originally.
- * To get the file opened in that certain way, the VMS mmap() closes the
- * file and re-opens it. When it does this, it doesn't flush any caches
- * out to disk before closing. The problem this causes us is that when the
- * memory cache doesn't get written out, the file isn't big enough to match
- * the memory chunk and the mmap() call fails. This call to fsync() fixes
- * the problem. DEC thinks this isn't a bug because of language in XPG5
- * discussing user responsibility for on-disk and in-memory synchronization.
- */
-#ifdef VMS
- if (__os_fsync(fd) == -1)
- return(errno);
-#endif
-
- /* MAP_FAILED was not defined in early mmap implementations. */
-#ifndef MAP_FAILED
-#define MAP_FAILED -1
-#endif
- if ((p =
- mmap(NULL, len, prot, flags, fd, (off_t)0)) == (void *)MAP_FAILED)
- return (errno);
-
- *addr = p;
- return (0);
-}
-#endif
-
-#ifdef HAVE_SHMGET
-/*
- * __os_shmget --
- * Call the shmget(2) family of functions.
- */
-static int
-__os_shmget(infop)
- REGINFO *infop;
-{
- if (F_ISSET(infop, REGION_CREATED) &&
- (infop->segid = shmget(0, infop->size, IPC_PRIVATE | 0600)) == -1)
- return (errno);
-
- if ((infop->addr = shmat(infop->segid, NULL, 0)) == (void *)-1) {
- /*
- * If we're trying to join the region and failing, assume
- * that there was a reboot and the region no longer exists.
- */
- if (!F_ISSET(infop, REGION_CREATED))
- errno = EAGAIN;
- return (errno);
- }
-
- F_SET(infop, REGION_HOLDINGSYS);
- return (0);
-}
-#endif
diff --git a/db2/os/os_oflags.c b/db2/os/os_oflags.c
deleted file mode 100644
index a4003dd..0000000
--- a/db2/os/os_oflags.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_oflags.c 10.6 (Sleepycat) 4/19/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <fcntl.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * __db_oflags --
- * Convert open(2) flags to DB flags.
- *
- * PUBLIC: u_int32_t __db_oflags __P((int));
- */
-u_int32_t
-__db_oflags(oflags)
- int oflags;
-{
- u_int32_t dbflags;
-
- /*
- * Convert POSIX 1003.1 open(2) flags to DB flags.
- */
- dbflags = 0;
- switch (oflags & O_ACCMODE) {
- case O_RDONLY:
- dbflags |= DB_RDONLY;
- break;
- case O_WRONLY:
- case O_RDWR:
- break;
- default: /* Bogus flags value from user. */
- /* XXX no way to return error from here */
- }
- if (oflags & O_CREAT)
- dbflags |= DB_CREATE;
- if (oflags & O_TRUNC)
- dbflags |= DB_TRUNCATE;
- return (dbflags);
-}
-
-/*
- * __db_omode --
- * Convert a permission string to the correct open(2) flags.
- *
- * PUBLIC: int __db_omode __P((const char *));
- */
-int
-__db_omode(perm)
- const char *perm;
-{
- int mode;
-
-#ifndef S_IRUSR
-#if defined(_WIN32) || defined(WIN16)
-#define S_IRUSR S_IREAD /* R for owner */
-#define S_IWUSR S_IWRITE /* W for owner */
-#define S_IRGRP 0 /* R for group */
-#define S_IWGRP 0 /* W for group */
-#define S_IROTH 0 /* R for other */
-#define S_IWOTH 0 /* W for other */
-#else
-#define S_IRUSR 0000400 /* R for owner */
-#define S_IWUSR 0000200 /* W for owner */
-#define S_IRGRP 0000040 /* R for group */
-#define S_IWGRP 0000020 /* W for group */
-#define S_IROTH 0000004 /* R for other */
-#define S_IWOTH 0000002 /* W for other */
-#endif /* _WIN32 || WIN16 */
-#endif
- mode = 0;
- if (perm[0] == 'r')
- mode |= S_IRUSR;
- if (perm[1] == 'w')
- mode |= S_IWUSR;
- if (perm[2] == 'r')
- mode |= S_IRGRP;
- if (perm[3] == 'w')
- mode |= S_IWGRP;
- if (perm[4] == 'r')
- mode |= S_IROTH;
- if (perm[5] == 'w')
- mode |= S_IWOTH;
- return (mode);
-}
diff --git a/db2/os/os_open.c b/db2/os/os_open.c
deleted file mode 100644
index c54fd73..0000000
--- a/db2/os/os_open.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_open.c 10.33 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __db_open --
- * Open a file descriptor.
- *
- * PUBLIC: int __db_open __P((const char *, u_int32_t, u_int32_t, int, int *));
- */
-int
-__db_open(name, arg_flags, ok_flags, mode, fdp)
- const char *name;
- u_int32_t arg_flags, ok_flags;
- int mode, *fdp;
-{
-#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
- sigset_t set, oset;
-#endif
- int flags, ret;
-
- if (arg_flags & ~ok_flags)
- return (EINVAL);
-
- flags = 0;
-
- /*
- * DB requires the semantic that two files opened at the same time
- * with O_CREAT and O_EXCL set will return failure in at least one.
- */
- if (arg_flags & DB_CREATE)
- flags |= O_CREAT;
-
- if (arg_flags & DB_EXCL)
- flags |= O_EXCL;
-
- if (arg_flags & DB_RDONLY)
- flags |= O_RDONLY;
- else
- flags |= O_RDWR;
-
-#if defined(_WIN32) || defined(WIN16)
-#ifdef _MSC_VER
- if (arg_flags & DB_SEQUENTIAL)
- flags |= _O_SEQUENTIAL;
- else
- flags |= _O_RANDOM;
-
- if (arg_flags & DB_TEMPORARY)
- flags |= _O_TEMPORARY;
-#endif
- flags |= O_BINARY | O_NOINHERIT;
-#endif
-
- if (arg_flags & DB_TRUNCATE)
- flags |= O_TRUNC;
-
-#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
- /*
- * We block every signal we can get our hands on so that the temporary
- * file isn't left around if we're interrupted at the wrong time. Of
- * course, if we drop core in-between the calls we'll hang forever, but
- * that's probably okay. ;-)
- */
- if (arg_flags & DB_TEMPORARY) {
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- }
-#endif
-
- /* Open the file. */
- if ((ret = __os_open(name, flags, mode, fdp)) != 0)
- return (ret);
-
-#if !defined(_WIN32)
- /* Delete any temporary file; done for Win32 by _O_TEMPORARY. */
- if (arg_flags & DB_TEMPORARY) {
- (void)__os_unlink(name);
-#if defined(HAVE_SIGFILLSET)
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
-#endif
- }
-#endif
-
-#if !defined(_WIN32) && !defined(WIN16) && !defined(VMS)
- /*
- * Deny access to any child process.
- * VMS: does not have fd inheritance.
- * Win32: done by O_NOINHERIT.
- */
- if (fcntl(*fdp, F_SETFD, 1) == -1) {
- ret = errno;
-
- (void)__os_close(*fdp);
- return (ret);
- }
-#endif
- return (0);
-}
-
-/*
- * __os_open --
- * Open a file.
- *
- * PUBLIC: int __os_open __P((const char *, int, int, int *));
- */
-int
-__os_open(name, flags, mode, fdp)
- const char *name;
- int flags, mode, *fdp;
-{
- *fdp = __db_jump.j_open != NULL ?
- __db_jump.j_open(name, flags, mode) : open(name, flags, mode);
- return (*fdp == -1 ? errno : 0);
-}
-
-/*
- * __os_close --
- * Close a file descriptor.
- *
- * PUBLIC: int __os_close __P((int));
- */
-int
-__os_close(fd)
- int fd;
-{
- int ret;
-
- ret = __db_jump.j_close != NULL ? __db_jump.j_close(fd) : close(fd);
- return (ret == 0 ? 0 : errno);
-}
diff --git a/db2/os/os_rpath.c b/db2/os/os_rpath.c
deleted file mode 100644
index 23867b3..0000000
--- a/db2/os/os_rpath.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_rpath.c 10.3 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <string.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * __db_rpath --
- * Return the last path separator in the path or NULL if none found.
- *
- * PUBLIC: char *__db_rpath __P((const char *));
- */
-char *
-__db_rpath(path)
- const char *path;
-{
- const char *s, *last;
-
- last = NULL;
- if (PATH_SEPARATOR[1] != '\0') {
- for (s = path; s[0] != '\0'; ++s)
- if (strchr(PATH_SEPARATOR, s[0]) != NULL)
- last = s;
- } else
- for (s = path; s[0] != '\0'; ++s)
- if (s[0] == PATH_SEPARATOR[0])
- last = s;
- return ((char *)last);
-}
diff --git a/db2/os/os_rw.c b/db2/os/os_rw.c
deleted file mode 100644
index e0a8163..0000000
--- a/db2/os/os_rw.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_rw.c 10.11 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_io --
- * Do an I/O.
- *
- * PUBLIC: int __os_io __P((DB_IO *, int, ssize_t *));
- */
-int
-__os_io(db_iop, op, niop)
- DB_IO *db_iop;
- int op;
- ssize_t *niop;
-{
- int ret;
-
-#ifdef HAVE_PREAD
- switch (op) {
- case DB_IO_READ:
- if (__db_jump.j_read != NULL)
- goto slow;
- *niop = pread(db_iop->fd_io, db_iop->buf,
- db_iop->bytes, (off_t)db_iop->pgno * db_iop->pagesize);
- break;
- case DB_IO_WRITE:
- if (__db_jump.j_write != NULL)
- goto slow;
- *niop = pwrite(db_iop->fd_io, db_iop->buf,
- db_iop->bytes, (off_t)db_iop->pgno * db_iop->pagesize);
- break;
- }
- if (*niop == db_iop->bytes)
- return (0);
-slow:
-#endif
- if (db_iop->mutexp != NULL)
- (void)__db_mutex_lock(db_iop->mutexp, db_iop->fd_lock);
-
- if ((ret = __os_seek(db_iop->fd_io,
- db_iop->pagesize, db_iop->pgno, 0, 0, SEEK_SET)) != 0)
- goto err;
- switch (op) {
- case DB_IO_READ:
- ret =
- __os_read(db_iop->fd_io, db_iop->buf, db_iop->bytes, niop);
- break;
- case DB_IO_WRITE:
- ret =
- __os_write(db_iop->fd_io, db_iop->buf, db_iop->bytes, niop);
- break;
- }
-
-err: if (db_iop->mutexp != NULL)
- (void)__db_mutex_unlock(db_iop->mutexp, db_iop->fd_lock);
-
- return (ret);
-
-}
-
-/*
- * __os_read --
- * Read from a file handle.
- *
- * PUBLIC: int __os_read __P((int, void *, size_t, ssize_t *));
- */
-int
-__os_read(fd, addr, len, nrp)
- int fd;
- void *addr;
- size_t len;
- ssize_t *nrp;
-{
- size_t offset;
- ssize_t nr;
- u_int8_t *taddr;
-
- for (taddr = addr,
- offset = 0; offset < len; taddr += nr, offset += nr) {
- if ((nr = __db_jump.j_read != NULL ?
- __db_jump.j_read(fd, taddr, len - offset) :
- read(fd, taddr, len - offset)) < 0)
- return (errno);
- if (nr == 0)
- break;
- }
- *nrp = taddr - (u_int8_t *)addr;
- return (0);
-}
-
-/*
- * __os_write --
- * Write to a file handle.
- *
- * PUBLIC: int __os_write __P((int, void *, size_t, ssize_t *));
- */
-int
-__os_write(fd, addr, len, nwp)
- int fd;
- const void *addr;
- size_t len;
- ssize_t *nwp;
-{
- size_t offset;
- ssize_t nw;
- const u_int8_t *taddr;
-
- for (taddr = addr,
- offset = 0; offset < len; taddr += nw, offset += nw)
- if ((nw = __db_jump.j_write != NULL ?
- __db_jump.j_write(fd, taddr, len - offset) :
- write(fd, taddr, len - offset)) < 0)
- return (errno);
- *nwp = len;
- return (0);
-}
diff --git a/db2/os/os_seek.c b/db2/os/os_seek.c
deleted file mode 100644
index ae5272b..0000000
--- a/db2/os/os_seek.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_seek.c 10.11 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_seek --
- * Seek to a page/byte offset in the file.
- *
- * PUBLIC: int __os_seek __P((int, size_t, db_pgno_t, u_int32_t, int, int));
- */
-int
-__os_seek(fd, pgsize, pageno, relative, isrewind, whence)
- int fd;
- size_t pgsize;
- db_pgno_t pageno;
- u_int32_t relative;
- int isrewind, whence;
-{
- off_t offset;
- int ret;
-
- if (__db_jump.j_seek != NULL)
- ret = __db_jump.j_seek(fd,
- pgsize, pageno, relative, isrewind, whence);
- else {
- offset = (off_t)pgsize * pageno + relative;
- if (isrewind)
- offset = -offset;
-
- ret = lseek(fd, offset, whence);
- }
- return (ret == -1 ? errno : 0);
-}
diff --git a/db2/os/os_sleep.c b/db2/os/os_sleep.c
deleted file mode 100644
index 5aa4763..0000000
--- a/db2/os/os_sleep.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_sleep.c 10.12 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <errno.h>
-#ifndef HAVE_SYS_TIME_H
-#include <time.h>
-#endif
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_sleep --
- * Yield the processor for a period of time.
- *
- * PUBLIC: int __os_sleep __P((u_long, u_long));
- */
-int
-__os_sleep(secs, usecs)
- u_long secs, usecs; /* Seconds and microseconds. */
-{
- struct timeval t;
-
- /* Don't require that the values be normalized. */
- for (; usecs >= 1000000; ++secs, usecs -= 1000000)
- ;
-
- if (__db_jump.j_sleep != NULL)
- return (__db_jump.j_sleep(secs, usecs));
-
- /*
- * It's important that we yield the processor here so that other
- * processes or threads are permitted to run.
- */
- t.tv_sec = secs;
- t.tv_usec = usecs;
- return (select(0, NULL, NULL, NULL, &t) == -1 ? errno : 0);
-}
diff --git a/db2/os/os_spin.c b/db2/os/os_spin.c
deleted file mode 100644
index cbde588..0000000
--- a/db2/os/os_spin.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_spin.c 10.10 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#if defined(HAVE_PSTAT_GETDYNAMIC)
-#include <sys/pstat.h>
-#endif
-
-#include <limits.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-#if defined(HAVE_PSTAT_GETDYNAMIC)
-/*
- * __os_pstat_getdynamic --
- * HP/UX.
- */
-static int
-__os_pstat_getdynamic()
-{
- struct pst_dynamic psd;
-
- return (pstat_getdynamic(&psd,
- sizeof(psd), (size_t)1, 0) == -1 ? 1 : psd.psd_proc_cnt);
-}
-#endif
-
-#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
-/*
- * __os_sysconf --
- * Solaris, Linux.
- */
-static int
-__os_sysconf(void)
-{
- int nproc;
-
- return ((nproc = sysconf(_SC_NPROCESSORS_ONLN)) > 1 ? nproc : 1);
-}
-#endif
-
-/*
- * __os_spin --
- * Return the number of default spins before blocking.
- *
- * PUBLIC: int __os_spin __P((void));
- */
-int
-__os_spin()
-{
- /*
- * If the application specified a value or we've already figured it
- * out, return it.
- *
- * XXX
- * We don't want to repeatedly call the underlying function because
- * it can be expensive (e.g., requiring multiple filesystem accesses
- * under Debian Linux).
- */
- if (DB_GLOBAL(db_tsl_spins) != 0)
- return (DB_GLOBAL(db_tsl_spins));
-
- DB_GLOBAL(db_tsl_spins) = 1;
-#if defined(HAVE_PSTAT_GETDYNAMIC)
- DB_GLOBAL(db_tsl_spins) = __os_pstat_getdynamic();
-#endif
-#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
- DB_GLOBAL(db_tsl_spins) = __os_sysconf();
-#endif
-
- /*
- * Spin 50 times per processor, we have anecdotal evidence that this
- * is a reasonable value.
- */
- DB_GLOBAL(db_tsl_spins) *= 50;
-
- return (DB_GLOBAL(db_tsl_spins));
-}
-
-/*
- * __os_yield --
- * Yield the processor.
- *
- * PUBLIC: void __os_yield __P((u_long));
- */
-void
-__os_yield(usecs)
- u_long usecs;
-{
- if (__db_jump.j_yield != NULL && __db_jump.j_yield() == 0)
- return;
- __os_sleep(0, usecs);
-}
diff --git a/db2/os/os_stat.c b/db2/os/os_stat.c
deleted file mode 100644
index 65cba82..0000000
--- a/db2/os/os_stat.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_stat.c 10.18 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_exists --
- * Return if the file exists.
- *
- * PUBLIC: int __os_exists __P((const char *, int *));
- */
-int
-__os_exists(path, isdirp)
- const char *path;
- int *isdirp;
-{
- struct stat sb;
-
- if (__db_jump.j_exists != NULL)
- return (__db_jump.j_exists(path, isdirp));
-
- if (stat(path, &sb) != 0)
- return (errno);
-
-#if !defined(S_ISDIR) || defined(STAT_MACROS_BROKEN)
-#if defined(_WIN32) || defined(WIN16)
-#define S_ISDIR(m) (_S_IFDIR & (m))
-#else
-#define S_ISDIR(m) (((m) & 0170000) == 0040000)
-#endif
-#endif
- if (isdirp != NULL)
- *isdirp = S_ISDIR(sb.st_mode);
-
- return (0);
-}
-
-/*
- * __os_ioinfo --
- * Return file size and I/O size; abstracted to make it easier
- * to replace.
- *
- * PUBLIC: int __os_ioinfo
- * PUBLIC: __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *));
- */
-int
-__os_ioinfo(path, fd, mbytesp, bytesp, iosizep)
- const char *path;
- int fd;
- u_int32_t *mbytesp, *bytesp, *iosizep;
-{
- struct stat sb;
-
- if (__db_jump.j_ioinfo != NULL)
- return (__db_jump.j_ioinfo(path, fd, mbytesp, bytesp, iosizep));
-
- if (fstat(fd, &sb) == -1)
- return (errno);
-
- /* Return the size of the file. */
- if (mbytesp != NULL)
- *mbytesp = sb.st_size / MEGABYTE;
- if (bytesp != NULL)
- *bytesp = sb.st_size % MEGABYTE;
-
- /*
- * Return the underlying filesystem blocksize, if available.
- *
- * XXX
- * Check for a 0 size -- the HP MPE/iX architecture has st_blksize,
- * but it's always 0.
- */
-#ifdef HAVE_ST_BLKSIZE
- if (iosizep != NULL && (*iosizep = sb.st_blksize) == 0)
- *iosizep = DB_DEF_IOSIZE;
-#else
- if (iosizep != NULL)
- *iosizep = DB_DEF_IOSIZE;
-#endif
- return (0);
-}
diff --git a/db2/os/os_tmpdir.c b/db2/os/os_tmpdir.c
deleted file mode 100644
index 0b0bbc7..0000000
--- a/db2/os/os_tmpdir.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_tmpdir.c 10.3 (Sleepycat) 10/13/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#endif
-
-#include "db_int.h"
-#include "common_ext.h"
-
-#ifdef macintosh
-#include <TFileSpec.h>
-#endif
-
-/*
- * __os_tmpdir --
- * Set the temporary directory path.
- *
- * The order of items in the list structure and the order of checks in
- * the environment are documented.
- *
- * PUBLIC: int __os_tmpdir __P((DB_ENV *, u_int32_t));
- */
-int
-__os_tmpdir(dbenv, flags)
- DB_ENV *dbenv;
- u_int32_t flags;
-{
- /*
- * !!!
- * Don't change this to:
- *
- * static const char * const list[]
- *
- * because it creates a text relocation in position independent code.
- */
- static const char * list[] = {
- "/var/tmp",
- "/usr/tmp",
- "/temp", /* Windows. */
- "/tmp",
- "C:/temp", /* Windows. */
- "C:/tmp", /* Windows. */
- NULL
- };
- const char * const *lp, *p;
-
- /* Use the environment if it's permitted and initialized. */
- p = NULL;
-#ifdef HAVE_GETEUID
- if (LF_ISSET(DB_USE_ENVIRON) ||
- (LF_ISSET(DB_USE_ENVIRON_ROOT) && getuid() == 0))
-#else
- if (LF_ISSET(DB_USE_ENVIRON))
-#endif
- {
- if ((p = getenv("TMPDIR")) != NULL && p[0] == '\0') {
- __db_err(dbenv, "illegal TMPDIR environment variable");
- return (EINVAL);
- }
- /* Windows */
- if (p == NULL && (p = getenv("TEMP")) != NULL && p[0] == '\0') {
- __db_err(dbenv, "illegal TEMP environment variable");
- return (EINVAL);
- }
- /* Windows */
- if (p == NULL && (p = getenv("TMP")) != NULL && p[0] == '\0') {
- __db_err(dbenv, "illegal TMP environment variable");
- return (EINVAL);
- }
- /* Macintosh */
- if (p == NULL &&
- (p = getenv("TempFolder")) != NULL && p[0] == '\0') {
- __db_err(dbenv,
- "illegal TempFolder environment variable");
- return (EINVAL);
- }
- }
-
-#ifdef macintosh
- /* Get the path to the temporary folder. */
- if (p == NULL) {
- FSSpec spec;
-
- if (!Special2FSSpec(kTemporaryFolderType,
- kOnSystemDisk, 0, &spec))
- (void)__os_strdup(FSp2FullPath(&spec), &p);
- }
-#endif
-
- /* Step through the list looking for a possibility. */
- if (p == NULL)
- for (lp = list; *lp != NULL; ++lp)
- if (__os_exists(p = *lp, NULL) == 0)
- break;
- if (p == NULL)
- return (0);
-
- return (__os_strdup(p, &dbenv->db_tmp_dir));
-}
diff --git a/db2/os/os_unlink.c b/db2/os/os_unlink.c
deleted file mode 100644
index aa484de..0000000
--- a/db2/os/os_unlink.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)os_unlink.c 10.7 (Sleepycat) 10/12/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "os_jump.h"
-
-/*
- * __os_unlink --
- * Remove a file.
- *
- * PUBLIC: int __os_unlink __P((const char *));
- */
-int
-__os_unlink(path)
- const char *path;
-{
- int ret;
-
- ret = __db_jump.j_unlink != NULL ?
- __db_jump.j_unlink(path) : unlink(path);
- return (ret == -1 ? errno : 0);
-}
diff --git a/db2/progs/db_archive/db_archive.c b/db2/progs/db_archive/db_archive.c
deleted file mode 100644
index ca48995..0000000
--- a/db2/progs/db_archive/db_archive.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_archive.c 10.20 (Sleepycat) 10/3/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "db_dispatch.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-DB_ENV *db_init __P((char *, int));
-int main __P((int, char *[]));
-void nosig __P((void));
-void usage __P((void));
-
-const char
- *progname = "db_archive"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- u_int32_t flags;
- int ch, verbose;
- char *home, **list;
-
- flags = verbose = 0;
- home = NULL;
- while ((ch = getopt(argc, argv, "ah:lsv")) != EOF)
- switch (ch) {
- case 'a':
- flags |= DB_ARCH_ABS;
- break;
- case 'h':
- home = optarg;
- break;
- case 'l':
- flags |= DB_ARCH_LOG;
- break;
- case 's':
- flags |= DB_ARCH_DATA;
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- usage();
-
- /*
- * Ignore signals -- we don't want to be interrupted because we're
- * spending all of our time in the DB library.
- */
- nosig();
- dbenv = db_init(home, verbose);
-
- /* Get the list of names. */
- if ((errno = log_archive(dbenv->lg_info, &list, flags, NULL)) != 0) {
- warn(NULL);
- (void)db_appexit(dbenv);
- return (1);
- }
-
- /* Print the names. */
- if (list != NULL)
- for (; *list != NULL; ++list)
- printf("%s\n", *list);
-
- if ((errno = db_appexit(dbenv)) != 0) {
- warn(NULL);
- return (1);
- }
-
- return (0);
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home, verbose)
- char *home;
- int verbose;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
- dbenv->db_verbose = verbose;
-
- if ((errno = db_appinit(home, NULL, dbenv,
- DB_CREATE | DB_INIT_LOG | DB_INIT_TXN | DB_USE_ENVIRON)) != 0)
- err(1, "db_appinit");
-
- return (dbenv);
-}
-
-/*
- * nosig --
- * We don't want to be interrupted.
- */
-void
-nosig()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, SIG_IGN);
-#endif
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGTERM, SIG_IGN);
-}
-
-void
-usage()
-{
- (void)fprintf(stderr, "usage: db_archive [-alsv] [-h home]\n");
- exit(1);
-}
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
deleted file mode 100644
index f0fe48a..0000000
--- a/db2/progs/db_checkpoint/db_checkpoint.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_checkpoint.c 10.21 (Sleepycat) 10/4/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "btree.h"
-#include "hash.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-char *check __P((DB_ENV *, long, long));
-DB_ENV *db_init __P((char *));
-int logpid __P((char *, int));
-int main __P((int, char *[]));
-void onint __P((int));
-void siginit __P((void));
-void usage __P((void));
-
-int interrupted;
-const char
- *progname = "db_checkpoint"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- time_t now;
- long argval;
- u_int32_t kbytes, minutes, seconds;
- int ch, once, ret, verbose;
- char *home, *logfile;
-
- /*
- * XXX
- * Don't allow a fully unsigned 32-bit number, some compilers get
- * upset and require it to be specified in hexadecimal and so on.
- */
-#define MAX_UINT32_T 2147483647
-
- kbytes = minutes = 0;
- once = ret = verbose = 0;
- home = logfile = NULL;
- while ((ch = getopt(argc, argv, "1h:k:L:p:v")) != EOF)
- switch (ch) {
- case '1':
- once = 1;
- break;
- case 'h':
- home = optarg;
- break;
- case 'k':
- get_long(optarg, 1, (long)MAX_UINT32_T, &argval);
- kbytes = argval;
- break;
- case 'L':
- logfile = optarg;
- break;
- case 'p':
- get_long(optarg, 1, (long)MAX_UINT32_T, &argval);
- minutes = argval;
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- usage();
-
- if (once == 0 && kbytes == 0 && minutes == 0) {
- warnx("at least one of -1, -k and -p must be specified");
- usage();
- }
-
- /* Initialize the environment. */
- siginit();
- dbenv = db_init(home);
-
- if (logfile != NULL && logpid(logfile, 1)) {
- (void)db_appexit(dbenv);
- return (1);
- }
-
- /*
- * If we have only a time delay, then we'll sleep the right amount
- * to wake up when a checkpoint is necessary. If we have a "kbytes"
- * field set, then we'll check every 30 seconds.
- */
- seconds = kbytes != 0 ? 30 : minutes * 60;
- while (!interrupted) {
- if (verbose) {
- (void)time(&now);
- warnx("checkpoint: %s", ctime(&now));
- }
-
- errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
- while (errno == DB_INCOMPLETE) {
- if (verbose)
- warnx("checkpoint did not finish, retrying\n");
- (void)sleep(2);
- errno = txn_checkpoint(dbenv->tx_info, 0, 0);
- }
-
- if (errno != 0) {
- ret = 1;
- warn(NULL);
- break;
- }
-
- if (once)
- break;
-
- (void)sleep(seconds);
- }
-
- if (logfile != NULL && logpid(logfile, 0))
- ret = 1;
-
- if ((errno = db_appexit(dbenv)) != 0) {
- ret = 1;
- warn(NULL);
- }
-
- if (interrupted) {
- (void)signal(interrupted, SIG_DFL);
- (void)raise(interrupted);
- /* NOTREACHED */
- }
-
- return (ret);
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home)
- char *home;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
-
- if ((errno = db_appinit(home, NULL, dbenv,
- DB_INIT_LOG | DB_INIT_TXN | DB_INIT_MPOOL | DB_USE_ENVIRON)) != 0)
- err(1, "db_appinit");
-
- if (memp_register(dbenv->mp_info,
- DB_FTYPE_BTREE, __bam_pgin, __bam_pgout) ||
- memp_register(dbenv->mp_info,
- DB_FTYPE_HASH, __ham_pgin, __ham_pgout)) {
- (void)db_appexit(dbenv);
- errx(1,
- "db_appinit: failed to register access method functions");
- }
-
- return (dbenv);
-}
-
-/*
- * logpid --
- * Log that we're running.
- */
-int
-logpid(fname, is_open)
- char *fname;
- int is_open;
-{
- FILE *fp;
- time_t now;
-
- if (is_open) {
- if ((fp = fopen(fname, "w")) == NULL) {
- warn("%s", fname);
- return (1);
- }
- (void)time(&now);
- fprintf(fp,
- "%.24s: %lu %s", progname, (u_long)getpid(), ctime(&now));
- fclose(fp);
- } else
- (void)remove(fname);
- return (0);
-}
-
-/*
- * siginit --
- * Initialize the set of signals for which we want to clean up.
- * Generally, we try not to leave the shared regions locked if
- * we can.
- */
-void
-siginit()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, onint);
-#endif
- (void)signal(SIGINT, onint);
- (void)signal(SIGTERM, onint);
-}
-
-/*
- * onint --
- * Interrupt signal handler.
- */
-void
-onint(signo)
- int signo;
-{
- if ((interrupted = signo) == 0)
- interrupted = SIGINT;
-}
-
-void
-usage()
-{
- (void)fprintf(stderr,
- "usage: db_checkpoint [-1v] [-h home] [-k kbytes] [-L file] [-p min]\n");
- exit(1);
-}
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
deleted file mode 100644
index bc5039e..0000000
--- a/db2/progs/db_deadlock/db_deadlock.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_deadlock.c 10.23 (Sleepycat) 10/4/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-#define BAD_KILLID 0xffffffff
-
-DB_ENV *db_init __P((char *, int));
-int logpid __P((char *, int));
-int main __P((int, char *[]));
-void onint __P((int));
-void siginit __P((void));
-void usage __P((void));
-
-int interrupted;
-const char
- *progname = "db_deadlock"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- u_int32_t atype;
- time_t now;
- long usecs;
- u_int32_t flags;
- int ch, ret, verbose;
- char *home, *logfile;
-
- atype = DB_LOCK_DEFAULT;
- home = logfile = NULL;
- usecs = 0;
- flags = 0;
- ret = verbose = 0;
- while ((ch = getopt(argc, argv, "a:h:L:t:vw")) != EOF)
- switch (ch) {
- case 'a':
- switch (optarg[0]) {
- case 'o':
- atype = DB_LOCK_OLDEST;
- break;
- case 'y':
- atype = DB_LOCK_YOUNGEST;
- break;
- default:
- usage();
- /* NOTREACHED */
- }
- if (optarg[1] != '\0')
- usage();
- break;
- case 'h':
- home = optarg;
- break;
- case 'L':
- logfile = optarg;
- break;
- case 't':
- get_long(optarg, 1, LONG_MAX, &usecs);
- usecs *= 1000000;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'w':
- LF_SET(DB_LOCK_CONFLICT);
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- usage();
-
- if (usecs == 0 && !LF_ISSET(DB_LOCK_CONFLICT)) {
- warnx("at least one of -t and -w must be specified");
- usage();
- }
-
- /*
- * We detect every 100ms (100000 us) when we're running in
- * DB_LOCK_CONFLICT mode.
- */
- if (usecs == 0)
- usecs = 100000;
-
- /* Initialize the deadlock detector by opening the lock manager. */
- siginit();
- dbenv = db_init(home, verbose);
-
- if (logfile != NULL && logpid(logfile, 1)) {
- (void)db_appexit(dbenv);
- return (1);
- }
-
- while (!interrupted) {
- if (dbenv->db_verbose != 0) {
- time(&now);
- warnx("Running at %.24s", ctime(&now));
- }
-
- if ((errno = lock_detect(dbenv->lk_info, flags, atype)) != 0) {
- ret = 1;
- warnx(NULL);
- break;
- }
-
- /* Make a pass every "usecs" usecs. */
- (void)usleep(usecs);
- }
-
- if (logfile != NULL && logpid(logfile, 0))
- ret = 1;
-
- if ((errno = db_appexit(dbenv)) != 0) {
- ret = 1;
- warn(NULL);
- }
-
- if (interrupted) {
- (void)signal(interrupted, SIG_DFL);
- (void)raise(interrupted);
- /* NOTREACHED */
- }
-
- return (ret);
-}
-
-DB_ENV *
-db_init(home, verbose)
- char *home;
- int verbose;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
- dbenv->db_verbose = verbose;
-
- if ((errno = db_appinit(home,
- NULL, dbenv, DB_INIT_LOCK | DB_USE_ENVIRON)) != 0)
- err(1, "db_appinit");
-
- return (dbenv);
-}
-
-/*
- * logpid --
- * Log that we're running.
- */
-int
-logpid(fname, is_open)
- char *fname;
- int is_open;
-{
- FILE *fp;
- time_t now;
-
- if (is_open) {
- if ((fp = fopen(fname, "w")) == NULL) {
- warn("%s", fname);
- return (1);
- }
- (void)time(&now);
- fprintf(fp,
- "%.24s: %lu %s", progname, (u_long)getpid(), ctime(&now));
- fclose(fp);
- } else
- (void)remove(fname);
- return (0);
-}
-
-/*
- * siginit --
- * Initialize the set of signals for which we want to clean up.
- * Generally, we try not to leave the shared regions locked if
- * we can.
- */
-void
-siginit()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, onint);
-#endif
- (void)signal(SIGINT, onint);
- (void)signal(SIGTERM, onint);
-}
-
-/*
- * onint --
- * Interrupt signal handler.
- */
-void
-onint(signo)
- int signo;
-{
- if ((interrupted = signo) == 0)
- interrupted = SIGINT;
-}
-
-void
-usage()
-{
- (void)fprintf(stderr,
- "usage: db_deadlock [-vw] [-a m | o | y] [-h home] [-L file] [-t sec]\n");
- exit(1);
-}
diff --git a/db2/progs/db_dump/db_dump.c b/db2/progs/db_dump/db_dump.c
deleted file mode 100644
index 0f34ddc..0000000
--- a/db2/progs/db_dump/db_dump.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_dump.c 10.24 (Sleepycat) 11/22/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#undef stat
-
-#include "db_int.h"
-#include "db_page.h"
-#include "btree.h"
-#include "hash.h"
-#include "clib_ext.h"
-
-void configure __P((char *));
-DB_ENV *db_init __P((char *));
-int main __P((int, char *[]));
-void pheader __P((DB *, int));
-void usage __P((void));
-
-const char
- *progname = "db_dump"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB *dbp;
- DBC *dbcp;
- DBT key, data;
- DB_ENV *dbenv;
- int ch, checkprint, dflag;
- char *home;
-
- home = NULL;
- checkprint = dflag = 0;
- while ((ch = getopt(argc, argv, "df:h:Np")) != EOF)
- switch (ch) {
- case 'd':
- dflag = 1;
- break;
- case 'f':
- if (freopen(optarg, "w", stdout) == NULL)
- err(1, "%s", optarg);
- break;
- case 'h':
- home = optarg;
- break;
- case 'N':
- (void)db_value_set(0, DB_MUTEXLOCKS);
- break;
- case 'p':
- checkprint = 1;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1)
- usage();
-
- if (dflag && checkprint)
- errx(1, "the -d and -p options may not both be specified");
-
- /* Initialize the environment. */
- dbenv = db_init(home);
-
- /* Open the DB file. */
- if ((errno =
- db_open(argv[0], DB_UNKNOWN, DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0)
- err(1, "%s", argv[0]);
-
- /* DB dump. */
- if (dflag) {
- (void)__db_dump(dbp, NULL, 1);
- if ((errno = dbp->close(dbp, 0)) != 0)
- err(1, "close");
- exit (0);
- }
-
- /* Get a cursor and step through the database. */
- if ((errno = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
- (void)dbp->close(dbp, 0);
- err(1, "cursor");
- }
-
- /* Print out the header. */
- pheader(dbp, checkprint);
-
- /* Print out the key/data pairs. */
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- while ((errno = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
- if (dbp->type != DB_RECNO &&
- (errno = __db_prdbt(&key, checkprint, stdout)) != 0)
- break;
- if ((errno = __db_prdbt(&data, checkprint, stdout)) != 0)
- break;
- }
-
- if (errno != DB_NOTFOUND)
- err(1, "cursor get");
-
- if ((errno = dbp->close(dbp, 0)) != 0)
- err(1, "close");
- return (0);
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home)
- char *home;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(1, sizeof(DB_ENV))) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
-
- /*
- * Try and use the shared mpool region so that we get pages that
- * haven't been flushed to disk (mostly useful for debugging).
- * If that fails, try again, without the DB_INIT_MPOOL flag.
- *
- * If it works, set the error output options so that future errors
- * are correctly reported.
- */
- if ((errno = db_appinit(home,
- NULL, dbenv, DB_USE_ENVIRON | DB_INIT_MPOOL)) == 0) {
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
- return (dbenv);
- }
-
- /* Set the error output options -- this time we want a message. */
- memset(dbenv, 0, sizeof(*dbenv));
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
-
- /* Try again, and it's fatal if we fail. */
- if ((errno = db_appinit(home, NULL, dbenv, DB_USE_ENVIRON)) != 0)
- err(1, "db_appinit");
-
- return (dbenv);
-}
-
-/*
- * pheader --
- * Write out the header information.
- */
-void
-pheader(dbp, pflag)
- DB *dbp;
- int pflag;
-{
- DBC *dbc;
- DB_BTREE_STAT *btsp;
- HASH_CURSOR *hcp;
- int ret;
-
- printf("format=%s\n", pflag ? "print" : "bytevalue");
- switch (dbp->type) {
- case DB_BTREE:
- printf("type=btree\n");
- if ((errno = dbp->stat(dbp, &btsp, NULL, 0)) != 0)
- err(1, "dbp->stat");
- if (F_ISSET(dbp, DB_BT_RECNUM))
- printf("recnum=1\n");
- if (btsp->bt_maxkey != 0)
- printf("bt_maxkey=%lu\n", (u_long)btsp->bt_maxkey);
- if (btsp->bt_minkey != 0)
- printf("bt_minkey=%lu\n", (u_long)btsp->bt_minkey);
- break;
- case DB_HASH:
- printf("type=hash\n");
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- break;
- hcp = (HASH_CURSOR *)dbc->internal;
- GET_META(dbp, hcp, ret);
- if (ret == 0) {
- if (hcp->hdr->ffactor != 0)
- printf("h_ffactor=%lu\n",
- (u_long)hcp->hdr->ffactor);
- if (hcp->hdr->nelem != 0)
- printf("h_nelem=%lu\n",
- (u_long)hcp->hdr->nelem);
- RELEASE_META(dbp, hcp);
- }
- (void)dbc->c_close(dbc);
- break;
- case DB_RECNO:
- printf("type=recno\n");
- if ((errno = dbp->stat(dbp, &btsp, NULL, 0)) != 0)
- err(1, "dbp->stat");
- if (F_ISSET(dbp, DB_RE_RENUMBER))
- printf("renumber=1\n");
- if (F_ISSET(dbp, DB_RE_FIXEDLEN))
- printf("re_len=%lu\n", (u_long)btsp->bt_re_len);
- if (F_ISSET(dbp, DB_RE_PAD))
- printf("re_pad=%#x\n", btsp->bt_re_pad);
- break;
- case DB_UNKNOWN:
- abort();
- /* NOTREACHED */
- }
-
- if (F_ISSET(dbp, DB_AM_DUP))
- printf("duplicates=1\n");
-
- if (dbp->dbenv->db_lorder != 0)
- printf("db_lorder=%lu\n", (u_long)dbp->dbenv->db_lorder);
-
- if (!F_ISSET(dbp, DB_AM_PGDEF))
- printf("db_pagesize=%lu\n", (u_long)dbp->pgsize);
-
- printf("HEADER=END\n");
-}
-
-/*
- * usage --
- * Display the usage message.
- */
-void
-usage()
-{
- (void)fprintf(stderr,
- "usage: db_dump [-dNp] [-f file] [-h home] db_file\n");
- exit(1);
-}
diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c
deleted file mode 100644
index 1745110..0000000
--- a/db2/progs/db_dump185/db_dump185.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_dump185.c 10.10 (Sleepycat) 4/10/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_185.h"
-#include "clib_ext.h"
-
-/* Hash Table Information */
-typedef struct hashhdr185 { /* Disk resident portion */
- int magic; /* Magic NO for hash tables */
- int version; /* Version ID */
- u_int32_t lorder; /* Byte Order */
- int bsize; /* Bucket/Page Size */
- int bshift; /* Bucket shift */
- int dsize; /* Directory Size */
- int ssize; /* Segment Size */
- int sshift; /* Segment shift */
- int ovfl_point; /* Where overflow pages are being
- * allocated */
- int last_freed; /* Last overflow page freed */
- int max_bucket; /* ID of Maximum bucket in use */
- int high_mask; /* Mask to modulo into entire table */
- int low_mask; /* Mask to modulo into lower half of
- * table */
- int ffactor; /* Fill factor */
- int nkeys; /* Number of keys in hash table */
-} HASHHDR185;
-typedef struct htab185 { /* Memory resident data structure */
- HASHHDR185 hdr; /* Header */
-} HTAB185;
-
-/* Hash Table Information */
-typedef struct hashhdr186 { /* Disk resident portion */
- int32_t magic; /* Magic NO for hash tables */
- int32_t version; /* Version ID */
- int32_t lorder; /* Byte Order */
- int32_t bsize; /* Bucket/Page Size */
- int32_t bshift; /* Bucket shift */
- int32_t ovfl_point; /* Where overflow pages are being allocated */
- int32_t last_freed; /* Last overflow page freed */
- int32_t max_bucket; /* ID of Maximum bucket in use */
- int32_t high_mask; /* Mask to modulo into entire table */
- int32_t low_mask; /* Mask to modulo into lower half of table */
- int32_t ffactor; /* Fill factor */
- int32_t nkeys; /* Number of keys in hash table */
- int32_t hdrpages; /* Size of table header */
- int32_t h_charkey; /* value of hash(CHARKEY) */
-#define NCACHED 32 /* number of bit maps and spare points */
- int32_t spares[NCACHED];/* spare pages for overflow */
- u_int16_t bitmaps[NCACHED]; /* address of overflow page bitmaps */
-} HASHHDR186;
-typedef struct htab186 { /* Memory resident data structure */
- HASHHDR186 hdr; /* Header */
-} HTAB186;
-
-typedef struct _epgno {
- u_int32_t pgno; /* the page number */
- u_int16_t index; /* the index on the page */
-} EPGNO;
-
-typedef struct _epg {
- void *page; /* the (pinned) page */
- u_int16_t index; /* the index on the page */
-} EPG;
-
-typedef struct _cursor {
- EPGNO pg; /* B: Saved tree reference. */
- DBT key; /* B: Saved key, or key.data == NULL. */
- u_int32_t rcursor; /* R: recno cursor (1-based) */
-
-#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
-#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
-#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
-#define CURS_INIT 0x08 /* RB: Cursor initialized. */
- u_int8_t flags;
-} CURSOR;
-
-/* The in-memory btree/recno data structure. */
-typedef struct _btree {
- void *bt_mp; /* memory pool cookie */
-
- void *bt_dbp; /* pointer to enclosing DB */
-
- EPG bt_cur; /* current (pinned) page */
- void *bt_pinned; /* page pinned across calls */
-
- CURSOR bt_cursor; /* cursor */
-
- EPGNO bt_stack[50]; /* stack of parent pages */
- EPGNO *bt_sp; /* current stack pointer */
-
- DBT bt_rkey; /* returned key */
- DBT bt_rdata; /* returned data */
-
- int bt_fd; /* tree file descriptor */
-
- u_int32_t bt_free; /* next free page */
- u_int32_t bt_psize; /* page size */
- u_int16_t bt_ovflsize; /* cut-off for key/data overflow */
- int bt_lorder; /* byte order */
- /* sorted order */
- enum { NOT, BACK, FORWARD } bt_order;
- EPGNO bt_last; /* last insert */
-
- /* B: key comparison function */
- int (*bt_cmp) __P((const DBT *, const DBT *));
- /* B: prefix comparison function */
- size_t (*bt_pfx) __P((const DBT *, const DBT *));
- /* R: recno input function */
- int (*bt_irec) __P((struct _btree *, u_int32_t));
-
- FILE *bt_rfp; /* R: record FILE pointer */
- int bt_rfd; /* R: record file descriptor */
-
- void *bt_cmap; /* R: current point in mapped space */
- void *bt_smap; /* R: start of mapped space */
- void *bt_emap; /* R: end of mapped space */
- size_t bt_msize; /* R: size of mapped region. */
-
- u_int32_t bt_nrecs; /* R: number of records */
- size_t bt_reclen; /* R: fixed record length */
- u_char bt_bval; /* R: delimiting byte/pad character */
-
-/*
- * NB:
- * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
- */
-#define B_INMEM 0x00001 /* in-memory tree */
-#define B_METADIRTY 0x00002 /* need to write metadata */
-#define B_MODIFIED 0x00004 /* tree modified */
-#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
-#define B_RDONLY 0x00010 /* read-only tree */
-
-#define B_NODUPS 0x00020 /* no duplicate keys permitted */
-#define R_RECNO 0x00080 /* record oriented tree */
-
-#define R_CLOSEFP 0x00040 /* opened a file pointer */
-#define R_EOF 0x00100 /* end of input file reached. */
-#define R_FIXLEN 0x00200 /* fixed length records */
-#define R_MEMMAPPED 0x00400 /* memory mapped file. */
-#define R_INMEM 0x00800 /* in-memory file */
-#define R_MODIFIED 0x01000 /* modified file */
-#define R_RDONLY 0x02000 /* read-only file */
-
-#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
-#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
-#define B_DB_TXN 0x10000 /* DB_TXN specified. */
- u_int32_t flags;
-} BTREE;
-
-void db_btree __P((DB *, int));
-void db_hash __P((DB *, int));
-void dbt_dump __P((DBT *));
-void dbt_print __P((DBT *));
-int main __P((int, char *[]));
-void usage __P((void));
-
-const char
- *progname = "db_dump185"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB *dbp;
- DBT key, data;
- int ch, pflag, rval;
-
- pflag = 0;
- while ((ch = getopt(argc, argv, "f:p")) != EOF)
- switch (ch) {
- case 'f':
- if (freopen(optarg, "w", stdout) == NULL)
- err(1, "%s", optarg);
- break;
- case 'p':
- pflag = 1;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1)
- usage();
-
- if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) {
- if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL)
- err(1, "%s", argv[0]);
- db_hash(dbp, pflag);
- } else
- db_btree(dbp, pflag);
-
- /*
- * !!!
- * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the
- * new dump/print routines.
- */
- if (pflag)
- while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
- dbt_print(&key);
- dbt_print(&data);
- }
- else
- while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
- dbt_dump(&key);
- dbt_dump(&data);
- }
-
- if (rval == -1)
- err(1, "seq");
- return (0);
-}
-
-/*
- * db_hash --
- * Dump out hash header information.
- */
-void
-db_hash(dbp, pflag)
- DB *dbp;
- int pflag;
-{
- HTAB185 *hash185p;
- HTAB186 *hash186p;
-
- printf("format=%s\n", pflag ? "print" : "bytevalue");
- printf("type=hash\n");
-
- /* DB 1.85 was version 2, DB 1.86 was version 3. */
- hash185p = dbp->internal;
- if (hash185p->hdr.version > 2) {
- hash186p = dbp->internal;
- printf("h_ffactor=%lu\n", (u_long)hash186p->hdr.ffactor);
- if (hash186p->hdr.lorder != 0)
- printf("db_lorder=%lu\n", (u_long)hash186p->hdr.lorder);
- printf("db_pagesize=%lu\n", (u_long)hash186p->hdr.bsize);
- } else {
- printf("h_ffactor=%lu\n", (u_long)hash185p->hdr.ffactor);
- if (hash185p->hdr.lorder != 0)
- printf("db_lorder=%lu\n", (u_long)hash185p->hdr.lorder);
- printf("db_pagesize=%lu\n", (u_long)hash185p->hdr.bsize);
- }
- printf("HEADER=END\n");
-}
-
-/*
- * db_btree --
- * Dump out btree header information.
- */
-void
-db_btree(dbp, pflag)
- DB *dbp;
- int pflag;
-{
- BTREE *btp;
-
- btp = dbp->internal;
-
- printf("format=%s\n", pflag ? "print" : "bytevalue");
- printf("type=btree\n");
-#ifdef NOT_AVAILABLE_IN_185
- printf("bt_minkey=%lu\n", (u_long)XXX);
- printf("bt_maxkey=%lu\n", (u_long)XXX);
-#endif
- if (btp->bt_lorder != 0)
- printf("db_lorder=%lu\n", (u_long)btp->bt_lorder);
- printf("db_pagesize=%lu\n", (u_long)btp->bt_psize);
- if (!(btp->flags & B_NODUPS))
- printf("duplicates=1\n");
- printf("HEADER=END\n");
-}
-
-static char hex[] = "0123456789abcdef";
-
-/*
- * dbt_dump --
- * Write out a key or data item using byte values.
- */
-void
-dbt_dump(dbtp)
- DBT *dbtp;
-{
- size_t len;
- u_int8_t *p;
-
- for (len = dbtp->size, p = dbtp->data; len--; ++p)
- (void)printf("%c%c",
- hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
- printf("\n");
-}
-
-/*
- * dbt_print --
- * Write out a key or data item using printable characters.
- */
-void
-dbt_print(dbtp)
- DBT *dbtp;
-{
- size_t len;
- u_int8_t *p;
-
- for (len = dbtp->size, p = dbtp->data; len--; ++p)
- if (isprint(*p)) {
- if (*p == '\\')
- (void)printf("\\");
- (void)printf("%c", *p);
- } else
- (void)printf("\\%c%c",
- hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
- printf("\n");
-}
-
-/*
- * usage --
- * Display the usage message.
- */
-void
-usage()
-{
- (void)fprintf(stderr, "usage: db_dump [-p] [-f file] db_file\n");
- exit(1);
-}
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
deleted file mode 100644
index a242602..0000000
--- a/db2/progs/db_load/db_load.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_load.c 10.23 (Sleepycat) 10/4/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_am.h"
-#include "clib_ext.h"
-
-void badnum __P((void));
-void configure __P((DB_INFO *, char **));
-DB_ENV *db_init __P((char *));
-int dbt_rdump __P((DBT *));
-int dbt_rprint __P((DBT *));
-int digitize __P((int));
-int main __P((int, char *[]));
-void onint __P((int));
-void rheader __P((DBTYPE *, int *, DB_INFO *));
-void siginit __P((void));
-void usage __P((void));
-
-int interrupted;
-const char
- *progname = "db_load"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB *dbp;
- DBT key, data;
- DBTYPE argtype, dbtype;
- DB_ENV *dbenv;
- DB_INFO dbinfo;
- db_recno_t recno;
- u_int32_t db_nooverwrite;
- int ch, checkprint, existed, no_header, ret;
- char **clist, **clp, *home;
-
- /* Allocate enough room for configuration arguments. */
- if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL)
- err(1, NULL);
-
- dbp = NULL;
- home = NULL;
- db_nooverwrite = 0;
- checkprint = existed = no_header = ret = 0;
- argtype = dbtype = DB_UNKNOWN;
- while ((ch = getopt(argc, argv, "c:f:h:nTt:")) != EOF)
- switch (ch) {
- case 'c':
- *clp++ = optarg;
- break;
- case 'f':
- if (freopen(optarg, "r", stdin) == NULL)
- err(1, "%s", optarg);
- break;
- case 'h':
- home = optarg;
- break;
- case 'n':
- db_nooverwrite = DB_NOOVERWRITE;
- break;
- case 'T':
- no_header = checkprint = 1;
- break;
- case 't':
- if (strcmp(optarg, "btree") == 0) {
- argtype = DB_BTREE;
- break;
- }
- if (strcmp(optarg, "hash") == 0) {
- argtype = DB_HASH;
- break;
- }
- if (strcmp(optarg, "recno") == 0) {
- argtype = DB_RECNO;
- break;
- }
- usage();
- /* NOTREACHED */
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1)
- usage();
-
- /*
- * Read the header. If there isn't any header, we're expecting flat
- * text, set the checkprint flag appropriately.
- */
- memset(&dbinfo, 0, sizeof(DB_INFO));
- if (no_header)
- dbtype = argtype;
- else {
- rheader(&dbtype, &checkprint, &dbinfo);
- if (argtype != DB_UNKNOWN) {
- /* Conversion to/from recno is prohibited. */
- if ((dbtype == DB_RECNO && argtype != DB_RECNO) ||
- (argtype == DB_RECNO && dbtype != DB_RECNO))
- errx(1,
- "databases of type recno may not be converted");
- dbtype = argtype;
- }
- }
-
- if (dbtype == DB_UNKNOWN)
- errx(1, "no database type specified");
-
- /* Apply command-line configuration changes. */
- configure(&dbinfo, clist);
-
- /* Initialize the key/data pair. */
- memset(&key, 0, sizeof(DBT));
- if (dbtype == DB_RECNO) {
- key.data = &recno;
- key.size = sizeof(recno);
- } else
- if ((key.data = (void *)malloc(key.ulen = 1024)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- memset(&data, 0, sizeof(DBT));
- if ((data.data = (void *)malloc(data.ulen = 1024)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
-
- /* Initialize the environment if the user specified one. */
- siginit();
- dbenv = home == NULL ? NULL : db_init(home);
-
- /* Open the DB file. */
- if ((errno = db_open(argv[0], dbtype, DB_CREATE,
- __db_omode("rwrwrw"), dbenv, &dbinfo, &dbp)) != 0) {
- warn("%s", argv[0]);
- goto err;
- }
-
- /* Get each key/data pair and add them to the database. */
- for (recno = 1; !interrupted; ++recno) {
- if (dbtype == DB_RECNO) {
- if (checkprint) {
- if (dbt_rprint(&data))
- break;
- } else {
- if (dbt_rdump(&data))
- break;
- }
- } else {
- if (checkprint) {
- if (dbt_rprint(&key))
- break;
- if (dbt_rprint(&data))
- goto fmt;
- } else {
- if (dbt_rdump(&key))
- break;
- if (dbt_rdump(&data)) {
-fmt: warnx("odd number of key/data pairs");
- goto err;
- }
- }
- }
- switch (errno =
- dbp->put(dbp, NULL, &key, &data, db_nooverwrite)) {
- case 0:
- break;
- case DB_KEYEXIST:
- existed = 1;
- warnx("%s: line %d: key already exists, not loaded:",
- argv[0],
- dbtype == DB_RECNO ? recno : recno * 2 - 1);
-
- (void)__db_prdbt(&key, checkprint, stderr);
- break;
- default:
- warn(NULL);
- goto err;
- }
- }
-
- if (0) {
-err: ret = 1;
- }
- if (dbp != NULL && (errno = dbp->close(dbp, 0)) != 0) {
- ret = 1;
- warn(NULL);
- }
-
- if (dbenv != NULL && (errno = db_appexit(dbenv)) != 0) {
- ret = 1;
- warn(NULL);
- }
-
- if (interrupted) {
- (void)signal(interrupted, SIG_DFL);
- (void)raise(interrupted);
- /* NOTREACHED */
- }
-
- /* Return 0 on success, 1 if keys existed already, and 2 on failure. */
- return (ret == 0 ? (existed == 0 ? 0 : 1) : 2);
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home)
- char *home;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
-
- /*
- * The database may be live, try and use the shared regions.
- *
- * If it works, we're done. Set the error output options so that
- * future errors are correctly reported.
- */
- if ((errno = db_appinit(home, NULL, dbenv, DB_INIT_LOCK |
- DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON)) == 0) {
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
- return (dbenv);
- }
-
- /*
- * If the db_appinit fails, assume the database isn't live, and don't
- * bother with an environment.
- */
- free(dbenv);
- return (NULL);
-}
-
-#define FLAG(name, value, keyword, flag) \
- if (strcmp(name, keyword) == 0) { \
- switch (*value) { \
- case '1': \
- dbinfop->flags |= (flag); \
- break; \
- case '0': \
- dbinfop->flags &= ~(flag); \
- break; \
- default: \
- badnum(); \
- /* NOTREACHED */ \
- } \
- continue; \
- }
-#define NUMBER(name, value, keyword, field, flag) \
- if (strcmp(name, keyword) == 0) { \
- get_long(value, 1, LONG_MAX, &val); \
- dbinfop->field = val; \
- if (flag != 0) \
- dbinfop->flags |= (flag); \
- continue; \
- }
-#define STRING(name, value, keyword, field, flag) \
- if (strcmp(name, keyword) == 0) { \
- dbinfop->field = value[0]; \
- if (flag != 0) \
- dbinfop->flags |= (flag); \
- continue; \
- }
-
-/*
- * configure --
- * Handle command-line configuration options.
- */
-void
-configure(dbinfop, clp)
- DB_INFO *dbinfop;
- char **clp;
-{
- long val;
- char *name, *value;
-
- for (; (name = *clp) != NULL; ++clp) {
- if ((value = strchr(name, '=')) == NULL)
- errx(1,
- "command-line configuration uses name=value format");
- *value++ = '\0';
-
- NUMBER(name, value, "bt_maxkey", bt_maxkey, 0);
- NUMBER(name, value, "bt_minkey", bt_minkey, 0);
- NUMBER(name, value, "db_lorder", db_lorder, 0);
- NUMBER(name, value, "db_pagesize", db_pagesize, 0);
- FLAG(name, value, "duplicates", DB_DUP);
- NUMBER(name, value, "h_ffactor", h_ffactor, 0);
- NUMBER(name, value, "h_nelem", h_nelem, 0);
- NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN);
- STRING(name, value, "re_pad", re_pad, DB_PAD);
- FLAG(name, value, "recnum", DB_RECNUM);
- FLAG(name, value, "renumber", DB_RENUMBER);
-
- errx(1, "unknown command-line configuration keyword");
- }
-}
-
-/*
- * rheader --
- * Read the header message.
- */
-void
-rheader(dbtypep, checkprintp, dbinfop)
- DBTYPE *dbtypep;
- int *checkprintp;
- DB_INFO *dbinfop;
-{
- long lineno, val;
- char name[256], value[256];
-
- *dbtypep = DB_UNKNOWN;
- *checkprintp = 0;
-
- for (lineno = 1;; ++lineno) {
- /* If we don't see the expected information, it's an error. */
- if (fscanf(stdin, "%[^=]=%s\n", name, value) != 2)
- errx(1, "line %lu: unexpected format", lineno);
-
- /* Check for the end of the header lines. */
- if (strcmp(name, "HEADER") == 0)
- break;
-
- if (strcmp(name, "format") == 0) {
- if (strcmp(value, "bytevalue") == 0) {
- *checkprintp = 0;
- continue;
- }
- if (strcmp(value, "print") == 0) {
- *checkprintp = 1;
- continue;
- }
- errx(1, "line %d: unknown format", lineno);
- }
- if (strcmp(name, "type") == 0) {
- if (strcmp(value, "btree") == 0) {
- *dbtypep = DB_BTREE;
- continue;
- }
- if (strcmp(value, "hash") == 0) {
- *dbtypep = DB_HASH;
- continue;
- }
- if (strcmp(value, "recno") == 0) {
- *dbtypep = DB_RECNO;
- continue;
- }
- errx(1, "line %d: unknown type", lineno);
- }
- NUMBER(name, value, "bt_maxkey", bt_maxkey, 0);
- NUMBER(name, value, "bt_minkey", bt_minkey, 0);
- NUMBER(name, value, "db_lorder", db_lorder, 0);
- NUMBER(name, value, "db_pagesize", db_pagesize, 0);
- FLAG(name, value, "duplicates", DB_DUP);
- NUMBER(name, value, "h_ffactor", h_ffactor, 0);
- NUMBER(name, value, "h_nelem", h_nelem, 0);
- NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN);
- STRING(name, value, "re_pad", re_pad, DB_PAD);
- FLAG(name, value, "recnum", DB_RECNUM);
- FLAG(name, value, "renumber", DB_RENUMBER);
-
- errx(1, "unknown input-file header configuration keyword");
- }
-}
-
-/*
- * dbt_rprint --
- * Read a printable line into a DBT structure.
- */
-int
-dbt_rprint(dbtp)
- DBT *dbtp;
-{
- u_int32_t len;
- u_int8_t *p;
- int c1, c2, escape;
-
- escape = 0;
- for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
- if (c1 == EOF) {
- if (len == 0)
- return (1);
- err(1, "unexpected end of key/data pair");
- }
- if (escape) {
- if (c1 != '\\') {
- if ((c2 = getchar()) == EOF)
- err(1,
- "unexpected end of key/data pair");
- c1 = digitize(c1) << 4 | digitize(c2);
- }
- escape = 0;
- } else
- if (c1 == '\\') {
- escape = 1;
- continue;
- }
- if (len >= dbtp->ulen - 10) {
- dbtp->ulen *= 2;
- if ((dbtp->data =
- (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- p = (u_int8_t *)dbtp->data + len;
- }
- ++len;
- *p++ = c1;
- }
- dbtp->size = len;
- return (0);
-}
-
-/*
- * dbt_rdump --
- * Read a byte dump line into a DBT structure.
- */
-int
-dbt_rdump(dbtp)
- DBT *dbtp;
-{
- u_int32_t len;
- u_int8_t *p;
- int c1, c2;
-
- for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
- if (c1 == EOF) {
- if (len == 0)
- return (1);
- err(1, "unexpected end of key/data pair");
- }
- if ((c2 = getchar()) == EOF)
- err(1, "unexpected end of key/data pair");
- if (len >= dbtp->ulen - 10) {
- dbtp->ulen *= 2;
- if ((dbtp->data =
- (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- p = (u_int8_t *)dbtp->data + len;
- }
- ++len;
- *p++ = digitize(c1) << 4 | digitize(c2);
- }
- dbtp->size = len;
- return (0);
-}
-
-/*
- * digitize --
- * Convert a character to an integer.
- */
-int
-digitize(c)
- int c;
-{
- switch (c) { /* Don't depend on ASCII ordering. */
- case '0': return (0);
- case '1': return (1);
- case '2': return (2);
- case '3': return (3);
- case '4': return (4);
- case '5': return (5);
- case '6': return (6);
- case '7': return (7);
- case '8': return (8);
- case '9': return (9);
- case 'a': return (10);
- case 'b': return (11);
- case 'c': return (12);
- case 'd': return (13);
- case 'e': return (14);
- case 'f': return (15);
- }
-
- err(1, "unexpected hexadecimal value");
- /* NOTREACHED */
-
- return (0);
-}
-
-/*
- * badnum --
- * Display the bad number message.
- */
-void
-badnum()
-{
- err(1, "boolean name=value pairs require a value of 0 or 1");
-}
-
-/*
- * siginit --
- * Initialize the set of signals for which we want to clean up.
- * Generally, we try not to leave the shared regions locked if
- * we can.
- */
-void
-siginit()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, onint);
-#endif
- (void)signal(SIGINT, onint);
- (void)signal(SIGTERM, onint);
-}
-
-/*
- * onint --
- * Interrupt signal handler.
- */
-void
-onint(signo)
- int signo;
-{
- if ((interrupted = signo) == 0)
- interrupted = SIGINT;
-}
-
-/*
- * usage --
- * Display the usage message.
- */
-void
-usage()
-{
- (void)fprintf(stderr, "%s\n\t%s\n",
- "usage: db_load [-nT]",
- "[-c name=value] [-f file] [-h home] [-t btree | hash | recno] db_file");
- exit(1);
-}
diff --git a/db2/progs/db_printlog/README b/db2/progs/db_printlog/README
deleted file mode 100644
index 05051f3..0000000
--- a/db2/progs/db_printlog/README
+++ /dev/null
@@ -1,22 +0,0 @@
-# @(#)README 10.3 (Sleepycat) 11/1/98
-
-Berkeley DB log dump utility. This utility dumps out a DB log in human
-readable form, a record at a time, to assist in recovery and transaction
-abort debugging.
-
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-commit.awk Output transaction ID of committed transactions.
-
-count.awk Print out the number of log records for transactions
- that we encountered.
-
-pgno.awk Take a comma-separated list of page numbers and spit
- out all the log records that affect those page numbers.
-
-range.awk Print out a range of the log.
-
-status.awk Read through db_printlog output and list the transactions
- encountered, and whether they commited or aborted.
-
-txn.awk Print out all the records for a comma-separated list of
- transaction IDs.
diff --git a/db2/progs/db_printlog/commit.awk b/db2/progs/db_printlog/commit.awk
deleted file mode 100644
index 711064b..0000000
--- a/db2/progs/db_printlog/commit.awk
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)commit.awk 10.1 (Sleepycat) 11/1/98
-#
-# Output tid of committed transactions.
-
-/txn_regop/ {
- print $5
-}
diff --git a/db2/progs/db_printlog/count.awk b/db2/progs/db_printlog/count.awk
deleted file mode 100644
index a0b214a..0000000
--- a/db2/progs/db_printlog/count.awk
+++ /dev/null
@@ -1,9 +0,0 @@
-# @(#)count.awk 10.1 (Sleepycat) 11/1/98
-#
-# Print out the number of log records for transactions that we
-# encountered.
-
-/^\[/{
- if ($5 != 0)
- print $5
-}
diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c
deleted file mode 100644
index 5a0c2eb..0000000
--- a/db2/progs/db_printlog/db_printlog.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_printlog.c 10.17 (Sleepycat) 11/1/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "btree.h"
-#include "hash.h"
-#include "log.h"
-#include "txn.h"
-#include "db_am.h"
-#include "clib_ext.h"
-
-DB_ENV *db_init __P((char *));
-int main __P((int, char *[]));
-void onint __P((int));
-void siginit __P((void));
-void usage __P((void));
-
-int interrupted;
-const char
- *progname = "db_printlog"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- DBT data;
- DB_LSN key;
- int ch, ret;
- char *home;
-
- ret = 0;
- home = NULL;
- while ((ch = getopt(argc, argv, "h:N")) != EOF)
- switch (ch) {
- case 'h':
- home = optarg;
- break;
- case 'N':
- (void)db_value_set(0, DB_MUTEXLOCKS);
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc > 0)
- usage();
-
- /* Initialize the environment. */
- siginit();
- dbenv = db_init(home);
-
- if ((errno = __bam_init_print(dbenv)) != 0 ||
- (errno = __db_init_print(dbenv)) != 0 ||
- (errno = __ham_init_print(dbenv)) != 0 ||
- (errno = __log_init_print(dbenv)) != 0 ||
- (errno = __txn_init_print(dbenv)) != 0) {
- warn("initialization");
- (void)db_appexit(dbenv);
- return (1);
- }
-
- memset(&data, 0, sizeof(data));
- while (!interrupted) {
- if ((errno =
- log_get(dbenv->lg_info, &key, &data, DB_NEXT)) != 0) {
- if (errno == DB_NOTFOUND)
- break;
- warn("log_get");
- goto err;
- }
- if (dbenv->tx_recover != NULL)
- errno = dbenv->tx_recover(dbenv->lg_info,
- &data, &key, 0, NULL);
- else
- errno = __db_dispatch(dbenv->lg_info,
- &data, &key, 0, NULL);
-
- fflush(stdout);
- if (errno != 0) {
- warn("dispatch");
- goto err;
- }
- }
-
- if (0) {
-err: ret = 1;
- }
-
- if (dbenv != NULL && (errno = db_appexit(dbenv)) != 0) {
- ret = 1;
- warn(NULL);
- }
-
- if (interrupted) {
- (void)signal(interrupted, SIG_DFL);
- (void)raise(interrupted);
- /* NOTREACHED */
- }
-
- return (ret);
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home)
- char *home;
-{
- DB_ENV *dbenv;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
-
- if ((errno =
- db_appinit(home, NULL, dbenv, DB_CREATE | DB_INIT_LOG)) != 0)
- err(1, "db_appinit");
- return (dbenv);
-}
-
-/*
- * siginit --
- * Initialize the set of signals for which we want to clean up.
- * Generally, we try not to leave the shared regions locked if
- * we can.
- */
-void
-siginit()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, onint);
-#endif
- (void)signal(SIGINT, onint);
- (void)signal(SIGTERM, onint);
-}
-
-/*
- * onint --
- * Interrupt signal handler.
- */
-void
-onint(signo)
- int signo;
-{
- if ((interrupted = signo) == 0)
- interrupted = SIGINT;
-}
-
-void
-usage()
-{
- fprintf(stderr, "usage: db_printlog [-N] [-h home]\n");
- exit (1);
-}
diff --git a/db2/progs/db_printlog/pgno.awk b/db2/progs/db_printlog/pgno.awk
deleted file mode 100644
index 99aa38f..0000000
--- a/db2/progs/db_printlog/pgno.awk
+++ /dev/null
@@ -1,43 +0,0 @@
-# @(#)pgno.awk 10.1 (Sleepycat) 11/1/98
-#
-# Take a comma-separated list of page numbers and spit out all the
-# log records that affect those page numbers.
-
-{
- if (NR == 1) {
- npages = 0
- while ((ndx = index(PGNO, ",")) != 0) {
- pgno[npages] = substr(PGNO, 1, ndx - 1);
- PGNO = substr(PGNO, ndx + 1, length(PGNO) - ndx);
- npages++
- }
- pgno[npages] = PGNO;
- }
-}
-/^\[/{
- if (printme == 1) {
- printf("%s\n", rec);
- printme = 0
- }
- rec = "";
-
- rec = $0
-}
-/^ /{
- rec = sprintf("%s\n%s", rec, $0);
-}
-/pgno/{
- for (i = 0; i <= npages; i++)
- if ($2 == pgno[i])
- printme = 1
-}
-/right/{
- for (i = 0; i <= npages; i++)
- if ($2 == pgno[i])
- printme = 1
-}
-/left/{
- for (i = 0; i <= npages; i++)
- if ($2 == pgno[i])
- printme = 1
-}
diff --git a/db2/progs/db_printlog/range.awk b/db2/progs/db_printlog/range.awk
deleted file mode 100644
index 89c56ea..0000000
--- a/db2/progs/db_printlog/range.awk
+++ /dev/null
@@ -1,27 +0,0 @@
-# @(#)range.awk 10.1 (Sleepycat) 11/1/98
-#
-# Print out a range of the log
-
-/^\[/{
- l = length($1) - 1;
- i = index($1, "]");
- file = substr($1, 2, i - 2);
- file += 0;
- start = i + 2;
- offset = substr($1, start, l - start + 1);
- i = index(offset, "]");
- offset = substr($1, start, i - 1);
- offset += 0;
-
- if ((file == START_FILE && offset >= START_OFFSET || file > START_FILE)\
- && (file < END_FILE || (file == END_FILE && offset < END_OFFSET)))
- printme = 1
- else if (file == END_FILE && offset > END_OFFSET || file > END_FILE)
- exit
- else
- printme = 0
-}
-{
- if (printme == 1)
- print $0
-}
diff --git a/db2/progs/db_printlog/status.awk b/db2/progs/db_printlog/status.awk
deleted file mode 100644
index d97e935..0000000
--- a/db2/progs/db_printlog/status.awk
+++ /dev/null
@@ -1,26 +0,0 @@
-# @(#)status.awk 10.1 (Sleepycat) 11/1/98
-#
-# Read through db_printlog output and list all the transactions encountered
-# and whether they commited or aborted.
-#
-# 1 = started
-# 2 = commited
-BEGIN {
- cur_txn = 0
-}
-/^\[/{
- if (status[$5] == 0) {
- status[$5] = 1;
- txns[cur_txn] = $5;
- cur_txn++;
- }
-}
-/txn_regop/ {
- status[$5] = 2
-}
-END {
- for (i = 0; i < cur_txn; i++) {
- printf("%s\t%s\n",
- txns[i], status[txns[i]] == 1 ? "ABORT" : "COMMIT");
- }
-}
diff --git a/db2/progs/db_printlog/txn.awk b/db2/progs/db_printlog/txn.awk
deleted file mode 100644
index c8d3bd3..0000000
--- a/db2/progs/db_printlog/txn.awk
+++ /dev/null
@@ -1,30 +0,0 @@
-# @(#)txn.awk 10.1 (Sleepycat) 11/1/98
-#
-# Print out all the records for a comma-separated list of transaction ids.
-{
- if (NR == 1) {
- ntxns = 0
- while ((ndx = index(TXN, ",")) != 0) {
- txn[ntxns] = substr(TXN, 1, ndx - 1);
- TXN = substr(TXN, ndx + 1, length(TXN) - ndx);
- ntxns++
- }
- txn[ntxns] = TXN;
- }
-}
-/^\[/{
- if (printme == 1) {
- printf("%s\n", rec);
- printme = 0
- }
- rec = "";
-
- for (i = 0; i <= ntxns; i++)
- if (txn[i] == $5) {
- rec = $0
- printme = 1
- }
-}
-/^ /{
- rec = sprintf("%s\n%s", rec, $0);
-}
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
deleted file mode 100644
index d946ca1..0000000
--- a/db2/progs/db_recover/db_recover.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_recover.c 10.23 (Sleepycat) 10/5/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "txn.h"
-#include "common_ext.h"
-#include "clib_ext.h"
-
-DB_ENV *db_init __P((char *, u_int32_t, int));
-int main __P((int, char *[]));
-void nosig __P((void));
-void usage __P((void));
-
-const char
- *progname = "db_recover"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- time_t now;
- u_int32_t flags;
- int ch, verbose;
- char *home;
-
- home = NULL;
- flags = verbose = 0;
- while ((ch = getopt(argc, argv, "ch:v")) != EOF)
- switch (ch) {
- case 'c':
- LF_SET(DB_RECOVER_FATAL);
- break;
- case 'h':
- home = optarg;
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- usage();
-
- /*
- * Ignore signals -- we don't want to be interrupted because we're
- * spending all of our time in the DB library.
- */
- nosig();
- dbenv = db_init(home, flags, verbose);
- if (verbose) {
- __db_err(dbenv, "Recovery complete at %.24s", ctime(&now));
- __db_err(dbenv, "%s %lx %s [%lu][%lu]",
- "Maximum transaction id",
- (u_long)dbenv->tx_info->region->last_txnid,
- "Recovery checkpoint",
- (u_long)dbenv->tx_info->region->last_ckp.file,
- (u_long)dbenv->tx_info->region->last_ckp.offset);
- }
-
- return (db_appexit(dbenv));
-}
-
-DB_ENV *
-db_init(home, flags, verbose)
- char *home;
- u_int32_t flags;
- int verbose;
-{
- DB_ENV *dbenv;
- u_int32_t local_flags;
-
- if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = "db_recover";
- dbenv->db_verbose = verbose;
-
- /* Initialize environment for pathnames only. */
- local_flags = DB_CREATE | DB_INIT_LOG |
- DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_USE_ENVIRON;
-
- if (LF_ISSET(DB_RECOVER_FATAL))
- local_flags |= DB_RECOVER_FATAL;
- else
- local_flags |= DB_RECOVER;
-
- if ((errno = db_appinit(home, NULL, dbenv, local_flags)) != 0)
- err(1, "appinit failed");
-
- return (dbenv);
-}
-
-/*
- * nosig --
- * We don't want to be interrupted.
- */
-void
-nosig()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, SIG_IGN);
-#endif
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGTERM, SIG_IGN);
-}
-
-void
-usage()
-{
- (void)fprintf(stderr, "usage: db_recover [-cv] [-h home]\n");
- exit(1);
-}
diff --git a/db2/progs/db_stat/db_stat.c b/db2/progs/db_stat/db_stat.c
deleted file mode 100644
index cef645d..0000000
--- a/db2/progs/db_stat/db_stat.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1996, 1997, 1998\n\
- Sleepycat Software Inc. All rights reserved.\n";
-static const char sccsid[] = "@(#)db_stat.c 8.41 (Sleepycat) 10/3/98";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#undef stat
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "mp.h"
-#include "clib_ext.h"
-
-typedef enum { T_NOTSET, T_DB, T_LOCK, T_LOG, T_MPOOL, T_TXN } test_t;
-
-int argcheck __P((char *, const char *));
-void btree_stats __P((DB *));
-DB_ENV *db_init __P((char *, test_t));
-void dl __P((const char *, u_long));
-void hash_stats __P((DB *));
-int lock_ok __P((char *));
-void lock_stats __P((DB_ENV *));
-void log_stats __P((DB_ENV *));
-int main __P((int, char *[]));
-int mpool_ok __P((char *));
-void mpool_stats __P((DB_ENV *));
-void nosig __P((void));
-void prflags __P((u_int32_t, const FN *));
-int txn_compare __P((const void *, const void *));
-void txn_stats __P((DB_ENV *));
-void usage __P((void));
-
-char *internal;
-const char
- *progname = "db_stat"; /* Program name. */
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB *dbp;
- DB_ENV *dbenv;
- test_t ttype;
- int ch;
- char *db, *home;
-
- ttype = T_NOTSET;
- db = home = NULL;
- while ((ch = getopt(argc, argv, "C:cd:h:lM:mNt")) != EOF)
- switch (ch) {
- case 'C':
- ttype = T_LOCK;
- if (!argcheck(internal = optarg, "Acflmo"))
- usage();
- break;
- case 'c':
- ttype = T_LOCK;
- break;
- case 'd':
- db = optarg;
- ttype = T_DB;
- break;
- case 'h':
- home = optarg;
- break;
- case 'l':
- ttype = T_LOG;
- break;
- case 'M':
- ttype = T_MPOOL;
- if (!argcheck(internal = optarg, "Ahlm"))
- usage();
- break;
- case 'm':
- ttype = T_MPOOL;
- break;
- case 'N':
- (void)db_value_set(0, DB_MUTEXLOCKS);
- break;
- case 't':
- ttype = T_TXN;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0 || ttype == T_NOTSET)
- usage();
-
- /*
- * Ignore signals -- we don't want to be interrupted because we're
- * spending all of our time in the DB library.
- */
- nosig();
- dbenv = db_init(home, ttype);
-
- switch (ttype) {
- case T_DB:
- if ((errno = db_open(db, DB_UNKNOWN,
- DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0) {
- warn("%s", db);
- return (1);
- }
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- btree_stats(dbp);
- break;
- case DB_HASH:
- hash_stats(dbp);
- break;
- case DB_UNKNOWN:
- abort(); /* Impossible. */
- /* NOTREACHED */
- }
- (void)dbp->close(dbp, 0);
- break;
- case T_LOCK:
- lock_stats(dbenv);
- break;
- case T_LOG:
- log_stats(dbenv);
- break;
- case T_MPOOL:
- mpool_stats(dbenv);
- break;
- case T_TXN:
- txn_stats(dbenv);
- break;
- case T_NOTSET:
- abort(); /* Impossible. */
- /* NOTREACHED */
- }
-
- if ((errno = db_appexit(dbenv)) != 0) {
- warn(NULL);
- return (1);
- }
- return (0);
-}
-
-/*
- * btree_stats --
- * Display btree/recno statistics.
- */
-void
-btree_stats(dbp)
- DB *dbp;
-{
- static const FN fn[] = {
- { DB_DUP, "DB_DUP" },
- { DB_FIXEDLEN, "DB_FIXEDLEN" },
- { DB_RECNUM, "DB_RECNUM" },
- { DB_RENUMBER, "DB_RENUMBER" },
- { 0 }
- };
- DB_BTREE_STAT *sp;
-
- if (dbp->stat(dbp, &sp, NULL, 0))
- err(1, "dbp->stat");
-
-#define PCT(f, t) \
- (t == 0 ? 0 : \
- (((double)((t * sp->bt_pagesize) - f) / (t * sp->bt_pagesize)) * 100))
-
- printf("%#lx\tBtree magic number.\n", (u_long)sp->bt_magic);
- printf("%lu\tBtree version number.\n", (u_long)sp->bt_version);
- prflags(sp->bt_flags, fn);
- if (dbp->type == DB_BTREE) {
-#ifdef NOT_IMPLEMENTED
- dl("Maximum keys per-page.\n", (u_long)sp->bt_maxkey);
-#endif
- dl("Minimum keys per-page.\n", (u_long)sp->bt_minkey);
- }
- if (dbp->type == DB_RECNO) {
- dl("Fixed-length record size.\n", (u_long)sp->bt_re_len);
- if (isprint(sp->bt_re_pad))
- printf("%c\tFixed-length record pad.\n",
- (int)sp->bt_re_pad);
- else
- printf("0x%x\tFixed-length record pad.\n",
- (int)sp->bt_re_pad);
- }
- dl("Underlying tree page size.\n", (u_long)sp->bt_pagesize);
- dl("Number of levels in the tree.\n", (u_long)sp->bt_levels);
- dl("Number of keys in the tree.\n", (u_long)sp->bt_nrecs);
- dl("Number of tree internal pages.\n", (u_long)sp->bt_int_pg);
- dl("Number of tree leaf pages.\n", (u_long)sp->bt_leaf_pg);
- dl("Number of tree duplicate pages.\n", (u_long)sp->bt_dup_pg);
- dl("Number of tree overflow pages.\n", (u_long)sp->bt_over_pg);
- dl("Number of pages on the free list.\n", (u_long)sp->bt_free);
- dl("Number of bytes free in tree internal pages",
- (u_long)sp->bt_int_pgfree);
- printf(" (%.0f%% ff).\n", PCT(sp->bt_int_pgfree, sp->bt_int_pg));
- dl("Number of bytes free in tree leaf pages",
- (u_long)sp->bt_leaf_pgfree);
- printf(" (%.0f%% ff).\n", PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg));
- dl("Number of bytes free in tree duplicate pages",
- (u_long)sp->bt_dup_pgfree);
- printf(" (%.0f%% ff).\n", PCT(sp->bt_dup_pgfree, sp->bt_dup_pg));
- dl("Number of bytes free in tree overflow pages",
- (u_long)sp->bt_over_pgfree);
- printf(" (%.0f%% ff).\n", PCT(sp->bt_over_pgfree, sp->bt_over_pg));
-}
-
-/*
- * hash_stats --
- * Display hash statistics.
- */
-void
-hash_stats(dbp)
- DB *dbp;
-{
- COMPQUIET(dbp, NULL);
-
- printf("Hash statistics not currently available.\n");
- return;
-}
-
-/*
- * lock_stats --
- * Display lock statistics.
- */
-void
-lock_stats(dbenv)
- DB_ENV *dbenv;
-{
- DB_LOCK_STAT *sp;
-
- if (internal != NULL) {
- __lock_dump_region(dbenv->lk_info, internal, stdout);
- return;
- }
-
- if (lock_stat(dbenv->lk_info, &sp, NULL))
- err(1, NULL);
-
- printf("%#lx\tLock magic number.\n", (u_long)sp->st_magic);
- printf("%lu\tLock version number.\n", (u_long)sp->st_version);
- dl("Lock region reference count.\n", (u_long)sp->st_refcnt);
- dl("Lock region size.\n", (u_long)sp->st_regsize);
- dl("Maximum number of locks.\n", (u_long)sp->st_maxlocks);
- dl("Number of lock modes.\n", (u_long)sp->st_nmodes);
- dl("Number of lock objects.\n", (u_long)sp->st_numobjs);
- dl("Number of lockers.\n", (u_long)sp->st_nlockers);
- dl("Number of lock conflicts.\n", (u_long)sp->st_nconflicts);
- dl("Number of lock requests.\n", (u_long)sp->st_nrequests);
- dl("Number of lock releases.\n", (u_long)sp->st_nreleases);
- dl("Number of deadlocks.\n", (u_long)sp->st_ndeadlocks);
- dl("The number of region locks granted without waiting.\n",
- (u_long)sp->st_region_nowait);
- dl("The number of region locks granted after waiting.\n",
- (u_long)sp->st_region_wait);
-}
-
-/*
- * log_stats --
- * Display log statistics.
- */
-void
-log_stats(dbenv)
- DB_ENV *dbenv;
-{
- DB_LOG_STAT *sp;
-
- if (log_stat(dbenv->lg_info, &sp, NULL))
- err(1, NULL);
-
- printf("%#lx\tLog magic number.\n", (u_long)sp->st_magic);
- printf("%lu\tLog version number.\n", (u_long)sp->st_version);
- dl("Log region reference count.\n", (u_long)sp->st_refcnt);
- dl("Log region size.\n", (u_long)sp->st_regsize);
- printf("%#o\tLog file mode.\n", sp->st_mode);
- if (sp->st_lg_max % MEGABYTE == 0)
- printf("%luMb\tLog file size.\n",
- (u_long)sp->st_lg_max / MEGABYTE);
- else if (sp->st_lg_max % 1024 == 0)
- printf("%luKb\tLog file size.\n", (u_long)sp->st_lg_max / 1024);
- else
- printf("%lu\tLog file size.\n", (u_long)sp->st_lg_max);
- printf("%luMb\tLog bytes written (+%lu bytes).\n",
- (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes);
- printf("%luMb\tLog bytes written since last checkpoint (+%lu bytes).\n",
- (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes);
- dl("Total log file writes.\n", (u_long)sp->st_wcount);
- dl("Total log file flushes.\n", (u_long)sp->st_scount);
- printf("%lu\tCurrent log file number.\n", (u_long)sp->st_cur_file);
- printf("%lu\tCurrent log file offset.\n", (u_long)sp->st_cur_offset);
- dl("The number of region locks granted without waiting.\n",
- (u_long)sp->st_region_nowait);
- dl("The number of region locks granted after waiting.\n",
- (u_long)sp->st_region_wait);
-}
-
-/*
- * mpool_stats --
- * Display mpool statistics.
- */
-void
-mpool_stats(dbenv)
- DB_ENV *dbenv;
-{
- DB_MPOOL_FSTAT **fsp;
- DB_MPOOL_STAT *gsp;
-
- if (internal != NULL) {
- __memp_dump_region(dbenv->mp_info, internal, stdout);
- return;
- }
-
- if (memp_stat(dbenv->mp_info, &gsp, &fsp, NULL))
- err(1, NULL);
-
- dl("Pool region reference count.\n", (u_long)gsp->st_refcnt);
- dl("Pool region size.\n", (u_long)gsp->st_regsize);
- dl("Cache size", (u_long)gsp->st_cachesize);
- printf(" (%luK).\n", (u_long)gsp->st_cachesize / 1024);
- dl("Requested pages found in the cache", (u_long)gsp->st_cache_hit);
- if (gsp->st_cache_hit + gsp->st_cache_miss != 0)
- printf(" (%.0f%%)", ((double)gsp->st_cache_hit /
- (gsp->st_cache_hit + gsp->st_cache_miss)) * 100);
- printf(".\n");
- dl("Requested pages mapped into the process' address space.\n",
- (u_long)gsp->st_map);
- dl("Requested pages not found in the cache.\n",
- (u_long)gsp->st_cache_miss);
- dl("Pages created in the cache.\n", (u_long)gsp->st_page_create);
- dl("Pages read into the cache.\n", (u_long)gsp->st_page_in);
- dl("Pages written from the cache to the backing file.\n",
- (u_long)gsp->st_page_out);
- dl("Clean pages forced from the cache.\n",
- (u_long)gsp->st_ro_evict);
- dl("Dirty pages forced from the cache.\n",
- (u_long)gsp->st_rw_evict);
- dl("Dirty buffers written by trickle-sync thread.\n",
- (u_long)gsp->st_page_trickle);
- dl("Current clean buffer count.\n",
- (u_long)gsp->st_page_clean);
- dl("Current dirty buffer count.\n",
- (u_long)gsp->st_page_dirty);
- dl("Number of hash buckets used for page location.\n",
- (u_long)gsp->st_hash_buckets);
- dl("Total number of times hash chains searched for a page.\n",
- (u_long)gsp->st_hash_searches);
- dl("The longest hash chain searched for a page.\n",
- (u_long)gsp->st_hash_longest);
- dl("Total number of hash buckets examined for page location.\n",
- (u_long)gsp->st_hash_examined);
- dl("The number of region locks granted without waiting.\n",
- (u_long)gsp->st_region_nowait);
- dl("The number of region locks granted after waiting.\n",
- (u_long)gsp->st_region_wait);
-
- for (; fsp != NULL && *fsp != NULL; ++fsp) {
- printf("%s\n", DB_LINE);
- printf("%s\n", (*fsp)->file_name);
- dl("Page size.\n", (u_long)(*fsp)->st_pagesize);
- dl("Requested pages found in the cache",
- (u_long)(*fsp)->st_cache_hit);
- if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0)
- printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit /
- ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) *
- 100);
- printf(".\n");
- dl("Requested pages mapped into the process' address space.\n",
- (u_long)(*fsp)->st_map);
- dl("Requested pages not found in the cache.\n",
- (u_long)(*fsp)->st_cache_miss);
- dl("Pages created in the cache.\n",
- (u_long)(*fsp)->st_page_create);
- dl("Pages read into the cache.\n",
- (u_long)(*fsp)->st_page_in);
- dl("Pages written from the cache to the backing file.\n",
- (u_long)(*fsp)->st_page_out);
- }
-}
-
-/*
- * txn_stats --
- * Display transaction statistics.
- */
-void
-txn_stats(dbenv)
- DB_ENV *dbenv;
-{
- DB_TXN_STAT *sp;
- u_int32_t i;
- const char *p;
-
- if (txn_stat(dbenv->tx_info, &sp, NULL))
- err(1, NULL);
-
- dl("Txn region reference count.\n", (u_long)sp->st_refcnt);
- dl("Txn region size.\n", (u_long)sp->st_regsize);
- p = sp->st_last_ckp.file == 0 ?
- "No checkpoint LSN." : "File/offset for last checkpoint LSN.";
- printf("%lu/%lu\t%s\n",
- (u_long)sp->st_last_ckp.file, (u_long)sp->st_last_ckp.offset, p);
- p = sp->st_pending_ckp.file == 0 ?
- "No pending checkpoint LSN." :
- "File/offset for last pending checkpoint LSN.";
- printf("%lu/%lu\t%s\n",
- (u_long)sp->st_pending_ckp.file,
- (u_long)sp->st_pending_ckp.offset, p);
- if (sp->st_time_ckp == 0)
- printf("0\tNo checkpoint timestamp.\n");
- else
- printf("%.24s\tCheckpoint timestamp.\n",
- ctime(&sp->st_time_ckp));
- printf("%lx\tLast transaction ID allocated.\n",
- (u_long)sp->st_last_txnid);
- dl("Maximum number of active transactions.\n", (u_long)sp->st_maxtxns);
- dl("Number of transactions begun.\n", (u_long)sp->st_nbegins);
- dl("Number of transactions aborted.\n", (u_long)sp->st_naborts);
- dl("Number of transactions committed.\n", (u_long)sp->st_ncommits);
- dl("The number of region locks granted without waiting.\n",
- (u_long)sp->st_region_nowait);
- dl("The number of region locks granted after waiting.\n",
- (u_long)sp->st_region_wait);
- dl("Active transactions.\n", (u_long)sp->st_nactive);
- qsort(sp->st_txnarray,
- sp->st_nactive, sizeof(sp->st_txnarray[0]), txn_compare);
- for (i = 0; i < sp->st_nactive; ++i)
- printf("\tid: %lx; initial LSN file/offest %lu/%lu\n",
- (u_long)sp->st_txnarray[i].txnid,
- (u_long)sp->st_txnarray[i].lsn.file,
- (u_long)sp->st_txnarray[i].lsn.offset);
-}
-
-int
-txn_compare(a1, b1)
- const void *a1, *b1;
-{
- const DB_TXN_ACTIVE *a, *b;
-
- a = a1;
- b = b1;
-
- if (a->txnid > b->txnid)
- return (1);
- if (a->txnid < b->txnid)
- return (-1);
- return (0);
-}
-
-/*
- * dl --
- * Display a big value.
- */
-void
-dl(msg, value)
- const char *msg;
- u_long value;
-{
- /*
- * Two formats: if less than 10 million, display as the number, if
- * greater than 10 million display as ###M.
- */
- if (value < 10000000)
- printf("%lu\t%s", value, msg);
- else
- printf("%luM\t%s", value / 1000000, msg);
-}
-
-/*
- * prflags --
- * Print out flag values.
- */
-void
-prflags(flags, fnp)
- u_int32_t flags;
- const FN *fnp;
-{
- const char *sep;
-
- sep = " ";
- printf("Flags:");
- for (; fnp->mask != 0; ++fnp)
- if (fnp->mask & flags) {
- printf("%s%s", sep, fnp->name);
- sep = ", ";
- }
- printf("\n");
-}
-
-/*
- * db_init --
- * Initialize the environment.
- */
-DB_ENV *
-db_init(home, ttype)
- char *home;
- test_t ttype;
-{
- DB_ENV *dbenv;
- u_int32_t flags;
-
- if ((dbenv = (DB_ENV *)malloc(sizeof(DB_ENV))) == NULL) {
- errno = ENOMEM;
- err(1, NULL);
- }
-
- /*
- * Try and use the shared regions when reporting statistics on the
- * DB databases, so our information is as up-to-date as possible,
- * even if the mpool cache hasn't been flushed. If that fails, we
- * turn off the DB_INIT_MPOOL flag and try again.
- */
- flags = DB_USE_ENVIRON;
- switch (ttype) {
- case T_DB:
- case T_MPOOL:
- LF_SET(DB_INIT_MPOOL);
- break;
- case T_LOCK:
- LF_SET(DB_INIT_LOCK);
- break;
- case T_LOG:
- LF_SET(DB_INIT_LOG);
- break;
- case T_TXN:
- LF_SET(DB_INIT_TXN);
- break;
- case T_NOTSET:
- abort();
- /* NOTREACHED */
- }
-
- /*
- * If it works, we're done. Set the error output options so that
- * future errors are correctly reported.
- */
- memset(dbenv, 0, sizeof(*dbenv));
- if ((errno = db_appinit(home, NULL, dbenv, flags)) == 0) {
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
- return (dbenv);
- }
-
- /* Turn off the DB_INIT_MPOOL flag if it's a database. */
- if (ttype == T_DB)
- LF_CLR(DB_INIT_MPOOL);
-
- /* Set the error output options -- this time we want a message. */
- memset(dbenv, 0, sizeof(*dbenv));
- dbenv->db_errfile = stderr;
- dbenv->db_errpfx = progname;
-
- /* Try again, and it's fatal if we fail. */
- if ((errno = db_appinit(home, NULL, dbenv, flags)) != 0)
- err(1, "db_appinit");
-
- return (dbenv);
-}
-
-/*
- * argcheck --
- * Return if argument flags are okay.
- */
-int
-argcheck(arg, ok_args)
- char *arg;
- const char *ok_args;
-{
- for (; *arg != '\0'; ++arg)
- if (strchr(ok_args, *arg) == NULL)
- return (0);
- return (1);
-}
-
-/*
- * nosig --
- * We don't want to be interrupted.
- */
-void
-nosig()
-{
-#ifdef SIGHUP
- (void)signal(SIGHUP, SIG_IGN);
-#endif
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGTERM, SIG_IGN);
-}
-
-void
-usage()
-{
- fprintf(stderr,
- "usage: db_stat [-clmNt] [-C Acflmo] [-d file] [-h home] [-M Ahlm]\n");
- exit (1);
-}
diff --git a/db2/txn/txn.c b/db2/txn/txn.c
deleted file mode 100644
index aa0b365..0000000
--- a/db2/txn/txn.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)txn.c 10.66 (Sleepycat) 1/3/99";
-#endif /* not lint */
-
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_shash.h"
-#include "txn.h"
-#include "db_dispatch.h"
-#include "lock.h"
-#include "log.h"
-#include "db_am.h"
-#include "common_ext.h"
-
-static int __txn_begin __P((DB_TXN *));
-static int __txn_check_running __P((const DB_TXN *, TXN_DETAIL **));
-static int __txn_end __P((DB_TXN *, int));
-static void __txn_freekids __P((DB_TXN *));
-static int __txn_grow_region __P((DB_TXNMGR *));
-static int __txn_init __P((DB_TXNREGION *));
-static int __txn_undo __P((DB_TXN *));
-static int __txn_validate_region __P((DB_TXNMGR *));
-
-/*
- * This file contains the top level routines of the transaction library.
- * It assumes that a lock manager and log manager that conform to the db_log(3)
- * and db_lock(3) interfaces exist.
- *
- * Initialize a transaction region in shared memory.
- * Return 0 on success, errno on failure.
- */
-static int
-__txn_init(txn_region)
- DB_TXNREGION *txn_region;
-{
- time_t now;
-
- (void)time(&now);
-
- /* maxtxns is already initialized. */
- txn_region->magic = DB_TXNMAGIC;
- txn_region->version = DB_TXNVERSION;
- txn_region->last_txnid = TXN_MINIMUM;
- /*
- * XXX
- * If we ever do more types of locking and logging, this changes.
- */
- txn_region->logtype = 0;
- txn_region->locktype = 0;
- txn_region->time_ckp = now;
- ZERO_LSN(txn_region->last_ckp);
- ZERO_LSN(txn_region->pending_ckp);
- SH_TAILQ_INIT(&txn_region->active_txn);
- __db_shalloc_init((void *)&txn_region[1],
- TXN_REGION_SIZE(txn_region->maxtxns) - sizeof(DB_TXNREGION));
-
- return (0);
-}
-
-int
-txn_open(path, flags, mode, dbenv, mgrpp)
- const char *path;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_TXNMGR **mgrpp;
-{
- DB_TXNMGR *tmgrp;
- u_int32_t maxtxns;
- int ret;
-
- /* Validate arguments. */
- if (dbenv == NULL)
- return (EINVAL);
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_THREAD | DB_TXN_NOSYNC)
-#else
-#define OKFLAGS (DB_CREATE | DB_TXN_NOSYNC)
-#endif
- if ((ret = __db_fchk(dbenv, "txn_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 20;
-
- /* Now, create the transaction manager structure and set its fields. */
- if ((ret = __os_calloc(1, sizeof(DB_TXNMGR), &tmgrp)) != 0)
- return (ret);
-
- /* Initialize the transaction manager structure. */
- tmgrp->mutexp = NULL;
- tmgrp->dbenv = dbenv;
- tmgrp->recover =
- dbenv->tx_recover == NULL ? __db_dispatch : dbenv->tx_recover;
- tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD);
- TAILQ_INIT(&tmgrp->txn_chain);
-
- /* Join/create the txn region. */
- tmgrp->reginfo.dbenv = dbenv;
- tmgrp->reginfo.appname = DB_APP_NONE;
- if (path == NULL)
- tmgrp->reginfo.path = NULL;
- else
- if ((ret = __os_strdup(path, &tmgrp->reginfo.path)) != 0)
- goto err;
- tmgrp->reginfo.file = DEFAULT_TXN_FILE;
- tmgrp->reginfo.mode = mode;
- tmgrp->reginfo.size = TXN_REGION_SIZE(maxtxns);
- tmgrp->reginfo.dbflags = flags;
- tmgrp->reginfo.addr = NULL;
- tmgrp->reginfo.fd = -1;
- tmgrp->reginfo.flags = dbenv->tx_max == 0 ? REGION_SIZEDEF : 0;
- if ((ret = __db_rattach(&tmgrp->reginfo)) != 0)
- goto err;
-
- /* Fill in region-related fields. */
- tmgrp->region = tmgrp->reginfo.addr;
- tmgrp->mem = &tmgrp->region[1];
-
- if (F_ISSET(&tmgrp->reginfo, REGION_CREATED)) {
- tmgrp->region->maxtxns = maxtxns;
- if ((ret = __txn_init(tmgrp->region)) != 0)
- goto err;
-
- } else if (tmgrp->region->magic != DB_TXNMAGIC) {
- /* Check if valid region. */
- __db_err(dbenv, "txn_open: Bad magic number");
- ret = EINVAL;
- goto err;
- }
-
- if (LF_ISSET(DB_THREAD)) {
- if ((ret = __db_shalloc(tmgrp->mem, sizeof(db_mutex_t),
- MUTEX_ALIGNMENT, &tmgrp->mutexp)) == 0)
- /*
- * Since we only get here if threading is turned on, we
- * know that we have spinlocks, so the offset is going
- * to be ignored. We put 0 here as a valid placeholder.
- */
- __db_mutex_init(tmgrp->mutexp, 0);
- if (ret != 0)
- goto err;
- }
-
- UNLOCK_TXNREGION(tmgrp);
- *mgrpp = tmgrp;
- return (0);
-
-err: if (tmgrp->reginfo.addr != NULL) {
- if (tmgrp->mutexp != NULL)
- __db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
-
- UNLOCK_TXNREGION(tmgrp);
- (void)__db_rdetach(&tmgrp->reginfo);
- if (F_ISSET(&tmgrp->reginfo, REGION_CREATED))
- (void)txn_unlink(path, 1, dbenv);
- }
-
- if (tmgrp->reginfo.path != NULL)
- __os_freestr(tmgrp->reginfo.path);
- __os_free(tmgrp, sizeof(*tmgrp));
- return (ret);
-}
-
-/*
- * __txn_panic --
- * Panic a transaction region.
- *
- * PUBLIC: void __txn_panic __P((DB_ENV *));
- */
-void
-__txn_panic(dbenv)
- DB_ENV *dbenv;
-{
- if (dbenv->tx_info != NULL)
- dbenv->tx_info->region->hdr.panic = 1;
-}
-
-/*
- * txn_begin --
- * This is a wrapper to the actual begin process. Normal txn_begin()
- * allocates a DB_TXN structure for the caller, while txn_xa_begin() does
- * not. Other than that, both call into the common __txn_begin code().
- *
- * Internally, we use TXN_DETAIL structures, but the DB_TXN structure
- * provides access to the transaction ID and the offset in the transaction
- * region of the TXN_DETAIL structure.
- */
-int
-txn_begin(tmgrp, parent, txnpp)
- DB_TXNMGR *tmgrp;
- DB_TXN *parent, **txnpp;
-{
- DB_TXN *txn;
- int ret;
-
- TXN_PANIC_CHECK(tmgrp);
-
- if ((ret = __os_calloc(1, sizeof(DB_TXN), &txn)) != 0)
- return (ret);
-
- txn->parent = parent;
- TAILQ_INIT(&txn->kids);
- txn->mgrp = tmgrp;
- txn->flags = TXN_MALLOC;
- if ((ret = __txn_begin(txn)) != 0) {
- __os_free(txn, sizeof(DB_TXN));
- txn = NULL;
- }
- if (txn != NULL && parent != NULL)
- TAILQ_INSERT_HEAD(&parent->kids, txn, klinks);
- *txnpp = txn;
- return (ret);
-}
-
-/*
- * __txn_xa_begin --
- * XA version of txn_begin.
- *
- * PUBLIC: int __txn_xa_begin __P((DB_ENV *, DB_TXN *));
- */
-int
-__txn_xa_begin(dbenv, txn)
- DB_ENV *dbenv;
- DB_TXN *txn;
-{
- TXN_PANIC_CHECK(dbenv->tx_info);
-
- memset(txn, 0, sizeof(DB_TXN));
-
- txn->mgrp = dbenv->tx_info;
-
- return (__txn_begin(txn));
-}
-
-/*
- * __txn_begin --
- * Normal DB version of txn_begin.
- */
-static int
-__txn_begin(txn)
- DB_TXN *txn;
-{
- DB_LSN begin_lsn;
- DB_TXNMGR *mgr;
- TXN_DETAIL *td;
- size_t off;
- u_int32_t id;
- int ret;
-
- /*
- * We do not have to write begin records (and if we do not, then we
- * need never write records for read-only transactions). However,
- * we do need to find the current LSN so that we can store it in the
- * transaction structure, so we can know where to take checkpoints.
- */
- mgr = txn->mgrp;
- if (mgr->dbenv->lg_info != NULL && (ret =
- log_put(mgr->dbenv->lg_info, &begin_lsn, NULL, DB_CURLSN)) != 0)
- goto err2;
-
- LOCK_TXNREGION(mgr);
-
- /* Make sure that last_txnid is not going to wrap around. */
- if (mgr->region->last_txnid == TXN_INVALID) {
- __db_err(mgr->dbenv, "txn_begin: %s %s",
- "Transaction ID wrapping.",
- "Snapshot your database and start a new log.");
- ret = EINVAL;
- goto err1;
- }
-
- if ((ret = __txn_validate_region(mgr)) != 0)
- goto err1;
-
- /* Allocate a new transaction detail structure. */
- if ((ret = __db_shalloc(mgr->mem, sizeof(TXN_DETAIL), 0, &td)) != 0
- && ret == ENOMEM && (ret = __txn_grow_region(mgr)) == 0)
- ret = __db_shalloc(mgr->mem, sizeof(TXN_DETAIL), 0, &td);
- if (ret != 0)
- goto err1;
-
- /* Place transaction on active transaction list. */
- SH_TAILQ_INSERT_HEAD(&mgr->region->active_txn, td, links, __txn_detail);
-
- id = ++mgr->region->last_txnid;
- ++mgr->region->nbegins;
-
- td->txnid = id;
- td->begin_lsn = begin_lsn;
- ZERO_LSN(td->last_lsn);
- td->last_lock = 0;
- td->status = TXN_RUNNING;
- if (txn->parent != NULL)
- td->parent = txn->parent->off;
- else
- td->parent = 0;
-
- off = (u_int8_t *)td - (u_int8_t *)mgr->region;
- UNLOCK_TXNREGION(mgr);
-
- ZERO_LSN(txn->last_lsn);
- txn->txnid = id;
- txn->off = off;
-
- if (F_ISSET(txn, TXN_MALLOC)) {
- LOCK_TXNTHREAD(mgr);
- TAILQ_INSERT_TAIL(&mgr->txn_chain, txn, links);
- UNLOCK_TXNTHREAD(mgr);
- }
-
- return (0);
-
-err1: UNLOCK_TXNREGION(mgr);
-
-err2: return (ret);
-}
-/*
- * txn_commit --
- * Commit a transaction.
- */
-int
-txn_commit(txnp)
- DB_TXN *txnp;
-{
- DB_LOG *logp;
- DB_TXNMGR *mgr;
- int ret;
-
- mgr = txnp->mgrp;
-
- TXN_PANIC_CHECK(mgr);
- if ((ret = __txn_check_running(txnp, NULL)) != 0)
- return (ret);
-
- /*
- * If there are any log records, write a log record and sync
- * the log, else do no log writes. If the commit is for a child
- * transaction, we do not need to commit the child synchronously
- * since if its parent aborts, it will abort too and its parent
- * (or ultimate ancestor) will write synchronously.
- */
- if ((logp = mgr->dbenv->lg_info) != NULL &&
- !IS_ZERO_LSN(txnp->last_lsn)) {
- if (txnp->parent == NULL)
- ret = __txn_regop_log(logp, txnp, &txnp->last_lsn,
- F_ISSET(mgr, DB_TXN_NOSYNC) ? 0 : DB_FLUSH,
- TXN_COMMIT);
- else
- ret = __txn_child_log(logp, txnp, &txnp->last_lsn, 0,
- TXN_COMMIT, txnp->parent->txnid);
- if (ret != 0)
- return (ret);
- }
-
- /*
- * If this is the senior ancestor (i.e., it has no children), then we
- * can release all the child transactions since everyone is committing.
- * Then we can release this transaction. If this is not the ultimate
- * ancestor, then we can neither free it or its children.
- */
- if (txnp->parent == NULL)
- __txn_freekids(txnp);
-
- return (__txn_end(txnp, 1));
-}
-
-/*
- * txn_abort --
- * Abort a transcation.
- */
-int
-txn_abort(txnp)
- DB_TXN *txnp;
-{
- int ret;
- DB_TXN *kids;
-
- TXN_PANIC_CHECK(txnp->mgrp);
- if ((ret = __txn_check_running(txnp, NULL)) != 0)
- return (ret);
-
- for (kids = TAILQ_FIRST(&txnp->kids);
- kids != NULL;
- kids = TAILQ_FIRST(&txnp->kids))
- txn_abort(kids);
-
- if ((ret = __txn_undo(txnp)) != 0) {
- __db_err(txnp->mgrp->dbenv,
- "txn_abort: Log undo failed %s", strerror(ret));
- return (ret);
- }
- return (__txn_end(txnp, 0));
-}
-
-/*
- * txn_prepare --
- * Flush the log so a future commit is guaranteed to succeed.
- */
-int
-txn_prepare(txnp)
- DB_TXN *txnp;
-{
- DBT xid;
- DB_ENV *dbenv;
- TXN_DETAIL *td;
- int ret;
-
- if ((ret = __txn_check_running(txnp, &td)) != 0)
- return (ret);
-
- dbenv = txnp->mgrp->dbenv;
- memset(&xid, 0, sizeof(xid));
- xid.data = td->xid;
- /*
- * We indicate that a transaction is an XA transaction by putting
- * a valid size in the xid.size fiels. XA requires that the transaction
- * be either ENDED or SUSPENDED when prepare is called, so we know
- * that if the xa_status isn't in one of those states, but we are
- * calling prepare that we are not an XA transaction.
- */
- xid.size =
- td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED ?
- 0 : sizeof(td->xid);
- if (dbenv->lg_info != NULL &&
- (ret = __txn_xa_regop_log(dbenv->lg_info, txnp, &txnp->last_lsn,
- F_ISSET(txnp->mgrp, DB_TXN_NOSYNC) ? 0 : DB_FLUSH, TXN_PREPARE,
- &xid, td->format, td->gtrid, td->bqual, &td->begin_lsn)) != 0) {
- __db_err(dbenv,
- "txn_prepare: log_write failed %s\n", strerror(ret));
- return (ret);
- }
-
- LOCK_TXNTHREAD(txnp->mgrp);
- td->status = TXN_PREPARED;
- UNLOCK_TXNTHREAD(txnp->mgrp);
- return (ret);
-}
-
-/*
- * Return the transaction ID associated with a particular transaction
- */
-u_int32_t
-txn_id(txnp)
- DB_TXN *txnp;
-{
- return (txnp->txnid);
-}
-
-/*
- * txn_close --
- * Close the transaction region, does not imply a checkpoint.
- */
-int
-txn_close(tmgrp)
- DB_TXNMGR *tmgrp;
-{
- DB_TXN *txnp;
- int ret, t_ret;
-
- TXN_PANIC_CHECK(tmgrp);
-
- ret = 0;
-
- /*
- * This function had better only be called once per process
- * (i.e., not per thread), so there should be no synchronization
- * required.
- */
- while ((txnp =
- TAILQ_FIRST(&tmgrp->txn_chain)) != TAILQ_END(&tmgrp->txn_chain))
- if ((t_ret = txn_abort(txnp)) != 0) {
- __txn_end(txnp, 0);
- if (ret == 0)
- ret = t_ret;
- }
-
- if (tmgrp->dbenv->lg_info &&
- (t_ret = log_flush(tmgrp->dbenv->lg_info, NULL)) != 0 && ret == 0)
- ret = t_ret;
-
- if (tmgrp->mutexp != NULL) {
- LOCK_TXNREGION(tmgrp);
- __db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
- UNLOCK_TXNREGION(tmgrp);
- }
-
- if ((t_ret = __db_rdetach(&tmgrp->reginfo)) != 0 && ret == 0)
- ret = t_ret;
-
- if (tmgrp->reginfo.path != NULL)
- __os_freestr(tmgrp->reginfo.path);
- __os_free(tmgrp, sizeof(*tmgrp));
-
- return (ret);
-}
-
-/*
- * txn_unlink --
- * Remove the transaction region.
- */
-int
-txn_unlink(path, force, dbenv)
- const char *path;
- int force;
- DB_ENV *dbenv;
-{
- REGINFO reginfo;
- int ret;
-
- memset(&reginfo, 0, sizeof(reginfo));
- reginfo.dbenv = dbenv;
- reginfo.appname = DB_APP_NONE;
- if (path != NULL && (ret = __os_strdup(path, &reginfo.path)) != 0)
- return (ret);
- reginfo.file = DEFAULT_TXN_FILE;
- ret = __db_runlink(&reginfo, force);
- if (reginfo.path != NULL)
- __os_freestr(reginfo.path);
- return (ret);
-}
-
-/* Internal routines. */
-
-/*
- * Return 0 if the txnp is reasonable, otherwise returns EINVAL.
- */
-static int
-__txn_check_running(txnp, tdp)
- const DB_TXN *txnp;
- TXN_DETAIL **tdp;
-{
- TXN_DETAIL *tp;
-
- tp = NULL;
- if (txnp != NULL && txnp->mgrp != NULL && txnp->mgrp->region != NULL) {
- tp = (TXN_DETAIL *)((u_int8_t *)txnp->mgrp->region + txnp->off);
- /*
- * Child transactions could be marked committed which is OK.
- */
- if (tp->status != TXN_RUNNING &&
- tp->status != TXN_PREPARED && tp->status != TXN_COMMITTED)
- tp = NULL;
- if (tdp != NULL)
- *tdp = tp;
- }
-
- return (tp == NULL ? EINVAL : 0);
-}
-
-static int
-__txn_end(txnp, is_commit)
- DB_TXN *txnp;
- int is_commit;
-{
- DB_LOCKREQ request;
- DB_TXNMGR *mgr;
- TXN_DETAIL *tp;
- u_int32_t locker;
- int ret;
-
- mgr = txnp->mgrp;
-
- /* Release the locks. */
- locker = txnp->txnid;
- request.op = txnp->parent == NULL ||
- is_commit == 0 ? DB_LOCK_PUT_ALL : DB_LOCK_INHERIT;
-
- if (mgr->dbenv->lk_info) {
- ret =
- lock_tvec(mgr->dbenv->lk_info, txnp, 0, &request, 1, NULL);
- if (ret != 0 && (ret != DB_LOCK_DEADLOCK || is_commit)) {
- __db_err(mgr->dbenv, "%s: release locks failed %s",
- is_commit ? "txn_commit" : "txn_abort",
- strerror(ret));
- return (ret);
- }
- }
-
- /* End the transaction. */
- LOCK_TXNREGION(mgr);
-
- /*
- * Child transactions that are committing cannot be released until
- * the parent commits, since the parent may abort, causing the child
- * to abort as well.
- */
- tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off);
- if (txnp->parent == NULL || !is_commit) {
- SH_TAILQ_REMOVE(&mgr->region->active_txn,
- tp, links, __txn_detail);
-
- __db_shalloc_free(mgr->mem, tp);
- } else
- tp->status = is_commit ? TXN_COMMITTED : TXN_ABORTED;
-
- if (is_commit)
- mgr->region->ncommits++;
- else
- mgr->region->naborts++;
-
- UNLOCK_TXNREGION(mgr);
-
- /*
- * If the transaction aborted, we can remove it from its parent links.
- * If it committed, then we need to leave it on, since the parent can
- * still abort.
- */
- if (txnp->parent != NULL && !is_commit)
- TAILQ_REMOVE(&txnp->parent->kids, txnp, klinks);
-
- /* Free the space. */
- if (F_ISSET(txnp, TXN_MALLOC) && (txnp->parent == NULL || !is_commit)) {
- LOCK_TXNTHREAD(mgr);
- TAILQ_REMOVE(&mgr->txn_chain, txnp, links);
- UNLOCK_TXNTHREAD(mgr);
-
- __os_free(txnp, sizeof(*txnp));
- }
-
- return (0);
-}
-
-
-/*
- * __txn_undo --
- * Undo the transaction with id txnid. Returns 0 on success and
- * errno on failure.
- */
-static int
-__txn_undo(txnp)
- DB_TXN *txnp;
-{
- DBT rdbt;
- DB_LOG *logp;
- DB_LSN key_lsn;
- DB_TXNMGR *mgr;
- int ret;
-
- mgr = txnp->mgrp;
- logp = mgr->dbenv->lg_info;
- if (logp == NULL)
- return (0);
-
- /*
- * This is the simplest way to code this, but if the mallocs during
- * recovery turn out to be a performance issue, we can do the
- * allocation here and use DB_DBT_USERMEM.
- */
- memset(&rdbt, 0, sizeof(rdbt));
- if (F_ISSET(logp, DB_AM_THREAD))
- F_SET(&rdbt, DB_DBT_MALLOC);
-
- key_lsn = txnp->last_lsn; /* structure assignment */
- for (ret = 0; ret == 0 && !IS_ZERO_LSN(key_lsn);) {
- /*
- * The dispatch routine returns the lsn of the record
- * before the current one in the key_lsn argument.
- */
- if ((ret = log_get(logp, &key_lsn, &rdbt, DB_SET)) == 0) {
- ret =
- mgr->recover(logp, &rdbt, &key_lsn, TXN_UNDO, NULL);
- if (F_ISSET(logp, DB_AM_THREAD) && rdbt.data != NULL) {
- __os_free(rdbt.data, rdbt.size);
- rdbt.data = NULL;
- }
- }
- if (ret != 0)
- return (ret);
- }
-
- return (ret);
-}
-
-/*
- * Transaction checkpoint.
- * If either kbytes or minutes is non-zero, then we only take the checkpoint
- * more than "minutes" minutes have passed since the last checkpoint or if
- * more than "kbytes" of log data have been written since the last checkpoint.
- * When taking a checkpoint, find the oldest active transaction and figure out
- * its first LSN. This is the lowest LSN we can checkpoint, since any record
- * written after since that point may be involved in a transaction and may
- * therefore need to be undone in the case of an abort.
- */
-int
-txn_checkpoint(mgr, kbytes, minutes)
- const DB_TXNMGR *mgr;
- u_int32_t kbytes, minutes;
-{
- DB_LOG *dblp;
- DB_LSN ckp_lsn, sync_lsn, last_ckp;
- TXN_DETAIL *txnp;
- time_t last_ckp_time, now;
- u_int32_t kbytes_written;
- int ret;
-
- TXN_PANIC_CHECK(mgr);
-
- /*
- * Check if we need to run recovery.
- */
- ZERO_LSN(ckp_lsn);
- if (minutes != 0) {
- (void)time(&now);
-
- LOCK_TXNREGION(mgr);
- last_ckp_time = mgr->region->time_ckp;
- UNLOCK_TXNREGION(mgr);
-
- if (now - last_ckp_time >= (time_t)(minutes * 60))
- goto do_ckp;
- }
-
- if (kbytes != 0) {
- dblp = mgr->dbenv->lg_info;
- LOCK_LOGREGION(dblp);
- kbytes_written =
- dblp->lp->stat.st_wc_mbytes * 1024 +
- dblp->lp->stat.st_wc_bytes / 1024;
- ckp_lsn = dblp->lp->lsn;
- UNLOCK_LOGREGION(dblp);
- if (kbytes_written >= (u_int32_t)kbytes)
- goto do_ckp;
- }
-
- /*
- * If we checked time and data and didn't go to checkpoint,
- * we're done.
- */
- if (minutes != 0 || kbytes != 0)
- return (0);
-
-do_ckp:
- if (IS_ZERO_LSN(ckp_lsn)) {
- dblp = mgr->dbenv->lg_info;
- LOCK_LOGREGION(dblp);
- ckp_lsn = dblp->lp->lsn;
- UNLOCK_LOGREGION(dblp);
- }
-
- /*
- * We have to find an LSN such that all transactions begun
- * before that LSN are complete.
- */
- LOCK_TXNREGION(mgr);
-
- if (!IS_ZERO_LSN(mgr->region->pending_ckp))
- ckp_lsn = mgr->region->pending_ckp;
- else
- for (txnp =
- SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
- txnp != NULL;
- txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
-
- /*
- * Look through the active transactions for the
- * lowest begin lsn.
- */
- if (!IS_ZERO_LSN(txnp->begin_lsn) &&
- log_compare(&txnp->begin_lsn, &ckp_lsn) < 0)
- ckp_lsn = txnp->begin_lsn;
- }
-
- mgr->region->pending_ckp = ckp_lsn;
- UNLOCK_TXNREGION(mgr);
-
- /*
- * memp_sync may change the lsn you pass it, so don't pass it
- * the actual ckp_lsn, pass it a temp instead.
- */
- sync_lsn = ckp_lsn;
- if (mgr->dbenv->mp_info != NULL &&
- (ret = memp_sync(mgr->dbenv->mp_info, &sync_lsn)) != 0) {
- /*
- * ret == DB_INCOMPLETE means that there are still buffers to
- * flush, the checkpoint is not complete. Wait and try again.
- */
- if (ret > 0)
- __db_err(mgr->dbenv,
- "txn_checkpoint: system failure in memp_sync %s\n",
- strerror(ret));
- return (ret);
- }
- if (mgr->dbenv->lg_info != NULL) {
- LOCK_TXNREGION(mgr);
- last_ckp = mgr->region->last_ckp;
- ZERO_LSN(mgr->region->pending_ckp);
- UNLOCK_TXNREGION(mgr);
-
- if ((ret = __txn_ckp_log(mgr->dbenv->lg_info,
- NULL, &ckp_lsn, DB_CHECKPOINT, &ckp_lsn, &last_ckp)) != 0) {
- __db_err(mgr->dbenv,
- "txn_checkpoint: log failed at LSN [%ld %ld] %s\n",
- (long)ckp_lsn.file, (long)ckp_lsn.offset,
- strerror(ret));
- return (ret);
- }
-
- LOCK_TXNREGION(mgr);
- mgr->region->last_ckp = ckp_lsn;
- (void)time(&mgr->region->time_ckp);
- UNLOCK_TXNREGION(mgr);
- }
- return (0);
-}
-
-/*
- * __txn_validate_region --
- * Called at every interface to verify if the region has changed size,
- * and if so, to remap the region in and reset the process' pointers.
- */
-static int
-__txn_validate_region(tp)
- DB_TXNMGR *tp;
-{
- int ret;
-
- if (tp->reginfo.size == tp->region->hdr.size)
- return (0);
-
- /* Detach/reattach the region. */
- if ((ret = __db_rreattach(&tp->reginfo, tp->region->hdr.size)) != 0)
- return (ret);
-
- /* Reset region information. */
- tp->region = tp->reginfo.addr;
- tp->mem = &tp->region[1];
-
- return (0);
-}
-
-static int
-__txn_grow_region(tp)
- DB_TXNMGR *tp;
-{
- size_t incr, oldsize;
- u_int32_t mutex_offset, oldmax;
- u_int8_t *curaddr;
- int ret;
-
- oldmax = tp->region->maxtxns;
- incr = oldmax * sizeof(DB_TXN);
- mutex_offset = tp->mutexp != NULL ?
- (u_int8_t *)tp->mutexp - (u_int8_t *)tp->region : 0;
-
- oldsize = tp->reginfo.size;
- if ((ret = __db_rgrow(&tp->reginfo, oldsize + incr)) != 0)
- return (ret);
- tp->region = tp->reginfo.addr;
-
- /* Throw the new space on the free list. */
- curaddr = (u_int8_t *)tp->region + oldsize;
- tp->mem = &tp->region[1];
- tp->mutexp = mutex_offset != 0 ?
- (db_mutex_t *)((u_int8_t *)tp->region + mutex_offset) : NULL;
-
- *((size_t *)curaddr) = incr - sizeof(size_t);
- curaddr += sizeof(size_t);
- __db_shalloc_free(tp->mem, curaddr);
-
- tp->region->maxtxns = 2 * oldmax;
-
- return (0);
-}
-
-int
-txn_stat(mgr, statp, db_malloc)
- DB_TXNMGR *mgr;
- DB_TXN_STAT **statp;
- void *(*db_malloc) __P((size_t));
-{
- DB_TXN_STAT *stats;
- TXN_DETAIL *txnp;
- size_t nbytes;
- u_int32_t nactive, ndx;
- int ret;
-
- TXN_PANIC_CHECK(mgr);
-
- LOCK_TXNREGION(mgr);
- nactive = mgr->region->nbegins -
- mgr->region->naborts - mgr->region->ncommits;
- UNLOCK_TXNREGION(mgr);
-
- /*
- * Allocate a bunch of extra active structures to handle any
- * that have been created since we unlocked the region.
- */
- nbytes = sizeof(DB_TXN_STAT) + sizeof(DB_TXN_ACTIVE) * (nactive + 200);
- if ((ret = __os_malloc(nbytes, db_malloc, &stats)) != 0)
- return (ret);
-
- LOCK_TXNREGION(mgr);
- stats->st_last_txnid = mgr->region->last_txnid;
- stats->st_last_ckp = mgr->region->last_ckp;
- stats->st_maxtxns = mgr->region->maxtxns;
- stats->st_naborts = mgr->region->naborts;
- stats->st_nbegins = mgr->region->nbegins;
- stats->st_ncommits = mgr->region->ncommits;
- stats->st_pending_ckp = mgr->region->pending_ckp;
- stats->st_time_ckp = mgr->region->time_ckp;
- stats->st_nactive = stats->st_nbegins -
- stats->st_naborts - stats->st_ncommits;
- if (stats->st_nactive > nactive + 200)
- stats->st_nactive = nactive + 200;
- stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1];
-
- ndx = 0;
- for (txnp = SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
- txnp != NULL;
- txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
- stats->st_txnarray[ndx].txnid = txnp->txnid;
- stats->st_txnarray[ndx].lsn = txnp->begin_lsn;
- ndx++;
-
- if (ndx >= stats->st_nactive)
- break;
- }
-
- stats->st_region_wait = mgr->region->hdr.lock.mutex_set_wait;
- stats->st_region_nowait = mgr->region->hdr.lock.mutex_set_nowait;
- stats->st_refcnt = mgr->region->hdr.refcnt;
- stats->st_regsize = mgr->region->hdr.size;
-
- UNLOCK_TXNREGION(mgr);
- *statp = stats;
- return (0);
-}
-
-static void
-__txn_freekids(txnp)
- DB_TXN *txnp;
-{
- DB_TXNMGR *mgr;
- TXN_DETAIL *tp;
- DB_TXN *kids;
-
- mgr = txnp->mgrp;
-
- for (kids = TAILQ_FIRST(&txnp->kids);
- kids != NULL;
- kids = TAILQ_FIRST(&txnp->kids)) {
- /* Free any children of this transaction. */
- __txn_freekids(kids);
-
- /* Free the transaction detail in the region. */
- LOCK_TXNREGION(mgr);
- tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + kids->off);
- SH_TAILQ_REMOVE(&mgr->region->active_txn,
- tp, links, __txn_detail);
-
- __db_shalloc_free(mgr->mem, tp);
- UNLOCK_TXNREGION(mgr);
-
- /* Now remove from its parent. */
- TAILQ_REMOVE(&txnp->kids, kids, klinks);
- if (F_ISSET(txnp, TXN_MALLOC)) {
- LOCK_TXNTHREAD(mgr);
- TAILQ_REMOVE(&mgr->txn_chain, kids, links);
- UNLOCK_TXNTHREAD(mgr);
- __os_free(kids, sizeof(*kids));
- }
- }
-}
-
-/*
- * __txn_is_ancestor --
- * Determine if a transaction is an ancestor of another transaction.
- * This is used during lock promotion when we do not have the per-process
- * data structures that link parents together. Instead, we'll have to
- * follow the links in the transaction region.
- *
- * PUBLIC: int __txn_is_ancestor __P((DB_TXNMGR *, size_t, size_t));
- */
-int
-__txn_is_ancestor(mgr, hold_off, req_off)
- DB_TXNMGR *mgr;
- size_t hold_off, req_off;
-{
- TXN_DETAIL *hold_tp, *req_tp;
-
- hold_tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + hold_off);
- req_tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + req_off);
-
- while (req_tp->parent != 0) {
- req_tp =
- (TXN_DETAIL *)((u_int8_t *)mgr->region + req_tp->parent);
- if (req_tp->txnid == hold_tp->txnid)
- return (1);
- }
-
- return (0);
-}
diff --git a/db2/txn/txn.src b/db2/txn/txn.src
deleted file mode 100644
index c9614f6..0000000
--- a/db2/txn/txn.src
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)txn.src 10.6 (Sleepycat) 1/3/99
- */
-
-PREFIX txn
-
-/*
- * This is the standard log operation for commit.
- */
-BEGIN regop
-ARG opcode u_int32_t lu
-END
-
-/*
- * This is the checkpoint record. It contains the lsn that the checkpoint
- * guarantees and a pointer to the last checkpoint so we can walk backwards
- * by checkpoint.
- *
- * ckp_lsn:
- * The lsn in the log of the most recent point at which all begun
- * transactions have been aborted. This is the point for which
- * the checkpoint is relevant.
- * last_ckp:
- * The previous checkpoint.
- */
-BEGIN ckp
-POINTER ckp_lsn DB_LSN * lu
-POINTER last_ckp DB_LSN * lu
-END
-
-/*
- * This is the standard log operation for prepare (since right now
- * we only use prepare in an XA environment).
- */
-BEGIN xa_regop
-ARG opcode u_int32_t lu
-DBT xid DBT s
-ARG formatID int32_t ld
-ARG gtrid u_int32_t u
-ARG bqual u_int32_t u
-POINTER begin_lsn DB_LSN * lu
-END
-
-/*
- * This is the log operation for a child commit.
- */
-BEGIN child
-ARG opcode u_int32_t lu
-ARG parent u_int32_t lu
-END
diff --git a/db2/txn/txn_auto.c b/db2/txn/txn_auto.c
deleted file mode 100644
index e6d431f..0000000
--- a/db2/txn/txn_auto.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "txn.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __txn_regop_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t));
- */
-int __txn_regop_log(logp, txnid, ret_lsnp, flags,
- opcode)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_txn_regop;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_regop_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_regop_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __txn_regop_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]txn_regop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_regop_read __P((void *, __txn_regop_args **));
- */
-int
-__txn_regop_read(recbuf, argpp)
- void *recbuf;
- __txn_regop_args **argpp;
-{
- __txn_regop_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__txn_regop_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_ckp_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: DB_LSN *, DB_LSN *));
- */
-int __txn_ckp_log(logp, txnid, ret_lsnp, flags,
- ckp_lsn, last_ckp)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- DB_LSN * ckp_lsn;
- DB_LSN * last_ckp;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_txn_ckp;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(*ckp_lsn)
- + sizeof(*last_ckp);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- if (ckp_lsn != NULL)
- memcpy(bp, ckp_lsn, sizeof(*ckp_lsn));
- else
- memset(bp, 0, sizeof(*ckp_lsn));
- bp += sizeof(*ckp_lsn);
- if (last_ckp != NULL)
- memcpy(bp, last_ckp, sizeof(*last_ckp));
- else
- memset(bp, 0, sizeof(*last_ckp));
- bp += sizeof(*last_ckp);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_ckp_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_ckp_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __txn_ckp_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]txn_ckp: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\tckp_lsn: [%lu][%lu]\n",
- (u_long)argp->ckp_lsn.file, (u_long)argp->ckp_lsn.offset);
- printf("\tlast_ckp: [%lu][%lu]\n",
- (u_long)argp->last_ckp.file, (u_long)argp->last_ckp.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_ckp_read __P((void *, __txn_ckp_args **));
- */
-int
-__txn_ckp_read(recbuf, argpp)
- void *recbuf;
- __txn_ckp_args **argpp;
-{
- __txn_ckp_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__txn_ckp_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->ckp_lsn, bp, sizeof(argp->ckp_lsn));
- bp += sizeof(argp->ckp_lsn);
- memcpy(&argp->last_ckp, bp, sizeof(argp->last_ckp));
- bp += sizeof(argp->last_ckp);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_xa_regop_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, const DBT *, int32_t, u_int32_t,
- * PUBLIC: u_int32_t, DB_LSN *));
- */
-int __txn_xa_regop_log(logp, txnid, ret_lsnp, flags,
- opcode, xid, formatID, gtrid, bqual, begin_lsn)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- const DBT *xid;
- int32_t formatID;
- u_int32_t gtrid;
- u_int32_t bqual;
- DB_LSN * begin_lsn;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_txn_xa_regop;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(u_int32_t) + (xid == NULL ? 0 : xid->size)
- + sizeof(formatID)
- + sizeof(gtrid)
- + sizeof(bqual)
- + sizeof(*begin_lsn);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- if (xid == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &xid->size, sizeof(xid->size));
- bp += sizeof(xid->size);
- memcpy(bp, xid->data, xid->size);
- bp += xid->size;
- }
- memcpy(bp, &formatID, sizeof(formatID));
- bp += sizeof(formatID);
- memcpy(bp, &gtrid, sizeof(gtrid));
- bp += sizeof(gtrid);
- memcpy(bp, &bqual, sizeof(bqual));
- bp += sizeof(bqual);
- if (begin_lsn != NULL)
- memcpy(bp, begin_lsn, sizeof(*begin_lsn));
- else
- memset(bp, 0, sizeof(*begin_lsn));
- bp += sizeof(*begin_lsn);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_xa_regop_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_xa_regop_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __txn_xa_regop_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __txn_xa_regop_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]txn_xa_regop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\txid: ");
- for (i = 0; i < argp->xid.size; i++) {
- ch = ((u_int8_t *)argp->xid.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tformatID: %ld\n", (long)argp->formatID);
- printf("\tgtrid: %u\n", argp->gtrid);
- printf("\tbqual: %u\n", argp->bqual);
- printf("\tbegin_lsn: [%lu][%lu]\n",
- (u_long)argp->begin_lsn.file, (u_long)argp->begin_lsn.offset);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_xa_regop_read __P((void *, __txn_xa_regop_args **));
- */
-int
-__txn_xa_regop_read(recbuf, argpp)
- void *recbuf;
- __txn_xa_regop_args **argpp;
-{
- __txn_xa_regop_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__txn_xa_regop_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->xid.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->xid.data = bp;
- bp += argp->xid.size;
- memcpy(&argp->formatID, bp, sizeof(argp->formatID));
- bp += sizeof(argp->formatID);
- memcpy(&argp->gtrid, bp, sizeof(argp->gtrid));
- bp += sizeof(argp->gtrid);
- memcpy(&argp->bqual, bp, sizeof(argp->bqual));
- bp += sizeof(argp->bqual);
- memcpy(&argp->begin_lsn, bp, sizeof(argp->begin_lsn));
- bp += sizeof(argp->begin_lsn);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_child_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, u_int32_t));
- */
-int __txn_child_log(logp, txnid, ret_lsnp, flags,
- opcode, parent)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- u_int32_t parent;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_txn_child;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(parent);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- memcpy(bp, &parent, sizeof(parent));
- bp += sizeof(parent);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_child_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_child_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __txn_child_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __txn_child_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]txn_child: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tparent: %lu\n", (u_long)argp->parent);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_child_read __P((void *, __txn_child_args **));
- */
-int
-__txn_child_read(recbuf, argpp)
- void *recbuf;
- __txn_child_args **argpp;
-{
- __txn_child_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__txn_child_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->parent, bp, sizeof(argp->parent));
- bp += sizeof(argp->parent);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_init_print __P((DB_ENV *));
- */
-int
-__txn_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __txn_regop_print, DB_txn_regop)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_ckp_print, DB_txn_ckp)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_xa_regop_print, DB_txn_xa_regop)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_child_print, DB_txn_child)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __txn_init_recover __P((DB_ENV *));
- */
-int
-__txn_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __txn_regop_recover, DB_txn_regop)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_ckp_recover, DB_txn_ckp)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_xa_regop_recover, DB_txn_xa_regop)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv,
- __txn_child_recover, DB_txn_child)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/txn/txn_rec.c b/db2/txn/txn_rec.c
deleted file mode 100644
index f21a0f9..0000000
--- a/db2/txn/txn_rec.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)txn_rec.c 10.15 (Sleepycat) 1/3/99";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "shqueue.h"
-#include "txn.h"
-#include "db_am.h"
-#include "log.h"
-#include "common_ext.h"
-
-static int __txn_restore_txn __P((DB_ENV *, DB_LSN *, __txn_xa_regop_args *));
-
-#define IS_XA_TXN(R) (R->xid.size != 0)
-
-/*
- * PUBLIC: int __txn_regop_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- *
- * These records are only ever written for commits.
- */
-int
-__txn_regop_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __txn_regop_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- (void)__txn_regop_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(redo, 0);
- COMPQUIET(logp, NULL);
-
- if ((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
- return (ret);
-
- if (argp->opcode != TXN_COMMIT)
- ret = EINVAL;
- else
- if (__db_txnlist_find(info, argp->txnid->txnid) == DB_NOTFOUND)
- ret = __db_txnlist_add(info, argp->txnid->txnid);
-
- if (ret == 0)
- *lsnp = argp->prev_lsn;
- __os_free(argp, 0);
-
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_xa_regop_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- *
- * These records are only ever written for prepares.
- */
-int
-__txn_xa_regop_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __txn_xa_regop_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- (void)__txn_xa_regop_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(redo, 0);
- COMPQUIET(logp, NULL);
-
- if ((ret = __txn_xa_regop_read(dbtp->data, &argp)) != 0)
- return (ret);
-
- if (argp->opcode != TXN_PREPARE)
- ret = EINVAL;
- else {
- /*
- * Whether we are in XA or not, we need to call
- * __db_txnlist_find so that we update the maxid.
- * If this is an XA transaction, then we treat
- * prepares like commits so that we roll forward to
- * a point where we can handle commit/abort calls
- * from the TMS. If this isn't XA, then a prepare
- * is treated like a No-op; we only care about the
- * commit.
- */
- ret = __db_txnlist_find(info, argp->txnid->txnid);
- if (IS_XA_TXN(argp) && ret == DB_NOTFOUND) {
- /*
- * This is an XA prepared, but not yet committed
- * transaction. We need to add it to the
- * transaction list, so that it gets rolled
- * forward. We also have to add it to the region's
- * internal state so it can be properly aborted
- * or recovered.
- */
- ret = __db_txnlist_add(info, argp->txnid->txnid);
- if (ret == 0)
- ret = __txn_restore_txn(logp->dbenv,
- lsnp, argp);
- }
- }
-
- if (ret == 0)
- *lsnp = argp->prev_lsn;
- __os_free(argp, 0);
-
- return (ret);
-}
-
-/*
- * PUBLIC: int __txn_ckp_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_ckp_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __txn_ckp_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- __txn_ckp_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(logp, NULL);
-
- if ((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
- return (ret);
-
- /*
- * Check for 'restart' checkpoint record. This occurs when the
- * checkpoint lsn is equal to the lsn of the checkpoint record
- * and means that we could set the transaction ID back to 1, so
- * that we don't exhaust the transaction ID name space.
- */
- if (argp->ckp_lsn.file == lsnp->file &&
- argp->ckp_lsn.offset == lsnp->offset)
- __db_txnlist_gen(info, redo ? -1 : 1);
-
- *lsnp = argp->last_ckp;
- __os_free(argp, 0);
- return (DB_TXN_CKP);
-}
-
-/*
- * __txn_child_recover
- * Recover a commit record for a child transaction.
- *
- * PUBLIC: int __txn_child_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__txn_child_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __txn_child_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- (void)__txn_child_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(redo, 0);
- COMPQUIET(logp, NULL);
-
- if ((ret = __txn_child_read(dbtp->data, &argp)) != 0)
- return (ret);
-
- /*
- * We count the child as committed only if its parent committed.
- * So, if we are not yet in the transaction list, but our parent
- * is, then we should go ahead and commit.
- */
- if (argp->opcode != TXN_COMMIT)
- ret = EINVAL;
- else
- if (__db_txnlist_find(info, argp->parent) == 0 &&
- __db_txnlist_find(info, argp->txnid->txnid) == DB_NOTFOUND)
- ret = __db_txnlist_add(info, argp->txnid->txnid);
-
- if (ret == 0)
- *lsnp = argp->prev_lsn;
- __os_free(argp, 0);
-
- return (ret);
-}
-
-/*
- * __txn_restore_txn --
- * Using only during XA recovery. If we find any transactions that are
- * prepared, but not yet committed, then we need to restore the transaction's
- * state into the shared region, because the TM is going to issue a txn_abort
- * or txn_commit and we need to respond correctly.
- *
- * lsnp is the LSN of the returned LSN
- * argp is the perpare record (in an appropriate structure)
- */
-static int
-__txn_restore_txn(dbenv, lsnp, argp)
- DB_ENV *dbenv;
- DB_LSN *lsnp;
- __txn_xa_regop_args *argp;
-{
- DB_TXNMGR *mgr;
- TXN_DETAIL *td;
- int ret;
-
- if (argp->xid.size == 0)
- return(0);
-
- mgr = dbenv->tx_info;
- LOCK_TXNREGION(mgr);
-
- /* Allocate a new transaction detail structure. */
- if ((ret = __db_shalloc(mgr->mem, sizeof(TXN_DETAIL), 0, &td)) != 0)
- return (ret);
-
- /* Place transaction on active transaction list. */
- SH_TAILQ_INSERT_HEAD(&mgr->region->active_txn, td, links, __txn_detail);
-
- td->txnid = argp->txnid->txnid;
- td->begin_lsn = argp->begin_lsn;
- td->last_lsn = *lsnp;
- td->last_lock = 0;
- td->parent = 0;
- td->status = TXN_PREPARED;
- td->xa_status = TXN_XA_PREPARED;
- memcpy(td->xid, argp->xid.data, argp->xid.size);
- td->bqual = argp->bqual;
- td->gtrid = argp->gtrid;
- td->format = argp->formatID;
-
- UNLOCK_TXNREGION(mgr);
- return (0);
-}
diff --git a/db2/xa/xa.c b/db2/xa/xa.c
deleted file mode 100644
index 94a96e7..0000000
--- a/db2/xa/xa.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- */
-
-/* XXX Remove the global transaction and hang it off the environment. */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)xa.c 10.4 (Sleepycat) 10/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "shqueue.h"
-#include "log.h"
-#include "txn.h"
-#include "db_auto.h"
-#include "db_ext.h"
-#include "db_dispatch.h"
-
-static int __db_xa_close __P((char *, int, long));
-static int __db_xa_commit __P((XID *, int, long));
-static int __db_xa_complete __P((int *, int *, int, long));
-static int __db_xa_end __P((XID *, int, long));
-static int __db_xa_forget __P((XID *, int, long));
-static int __db_xa_open __P((char *, int, long));
-static int __db_xa_prepare __P((XID *, int, long));
-static int __db_xa_recover __P((XID *, long, int, long));
-static int __db_xa_rollback __P((XID *, int, long));
-static int __db_xa_start __P((XID *, int, long));
-static void __xa_txn_end __P((DB_ENV *));
-static void __xa_txn_init __P((DB_ENV *, TXN_DETAIL *, size_t));
-
-/*
- * Possible flag values:
- * Dynamic registration 0 => no dynamic registration
- * TMREGISTER => dynamic registration
- * Asynchronous operation 0 => no support for asynchrony
- * TMUSEASYNC => async support
- * Migration support 0 => migration of transactions across
- * threads is possible
- * TMNOMIGRATE => no migration across threads
- */
-const struct xa_switch_t db_xa_switch = {
- "Berkeley DB", /* name[RMNAMESZ] */
- TMNOMIGRATE, /* flags */
- 0, /* version */
- __db_xa_open, /* xa_open_entry */
- __db_xa_close, /* xa_close_entry */
- __db_xa_start, /* xa_start_entry */
- __db_xa_end, /* xa_end_entry */
- __db_xa_rollback, /* xa_rollback_entry */
- __db_xa_prepare, /* xa_prepare_entry */
- __db_xa_commit, /* xa_commit_entry */
- __db_xa_recover, /* xa_recover_entry */
- __db_xa_forget, /* xa_forget_entry */
- __db_xa_complete /* xa_complete_entry */
-};
-
-/*
- * __db_xa_open --
- * The open call in the XA protocol. The rmid field is an id number
- * that the TM assigned us and will pass us on every xa call. We need to
- * map that rmid number into a dbenv structure that we create during
- * initialization. Since this id number is thread specific, we do not
- * need to store it in shared memory. The file xa_map.c implements all
- * such xa->db mappings.
- * The xa_info field is instance specific information. We require
- * that the value of DB_HOME be passed in xa_info. Since xa_info is the
- * only thing that we get to pass to db_appinit, any config information
- * will have to be done via a config file instead of via the db_appinit
- * call.
- */
-static int
-__db_xa_open(xa_info, rmid, flags)
- char *xa_info;
- int rmid;
- long flags;
-{
- DB_ENV *env;
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
- if (flags != TMNOFLAGS)
- return (XAER_INVAL);
-
- /* Verify if we already have this environment open. */
- if (__db_rmid_to_env(rmid, &env, 0) == 0)
- return (XA_OK);
-
- /*
- * Since we cannot tell whether the environment is OK or not,
- * we can't actually do the db_appinit in xa_open. Instead,
- * we save the mapping between the rmid and the xa_info. If
- * we next get a call to __xa_recover, we do the db_appinit
- * with DB_RECOVER set. If we get any other call, then we
- * do the db_appinit.
- */
- return (__db_map_rmid_name(rmid, xa_info));
-}
-
-/*
- * __db_xa_close --
- * The close call of the XA protocol. The only trickiness here
- * is that if there are any active transactions, we must fail. It is
- * *not* an error to call close on an environment that has already been
- * closed (I am interpreting that to mean it's OK to call close on an
- * environment that has never been opened).
- */
-static int
-__db_xa_close(xa_info, rmid, flags)
- char *xa_info;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- int ret, t_ret;
-
- COMPQUIET(xa_info, NULL);
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
- if (flags != TMNOFLAGS)
- return (XAER_INVAL);
-
- /* If the environment is closed, then we're done. */
- if (__db_rmid_to_env(rmid, &env, 0) != 0)
- return (XA_OK);
-
- /* Check if there are any pending transactions. */
- if (env->xa_txn != NULL && env->xa_txn->txnid != TXN_INVALID)
- return (XAER_PROTO);
-
- /* Now, destroy the mapping and close the environment. */
- ret = __db_unmap_rmid(rmid);
- if ((t_ret = db_appexit(env)) != 0 && ret == 0)
- ret = t_ret;
-
- __os_free(env, sizeof(DB_ENV));
-
- return (ret == 0 ? XA_OK : XAER_RMERR);
-}
-
-/*
- * __db_xa_start --
- * Begin a transaction for the current resource manager.
- */
-static int
-__db_xa_start(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- TXN_DETAIL *td;
- size_t off;
- int is_known;
-
-#define OK_FLAGS (TMJOIN | TMRESUME | TMNOWAIT | TMASYNC | TMNOFLAGS)
- if (LF_ISSET(~OK_FLAGS))
- return (XAER_INVAL);
-
- if (LF_ISSET(TMJOIN) && LF_ISSET(TMRESUME))
- return (XAER_INVAL);
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
-
- if (__db_rmid_to_env(rmid, &env, 1) != 0)
- return (XAER_PROTO);
-
- is_known = __db_xid_to_txn(env, xid, &off) == 0;
-
- if (is_known && !LF_ISSET(TMRESUME) && !LF_ISSET(TMJOIN))
- return (XAER_DUPID);
-
- if (!is_known && LF_ISSET(TMRESUME | TMJOIN))
- return (XAER_NOTA);
-
- /*
- * This can't block, so we can ignore TMNOWAIT.
- *
- * Other error conditions: RMERR, RMFAIL, OUTSIDE, PROTO, RB*
- */
- if (is_known) {
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
- if (td->xa_status == TXN_XA_SUSPENDED && !LF_SET(TMRESUME))
- return (XAER_PROTO);
- if (td->xa_status == TXN_XA_DEADLOCKED)
- return (XA_RBDEADLOCK);
- if (td->xa_status == TXN_XA_ABORTED)
- return (XA_RBOTHER);
-
- /* Now, fill in the global transaction structure. */
- __xa_txn_init(env, td, off);
- td->xa_status = TXN_XA_STARTED;
- } else {
- if (__txn_xa_begin(env, env->xa_txn) != 0)
- return (XAER_RMERR);
- (void)__db_map_xid(env, xid, env->xa_txn->off);
- td = (TXN_DETAIL *)
- ((u_int8_t *)env->tx_info->region + env->xa_txn->off);
- td->xa_status = TXN_XA_STARTED;
- }
- return (XA_OK);
-}
-
-/*
- * __db_xa_end --
- * Disassociate the current transaction from the current process.
- */
-static int
-__db_xa_end(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- DB_TXN *txn;
- TXN_DETAIL *td;
- size_t off;
-
- if (flags != TMNOFLAGS && !LF_ISSET(TMSUSPEND | TMSUCCESS | TMFAIL))
- return (XAER_INVAL);
-
- if (__db_rmid_to_env(rmid, &env, 0) != 0)
- return (XAER_PROTO);
-
- if (__db_xid_to_txn(env, xid, &off) != 0)
- return (XAER_NOTA);
-
- txn = env->xa_txn;
- if (off != txn->off)
- return (XAER_PROTO);
-
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
- if (td->xa_status == TXN_XA_DEADLOCKED)
- return (XA_RBDEADLOCK);
-
- if (td->status == TXN_ABORTED)
- return (XA_RBOTHER);
-
- if (td->xa_status != TXN_XA_STARTED)
- return (XAER_PROTO);
-
- /* Update the shared memory last_lsn field */
- td->last_lsn = txn->last_lsn;
-
- /*
- * If we ever support XA migration, we cannot keep SUSPEND/END
- * status in the shared region; it would have to be process local.
- */
- if (LF_ISSET(TMSUSPEND))
- td->xa_status = TXN_XA_SUSPENDED;
- else
- td->xa_status = TXN_XA_ENDED;
-
- txn->txnid = TXN_INVALID;
- return (XA_OK);
-}
-
-/*
- * __db_xa_prepare --
- * Sync the log to disk so we can guarantee recoverability.
- */
-static int
-__db_xa_prepare(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- TXN_DETAIL *td;
- size_t off;
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
- if (flags != TMNOFLAGS)
- return (XAER_INVAL);
-
- /*
- * We need to know if we've ever called prepare on this.
- * As part of the prepare, we set the xa_status field to
- * reflect that fact that prepare has been called, and if
- * it's ever called again, it's an error.
- */
- if (__db_rmid_to_env(rmid, &env, 1) != 0)
- return (XAER_PROTO);
-
- if (__db_xid_to_txn(env, xid, &off) != 0)
- return (XAER_NOTA);
-
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
-
- if (td->xa_status == TXN_XA_DEADLOCKED)
- return (XA_RBDEADLOCK);
-
- if (td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
- return (XAER_PROTO);
-
- /* Now, fill in the global transaction structure. */
- __xa_txn_init(env, td, off);
-
- if (txn_prepare(env->xa_txn) != 0)
- return (XAER_RMERR);
-
- td->xa_status = TXN_XA_PREPARED;
-
- /* No fatal value that would require an XAER_RMFAIL. */
- __xa_txn_end(env);
- return (XA_OK);
-}
-
-/*
- * __db_xa_commit --
- * Commit the transaction
- */
-static int
-__db_xa_commit(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- TXN_DETAIL *td;
- size_t off;
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
-#undef OK_FLAGS
-#define OK_FLAGS (TMNOFLAGS | TMNOWAIT | TMONEPHASE)
- if (LF_ISSET(~OK_FLAGS))
- return (XAER_INVAL);
-
- /*
- * We need to know if we've ever called prepare on this.
- * We can verify this by examining the xa_status field.
- */
- if (__db_rmid_to_env(rmid, &env, 1) != 0)
- return (XAER_PROTO);
-
- if (__db_xid_to_txn(env, xid, &off) != 0)
- return (XAER_NOTA);
-
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
-
- if (td->xa_status == TXN_XA_DEADLOCKED)
- return (XA_RBDEADLOCK);
-
- if (td->xa_status == TXN_XA_ABORTED)
- return (XA_RBOTHER);
-
- if (LF_SET(TMONEPHASE) &&
- td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
- return (XAER_PROTO);
-
- if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED)
- return (XAER_PROTO);
-
- /* Now, fill in the global transaction structure. */
- __xa_txn_init(env, td, off);
-
- if (txn_commit(env->xa_txn) != 0)
- return (XAER_RMERR);
-
- /* No fatal value that would require an XAER_RMFAIL. */
- __xa_txn_end(env);
- return (XA_OK);
-}
-
-/*
- * __db_xa_recover --
- * Returns a list of prepared and heuristically completed transactions.
- *
- * The return value is the number of xids placed into the xid array (less
- * than or equal to the count parameter). The flags are going to indicate
- * whether we are starting a scan or continuing one.
- */
-static int
-__db_xa_recover(xids, count, rmid, flags)
- XID *xids;
- long count, flags;
- int rmid;
-{
- __txn_xa_regop_args *argp;
- DBT data;
- DB_ENV *env;
- DB_LOG *log;
- XID *xidp;
- char *dbhome;
- int err, ret;
- u_int32_t rectype, txnid;
-
- ret = 0;
- xidp = xids;
-
-
- /*
- * If we are starting a scan, then we need to open the environment
- * and run recovery. This recovery puts us in a state where we can
- * either commit or abort any transactions that were prepared but not
- * yet committed. Once we've done that, we need to figure out where
- * to begin checking for such transactions. If we are not starting
- * a scan, then the environment had better have already been recovered
- * and we'll start from * wherever the log cursor is. Since XA apps
- * cannot be threaded, we don't have to worry about someone else
- * having moved it.
- */
- if (LF_ISSET(TMSTARTRSCAN)) {
- /* If the environment is open, we have a problem. */
- if (__db_rmid_to_env(rmid, &env, 0) == XA_OK)
- return (XAER_PROTO);
-
- if ((ret = __os_calloc(1, sizeof(DB_ENV), &env)) != 0)
- return (XAER_RMERR);
-
- if (__db_rmid_to_name(rmid, &dbhome) != 0)
- goto err1;
-
-#undef XA_FLAGS
-#define XA_FLAGS DB_RECOVER | \
- DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN
- if ((ret = db_appinit(dbhome, NULL, env, XA_FLAGS)) != 0)
- goto err1;
-
- if (__db_map_rmid(rmid, env) != 0)
- goto err2;
-
- /* Now figure out from where to begin scan. */
- log = env->lg_info;
- if ((err = __log_findckp(log, &log->xa_first)) == DB_NOTFOUND) {
- /*
- * If there were no log files, then we have no
- * transactions to return, so we simply return 0.
- */
- return (0);
- }
- if ((err = __db_txnlist_init(&log->xa_info)) != 0)
- goto err3;
- } else {
- /* We had better already know about this rmid. */
- if (__db_rmid_to_env(rmid, &env, 0) != 0)
- return (XAER_PROTO);
- /*
- * If we are not starting a scan, the log cursor had
- * better be set.
- */
- log = env->lg_info;
- if (IS_ZERO_LSN(log->xa_lsn))
- return (XAER_PROTO);
- }
-
- /*
- * At this point log->xa_first contains the point in the log
- * to which we need to roll back. If we are starting a scan,
- * we'll start at the last record; if we're continuing a scan,
- * we'll have to start at log->xa_lsn.
- */
-
- memset(&data, 0, sizeof(data));
- for (err = log_get(log, &log->xa_lsn, &data,
- LF_ISSET(TMSTARTRSCAN) ? DB_LAST : DB_SET);
- err == 0 && log_compare(&log->xa_lsn, &log->xa_first) > 0;
- err = log_get(log, &log->xa_lsn, &data, DB_PREV)) {
- memcpy(&rectype, data.data, sizeof(rectype));
-
- /*
- * The only record type we care about is an DB_txn_xa_regop.
- * If it's a commit, we have to add it to a txnlist. If it's
- * a prepare, and we don't have a commit, then we return it.
- * We are redoing some of what's in the xa_regop_recovery
- * code, but we have to do it here so we can get at the xid
- * in the record.
- */
- if (rectype != DB_txn_xa_regop && rectype != DB_txn_regop)
- continue;
-
- memcpy(&txnid, (u_int8_t *)data.data + sizeof(rectype),
- sizeof(txnid));
- err = __db_txnlist_find(log->xa_info, txnid);
- switch (rectype) {
- case DB_txn_regop:
- if (err == DB_NOTFOUND)
- __db_txnlist_add(log->xa_info, txnid);
- err = 0;
- break;
- case DB_txn_xa_regop:
- /*
- * This transaction is commited, so we needn't read
- * the record and do anything.
- */
- if (err == 0)
- break;
- if ((err =
- __txn_xa_regop_read(data.data, &argp)) != 0) {
- ret = XAER_RMERR;
- goto out;
- }
-
- xidp->formatID = argp->formatID;
- xidp->gtrid_length = argp->gtrid;
- xidp->bqual_length = argp->bqual;
- memcpy(xidp->data, argp->xid.data, argp->xid.size);
- ret++;
- xidp++;
- __os_free(argp, sizeof(*argp));
- if (ret == count)
- goto done;
- break;
- }
- }
-
- if (err != 0 && err != DB_NOTFOUND)
- goto out;
-
-done: if (LF_ISSET(TMENDRSCAN)) {
- ZERO_LSN(log->xa_lsn);
- ZERO_LSN(log->xa_first);
-
-out: __db_txnlist_end(log->xa_info);
- log->xa_info = NULL;
- }
- return (ret);
-
-err3: (void)__db_unmap_rmid(rmid);
-err2: (void)db_appexit(env);
-err1: __os_free(env, sizeof(DB_ENV));
- return (XAER_RMERR);
-}
-
-/*
- * __db_xa_rollback
- * Abort an XA transaction.
- */
-static int
-__db_xa_rollback(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- TXN_DETAIL *td;
- size_t off;
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
- if (flags != TMNOFLAGS)
- return (XAER_INVAL);
-
- if (__db_rmid_to_env(rmid, &env, 1) != 0)
- return (XAER_PROTO);
-
- if (__db_xid_to_txn(env, xid, &off) != 0)
- return (XAER_NOTA);
-
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
-
- if (td->xa_status == TXN_XA_DEADLOCKED)
- return (XA_RBDEADLOCK);
-
- if (td->xa_status == TXN_XA_ABORTED)
- return (XA_RBOTHER);
-
- if (LF_SET(TMONEPHASE) &&
- td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
- return (XAER_PROTO);
-
- if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED)
- return (XAER_PROTO);
-
- /* Now, fill in the global transaction structure. */
- __xa_txn_init(env, td, off);
- if (txn_abort(env->xa_txn) != 0)
- return (XAER_RMERR);
-
- /* No fatal value that would require an XAER_RMFAIL. */
- __xa_txn_end(env);
- return (XA_OK);
-}
-
-/*
- * __db_xa_forget --
- * Forget about an XID for a transaction that was heuristically
- * completed. Since we do not heuristically complete anything, I
- * don't think we have to do anything here, but we should make sure
- * that we reclaim the slots in the txnid table.
- */
-static int
-__db_xa_forget(xid, rmid, flags)
- XID *xid;
- int rmid;
- long flags;
-{
- DB_ENV *env;
- size_t off;
-
- if (LF_ISSET(TMASYNC))
- return (XAER_ASYNC);
- if (flags != TMNOFLAGS)
- return (XAER_INVAL);
-
- if (__db_rmid_to_env(rmid, &env, 1) != 0)
- return (XAER_PROTO);
-
- /*
- * If mapping is gone, then we're done.
- */
- if (__db_xid_to_txn(env, xid, &off) != 0)
- return (XA_OK);
-
- __db_unmap_xid(env, xid, off);
-
- /* No fatal value that would require an XAER_RMFAIL. */
- return (XA_OK);
-}
-
-/*
- * __db_xa_complete --
- * Used to wait for asynchronous operations to complete. Since we're
- * not doing asynch, this is an invalid operation.
- */
-static int
-__db_xa_complete(handle, retval, rmid, flags)
- int *handle, *retval, rmid;
- long flags;
-{
- COMPQUIET(handle, NULL);
- COMPQUIET(retval, NULL);
- COMPQUIET(rmid, 0);
- COMPQUIET(flags, 0);
-
- return (XAER_INVAL);
-}
-
-/*
- * __xa_txn_init --
- * Fill in the fields of the local transaction structure given
- * the detail transaction structure.
- */
-static void
-__xa_txn_init(env, td, off)
- DB_ENV *env;
- TXN_DETAIL *td;
- size_t off;
-{
- DB_TXN *txn;
-
- txn = env->xa_txn;
- txn->mgrp = env->tx_info;
- txn->parent = NULL;
- txn->last_lsn = td->last_lsn;
- txn->txnid = td->txnid;
- txn->off = off;
- txn->flags = 0;
-}
-
-/*
- * __xa_txn_end --
- * Invalidate a transaction structure that was generated by xa_txn_init.
- */
-static void
-__xa_txn_end(env)
- DB_ENV *env;
-{
- DB_TXN *txn;
-
- txn = env->xa_txn;
- if (txn != NULL)
- txn->txnid = TXN_INVALID;
-}
-
diff --git a/db2/xa/xa_db.c b/db2/xa/xa_db.c
deleted file mode 100644
index 4aaaeff..0000000
--- a/db2/xa/xa_db.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)xa_db.c 10.6 (Sleepycat) 12/19/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#endif
-
-#undef stat
-
-#include "db_int.h"
-#include "db_page.h"
-#include "xa.h"
-#include "xa_ext.h"
-#include "db_am.h"
-#include "db_ext.h"
-#include "common_ext.h"
-
-static int __xa_c_close __P((DBC *));
-static int __xa_c_del __P((DBC *, u_int32_t));
-static int __xa_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __xa_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __xa_close __P((DB *, u_int32_t));
-static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
-static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t));
-static int __xa_fd __P((DB *, int *));
-static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-static int __xa_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-static int __xa_sync __P((DB *, u_int32_t));
-
-int
-db_xa_open(fname, type, flags, mode, dbinfo, dbpp)
- const char *fname;
- DBTYPE type;
- u_int32_t flags;
- int mode;
- DB_INFO *dbinfo;
- DB **dbpp;
-{
- DB *dbp, *real_dbp;
- DB_ENV *dbenv;
- struct __rmname *rp;
- int ret;
-
- /*
- * First try to open up the underlying DB.
- *
- * !!!
- * The dbenv argument is taken from the global list of environments.
- * When the transaction manager called xa_start() (__db_xa_start()),
- * the "current" DB environment was moved to the start of the list.
- * However, if we were called in a tpsvrinit function (which is
- * entirely plausible), then it's possible that xa_open was called
- * (which simply recorded the name of the environment to open) and
- * this is the next call into DB. In that case, we still have to
- * open the environment.
- *
- * The way that we know that xa_open and nothing else was called
- * is because the nameq is not NULL.
- */
- if ((rp = TAILQ_FIRST(&DB_GLOBAL(db_nameq))) != NULL &&
- (ret = __db_rmid_to_env(rp->rmid, &dbenv, 1)) != 0)
- return (ret);
-
- dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq));
- if ((ret = db_open(fname,
- type, flags, mode, dbenv, dbinfo, &real_dbp)) != 0)
- return (ret);
-
- /*
- * Allocate our own DB handle, and copy the exported fields and
- * function pointers into it. The internal pointer references
- * the real underlying DB handle.
- */
- if ((ret = __os_calloc(1, sizeof(DB), &dbp)) != 0) {
- (void)real_dbp->close(real_dbp, 0);
- return (ret);
- }
- dbp->type = real_dbp->type;
- dbp->byteswapped = real_dbp->byteswapped;
- dbp->dbenv = dbenv;
- dbp->internal = real_dbp;
- TAILQ_INIT(&dbp->active_queue);
- TAILQ_INIT(&dbp->free_queue);
- dbp->close = __xa_close;
- dbp->cursor = __xa_cursor;
- dbp->del = __xa_del;
- dbp->fd = __xa_fd;
- dbp->get = __xa_get;
- dbp->join = real_dbp->join;
- dbp->put = __xa_put;
- dbp->stat = __xa_stat;
- dbp->sync = __xa_sync;
-
- *dbpp = dbp;
- return (0);
-}
-
-static int
-__xa_close(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB *real_dbp;
- DBC *dbc;
- int ret;
-
- /* Close any associated cursors. */
- while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
- (void)dbc->c_close(dbc);
-
- /* Close the DB handle. */
- real_dbp = (DB *)dbp->internal;
- ret = real_dbp->close(real_dbp, flags);
-
- __os_free(dbp, sizeof(DB));
- return (ret);
-}
-
-static int
-__xa_cursor(dbp, txn, dbcp, flags)
- DB *dbp;
- DB_TXN *txn;
- DBC **dbcp;
- u_int32_t flags;
-{
- DB *real_dbp;
- DBC *real_dbc, *dbc;
- int ret;
-
- real_dbp = (DB *)dbp->internal;
- txn = dbp->dbenv->xa_txn;
-
- if ((ret = real_dbp->cursor(real_dbp, txn, &real_dbc, flags)) != 0)
- return (ret);
-
- /*
- * Allocate our own DBC handle, and copy the exported fields and
- * function pointers into it. The internal pointer references
- * the real underlying DBC handle.
- */
- if ((ret = __os_calloc(1, sizeof(DBC), &dbc)) != 0) {
- (void)real_dbc->c_close(real_dbc);
- return (ret);
- }
- dbc->dbp = dbp;
- dbc->c_close = __xa_c_close;
- dbc->c_del = __xa_c_del;
- dbc->c_get = __xa_c_get;
- dbc->c_put = __xa_c_put;
- dbc->internal = real_dbc;
- TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
-
- *dbcp = dbc;
- return (0);
-}
-
-static int
-__xa_fd(dbp, fdp)
- DB *dbp;
- int *fdp;
-{
- DB *real_dbp;
-
- COMPQUIET(fdp, NULL);
-
- real_dbp = (DB *)dbp->internal;
- return (__db_eopnotsup(real_dbp->dbenv));
-}
-
-static int
-__xa_del(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DB *real_dbp;
-
- real_dbp = (DB *)dbp->internal;
- txn = dbp->dbenv->xa_txn;
-
- return (real_dbp->del(real_dbp, txn, key, flags));
-}
-
-static int
-__xa_get(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *real_dbp;
-
- real_dbp = (DB *)dbp->internal;
- txn = dbp->dbenv->xa_txn;
-
- return (real_dbp->get(real_dbp, txn, key, data, flags));
-}
-
-static int
-__xa_put(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *real_dbp;
-
- real_dbp = (DB *)dbp->internal;
- txn = dbp->dbenv->xa_txn;
-
- return (real_dbp->put(real_dbp, txn, key, data, flags));
-}
-
-static int
-__xa_stat(dbp, spp, db_malloc, flags)
- DB *dbp;
- void *spp;
- void *(*db_malloc) __P((size_t));
- u_int32_t flags;
-{
- DB *real_dbp;
-
- real_dbp = (DB *)dbp->internal;
- return (real_dbp->stat(real_dbp, spp, db_malloc, flags));
-}
-
-static int
-__xa_sync(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB *real_dbp;
-
- real_dbp = (DB *)dbp->internal;
- return (real_dbp->sync(real_dbp, flags));
-}
-
-static int
-__xa_c_close(dbc)
- DBC *dbc;
-{
- DBC *real_dbc;
- int ret;
-
- real_dbc = (DBC *)dbc->internal;
-
- ret = real_dbc->c_close(real_dbc);
-
- TAILQ_REMOVE(&dbc->dbp->active_queue, dbc, links);
- __os_free(dbc, sizeof(DBC));
-
- return (ret);
-}
-
-static int
-__xa_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DBC *real_dbc;
-
- real_dbc = (DBC *)dbc->internal;
- return (real_dbc->c_del(real_dbc, flags));
-}
-
-static int
-__xa_c_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DBC *real_dbc;
-
- real_dbc = (DBC *)dbc->internal;
- return (real_dbc->c_get(real_dbc, key, data, flags));
-}
-
-static int
-__xa_c_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DBC *real_dbc;
-
- real_dbc = (DBC *)dbc->internal;
- return (real_dbc->c_put(real_dbc, key, data, flags));
-}
diff --git a/db2/xa/xa_map.c b/db2/xa/xa_map.c
deleted file mode 100644
index d4ebbae..0000000
--- a/db2/xa/xa_map.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)xa_map.c 10.4 (Sleepycat) 10/20/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "txn.h"
-
-/*
- * This file contains all the mapping information that we need to support
- * the DB/XA interface.
- */
-
-/*
- * __db_rmid_to_env
- * Return the environment associated with a given XA rmid.
- *
- * PUBLIC: int __db_rmid_to_env __P((int rmid, DB_ENV **envp, int open_ok));
- */
-int
-__db_rmid_to_env(rmid, envp, open_ok)
- int rmid;
- DB_ENV **envp;
- int open_ok;
-{
- DB_ENV *env;
- char *dbhome;
-
- env = TAILQ_FIRST(&DB_GLOBAL(db_envq));
- if (env != NULL && env->xa_rmid == rmid) {
- *envp = env;
- return (0);
- }
-
- /*
- * When we map an rmid, move that environment to be the first one in
- * the list of environments, so we pass the correct environment from
- * the upcoming db_xa_open() call into db_open().
- */
- for (; env != NULL; env = TAILQ_NEXT(env, links))
- if (env->xa_rmid == rmid) {
- TAILQ_REMOVE(&DB_GLOBAL(db_envq), env, links);
- TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), env, links);
- *envp = env;
- return (0);
- }
-
- /*
- * We have not found the rmid on the environment list. If we
- * are allowed to do an open, search for the rmid on the name
- * list and, if we find it, then open it.
- */
- if (!open_ok)
- return (1);
-
- if (__db_rmid_to_name(rmid, &dbhome) != 0)
- return (1);
-#undef XA_FLAGS
-#define XA_FLAGS \
- DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN
-
- if (__os_calloc(1, sizeof(DB_ENV), &env) != 0)
- return (1);
-
- if (db_appinit(dbhome, NULL, env, XA_FLAGS) != 0)
- goto err;
-
- if (__db_map_rmid(rmid, env) != 0)
- goto err1;
-
- __db_unmap_rmid_name(rmid);
-
- *envp = env;
- return (0);
-
-err1: (void)db_appexit(env);
-err: __os_free(env, sizeof(DB_ENV));
- return (1);
-}
-
-/*
- * __db_xid_to_txn
- * Return the txn that corresponds to this XID.
- *
- * PUBLIC: int __db_xid_to_txn __P((DB_ENV *, XID *, size_t *));
- */
-int
-__db_xid_to_txn(dbenv, xid, offp)
- DB_ENV *dbenv;
- XID *xid;
- size_t *offp;
-{
- DB_TXNREGION *tmr;
- struct __txn_detail *td;
-
- /*
- * Search the internal active transaction table to find the
- * matching xid. If this is a performance hit, then we
- * can create a hash table, but I doubt it's worth it.
- */
- tmr = dbenv->tx_info->region;
-
- LOCK_TXNREGION(dbenv->tx_info);
- for (td = SH_TAILQ_FIRST(&tmr->active_txn, __txn_detail);
- td != NULL;
- td = SH_TAILQ_NEXT(td, links, __txn_detail))
- if (memcmp(xid->data, td->xid, XIDDATASIZE) == 0)
- break;
- UNLOCK_TXNREGION(dbenv->tx_info);
-
- if (td == NULL)
- return (EINVAL);
-
- *offp = (u_int8_t *)td - (u_int8_t *)tmr;
- return (0);
-}
-
-/*
- * __db_map_rmid
- * Create a mapping between the specified rmid and environment.
- *
- * PUBLIC: int __db_map_rmid __P((int, DB_ENV *));
- */
-int
-__db_map_rmid(rmid, env)
- int rmid;
- DB_ENV *env;
-{
- if (__os_calloc(1, sizeof(DB_TXN), &env->xa_txn) != 0)
- return (XAER_RMERR);
- env->xa_txn->txnid = TXN_INVALID;
- env->xa_rmid = rmid;
- TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), env, links);
- return (XA_OK);
-}
-
-/*
- * __db_unmap_rmid
- * Destroy the mapping for the given rmid.
- *
- * PUBLIC: int __db_unmap_rmid __P((int));
- */
-int
-__db_unmap_rmid(rmid)
- int rmid;
-{
- DB_ENV *e;
-
- for (e = TAILQ_FIRST(&DB_GLOBAL(db_envq));
- e->xa_rmid != rmid;
- e = TAILQ_NEXT(e, links));
-
- if (e == NULL)
- return (EINVAL);
-
- TAILQ_REMOVE(&DB_GLOBAL(db_envq), e, links);
- if (e->xa_txn != NULL)
- __os_free(e->xa_txn, sizeof(DB_TXN));
- return (0);
-}
-
-/*
- * __db_map_xid
- * Create a mapping between this XID and the transaction at
- * "off" in the shared region.
- *
- * PUBLIC: int __db_map_xid __P((DB_ENV *, XID *, size_t));
- */
-int
-__db_map_xid(env, xid, off)
- DB_ENV *env;
- XID *xid;
- size_t off;
-{
- DB_TXNMGR *tm;
- TXN_DETAIL *td;
-
- tm = env->tx_info;
- td = (TXN_DETAIL *)((u_int8_t *)tm->region + off);
-
- LOCK_TXNREGION(tm);
- memcpy(td->xid, xid->data, XIDDATASIZE);
- UNLOCK_TXNREGION(tm);
-
- return (0);
-}
-
-/*
- * __db_unmap_xid
- * Destroy the mapping for the specified XID.
- *
- * PUBLIC: void __db_unmap_xid __P((DB_ENV *, XID *, size_t));
- */
-
-void
-__db_unmap_xid(env, xid, off)
- DB_ENV *env;
- XID *xid;
- size_t off;
-{
- TXN_DETAIL *td;
-
- COMPQUIET(xid, NULL);
-
- td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
- memset(td->xid, 0, sizeof(td->xid));
-}
-
-/*
- * __db_map_rmid_name --
- * Create a mapping from an rmid to a name (the xa_info argument).
- * We use this during create and then at some later point when we are
- * trying to map an rmid, we might indicate that it's OK to do an open
- * in which case, we'll get the xa_info parameter from here and then
- * free it up.
- *
- * PUBLIC: int __db_map_rmid_name __P((int, char *));
- */
-
-int
-__db_map_rmid_name(rmid, dbhome)
- int rmid;
- char *dbhome;
-{
- struct __rmname *entry;
- int ret;
-
- if ((ret = __os_malloc(sizeof(struct __rmname), NULL, &entry)) != 0)
- return (ret);
-
- if ((ret = __os_strdup(dbhome, &entry->dbhome)) != 0) {
- __os_free(entry, sizeof(struct __rmname));
- return (ret);
- }
-
- entry->rmid = rmid;
-
- TAILQ_INSERT_HEAD(&DB_GLOBAL(db_nameq), entry, links);
- return (0);
-}
-
-/*
- * __db_rmid_to_name --
- * Given an rmid, return the name of the home directory for that
- * rmid.
- *
- * PUBLIC: int __db_rmid_to_name __P((int, char **));
- */
-int
-__db_rmid_to_name(rmid, dbhomep)
- int rmid;
- char **dbhomep;
-{
- struct __rmname *np;
-
- for (np = TAILQ_FIRST(&DB_GLOBAL(db_nameq)); np != NULL;
- np = TAILQ_NEXT(np, links)) {
- if (np->rmid == rmid) {
- *dbhomep = np->dbhome;
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * __db_unmap_rmid_name --
- * Given an rmid, remove its entry from the name list.
- *
- * PUBLIC: void __db_unmap_rmid_name __P((int));
- */
-void
-__db_unmap_rmid_name(rmid)
- int rmid;
-{
- struct __rmname *np, *next;
-
- for (np = TAILQ_FIRST(&DB_GLOBAL(db_nameq)); np != NULL; np = next) {
- next = TAILQ_NEXT(np, links);
- if (np->rmid == rmid) {
- TAILQ_REMOVE(&DB_GLOBAL(db_nameq), np, links);
- __os_freestr(np->dbhome);
- __os_free(np, sizeof(struct __rmname));
- return;
- }
- }
- return;
-}