mirror of
git://sourceware.org/git/glibc.git
synced 2025-03-31 14:01:18 +08:00
Update.
1997-11-11 21:30 Ulrich Drepper <drepper@cygnus.com> * include/sys/stat.h: Define stat, fstat, lstat and *64 variants as macros so the the library compiles correctly even without optimization. * io/fstat.c: Undef fstat. * io/fstat64.c: Undef fstat64 * io/lstat.c: Undef lstat. * io/lstat64.c: Undef lstat64 * io/stat.c: Undef stat. * io/stat64.c: Undef stat64 * io/fts.c: Include <include/sys/stat.h> to get macro definitions. * io/ftw.c: Likewise. * io/getdirname.c: Likewise. * Makefile (install): Run test-installation.pl if possible. * db2/Makefile: Update from db-2.3.12. * db2/db.h: Likewise. * db2/db_int.h: Likewise. * db2/btree/bt_cursor.c: Likewise. * db2/btree/bt_delete.c: Likewise. * db2/btree/bt_open.c: Likewise. * db2/btree/bt_put.c: Likewise. * db2/btree/bt_rec.c: Likewise. * db2/btree/bt_recno.c: Likewise. * db2/btree/bt_search.c: Likewise. * db2/btree/bt_split.c: Likewise. * db2/btree/bt_stat.c: Likewise. * db2/btree/btree.src: Likewise. * db2/btree/btree_auto.c: Likewise. * db2/btree/bt_cursor.c: Likewise. * db2/btree/bt_delete.c: Likewise. * db2/btree/bt_open.c: Likewise. * db2/btree/bt_put.c: Likewise. * db2/btree/bt_rec.c: Likewise. * db2/btree/bt_recno.c: Likewise. * db2/btree/bt_search.c: Likewise. * db2/btree/bt_split.c: Likewise. * db2/btree/bt_stat.c: Likewise. * db2/btree/btree.src: Likewise. * db2/btree/btree_auto.c: Likewise. * db2/common/db_appinit.c: Likewise. * db2/common/db_apprec.c: Likewise. * db2/common/db_byteorder.c: Likewise. * db2/common/db_region.c: Likewise. * db2/db/db.c: Likewise * db2/db/db.src: Likewise * db2/db/db_auto.c: Likewise * db2/db/db_dispatch.c: Likewise * db2/db/db_dup.c: Likewise * db2/db/db_overflow.c: Likewise * db2/db/db_pr.c: Likewise * db2/db/db_rec.c: Likewise * db2/db/db_ret.c: Likewise * db2/db/db_thread.c: Likewise * db2/db185/db185.c: Likewise. * db2/hash/hash.c: Likewise. * db2/hash/hash.src: Likewise. * db2/hash/hash_auto.c: Likewise. * db2/hash/hash_dup.c: Likewise. * db2/hash/hash_page.c: Likewise. * db2/hash/hash_rec.c: Likewise. * db2/include/btree_auto.h: Likewise. * db2/include/btree_ext.h: Likewise. * db2/include/clib_ext.h: Likewise. * db2/include/common_ext.h: Likewise. * db2/include/db.h.src: Likewise. * db2/include/db_am.h: Likewise. * db2/include/db_auto.h: Likewise. * db2/include/db_cxx.h: Likewise. * db2/include/db_ext.h: Likewise. * db2/include/db_int.h.src: Likewise. * db2/include/hash.h: Likewise. * db2/include/hash_auto.h: Likewise. * db2/include/hash_ext.h: Likewise. * db2/include/lock.h: Likewise. * db2/include/lock_ext.h: Likewise. * db2/include/log.h: Likewise. * db2/include/log_ext.h: Likewise. * db2/include/mp.h: Likewise. * db2/include/mp_ext.h: Likewise. * db2/include/mutex_ext.h: Likewise. * db2/include/os_ext.h: Likewise. * db2/include/os_func.h: Likewise. * db2/include/txn.h: Likewise. * db2/include/txn_ext.h: Likewise. * db2/lock/lock.c: Likewise. * db2/lock/lock_deadlock.c: Likewise. * db2/log/log.c: Likewise. * db2/log/log_archive.c: Likewise. * db2/log/log_auto.c: Likewise. * db2/log/log_findckp.c: Likewise. * db2/log/log_get.c: Likewise. * db2/log/log_put.c: Likewise. * db2/log/log_rec.c: Likewise. * db2/log/log_register.c: Likewise. * db2/mp/mp_bh.c: Likewise. * db2/mp/mp_fget.c: Likewise. * db2/mp/mp_fopen.c: Likewise. * db2/mp/mp_fput.c: Likewise. * db2/mp/mp_fset.c: Likewise. * db2/mp/mp_open.c: Likewise. * db2/mp/mp_pr.c: Likewise. * db2/mp/mp_region.c: Likewise. * db2/mp/mp_sync.c: Likewise. * db2/mutex/mutex.c: Likewise. * db2/os/os_abs.c: Likewise. * db2/os/os_dir.c: Likewise. * db2/os/os_fid.c: Likewise. * db2/os/os_fsync.c: Likewise. * db2/os/os_func.c: Likewise. * db2/os/os_map.c: Likewise. * db2/os/os_oflags.c: Likewise. * db2/os/os_open.c: Likewise. * db2/os/os_rpath.c: Likewise. * db2/os/os_rw.c: Likewise. * db2/os/os_seek.c: Likewise. * db2/os/os_sleep.c: Likewise. * db2/os/os_stat.c: Likewise. * db2/os/os_unlink.c: Likewise. * db2/progs/db_deadlock/db_deadlock.c: Likewise. * db2/progs/db_dump/db_dump.c: Likewise. * db2/progs/db_load/db_load.c: Likewise. * db2/progs/db_recover/db_recover.c: Likewise. * db2/progs/db_stat/db_stat.c: Likewise. * db2/txn/txn.c: Likewise. * db2/txn/txn_auto.c: Likewise. * db2/txn/txn_rec.c: Likewise. * db2/os/db_os_abs.c: Removed. * db2/os/db_os_dir.c: Removed. * db2/os/db_os_fid.c: Removed. * db2/os/db_os_lseek.c: Removed. * db2/os/db_os_mmap.c: Removed. * db2/os/db_os_open.c: Removed. * db2/os/db_os_rw.c: Removed. * db2/os/db_os_sleep.c: Removed. * db2/os/db_os_stat.c: Removed. * db2/os/db_os_unlink.c: Removed. * libio/stdio.h (fopen): Add __restrict to parameters. * manual/process.texi (system): Describe behaviour for NULL argument. * stdio-common/printf-parse.h: Parse hh modifier. * stdio-common/vfprintf.c: Handle hh modifier. * stdio-common/vfscanf.c: Likewise. * manual/stdio.texi: Describe hh modifier for scanf/printf. * math/complex.h: Don't define _Imaginary_I, but instead _Complex_I. gcc does no yet know the `imaginary' keyword. * math/test-math.c: Add little test for know gcc bug. * math/tgmath.h: Make complex versions of log10() only available if __USE_GNU. * stdlib/test-canon.c: Fix typo. * sysdeps/generic/setenv.c: Avoid compilation warnings. Reported by Jim Meyering. * sysdeps/generic/bits/errno.h: EILSEQ is an ISO C error number. * sysdeps/mach/hurd/bits/errno.h: Likewise. * sysdeps/standalone/bits/errno.h: Likewise. * sysdeps/unix/sysv/linux/bits/errno.h: Likewise. * sysdeps/i386/i586/memcpy.S: New file. * sysdeps/i386/i586/mempcpy.S: New file. * sysdeps/i386/i586/memset.S: Fix typo. * sysdeps/posix/getcwd.c: Define HAVE_MEMPCPY for _LIBC. Add casts. * sysdeps/posix/system.c: Add comment to explain code. * sysdeps/wordsize-32/inttypes.h: Include <stddef.h> for wchar_t. Define PTRDIFF_{MIN,MAX}, SIG_ATOMIC_{MIN,MAX}, SIZE_MAX, WCHAR_{MIN,MAX}, WINT_{MIN,MAX}. Define wcstoimax, wcstoumax. * sysdeps/wordsize-64/inttypes.h: Likewise. * wcsmbs/wchar.h: Define WCHAR_{MIN,MAX} if not already defined. Declare __wcsto{l,ul,ll,ull}_internal only if not already done. * time/Makefile (routines): Add strfxtime. * time/strftime.c: Implement %F and %f format. * time/strfxtime.c: New file. * time/time.h: Define new types and symbols from ISO C 9X. * time/mktime.c: Little comment correction. 1997-11-10 Andreas Jaeger <aj@arthur.rhein-neckar.de> * sysdeps/libm-ieee754/s_sincosl.c: Fix typo. * sysdeps/libm-ieee754/s_tanl.c: Fix typo. * sysdeps/libm-ieee754/s_floorl.c: Correct typos. * sysdeps/libm-ieee754/e_remainderl.c: Replace EXTRACT_LDOUBLE_WORDS by GET_LDOUBLE_WORDS. * sysdeps/libm-ieee754/e_atan2l.c: Replace EXTRACT_LDOUBLE_WORDS by GET_LDOUBLE_WORDS. * sysdeps/libm-ieee754/s_scalbnl.c: Replace ";" by "," for correct variable declaration. * sysdeps/libm-ieee754/s_scalblnl.c: Likewise. * sysdeps/libm-ieee754/s_lrint.c (__lrint): Correct function. * math/libm-test.c (sqrt_test): Add test for sqrt (0.25). (asin_test): Add more test. 1997-11-10 23:34 Ulrich Drepper <drepper@cygnus.com> * sysdeps/libm-ieee754/e_asin.c: Add braces to make code clearer and to not confuse the poor compiler. * sysdeps/libm-ieee754/e_asinf.c: Likewise. Reported by vertex@cagent.com. 1997-11-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * elf/dl-lookup.c (do_lookup): Don't accept the base version if we require a specific one. * libio/oldfreopen.c: Bind old symbols to version GLIBC_2.0. * libio/oldiofopen.c: Likewise. * libio/oldstdfiles.c: Likewise. * libc.map: Export them. 1997-11-10 07:40 H.J. Lu <hjl@gnu.ai.mit.edu> * stdlib/exit.c (exit): Handle recursive calls to exit (). 1997-11-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/s_llrint.c: Fixed to take double argument instead of long double. * sysdeps/m68k/fpu/s_llrintf.c: New file. * sysdeps/m68k/fpu/s_llrintl.c: New file. * sysdeps/libm-ieee754/s_llrint.c: Make compilable and fix overflow condition. * sysdeps/libm-ieee754/s_llrintf.c: Fix overflow condition. * sysdeps/libm-ieee754/s_llrintl.c: Likewise. * sysdeps/libm-ieee754/s_llround.c: Likewise. * sysdeps/libm-ieee754/s_llroundf.c: Likewise. * sysdeps/libm-ieee754/s_llroundl.c: Likewise. * sysdeps/libm-ieee754/s_lrint.c: Likewise. * sysdeps/libm-ieee754/s_lrintf.c: Likewise. * sysdeps/libm-ieee754/s_lrintl.c: Likewise. * sysdeps/libm-ieee754/s_lround.c: Likewise. * sysdeps/libm-ieee754/s_lroundf.c: Likewise. * sysdeps/libm-ieee754/s_lroundl.c: Likewise. * math/libm-test.c: Test all three variants of lrint and llrint. Fix typos in lround and llround tests. Add tests for boundary cases for lrint and llround. 1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * manual/arith.texi: Misc doc fixes. * manual/ctype.texi: Likewise. * manual/pattern.texi: Likewise. * manual/terminal.texi: Likewise. 1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/xstatconv.c: Use struct assignment instead of memcpy to let the compiler use whatever it regards as optimal. * sysdeps/unix/sysv/linux/alpha/xstatconv.c: Likewise. 1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/Makefile (sysdep_headers) [$(subdir)=misc]: Add sys/prctl.h. * sysdeps/unix/sysv/linux/Dist: Distribute it. 1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * io/ftwtest-sh: Don't use the unknown which command, instead try pwd as /bin/pwd and /usr/bin/pwd. 1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * manual/maint.texi (Tools for Installation): Don't recommend broken version 3.76.1 of make. (Porting): Fix wording. 1997-11-06 06:13 H.J. Lu <hjl@gnu.ai.mit.edu> * config.make.in (build-pic-default): New, defined with pic_default. * configure.in (pic_default): New, set to yes if PIC is default. * Makeconfig (CPPFLAGS-.o, CPPFLAGS-.op, CPPFLAGS-.og, CPPFLAGS-.ob): Add -DPIC if $(build-pic-default) is yes. 1997-11-09 18:15 Ulrich Drepper <drepper@cygnus.com> * Makerules (libc.so): Fix typo. * csu/Makefile (CFLAGS-initfini.s): Correctly fix moving function definition. Patch by Zack Weinberg <zack@rabi.phys.columbia.edu>. * stdlib/strtod.c: Handle numbers like 0.0e10000 correctly which produce 0.0. Reported by Joe Keane <jgk@jgk.org>. * sysdeps/libm-ieee754/s_ceill.c: Fix typos. * sysdeps/libm-ieee754/s_llrint.c: Correct code, it never worked. 1997-11-06 07:00 H.J. Lu <hjl@gnu.ai.mit.edu> * sysdeps/unix/sysv/i386/i686/time.S: Removed. 1997-11-08 14:07 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * nis/libnsl.map: Add __do_niscall2 for nis_cachemgr. * nis/nis_call.c: Set UDP resend timeout correct. * nis/nss_compat/compat-grp.c: Rewritten to make it faster. * nis/nss_compat/compat-pwd.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise. * nis/ypclnt.c: Fix UDP resend timeout, fix yp_bind/do_ypcall interaction. * inet/protocols/routed.h: Include sys/socket.h. * inet/protocols/talkd.h: Likewise. * inet/protocols/timed.h: Include rpc/types.h. * sunrpc/rpc/pmap_clnt.h: Include rpc/clnt.h. 1997-11-06 01:39 Ulrich Drepper <drepper@cygnus.com> * Makerules (libc.so): Add missing closing brace. 1997-11-05 Brendan Kehoe <brendan@lisa.cygnus.com> * libio.h (__P): Name its arg `p' instead of `params'. This was added solely to work around problems with the definition of __P in the Solaris math.h header.
This commit is contained in:
parent
86187531d3
commit
cc3fa75512
347
ChangeLog
347
ChangeLog
@ -1,3 +1,350 @@
|
||||
1997-11-11 21:30 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* include/sys/stat.h: Define stat, fstat, lstat and *64 variants
|
||||
as macros so the the library compiles correctly even without
|
||||
optimization.
|
||||
* io/fstat.c: Undef fstat.
|
||||
* io/fstat64.c: Undef fstat64
|
||||
* io/lstat.c: Undef lstat.
|
||||
* io/lstat64.c: Undef lstat64
|
||||
* io/stat.c: Undef stat.
|
||||
* io/stat64.c: Undef stat64
|
||||
* io/fts.c: Include <include/sys/stat.h> to get macro definitions.
|
||||
* io/ftw.c: Likewise.
|
||||
* io/getdirname.c: Likewise.
|
||||
|
||||
* Makefile (install): Run test-installation.pl if possible.
|
||||
|
||||
* db2/Makefile: Update from db-2.3.12.
|
||||
* db2/db.h: Likewise.
|
||||
* db2/db_int.h: Likewise.
|
||||
* db2/btree/bt_cursor.c: Likewise.
|
||||
* db2/btree/bt_delete.c: Likewise.
|
||||
* db2/btree/bt_open.c: Likewise.
|
||||
* db2/btree/bt_put.c: Likewise.
|
||||
* db2/btree/bt_rec.c: Likewise.
|
||||
* db2/btree/bt_recno.c: Likewise.
|
||||
* db2/btree/bt_search.c: Likewise.
|
||||
* db2/btree/bt_split.c: Likewise.
|
||||
* db2/btree/bt_stat.c: Likewise.
|
||||
* db2/btree/btree.src: Likewise.
|
||||
* db2/btree/btree_auto.c: Likewise.
|
||||
* db2/btree/bt_cursor.c: Likewise.
|
||||
* db2/btree/bt_delete.c: Likewise.
|
||||
* db2/btree/bt_open.c: Likewise.
|
||||
* db2/btree/bt_put.c: Likewise.
|
||||
* db2/btree/bt_rec.c: Likewise.
|
||||
* db2/btree/bt_recno.c: Likewise.
|
||||
* db2/btree/bt_search.c: Likewise.
|
||||
* db2/btree/bt_split.c: Likewise.
|
||||
* db2/btree/bt_stat.c: Likewise.
|
||||
* db2/btree/btree.src: Likewise.
|
||||
* db2/btree/btree_auto.c: Likewise.
|
||||
* db2/common/db_appinit.c: Likewise.
|
||||
* db2/common/db_apprec.c: Likewise.
|
||||
* db2/common/db_byteorder.c: Likewise.
|
||||
* db2/common/db_region.c: Likewise.
|
||||
* db2/db/db.c: Likewise
|
||||
* db2/db/db.src: Likewise
|
||||
* db2/db/db_auto.c: Likewise
|
||||
* db2/db/db_dispatch.c: Likewise
|
||||
* db2/db/db_dup.c: Likewise
|
||||
* db2/db/db_overflow.c: Likewise
|
||||
* db2/db/db_pr.c: Likewise
|
||||
* db2/db/db_rec.c: Likewise
|
||||
* db2/db/db_ret.c: Likewise
|
||||
* db2/db/db_thread.c: Likewise
|
||||
* db2/db185/db185.c: Likewise.
|
||||
* db2/hash/hash.c: Likewise.
|
||||
* db2/hash/hash.src: Likewise.
|
||||
* db2/hash/hash_auto.c: Likewise.
|
||||
* db2/hash/hash_dup.c: Likewise.
|
||||
* db2/hash/hash_page.c: Likewise.
|
||||
* db2/hash/hash_rec.c: Likewise.
|
||||
* db2/include/btree_auto.h: Likewise.
|
||||
* db2/include/btree_ext.h: Likewise.
|
||||
* db2/include/clib_ext.h: Likewise.
|
||||
* db2/include/common_ext.h: Likewise.
|
||||
* db2/include/db.h.src: Likewise.
|
||||
* db2/include/db_am.h: Likewise.
|
||||
* db2/include/db_auto.h: Likewise.
|
||||
* db2/include/db_cxx.h: Likewise.
|
||||
* db2/include/db_ext.h: Likewise.
|
||||
* db2/include/db_int.h.src: Likewise.
|
||||
* db2/include/hash.h: Likewise.
|
||||
* db2/include/hash_auto.h: Likewise.
|
||||
* db2/include/hash_ext.h: Likewise.
|
||||
* db2/include/lock.h: Likewise.
|
||||
* db2/include/lock_ext.h: Likewise.
|
||||
* db2/include/log.h: Likewise.
|
||||
* db2/include/log_ext.h: Likewise.
|
||||
* db2/include/mp.h: Likewise.
|
||||
* db2/include/mp_ext.h: Likewise.
|
||||
* db2/include/mutex_ext.h: Likewise.
|
||||
* db2/include/os_ext.h: Likewise.
|
||||
* db2/include/os_func.h: Likewise.
|
||||
* db2/include/txn.h: Likewise.
|
||||
* db2/include/txn_ext.h: Likewise.
|
||||
* db2/lock/lock.c: Likewise.
|
||||
* db2/lock/lock_deadlock.c: Likewise.
|
||||
* db2/log/log.c: Likewise.
|
||||
* db2/log/log_archive.c: Likewise.
|
||||
* db2/log/log_auto.c: Likewise.
|
||||
* db2/log/log_findckp.c: Likewise.
|
||||
* db2/log/log_get.c: Likewise.
|
||||
* db2/log/log_put.c: Likewise.
|
||||
* db2/log/log_rec.c: Likewise.
|
||||
* db2/log/log_register.c: Likewise.
|
||||
* db2/mp/mp_bh.c: Likewise.
|
||||
* db2/mp/mp_fget.c: Likewise.
|
||||
* db2/mp/mp_fopen.c: Likewise.
|
||||
* db2/mp/mp_fput.c: Likewise.
|
||||
* db2/mp/mp_fset.c: Likewise.
|
||||
* db2/mp/mp_open.c: Likewise.
|
||||
* db2/mp/mp_pr.c: Likewise.
|
||||
* db2/mp/mp_region.c: Likewise.
|
||||
* db2/mp/mp_sync.c: Likewise.
|
||||
* db2/mutex/mutex.c: Likewise.
|
||||
* db2/os/os_abs.c: Likewise.
|
||||
* db2/os/os_dir.c: Likewise.
|
||||
* db2/os/os_fid.c: Likewise.
|
||||
* db2/os/os_fsync.c: Likewise.
|
||||
* db2/os/os_func.c: Likewise.
|
||||
* db2/os/os_map.c: Likewise.
|
||||
* db2/os/os_oflags.c: Likewise.
|
||||
* db2/os/os_open.c: Likewise.
|
||||
* db2/os/os_rpath.c: Likewise.
|
||||
* db2/os/os_rw.c: Likewise.
|
||||
* db2/os/os_seek.c: Likewise.
|
||||
* db2/os/os_sleep.c: Likewise.
|
||||
* db2/os/os_stat.c: Likewise.
|
||||
* db2/os/os_unlink.c: Likewise.
|
||||
* db2/progs/db_deadlock/db_deadlock.c: Likewise.
|
||||
* db2/progs/db_dump/db_dump.c: Likewise.
|
||||
* db2/progs/db_load/db_load.c: Likewise.
|
||||
* db2/progs/db_recover/db_recover.c: Likewise.
|
||||
* db2/progs/db_stat/db_stat.c: Likewise.
|
||||
* db2/txn/txn.c: Likewise.
|
||||
* db2/txn/txn_auto.c: Likewise.
|
||||
* db2/txn/txn_rec.c: Likewise.
|
||||
* db2/os/db_os_abs.c: Removed.
|
||||
* db2/os/db_os_dir.c: Removed.
|
||||
* db2/os/db_os_fid.c: Removed.
|
||||
* db2/os/db_os_lseek.c: Removed.
|
||||
* db2/os/db_os_mmap.c: Removed.
|
||||
* db2/os/db_os_open.c: Removed.
|
||||
* db2/os/db_os_rw.c: Removed.
|
||||
* db2/os/db_os_sleep.c: Removed.
|
||||
* db2/os/db_os_stat.c: Removed.
|
||||
* db2/os/db_os_unlink.c: Removed.
|
||||
|
||||
* libio/stdio.h (fopen): Add __restrict to parameters.
|
||||
|
||||
* manual/process.texi (system): Describe behaviour for NULL argument.
|
||||
|
||||
* stdio-common/printf-parse.h: Parse hh modifier.
|
||||
* stdio-common/vfprintf.c: Handle hh modifier.
|
||||
* stdio-common/vfscanf.c: Likewise.
|
||||
* manual/stdio.texi: Describe hh modifier for scanf/printf.
|
||||
|
||||
* math/complex.h: Don't define _Imaginary_I, but instead _Complex_I.
|
||||
gcc does no yet know the `imaginary' keyword.
|
||||
|
||||
* math/test-math.c: Add little test for know gcc bug.
|
||||
|
||||
* math/tgmath.h: Make complex versions of log10() only available
|
||||
if __USE_GNU.
|
||||
|
||||
* stdlib/test-canon.c: Fix typo.
|
||||
|
||||
* sysdeps/generic/setenv.c: Avoid compilation warnings.
|
||||
Reported by Jim Meyering.
|
||||
|
||||
* sysdeps/generic/bits/errno.h: EILSEQ is an ISO C error number.
|
||||
* sysdeps/mach/hurd/bits/errno.h: Likewise.
|
||||
* sysdeps/standalone/bits/errno.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/bits/errno.h: Likewise.
|
||||
|
||||
* sysdeps/i386/i586/memcpy.S: New file.
|
||||
* sysdeps/i386/i586/mempcpy.S: New file.
|
||||
|
||||
* sysdeps/i386/i586/memset.S: Fix typo.
|
||||
|
||||
* sysdeps/posix/getcwd.c: Define HAVE_MEMPCPY for _LIBC. Add casts.
|
||||
|
||||
* sysdeps/posix/system.c: Add comment to explain code.
|
||||
|
||||
* sysdeps/wordsize-32/inttypes.h: Include <stddef.h> for wchar_t.
|
||||
Define PTRDIFF_{MIN,MAX}, SIG_ATOMIC_{MIN,MAX}, SIZE_MAX,
|
||||
WCHAR_{MIN,MAX}, WINT_{MIN,MAX}.
|
||||
Define wcstoimax, wcstoumax.
|
||||
* sysdeps/wordsize-64/inttypes.h: Likewise.
|
||||
|
||||
* wcsmbs/wchar.h: Define WCHAR_{MIN,MAX} if not already defined.
|
||||
Declare __wcsto{l,ul,ll,ull}_internal only if not already done.
|
||||
|
||||
* time/Makefile (routines): Add strfxtime.
|
||||
* time/strftime.c: Implement %F and %f format.
|
||||
* time/strfxtime.c: New file.
|
||||
* time/time.h: Define new types and symbols from ISO C 9X.
|
||||
|
||||
* time/mktime.c: Little comment correction.
|
||||
|
||||
1997-11-10 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
|
||||
* sysdeps/libm-ieee754/s_sincosl.c: Fix typo.
|
||||
|
||||
* sysdeps/libm-ieee754/s_tanl.c: Fix typo.
|
||||
|
||||
* sysdeps/libm-ieee754/s_floorl.c: Correct typos.
|
||||
|
||||
* sysdeps/libm-ieee754/e_remainderl.c: Replace
|
||||
EXTRACT_LDOUBLE_WORDS by GET_LDOUBLE_WORDS.
|
||||
|
||||
* sysdeps/libm-ieee754/e_atan2l.c: Replace EXTRACT_LDOUBLE_WORDS
|
||||
by GET_LDOUBLE_WORDS.
|
||||
|
||||
* sysdeps/libm-ieee754/s_scalbnl.c: Replace ";" by "," for correct
|
||||
variable declaration.
|
||||
* sysdeps/libm-ieee754/s_scalblnl.c: Likewise.
|
||||
|
||||
* sysdeps/libm-ieee754/s_lrint.c (__lrint): Correct function.
|
||||
|
||||
* math/libm-test.c (sqrt_test): Add test for sqrt (0.25).
|
||||
(asin_test): Add more test.
|
||||
|
||||
1997-11-10 23:34 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sysdeps/libm-ieee754/e_asin.c: Add braces to make code clearer
|
||||
and to not confuse the poor compiler.
|
||||
* sysdeps/libm-ieee754/e_asinf.c: Likewise.
|
||||
Reported by vertex@cagent.com.
|
||||
|
||||
1997-11-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* elf/dl-lookup.c (do_lookup): Don't accept the base version if we
|
||||
require a specific one.
|
||||
|
||||
* libio/oldfreopen.c: Bind old symbols to version GLIBC_2.0.
|
||||
* libio/oldiofopen.c: Likewise.
|
||||
* libio/oldstdfiles.c: Likewise.
|
||||
* libc.map: Export them.
|
||||
|
||||
1997-11-10 07:40 H.J. Lu <hjl@gnu.ai.mit.edu>
|
||||
|
||||
* stdlib/exit.c (exit): Handle recursive calls to exit ().
|
||||
|
||||
1997-11-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/m68k/fpu/s_llrint.c: Fixed to take double argument
|
||||
instead of long double.
|
||||
* sysdeps/m68k/fpu/s_llrintf.c: New file.
|
||||
* sysdeps/m68k/fpu/s_llrintl.c: New file.
|
||||
|
||||
* sysdeps/libm-ieee754/s_llrint.c: Make compilable and fix
|
||||
overflow condition.
|
||||
* sysdeps/libm-ieee754/s_llrintf.c: Fix overflow condition.
|
||||
* sysdeps/libm-ieee754/s_llrintl.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_llround.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_llroundf.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_llroundl.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lrint.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lrintf.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lrintl.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lround.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lroundf.c: Likewise.
|
||||
* sysdeps/libm-ieee754/s_lroundl.c: Likewise.
|
||||
|
||||
* math/libm-test.c: Test all three variants of lrint and llrint.
|
||||
Fix typos in lround and llround tests. Add tests for boundary
|
||||
cases for lrint and llround.
|
||||
|
||||
1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* manual/arith.texi: Misc doc fixes.
|
||||
* manual/ctype.texi: Likewise.
|
||||
* manual/pattern.texi: Likewise.
|
||||
* manual/terminal.texi: Likewise.
|
||||
|
||||
1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/xstatconv.c: Use struct assignment
|
||||
instead of memcpy to let the compiler use whatever it regards as
|
||||
optimal.
|
||||
* sysdeps/unix/sysv/linux/alpha/xstatconv.c: Likewise.
|
||||
|
||||
1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers)
|
||||
[$(subdir)=misc]: Add sys/prctl.h.
|
||||
* sysdeps/unix/sysv/linux/Dist: Distribute it.
|
||||
|
||||
1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* io/ftwtest-sh: Don't use the unknown which command, instead try
|
||||
pwd as /bin/pwd and /usr/bin/pwd.
|
||||
|
||||
1997-11-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* manual/maint.texi (Tools for Installation): Don't recommend
|
||||
broken version 3.76.1 of make.
|
||||
(Porting): Fix wording.
|
||||
|
||||
1997-11-06 06:13 H.J. Lu <hjl@gnu.ai.mit.edu>
|
||||
|
||||
* config.make.in (build-pic-default): New, defined with
|
||||
pic_default.
|
||||
|
||||
* configure.in (pic_default): New, set to yes if PIC is
|
||||
default.
|
||||
|
||||
* Makeconfig (CPPFLAGS-.o, CPPFLAGS-.op, CPPFLAGS-.og,
|
||||
CPPFLAGS-.ob): Add -DPIC if $(build-pic-default) is yes.
|
||||
|
||||
1997-11-09 18:15 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* Makerules (libc.so): Fix typo.
|
||||
|
||||
* csu/Makefile (CFLAGS-initfini.s): Correctly fix moving function
|
||||
definition. Patch by Zack Weinberg <zack@rabi.phys.columbia.edu>.
|
||||
|
||||
* stdlib/strtod.c: Handle numbers like 0.0e10000 correctly which
|
||||
produce ±0.0. Reported by Joe Keane <jgk@jgk.org>.
|
||||
|
||||
* sysdeps/libm-ieee754/s_ceill.c: Fix typos.
|
||||
* sysdeps/libm-ieee754/s_llrint.c: Correct code, it never worked.
|
||||
|
||||
1997-11-06 07:00 H.J. Lu <hjl@gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/unix/sysv/i386/i686/time.S: Removed.
|
||||
|
||||
1997-11-08 14:07 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
|
||||
|
||||
* nis/libnsl.map: Add __do_niscall2 for nis_cachemgr.
|
||||
|
||||
* nis/nis_call.c: Set UDP resend timeout correct.
|
||||
|
||||
* nis/nss_compat/compat-grp.c: Rewritten to make it faster.
|
||||
* nis/nss_compat/compat-pwd.c: Likewise.
|
||||
* nis/nss_compat/compat-spwd.c: Likewise.
|
||||
* nis/ypclnt.c: Fix UDP resend timeout, fix yp_bind/do_ypcall
|
||||
interaction.
|
||||
|
||||
* inet/protocols/routed.h: Include sys/socket.h.
|
||||
* inet/protocols/talkd.h: Likewise.
|
||||
* inet/protocols/timed.h: Include rpc/types.h.
|
||||
* sunrpc/rpc/pmap_clnt.h: Include rpc/clnt.h.
|
||||
|
||||
1997-11-06 01:39 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* Makerules (libc.so): Add missing closing brace.
|
||||
|
||||
1997-11-05 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||
|
||||
* libio.h (__P): Name its arg `p' instead of `params'.
|
||||
This was added solely to work around problems with
|
||||
the definition of __P in the Solaris math.h header.
|
||||
|
||||
1997-11-06 00:06 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* argp/argp-help.c: Optimize a bit by using mempcpy.
|
||||
|
12
Makeconfig
12
Makeconfig
@ -529,6 +529,12 @@ LDFLAGS := -g
|
||||
endif
|
||||
|
||||
|
||||
# If everything is compiled with -fPIC (implicitly) we must tell this by
|
||||
# defining the PIC symbol.
|
||||
ifeq (yes,$(build-pic-default))
|
||||
pic-default = -DPIC
|
||||
endif
|
||||
|
||||
# Enable object files for different versions of the library.
|
||||
# Various things use $(object-suffixes) to know what all to make.
|
||||
# The compilation rules use $(CPPFLAGS-${SUFFIX}) and $(CFLAGS-${SUFFIX})
|
||||
@ -537,6 +543,7 @@ libtypes = $(foreach o,$(object-suffixes),$(libtype$o))
|
||||
all-object-suffixes := .o .os .op .og .ob
|
||||
object-suffixes :=
|
||||
ifeq (yes,$(build-static))
|
||||
CPPFLAGS-.o = $(pic-default)
|
||||
libtype.o := lib%.a
|
||||
object-suffixes += .o
|
||||
endif
|
||||
@ -554,7 +561,7 @@ ifeq (yes,$(build-profile))
|
||||
# Under --enable-profile, we will build a static library of profiled objects.
|
||||
# The profiled object files are named foo.op.
|
||||
object-suffixes += .op
|
||||
CPPFLAGS-.op = -DPROF
|
||||
CPPFLAGS-.op = -DPROF $(pic-default)
|
||||
CFLAGS-.op = -pg
|
||||
libtype.op = lib%_p.a
|
||||
endif
|
||||
@ -563,6 +570,7 @@ ifeq (yes,$(build-omitfp))
|
||||
# debugging information using -fomit-frame-pointer, and build an extra
|
||||
# library with debugging information. The debuggable objects are named foo.og.
|
||||
object-suffixes += .og
|
||||
CPPFLAGS-.og = $(pic-default)
|
||||
CFLAGS-.og = -g
|
||||
CFLAGS-.o = -g0 -O99 -fomit-frame-pointer -D__USE_STRING_INLINES
|
||||
CFLAGS-.os += $(CFLAGS-.o)
|
||||
@ -572,7 +580,7 @@ ifeq (yes,$(build-bounded))
|
||||
# Under --enable-bounded, we build the library with `-fbounded-pointers -g'
|
||||
# to runtime bounds checking. The bounded-pointer objects are named foo.ob.
|
||||
object-suffixes += .ob
|
||||
CPPFLAGS-.ob = -DBOUNDED_POINTERS
|
||||
CPPFLAGS-.ob = -DBOUNDED_POINTERS $(pic-default)
|
||||
CFLAGS-.ob = -g -fbounded-pointers
|
||||
libtype.ob = lib%_b.a
|
||||
endif
|
||||
|
7
Makefile
7
Makefile
@ -124,6 +124,13 @@ ifeq (yes,$(build-shared))
|
||||
install:
|
||||
-test ! -x $(common-objpfx)elf/ldconfig || \
|
||||
$(common-objpfx)elf/ldconfig -d $(inst_slibdir) $(inst_libdir)
|
||||
ifneq (no,$(PERL))
|
||||
ifeq (/usr,$(prefix))
|
||||
ifeq (,$(install_root))
|
||||
CC=$(CC) $(PERL) test-installation.pl $(common-objpfx)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -692,7 +692,7 @@ $(inst_libdir)/libc.so: $(common-objpfx)libc.so$(libc.so-version) \
|
||||
echo ' dependencies of $(<F) to find $(rtld-installed-name). */';\
|
||||
echo 'GROUP ( $(slibdir)/libc.so$(libc.so-version)' \
|
||||
'$(slibdir)/$(rtld-installed-name)' \
|
||||
'$(libdir)/lib$(libc-name).a' \
|
||||
'$(libdir)/lib$(libc-name).a )' \
|
||||
) > $@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define __Emath_defined 1
|
||||
|
||||
# define EDOM XXX <--- fill in what is actually needed
|
||||
# define EILSEQ XXX <--- fill in what is actually needed
|
||||
# define ERANGE XXX <--- fill in what is actually needed
|
||||
#endif
|
||||
|
||||
|
@ -39,6 +39,7 @@ gnu-as = @gnu_as@
|
||||
gnu-ld = @gnu_ld@
|
||||
build-static = @static@
|
||||
build-shared = @shared@
|
||||
build-pic-default= @pic_default@
|
||||
build-profile = @profile@
|
||||
build-omitfp = @omitfp@
|
||||
build-bounded = @bounded@
|
||||
|
22
configure
vendored
22
configure
vendored
@ -2441,6 +2441,27 @@ if test $shared = default; then
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
|
||||
echo "configure:2446: checking whether -fPIC is default" >&5
|
||||
if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
pic_default=yes
|
||||
cat > conftest.c <<EOF
|
||||
#if defined(__PIC__) || defined(__pic__) || defined(PIC) || defined(pic)
|
||||
# error PIC is default.
|
||||
#endif
|
||||
EOF
|
||||
if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
|
||||
pic_default=no
|
||||
fi
|
||||
rm -f conftest.*
|
||||
fi
|
||||
|
||||
echo "$ac_t""$pic_default" 1>&6
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2650,6 +2671,7 @@ s%@gnu_as@%$gnu_as%g
|
||||
s%@elf@%$elf%g
|
||||
s%@static@%$static%g
|
||||
s%@shared@%$shared%g
|
||||
s%@pic_default@%$pic_default%g
|
||||
s%@profile@%$profile%g
|
||||
s%@omitfp@%$omitfp%g
|
||||
s%@bounded@%$bounded%g
|
||||
|
14
configure.in
14
configure.in
@ -971,6 +971,20 @@ if test $shared = default; then
|
||||
shared=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether -fPIC is default], pic_default,
|
||||
[pic_default=yes
|
||||
cat > conftest.c <<EOF
|
||||
#if defined(__PIC__) || defined(__pic__) || defined(PIC) || defined(pic)
|
||||
# error PIC is default.
|
||||
#endif
|
||||
EOF
|
||||
if eval "${CC-cc} -S conftest.c 2>&AC_FD_CC 1>&AC_FD_CC"; then
|
||||
pic_default=no
|
||||
fi
|
||||
rm -f conftest.*])
|
||||
AC_SUBST(pic_default)
|
||||
|
||||
AC_SUBST(profile)
|
||||
AC_SUBST(omitfp)
|
||||
AC_SUBST(bounded)
|
||||
|
@ -64,7 +64,7 @@ omit-deps += $(crtstuff)
|
||||
$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
|
||||
$(compile.S) -g0 $(ASFLAGS-.os) -o $@
|
||||
|
||||
CFLAGS-initfini.s = -O0 -g0 -fPIC
|
||||
CFLAGS-initfini.s = -g0 -fPIC -fno-inline-functions
|
||||
|
||||
$(objpfx)initfini.s: initfini.c
|
||||
$(compile.c) -S $(CFLAGS-initfini.s) -finhibit-size-directive \
|
||||
|
@ -58,8 +58,8 @@ libdb-routines := bt_close bt_compare bt_conv bt_cursor bt_delete \
|
||||
bt_split bt_stat btree_auto db db_appinit db_apprec \
|
||||
db_auto \
|
||||
db_byteorder db_conv db_dispatch db_dup db_err db_log2 \
|
||||
db_os_abs db_os_dir db_os_fid db_os_lseek db_os_mmap \
|
||||
db_os_open db_os_rw db_os_sleep db_os_stat db_os_unlink \
|
||||
os_abs os_dir os_fid os_fsync os_func os_map os_oflags \
|
||||
os_open os_rpath os_rw os_seek os_sleep os_stat os_unlink \
|
||||
db_overflow db_pr db_rec db_region db_ret db_salloc \
|
||||
db_shash db_thread hash hash_auto hash_conv hash_debug \
|
||||
hash_dup hash_func hash_page hash_rec hash_stat lock \
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_cursor.c 10.33 (Sleepycat) 9/24/97";
|
||||
static const char sccsid[] = "@(#)bt_cursor.c 10.35 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -62,10 +62,10 @@ __bam_cursor(dbp, txn, dbcp)
|
||||
|
||||
DEBUG_LWRITE(dbp, txn, "bam_cursor", NULL, NULL, 0);
|
||||
|
||||
if ((dbc = (DBC *)calloc(1, sizeof(DBC))) == NULL)
|
||||
if ((dbc = (DBC *)__db_calloc(1, sizeof(DBC))) == NULL)
|
||||
return (ENOMEM);
|
||||
if ((cp = (CURSOR *)calloc(1, sizeof(CURSOR))) == NULL) {
|
||||
free(dbc);
|
||||
if ((cp = (CURSOR *)__db_calloc(1, sizeof(CURSOR))) == NULL) {
|
||||
__db_free(dbc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -474,7 +474,7 @@ __bam_c_rget(dbp, cp, key, data, flags)
|
||||
__bam_stkrel(dbp);
|
||||
|
||||
err: (void)memp_fput(dbp->mpf, cp->page, 0);
|
||||
free(dbt.data);
|
||||
__db_free(dbt.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1422,7 +1422,7 @@ __bam_c_physdel(dbp, cp, h)
|
||||
DB_LOCK lock;
|
||||
db_indx_t indx;
|
||||
db_pgno_t pgno, next_pgno, prev_pgno;
|
||||
int local, ret;
|
||||
int local, normal, ret;
|
||||
|
||||
t = dbp->internal;
|
||||
ret = 0;
|
||||
@ -1457,51 +1457,65 @@ __bam_c_physdel(dbp, cp, h)
|
||||
local = 0;
|
||||
|
||||
/*
|
||||
* If we're deleting a duplicate entry, call the common code to do
|
||||
* the work.
|
||||
* 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 ((ret = __db_drem(dbp, &h, indx, __bam_free)) != 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* There are 4 cases:
|
||||
*
|
||||
* 1. We removed an item on a page, but there are more items
|
||||
* on the page.
|
||||
* 2. We removed the last item on a page, removing the last
|
||||
* duplicate.
|
||||
* 3. We removed the last item on a page, but there is a
|
||||
* following page of duplicates.
|
||||
* 4. We removed the last item on a page, but there is a
|
||||
* previous page of duplicates.
|
||||
*
|
||||
* In case 1, h != NULL, h->pgno == pgno
|
||||
* In case 2, h == NULL,
|
||||
* prev_pgno == PGNO_INVALID, next_pgno == PGNO_INVALID
|
||||
* In case 3, h != NULL, next_pgno != PGNO_INVALID
|
||||
* In case 4, h == NULL, prev_pgno != PGNO_INVALID
|
||||
*
|
||||
* In case 1, there's nothing else to do.
|
||||
* In case 2, remove the entry from the parent page.
|
||||
* In case 3 or 4, if the deleted page was the first in a chain
|
||||
* of duplicate pages, update the parent page's entry.
|
||||
*
|
||||
* Test:
|
||||
* If there were previous pages of duplicates or we didn't
|
||||
* empty the current page of duplicates, we don't need to
|
||||
* touch the parent page.
|
||||
*/
|
||||
if (prev_pgno != PGNO_INVALID || (h != NULL && pgno == h->pgno))
|
||||
goto done;
|
||||
if (NUM_ENT(h) == 1 &&
|
||||
prev_pgno == PGNO_INVALID && next_pgno == PGNO_INVALID)
|
||||
normal = 1;
|
||||
else {
|
||||
normal = 0;
|
||||
|
||||
/*
|
||||
* Release any page we're holding and the lock on the deleted
|
||||
* page.
|
||||
*/
|
||||
/* Delete the duplicate. */
|
||||
if ((ret = __db_drem(dbp, &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)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Release any page we're holding and its lock. */
|
||||
if (local) {
|
||||
if (h != NULL)
|
||||
(void)memp_fput(dbp->mpf, h, 0);
|
||||
@ -1519,37 +1533,33 @@ __bam_c_physdel(dbp, cp, h)
|
||||
}
|
||||
local = 1;
|
||||
|
||||
/*
|
||||
* If we deleted the last duplicate, we can fall out and do a
|
||||
* normal btree delete in the context of the parent page. If
|
||||
* not, we have to update the parent's page.
|
||||
*/
|
||||
/* Switch to the parent page's entry. */
|
||||
indx = cp->indx;
|
||||
if (next_pgno != PGNO_INVALID) {
|
||||
/*
|
||||
* Copy, delete, update and re-insert the parent page's
|
||||
* entry.
|
||||
*/
|
||||
bo = *GET_BOVERFLOW(h, indx);
|
||||
(void)__db_ditem(dbp, h, indx, BOVERFLOW_SIZE);
|
||||
bo.pgno = next_pgno;
|
||||
memset(&dbt, 0, sizeof(dbt));
|
||||
dbt.data = &bo;
|
||||
dbt.size = BOVERFLOW_SIZE;
|
||||
(void)__db_pitem(dbp,
|
||||
h, indx, BOVERFLOW_SIZE, &dbt, NULL);
|
||||
if (normal)
|
||||
goto btd;
|
||||
|
||||
/* Discard the parent page. */
|
||||
(void)memp_fput(dbp->mpf, h, 0);
|
||||
(void)__BT_TLPUT(dbp, lock);
|
||||
local = 0;
|
||||
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* 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(dbp, h, indx, BOVERFLOW_SIZE);
|
||||
bo.pgno = next_pgno;
|
||||
memset(&dbt, 0, sizeof(dbt));
|
||||
dbt.data = &bo;
|
||||
dbt.size = BOVERFLOW_SIZE;
|
||||
(void)__db_pitem(dbp, h, indx, BOVERFLOW_SIZE, &dbt, NULL);
|
||||
(void)memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Otherwise, do a normal btree delete. */
|
||||
if ((ret = __bam_ditem(dbp, h, indx)) != 0)
|
||||
btd: if ((ret = __bam_ditem(dbp, h, indx)) != 0)
|
||||
goto err;
|
||||
if ((ret = __bam_ditem(dbp, h, indx)) != 0)
|
||||
goto err;
|
||||
@ -1584,7 +1594,7 @@ __bam_c_physdel(dbp, cp, h)
|
||||
}
|
||||
|
||||
ret = __bam_dpage(dbp, &dbt);
|
||||
free(dbt.data);
|
||||
__db_free(dbt.data);
|
||||
}
|
||||
|
||||
err:
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_delete.c 10.21 (Sleepycat) 9/3/97";
|
||||
static const char sccsid[] = "@(#)bt_delete.c 10.22 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -266,9 +266,10 @@ __bam_ditem(dbp, h, indx)
|
||||
case B_DUPLICATE:
|
||||
case B_OVERFLOW:
|
||||
nbytes = BINTERNAL_SIZE(bi->len);
|
||||
bo = (BOVERFLOW *)bi->data;
|
||||
goto offpage;
|
||||
case B_KEYDATA:
|
||||
nbytes = BKEYDATA_SIZE(bi->len);
|
||||
nbytes = BINTERNAL_SIZE(bi->len);
|
||||
break;
|
||||
default:
|
||||
return (__db_pgfmt(dbp, h->pgno));
|
||||
@ -289,7 +290,7 @@ __bam_ditem(dbp, h, indx)
|
||||
if (indx > 0 && h->inp[indx] == h->inp[indx - P_INDX])
|
||||
return (__bam_adjindx(dbp,
|
||||
h, indx, indx - P_INDX, 0));
|
||||
if (indx < (u_int32_t)(NUM_ENT(h) - P_INDX) &&
|
||||
if (indx + P_INDX < (u_int32_t)NUM_ENT(h) &&
|
||||
h->inp[indx] == h->inp[indx + P_INDX])
|
||||
return (__bam_adjindx(dbp,
|
||||
h, indx, indx + O_INDX, 0));
|
||||
@ -301,9 +302,9 @@ __bam_ditem(dbp, h, indx)
|
||||
case B_DUPLICATE:
|
||||
case B_OVERFLOW:
|
||||
nbytes = BOVERFLOW_SIZE;
|
||||
bo = GET_BOVERFLOW(h, indx);
|
||||
|
||||
offpage: /* Delete duplicate/offpage chains. */
|
||||
bo = GET_BOVERFLOW(h, indx);
|
||||
if (B_TYPE(bo->type) == B_DUPLICATE) {
|
||||
if ((ret =
|
||||
__db_ddup(dbp, bo->pgno, __bam_free)) != 0)
|
||||
@ -523,7 +524,7 @@ __bam_dpages(dbp, t)
|
||||
|
||||
/*
|
||||
* If we deleted the next-to-last item from the root page, the tree
|
||||
* has collapsed a level. Try and write lock the remaining root + 1
|
||||
* can collapse a level. Try and write lock the remaining root + 1
|
||||
* page and copy it onto the root page. If we can't get the lock,
|
||||
* that's okay, the tree just stays a level deeper than we'd like.
|
||||
*/
|
||||
@ -546,8 +547,8 @@ __bam_dpages(dbp, t)
|
||||
b.data = P_ENTRY(epg->page, 0);
|
||||
b.size = BINTERNAL_SIZE(((BINTERNAL *)b.data)->len);
|
||||
__bam_rsplit_log(dbp->dbenv->lg_info, dbp->txn,
|
||||
&h->lsn, 0, dbp->log_fileid, h->pgno, &a, &b,
|
||||
&epg->page->lsn);
|
||||
&h->lsn, 0, dbp->log_fileid, h->pgno, &a,
|
||||
RE_NREC(epg->page), &b, &epg->page->lsn);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -565,15 +566,19 @@ __bam_dpages(dbp, t)
|
||||
if (TYPE(h) == P_IRECNO ||
|
||||
(TYPE(h) == P_IBTREE && F_ISSET(dbp, DB_BT_RECNUM)))
|
||||
RE_NREC_SET(epg->page, rcnt);
|
||||
(void)memp_fset(dbp->mpf, epg->page, DB_MPOOL_DIRTY);
|
||||
|
||||
/* Free the last page in that level of the btree. */
|
||||
++t->lstat.bt_freed;
|
||||
/*
|
||||
* Free the last page in that level of the btree and discard
|
||||
* the lock. (The call to __bam_free discards our reference
|
||||
* to the page.)
|
||||
*/
|
||||
(void)__bam_free(dbp, h);
|
||||
(void)__BT_TLPUT(dbp, lock);
|
||||
++t->lstat.bt_freed;
|
||||
|
||||
/* Adjust the cursors. */
|
||||
__bam_ca_move(dbp, t, h->pgno, PGNO_ROOT);
|
||||
|
||||
(void)__BT_TLPUT(dbp, lock);
|
||||
}
|
||||
|
||||
/* Release the top page in the subtree. */
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_open.c 10.20 (Sleepycat) 8/19/97";
|
||||
static const char sccsid[] = "@(#)bt_open.c 10.21 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -95,7 +95,7 @@ __bam_open(dbp, type, dbinfo)
|
||||
int ret;
|
||||
|
||||
/* Allocate the btree internal structure. */
|
||||
if ((t = (BTREE *)calloc(1, sizeof(BTREE))) == NULL)
|
||||
if ((t = (BTREE *)__db_calloc(1, sizeof(BTREE))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
t->bt_sp = t->bt_csp = t->bt_stack;
|
||||
@ -179,7 +179,7 @@ einval: ret = EINVAL;
|
||||
err: if (t != NULL) {
|
||||
/* If we allocated room for key/data return, discard it. */
|
||||
if (t->bt_rkey.data != NULL)
|
||||
free(t->bt_rkey.data);
|
||||
__db_free(t->bt_rkey.data);
|
||||
|
||||
FREE(t, sizeof(BTREE));
|
||||
}
|
||||
@ -201,7 +201,7 @@ __bam_bdup(orig, new)
|
||||
|
||||
ot = orig->internal;
|
||||
|
||||
if ((t = (BTREE *)calloc(1, sizeof(*t))) == NULL)
|
||||
if ((t = (BTREE *)__db_calloc(1, sizeof(*t))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/*
|
||||
@ -248,7 +248,7 @@ __bam_keyalloc(t)
|
||||
* Recno keys are always the same size, and we don't want to have
|
||||
* to check for space on each return. Allocate it now.
|
||||
*/
|
||||
if ((t->bt_rkey.data = (void *)malloc(sizeof(db_recno_t))) == NULL)
|
||||
if ((t->bt_rkey.data = (void *)__db_malloc(sizeof(db_recno_t))) == NULL)
|
||||
return (ENOMEM);
|
||||
t->bt_rkey.ulen = sizeof(db_recno_t);
|
||||
return (0);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_put.c 10.25 (Sleepycat) 9/17/97";
|
||||
static const char sccsid[] = "@(#)bt_put.c 10.31 (Sleepycat) 10/26/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -66,7 +66,10 @@ static const char sccsid[] = "@(#)bt_put.c 10.25 (Sleepycat) 9/17/97";
|
||||
static int __bam_fixed __P((BTREE *, DBT *));
|
||||
static int __bam_lookup __P((DB *, DBT *, int *));
|
||||
static int __bam_ndup __P((DB *, PAGE *, u_int32_t));
|
||||
static int __bam_partial __P((DB *, DBT *, PAGE *, u_int32_t));
|
||||
static int __bam_ovput __P((DB *, PAGE *, u_int32_t, DBT *));
|
||||
static int __bam_partial __P((DB *, DBT *, PAGE *, u_int32_t, u_int32_t));
|
||||
static u_int32_t
|
||||
__bam_partsize __P((DB *, DBT *, PAGE *, u_int32_t));
|
||||
|
||||
/*
|
||||
* __bam_put --
|
||||
@ -333,21 +336,6 @@ miss: ++t->lstat.bt_cache_miss;
|
||||
slow: return (__bam_search(dbp, key, S_INSERT, 1, NULL, exactp));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(dbp, \
|
||||
h, indx, BOVERFLOW_SIZE, &__hdr, NULL)) != 0) \
|
||||
return (ret); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* __bam_iitem --
|
||||
* Insert an item into the tree.
|
||||
@ -365,19 +353,18 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
{
|
||||
BTREE *t;
|
||||
BKEYDATA *bk;
|
||||
BOVERFLOW kbo, dbo;
|
||||
DBT tdbt;
|
||||
PAGE *h;
|
||||
db_indx_t indx;
|
||||
u_int32_t have_bytes, need_bytes, needed;
|
||||
int bigkey, bigdata, dcopy, dupadjust, ret;
|
||||
u_int32_t data_size, have_bytes, need_bytes, needed;
|
||||
int bigkey, bigdata, dupadjust, replace, ret;
|
||||
|
||||
t = dbp->internal;
|
||||
h = *hp;
|
||||
indx = *indxp;
|
||||
|
||||
dupadjust = 0;
|
||||
bk = NULL; /* XXX: Shut the compiler up. */
|
||||
dupadjust = replace = 0;
|
||||
|
||||
/*
|
||||
* If it's a page of duplicates, call the common code to do the work.
|
||||
@ -385,7 +372,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
* !!!
|
||||
* 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 stack has to change.
|
||||
* 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. */
|
||||
@ -401,24 +388,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
return (__db_dput(dbp, data, hp, indxp, __bam_new));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Handle partial puts.
|
||||
*
|
||||
* This is truly awful from a performance standput. We don't optimize
|
||||
* for partial puts at all, we delete the record and add it back in,
|
||||
* regardless of size or if we're simply overwriting current data.
|
||||
* The hash access method does this a lot better than we do, and we're
|
||||
* eventually going to have to fix it.
|
||||
*/
|
||||
if (F_ISSET(data, DB_DBT_PARTIAL)) {
|
||||
tdbt = *data;
|
||||
if ((ret = __bam_partial(dbp, &tdbt, h, indx)) != 0)
|
||||
return (ret);
|
||||
data = &tdbt;
|
||||
}
|
||||
|
||||
/* If it's a short fixed-length record, fix it up. */
|
||||
/* Handle fixed-length records: build the real record. */
|
||||
if (F_ISSET(dbp, DB_RE_FIXEDLEN) && data->size != t->bt_recno->re_len) {
|
||||
tdbt = *data;
|
||||
if ((ret = __bam_fixed(t, &tdbt)) != 0)
|
||||
@ -427,30 +397,15 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the key or data item won't fit on a page, store it in the
|
||||
* overflow pages.
|
||||
*
|
||||
* !!!
|
||||
* From this point on, we have to recover the allocated overflow
|
||||
* pages on error.
|
||||
* 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 = bigdata = 0;
|
||||
if (LF_ISSET(BI_NEWKEY) && key->size > t->bt_ovflsize) {
|
||||
B_TSET(kbo.type, B_OVERFLOW, 0);
|
||||
kbo.tlen = key->size;
|
||||
if ((ret = __db_poff(dbp, key, &kbo.pgno, __bam_new)) != 0)
|
||||
goto err;
|
||||
bigkey = 1;
|
||||
}
|
||||
if (data->size > t->bt_ovflsize) {
|
||||
B_TSET(dbo.type, B_OVERFLOW, 0);
|
||||
dbo.tlen = data->size;
|
||||
if ((ret = __db_poff(dbp, data, &dbo.pgno, __bam_new)) != 0)
|
||||
goto err;
|
||||
bigdata = 1;
|
||||
}
|
||||
bigkey = LF_ISSET(BI_NEWKEY) && key->size > t->bt_ovflsize;
|
||||
data_size = F_ISSET(data, DB_DBT_PARTIAL) ?
|
||||
__bam_partsize(dbp, data, h, indx) : data->size;
|
||||
bigdata = data_size > t->bt_ovflsize;
|
||||
|
||||
dcopy = 0;
|
||||
needed = 0;
|
||||
if (LF_ISSET(BI_NEWKEY)) {
|
||||
/* If BI_NEWKEY is set we're adding a new key and data pair. */
|
||||
@ -461,7 +416,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
if (bigdata)
|
||||
needed += BOVERFLOW_PSIZE;
|
||||
else
|
||||
needed += BKEYDATA_PSIZE(data->size);
|
||||
needed += BKEYDATA_PSIZE(data_size);
|
||||
} else {
|
||||
/*
|
||||
* We're either overwriting the data item of a key/data pair
|
||||
@ -482,16 +437,8 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
if (bigdata)
|
||||
need_bytes += BOVERFLOW_PSIZE;
|
||||
else
|
||||
need_bytes += BKEYDATA_PSIZE(data->size);
|
||||
need_bytes += BKEYDATA_PSIZE(data_size);
|
||||
|
||||
/*
|
||||
* If we're overwriting a data item, we copy it if it's not a
|
||||
* special record type and it's the same size (including any
|
||||
* alignment) and do a delete/insert otherwise.
|
||||
*/
|
||||
if (op == DB_CURRENT && !bigdata &&
|
||||
B_TYPE(bk->type) == B_KEYDATA && have_bytes == need_bytes)
|
||||
dcopy = 1;
|
||||
if (have_bytes < need_bytes)
|
||||
needed += need_bytes - have_bytes;
|
||||
}
|
||||
@ -505,9 +452,15 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
* 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)) {
|
||||
ret = DB_NEEDSPLIT;
|
||||
goto err;
|
||||
(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(dbp, &tdbt, h, indx, data_size)) != 0)
|
||||
return (ret);
|
||||
data = &tdbt;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -515,10 +468,10 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
*
|
||||
* 1. Append a new key/data pair.
|
||||
* 2. Insert a new key/data pair.
|
||||
* 3. Copy the data item.
|
||||
* 4. Delete/insert the data item.
|
||||
* 5. Append a new data item.
|
||||
* 6. Insert a new data item.
|
||||
* 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) {
|
||||
@ -533,42 +486,17 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
}
|
||||
|
||||
/* Add the key. */
|
||||
if (bigkey)
|
||||
OVPUT(h, indx, kbo);
|
||||
else {
|
||||
DBT __data;
|
||||
memset(&__data, 0, sizeof(__data));
|
||||
__data.data = key->data;
|
||||
__data.size = key->size;
|
||||
if (bigkey) {
|
||||
if ((ret = __bam_ovput(dbp, h, indx, key)) != 0)
|
||||
return (ret);
|
||||
} else
|
||||
if ((ret = __db_pitem(dbp, h, indx,
|
||||
BKEYDATA_SIZE(key->size), NULL, &__data)) != 0)
|
||||
goto err;
|
||||
}
|
||||
BKEYDATA_SIZE(key->size), NULL, key)) != 0)
|
||||
return (ret);
|
||||
++indx;
|
||||
} else {
|
||||
switch (op) {
|
||||
case DB_CURRENT: /* 3. Copy the data item. */
|
||||
/*
|
||||
* If we're not logging and it's possible, overwrite
|
||||
* the current item.
|
||||
*
|
||||
* XXX
|
||||
* We should add a separate logging message so that
|
||||
* we can do this anytime it's possible, including
|
||||
* for partial record puts.
|
||||
*/
|
||||
if (dcopy && !DB_LOGGING(dbp)) {
|
||||
bk->len = data->size;
|
||||
memcpy(bk->data, data->data, data->size);
|
||||
goto done;
|
||||
}
|
||||
/* 4. Delete/insert the data item. */
|
||||
if (TYPE(h) == P_LBTREE)
|
||||
++indx;
|
||||
if ((ret = __bam_ditem(dbp, h, indx)) != 0)
|
||||
goto err;
|
||||
break;
|
||||
case DB_AFTER: /* 5. Append a new data item. */
|
||||
case DB_AFTER: /* 3. Append a new data item. */
|
||||
if (TYPE(h) == P_LBTREE) {
|
||||
/*
|
||||
* Adjust the cursor and copy in the key for
|
||||
@ -576,7 +504,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
*/
|
||||
if ((ret = __bam_adjindx(dbp,
|
||||
h, indx + P_INDX, indx, 1)) != 0)
|
||||
goto err;
|
||||
return (ret);
|
||||
|
||||
indx += 3;
|
||||
dupadjust = 1;
|
||||
@ -589,7 +517,7 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
*indxp += 1;
|
||||
}
|
||||
break;
|
||||
case DB_BEFORE: /* 6. Insert a new data item. */
|
||||
case DB_BEFORE: /* 4. Insert a new data item. */
|
||||
if (TYPE(h) == P_LBTREE) {
|
||||
/*
|
||||
* Adjust the cursor and copy in the key for
|
||||
@ -597,43 +525,62 @@ __bam_iitem(dbp, hp, indxp, key, data, op, flags)
|
||||
*/
|
||||
if ((ret =
|
||||
__bam_adjindx(dbp, h, indx, indx, 1)) != 0)
|
||||
goto err;
|
||||
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_OVERFLOW) {
|
||||
if ((ret = __bam_ditem(dbp, h, indx)) != 0)
|
||||
return (ret);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 6. Replace the data item. */
|
||||
replace = 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the data. */
|
||||
if (bigdata)
|
||||
OVPUT(h, indx, dbo);
|
||||
else {
|
||||
if (bigdata) {
|
||||
if ((ret = __bam_ovput(dbp, h, indx, data)) != 0)
|
||||
return (ret);
|
||||
} else {
|
||||
BKEYDATA __bk;
|
||||
DBT __hdr, __data;
|
||||
memset(&__data, 0, sizeof(__data));
|
||||
__data.data = data->data;
|
||||
__data.size = data->size;
|
||||
DBT __hdr;
|
||||
|
||||
if (LF_ISSET(BI_DELETED)) {
|
||||
B_TSET(__bk.type, B_KEYDATA, 1);
|
||||
__bk.len = __data.size;
|
||||
__bk.len = data->size;
|
||||
__hdr.data = &__bk;
|
||||
__hdr.size = SSZA(BKEYDATA, data);
|
||||
ret = __db_pitem(dbp, h, indx,
|
||||
BKEYDATA_SIZE(__data.size), &__hdr, &__data);
|
||||
} else
|
||||
BKEYDATA_SIZE(data->size), &__hdr, data);
|
||||
} else if (replace)
|
||||
ret = __bam_ritem(dbp, h, indx, data);
|
||||
else
|
||||
ret = __db_pitem(dbp, h, indx,
|
||||
BKEYDATA_SIZE(data->size), NULL, &__data);
|
||||
BKEYDATA_SIZE(data->size), NULL, data);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
done: ++t->lstat.bt_added;
|
||||
++t->lstat.bt_added;
|
||||
|
||||
ret = memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY);
|
||||
|
||||
@ -645,21 +592,205 @@ done: ++t->lstat.bt_added;
|
||||
if (dupadjust && P_FREESPACE(h) <= dbp->pgsize / 2) {
|
||||
--indx;
|
||||
if ((ret = __bam_ndup(dbp, h, indx)) != 0)
|
||||
goto err;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
if (t->bt_recno != NULL)
|
||||
F_SET(t->bt_recno, RECNO_MODIFIED);
|
||||
|
||||
if (0) {
|
||||
err: if (bigkey)
|
||||
(void)__db_doff(dbp, kbo.pgno, __bam_free);
|
||||
if (bigdata)
|
||||
(void)__db_doff(dbp, dbo.pgno, __bam_free);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* __bam_partsize --
|
||||
* Figure out how much space a partial data item is in total.
|
||||
*/
|
||||
static u_int32_t
|
||||
__bam_partsize(dbp, data, h, indx)
|
||||
DB *dbp;
|
||||
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(dbp, \
|
||||
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(dbp, h, indx, item)
|
||||
DB *dbp;
|
||||
PAGE *h;
|
||||
u_int32_t indx;
|
||||
DBT *item;
|
||||
{
|
||||
BOVERFLOW bo;
|
||||
int ret;
|
||||
|
||||
B_TSET(bo.type, B_OVERFLOW, 0);
|
||||
bo.tlen = item->size;
|
||||
if ((ret = __db_poff(dbp, item, &bo.pgno, __bam_new)) != 0)
|
||||
return (ret);
|
||||
|
||||
OVPUT(h, indx, bo);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __bam_ritem --
|
||||
* Replace an item on a page.
|
||||
*
|
||||
* PUBLIC: int __bam_ritem __P((DB *, PAGE *, u_int32_t, DBT *));
|
||||
*/
|
||||
int
|
||||
__bam_ritem(dbp, h, indx, data)
|
||||
DB *dbp;
|
||||
PAGE *h;
|
||||
u_int32_t indx;
|
||||
DBT *data;
|
||||
{
|
||||
BKEYDATA *bk;
|
||||
DBT orig, repl;
|
||||
db_indx_t lo, ln, min, off, prefix, suffix;
|
||||
int32_t nbytes;
|
||||
int cnt, ret;
|
||||
u_int8_t *p, *t;
|
||||
|
||||
/*
|
||||
* 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(dbp)) {
|
||||
/*
|
||||
* 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, dbp->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.
|
||||
@ -766,16 +897,21 @@ __bam_fixed(t, dbt)
|
||||
rp = t->bt_recno;
|
||||
|
||||
/*
|
||||
* 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 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 (t->bt_rdata.ulen < rp->re_len) {
|
||||
t->bt_rdata.data = t->bt_rdata.data == NULL ?
|
||||
(void *)malloc(rp->re_len) :
|
||||
(void *)realloc(t->bt_rdata.data, rp->re_len);
|
||||
(void *)__db_malloc(rp->re_len) :
|
||||
(void *)__db_realloc(t->bt_rdata.data, rp->re_len);
|
||||
if (t->bt_rdata.data == NULL) {
|
||||
t->bt_rdata.ulen = 0;
|
||||
return (ENOMEM);
|
||||
@ -786,12 +922,16 @@ __bam_fixed(t, dbt)
|
||||
memset((u_int8_t *)t->bt_rdata.data + dbt->size,
|
||||
rp->re_pad, rp->re_len - dbt->size);
|
||||
|
||||
/* Set the DBT to reference our new record. */
|
||||
/*
|
||||
* Clean up our flags and other information just in case, and
|
||||
* change the caller's DBT to reference our created record.
|
||||
*/
|
||||
t->bt_rdata.size = rp->re_len;
|
||||
t->bt_rdata.dlen = 0;
|
||||
t->bt_rdata.doff = 0;
|
||||
t->bt_rdata.flags = 0;
|
||||
*dbt = t->bt_rdata;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -800,47 +940,28 @@ __bam_fixed(t, dbt)
|
||||
* Build the real record for a partial put.
|
||||
*/
|
||||
static int
|
||||
__bam_partial(dbp, dbt, h, indx)
|
||||
__bam_partial(dbp, dbt, h, indx, nbytes)
|
||||
DB *dbp;
|
||||
DBT *dbt;
|
||||
PAGE *h;
|
||||
u_int32_t indx;
|
||||
u_int32_t indx, nbytes;
|
||||
{
|
||||
BTREE *t;
|
||||
BKEYDATA *bk, tbk;
|
||||
BOVERFLOW *bo;
|
||||
DBT copy;
|
||||
u_int32_t len, nbytes, tlen;
|
||||
u_int32_t len, tlen;
|
||||
int ret;
|
||||
u_int8_t *p;
|
||||
|
||||
bo = NULL; /* XXX: Shut the compiler up. */
|
||||
t = dbp->internal;
|
||||
|
||||
/*
|
||||
* Figure out how much total space we'll need. Worst case is where
|
||||
* the record is 0 bytes long, in which case doff causes the record
|
||||
* to extend, and the put data is appended to it.
|
||||
*/
|
||||
if (indx < NUM_ENT(h)) {
|
||||
bk = GET_BKEYDATA(h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
|
||||
if (B_TYPE(bk->type) == B_OVERFLOW) {
|
||||
bo = (BOVERFLOW *)bk;
|
||||
nbytes = bo->tlen;
|
||||
} else
|
||||
nbytes = bk->len;
|
||||
} else {
|
||||
bk = &tbk;
|
||||
B_TSET(bk->type, B_KEYDATA, 0);
|
||||
nbytes = bk->len = 0;
|
||||
}
|
||||
nbytes += dbt->doff + dbt->size + dbt->dlen;
|
||||
|
||||
/* Allocate the space. */
|
||||
/* We use the record data return memory, it's only a short-term use. */
|
||||
if (t->bt_rdata.ulen < nbytes) {
|
||||
t->bt_rdata.data = t->bt_rdata.data == NULL ?
|
||||
(void *)malloc(nbytes) :
|
||||
(void *)realloc(t->bt_rdata.data, nbytes);
|
||||
(void *)__db_malloc(nbytes) :
|
||||
(void *)__db_realloc(t->bt_rdata.data, nbytes);
|
||||
if (t->bt_rdata.data == NULL) {
|
||||
t->bt_rdata.ulen = 0;
|
||||
return (ENOMEM);
|
||||
@ -848,6 +969,16 @@ __bam_partial(dbp, dbt, h, indx)
|
||||
t->bt_rdata.ulen = nbytes;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* We use nul bytes for extending the record, get it over with. */
|
||||
memset(t->bt_rdata.data, 0, nbytes);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_rec.c 10.14 (Sleepycat) 9/6/97";
|
||||
static const char sccsid[] = "@(#)bt_rec.c 10.17 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -298,8 +298,8 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
|
||||
goto done;
|
||||
|
||||
/* Allocate and initialize new left/right child pages. */
|
||||
if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL ||
|
||||
(_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
|
||||
if ((_lp = (PAGE *)__db_malloc(file_dbp->pgsize)) == NULL ||
|
||||
(_rp = (PAGE *)__db_malloc(file_dbp->pgsize)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
__db_err(file_dbp->dbenv, "%s", strerror(ret));
|
||||
goto out;
|
||||
@ -490,9 +490,9 @@ out: /* Free any pages that weren't dirtied. */
|
||||
|
||||
/* Free any allocated space. */
|
||||
if (_lp != NULL)
|
||||
free(_lp);
|
||||
__db_free(_lp);
|
||||
if (_rp != NULL)
|
||||
free(_rp);
|
||||
__db_free(_rp);
|
||||
|
||||
REC_CLOSE;
|
||||
}
|
||||
@ -541,7 +541,8 @@ __bam_rsplit_recover(logp, dbtp, lsnp, redo, info)
|
||||
} else if (cmp_n == 0 && !redo) {
|
||||
/* Need to undo update described. */
|
||||
P_INIT(pagep, file_dbp->pgsize, PGNO_ROOT,
|
||||
PGNO_INVALID, PGNO_INVALID, pagep->level + 1, TYPE(pagep));
|
||||
argp->nrec, PGNO_INVALID, pagep->level + 1,
|
||||
file_dbp->type == DB_BTREE ? P_IBTREE : P_IRECNO);
|
||||
if ((ret = __db_pitem(file_dbp, pagep, 0,
|
||||
argp->rootent.size, &argp->rootent, NULL)) != 0)
|
||||
goto out;
|
||||
@ -764,3 +765,106 @@ __bam_cdel_recover(logp, dbtp, lsnp, redo, info)
|
||||
|
||||
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, *mdbp;
|
||||
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);
|
||||
|
||||
if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||
(void)__db_pgerr(file_dbp, argp->pgno);
|
||||
pagep = NULL;
|
||||
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 ((dbt.data = __db_malloc(dbt.size)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
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(file_dbp, pagep, argp->indx, &dbt);
|
||||
__db_free(dbt.data);
|
||||
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 ((dbt.data = __db_malloc(dbt.size)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
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(file_dbp, pagep, argp->indx, &dbt);
|
||||
__db_free(dbt.data);
|
||||
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)
|
||||
*lsnp = argp->prev_lsn;
|
||||
|
||||
if (0) {
|
||||
err: (void)memp_fput(mpf, pagep, 0);
|
||||
}
|
||||
out: REC_CLOSE;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_recno.c 10.19 (Sleepycat) 9/20/97";
|
||||
static const char sccsid[] = "@(#)bt_recno.c 10.22 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -75,7 +75,7 @@ __ram_open(dbp, type, dbinfo)
|
||||
ret = 0;
|
||||
|
||||
/* Allocate and initialize the private RECNO structure. */
|
||||
if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL)
|
||||
if ((rp = (RECNO *)__db_calloc(1, sizeof(*rp))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if (dbinfo != NULL) {
|
||||
@ -140,7 +140,7 @@ __ram_open(dbp, type, dbinfo)
|
||||
|
||||
err: /* If we mmap'd a source file, discard it. */
|
||||
if (rp->re_smap != NULL)
|
||||
(void)__db_munmap(rp->re_smap, rp->re_msize);
|
||||
(void)__db_unmap(rp->re_smap, rp->re_msize);
|
||||
|
||||
/* If we opened a source file, discard it. */
|
||||
if (rp->re_fd != -1)
|
||||
@ -151,7 +151,7 @@ err: /* If we mmap'd a source file, discard it. */
|
||||
/* If we allocated room for key/data return, discard it. */
|
||||
t = dbp->internal;
|
||||
if (t != NULL && t->bt_rkey.data != NULL)
|
||||
free(t->bt_rkey.data);
|
||||
__db_free(t->bt_rkey.data);
|
||||
|
||||
FREE(rp, sizeof(*rp));
|
||||
|
||||
@ -175,10 +175,10 @@ __ram_cursor(dbp, txn, dbcp)
|
||||
|
||||
DEBUG_LWRITE(dbp, txn, "ram_cursor", NULL, NULL, 0);
|
||||
|
||||
if ((dbc = (DBC *)calloc(1, sizeof(DBC))) == NULL)
|
||||
if ((dbc = (DBC *)__db_calloc(1, sizeof(DBC))) == NULL)
|
||||
return (ENOMEM);
|
||||
if ((cp = (RCURSOR *)calloc(1, sizeof(RCURSOR))) == NULL) {
|
||||
free(dbc);
|
||||
if ((cp = (RCURSOR *)__db_calloc(1, sizeof(RCURSOR))) == NULL) {
|
||||
__db_free(dbc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ __ram_close(argdbp)
|
||||
|
||||
/* Close any underlying mmap region. */
|
||||
if (rp->re_smap != NULL)
|
||||
(void)__db_munmap(rp->re_smap, rp->re_msize);
|
||||
(void)__db_unmap(rp->re_smap, rp->re_msize);
|
||||
|
||||
/* Close any backing source file descriptor. */
|
||||
if (rp->re_fd != -1)
|
||||
@ -814,8 +814,8 @@ __ram_update(dbp, recno, can_create)
|
||||
if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
|
||||
if (t->bt_rdata.ulen < rp->re_len) {
|
||||
t->bt_rdata.data = t->bt_rdata.data == NULL ?
|
||||
(void *)malloc(rp->re_len) :
|
||||
(void *)realloc(t->bt_rdata.data, rp->re_len);
|
||||
(void *)__db_malloc(rp->re_len) :
|
||||
(void *)__db_realloc(t->bt_rdata.data, rp->re_len);
|
||||
if (t->bt_rdata.data == NULL) {
|
||||
t->bt_rdata.ulen = 0;
|
||||
return (ENOMEM);
|
||||
@ -853,7 +853,7 @@ __ram_source(dbp, rp, fname)
|
||||
|
||||
oflags = F_ISSET(dbp, DB_AM_RDONLY) ? DB_RDONLY : 0;
|
||||
if ((ret =
|
||||
__db_fdopen(rp->re_source, oflags, oflags, 0, &rp->re_fd)) != 0) {
|
||||
__db_open(rp->re_source, oflags, oflags, 0, &rp->re_fd)) != 0) {
|
||||
__db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
@ -866,15 +866,16 @@ __ram_source(dbp, rp, fname)
|
||||
* 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 =
|
||||
__db_stat(dbp->dbenv, rp->re_source, rp->re_fd, &size, NULL)) != 0)
|
||||
if ((ret = __db_ioinfo(rp->re_source, rp->re_fd, &size, NULL)) != 0) {
|
||||
__db_err(dbp->dbenv, "%s: %s", rp->re_source, strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
if (size == 0) {
|
||||
F_SET(rp, RECNO_EOF);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((ret = __db_mmap(rp->re_fd, (size_t)size, 1, 1, &rp->re_smap)) != 0)
|
||||
if ((ret = __db_map(rp->re_fd, (size_t)size, 1, 1, &rp->re_smap)) != 0)
|
||||
goto err;
|
||||
rp->re_cmap = rp->re_smap;
|
||||
rp->re_emap = (u_int8_t *)rp->re_smap + (rp->re_msize = size);
|
||||
@ -940,7 +941,7 @@ __ram_writeback(dbp)
|
||||
* open will fail.
|
||||
*/
|
||||
if (rp->re_smap != NULL) {
|
||||
(void)__db_munmap(rp->re_smap, rp->re_msize);
|
||||
(void)__db_unmap(rp->re_smap, rp->re_msize);
|
||||
rp->re_smap = NULL;
|
||||
}
|
||||
|
||||
@ -951,7 +952,7 @@ __ram_writeback(dbp)
|
||||
}
|
||||
|
||||
/* Open the file, truncating it. */
|
||||
if ((ret = __db_fdopen(rp->re_source,
|
||||
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));
|
||||
@ -974,7 +975,7 @@ __ram_writeback(dbp)
|
||||
*/
|
||||
delim = rp->re_delim;
|
||||
if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
|
||||
if ((pad = malloc(rp->re_len)) == NULL) {
|
||||
if ((pad = (u_int8_t *)__db_malloc(rp->re_len)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -1051,8 +1052,8 @@ __ram_fmap(dbp, top)
|
||||
rp = t->bt_recno;
|
||||
if (t->bt_rdata.ulen < rp->re_len) {
|
||||
t->bt_rdata.data = t->bt_rdata.data == NULL ?
|
||||
(void *)malloc(rp->re_len) :
|
||||
(void *)realloc(t->bt_rdata.data, rp->re_len);
|
||||
(void *)__db_malloc(rp->re_len) :
|
||||
(void *)__db_realloc(t->bt_rdata.data, rp->re_len);
|
||||
if (t->bt_rdata.data == NULL) {
|
||||
t->bt_rdata.ulen = 0;
|
||||
return (ENOMEM);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_search.c 10.7 (Sleepycat) 9/3/97";
|
||||
static const char sccsid[] = "@(#)bt_search.c 10.8 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -323,7 +323,7 @@ __bam_stkgrow(t)
|
||||
|
||||
entries = t->bt_esp - t->bt_sp;
|
||||
|
||||
if ((p = (EPG *)calloc(entries * 2, sizeof(EPG))) == NULL)
|
||||
if ((p = (EPG *)__db_calloc(entries * 2, sizeof(EPG))) == NULL)
|
||||
return (ENOMEM);
|
||||
memcpy(p, t->bt_sp, entries * sizeof(EPG));
|
||||
if (t->bt_sp != t->bt_stack)
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_split.c 10.14 (Sleepycat) 9/3/97";
|
||||
static const char sccsid[] = "@(#)bt_split.c 10.17 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -255,7 +255,7 @@ __bam_page(dbp, pp, cp)
|
||||
cp->page->level, TYPE(cp->page));
|
||||
|
||||
/* Create new left page for the split. */
|
||||
if ((lp = (PAGE *)malloc(dbp->pgsize)) == NULL) {
|
||||
if ((lp = (PAGE *)__db_malloc(dbp->pgsize)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -389,6 +389,9 @@ __bam_broot(dbp, rootp, lp, rp)
|
||||
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.
|
||||
@ -399,15 +402,12 @@ __bam_broot(dbp, rootp, lp, rp)
|
||||
if (F_ISSET(dbp, DB_BT_RECNUM)) {
|
||||
bi.nrecs = __bam_total(lp);
|
||||
RE_NREC_SET(rootp, bi.nrecs);
|
||||
}
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
} else
|
||||
bi.nrecs = 0;
|
||||
hdr.data = &bi;
|
||||
hdr.size = SSZA(BINTERNAL, data);
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.data = (char *)"";
|
||||
data.size = 0;
|
||||
if ((ret =
|
||||
__db_pitem(dbp, rootp, 0, BINTERNAL_SIZE(0), &hdr, &data)) != 0)
|
||||
__db_pitem(dbp, rootp, 0, BINTERNAL_SIZE(0), &hdr, NULL)) != 0)
|
||||
return (ret);
|
||||
|
||||
switch (TYPE(rp)) {
|
||||
@ -431,9 +431,10 @@ __bam_broot(dbp, rootp, lp, rp)
|
||||
return (ret);
|
||||
|
||||
/* Increment the overflow ref count. */
|
||||
if (B_TYPE(child_bi->type) == B_OVERFLOW && (ret =
|
||||
__db_ioff(dbp, ((BOVERFLOW *)(child_bi->data))->pgno)) != 0)
|
||||
return (ret);
|
||||
if (B_TYPE(child_bi->type) == B_OVERFLOW)
|
||||
if ((ret = __db_ovref(dbp,
|
||||
((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. */
|
||||
@ -473,9 +474,10 @@ __bam_broot(dbp, rootp, lp, rp)
|
||||
return (ret);
|
||||
|
||||
/* Increment the overflow ref count. */
|
||||
if (B_TYPE(child_bk->type) == B_OVERFLOW && (ret =
|
||||
__db_ioff(dbp, ((BOVERFLOW *)child_bk)->pgno)) != 0)
|
||||
return (ret);
|
||||
if (B_TYPE(child_bk->type) == B_OVERFLOW)
|
||||
if ((ret = __db_ovref(dbp,
|
||||
((BOVERFLOW *)child_bk)->pgno, 1)) != 0)
|
||||
return (ret);
|
||||
break;
|
||||
default:
|
||||
return (__db_pgfmt(dbp, rp->pgno));
|
||||
@ -604,9 +606,10 @@ __bam_pinsert(dbp, parent, lchild, rchild)
|
||||
return (ret);
|
||||
|
||||
/* Increment the overflow ref count. */
|
||||
if (B_TYPE(child_bi->type) == B_OVERFLOW && (ret =
|
||||
__db_ioff(dbp, ((BOVERFLOW *)(child_bi->data))->pgno)) != 0)
|
||||
return (ret);
|
||||
if (B_TYPE(child_bi->type) == B_OVERFLOW)
|
||||
if ((ret = __db_ovref(dbp,
|
||||
((BOVERFLOW *)(child_bi->data))->pgno, 1)) != 0)
|
||||
return (ret);
|
||||
break;
|
||||
case P_LBTREE:
|
||||
child_bk = GET_BKEYDATA(rchild, 0);
|
||||
@ -673,9 +676,10 @@ noprefix: nksize = child_bk->len;
|
||||
return (ret);
|
||||
|
||||
/* Increment the overflow ref count. */
|
||||
if (B_TYPE(child_bk->type) == B_OVERFLOW && (ret =
|
||||
__db_ioff(dbp, ((BOVERFLOW *)child_bk)->pgno)) != 0)
|
||||
return (ret);
|
||||
if (B_TYPE(child_bk->type) == B_OVERFLOW)
|
||||
if ((ret = __db_ovref(dbp,
|
||||
((BOVERFLOW *)child_bk)->pgno, 1)) != 0)
|
||||
return (ret);
|
||||
break;
|
||||
default:
|
||||
return (__db_pgfmt(dbp, rchild->pgno));
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)bt_stat.c 10.12 (Sleepycat) 9/3/97";
|
||||
static const char sccsid[] = "@(#)bt_stat.c 10.14 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -61,7 +61,7 @@ __bam_stat(argdbp, spp, db_malloc, flags)
|
||||
|
||||
/* Allocate and clear the structure. */
|
||||
if ((sp = db_malloc == NULL ?
|
||||
(DB_BTREE_STAT *)malloc(sizeof(*sp)) :
|
||||
(DB_BTREE_STAT *)__db_malloc(sizeof(*sp)) :
|
||||
(DB_BTREE_STAT *)db_malloc(sizeof(*sp))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
@ -100,14 +100,13 @@ __bam_stat(argdbp, spp, db_malloc, flags)
|
||||
if (F_ISSET(meta, BTM_RENUMBER))
|
||||
sp->bt_flags |= DB_RENUMBER;
|
||||
|
||||
/*
|
||||
* Get the maxkey, minkey, re_len and re_pad fields from the
|
||||
* metadata.
|
||||
*/
|
||||
/* 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;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)btree.src 10.4 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)btree.src 10.6 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
PREFIX bam
|
||||
@ -75,6 +75,7 @@ END
|
||||
*
|
||||
* pgno: the page number of the page copied over the root.
|
||||
* pgdbt: the page being copied on the root page.
|
||||
* nrec: the tree's record count.
|
||||
* rootent: last entry on the root page.
|
||||
* rootlsn: the root page's original lsn.
|
||||
*/
|
||||
@ -82,6 +83,7 @@ BEGIN rsplit
|
||||
ARG fileid u_int32_t lu
|
||||
ARG pgno db_pgno_t lu
|
||||
DBT pgdbt DBT s
|
||||
ARG nrec db_pgno_t lu
|
||||
DBT rootent DBT s
|
||||
POINTER rootlsn DB_LSN * lu
|
||||
END
|
||||
@ -135,3 +137,24 @@ ARG pgno db_pgno_t lu
|
||||
POINTER lsn DB_LSN * lu
|
||||
ARG indx u_int32_t lu
|
||||
END
|
||||
|
||||
/*
|
||||
* BTREE-repl: used to log the replacement of an item.
|
||||
*
|
||||
* pgno: the page modified.
|
||||
* lsn: the page's original lsn.
|
||||
* orig: the original data.
|
||||
* new: the replacement data.
|
||||
* duplicate: the prefix of the replacement that matches the original.
|
||||
*/
|
||||
BEGIN repl
|
||||
ARG fileid u_int32_t lu
|
||||
ARG pgno db_pgno_t lu
|
||||
POINTER lsn DB_LSN * lu
|
||||
ARG indx u_int32_t lu
|
||||
ARG isdeleted u_int32_t lu
|
||||
DBT orig DBT s
|
||||
DBT repl DBT s
|
||||
ARG prefix u_int32_t lu
|
||||
ARG suffix u_int32_t lu
|
||||
END
|
||||
|
@ -57,7 +57,7 @@ int __bam_pg_alloc_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(pgno)
|
||||
+ sizeof(ptype)
|
||||
+ sizeof(next);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -92,7 +92,7 @@ int __bam_pg_alloc_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ __bam_pg_alloc_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tptype: %lu\n", (u_long)argp->ptype);
|
||||
printf("\tnext: %lu\n", (u_long)argp->next);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ __bam_pg_alloc_read(recbuf, argpp)
|
||||
__bam_pg_alloc_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_pg_alloc_args *)malloc(sizeof(__bam_pg_alloc_args) +
|
||||
argp = (__bam_pg_alloc_args *)__db_malloc(sizeof(__bam_pg_alloc_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -219,7 +219,7 @@ int __bam_pg_free_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*meta_lsn)
|
||||
+ sizeof(u_int32_t) + (header == NULL ? 0 : header->size)
|
||||
+ sizeof(next);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -257,7 +257,7 @@ int __bam_pg_free_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ __bam_pg_free_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\n");
|
||||
printf("\tnext: %lu\n", (u_long)argp->next);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -323,7 +323,7 @@ __bam_pg_free_read(recbuf, argpp)
|
||||
__bam_pg_free_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_pg_free_args *)malloc(sizeof(__bam_pg_free_args) +
|
||||
argp = (__bam_pg_free_args *)__db_malloc(sizeof(__bam_pg_free_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -400,7 +400,7 @@ int __bam_split_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(npgno)
|
||||
+ sizeof(*nlsn)
|
||||
+ sizeof(u_int32_t) + (pg == NULL ? 0 : pg->size);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -452,7 +452,7 @@ int __bam_split_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ __bam_split_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ __bam_split_read(recbuf, argpp)
|
||||
__bam_split_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_split_args *)malloc(sizeof(__bam_split_args) +
|
||||
argp = (__bam_split_args *)__db_malloc(sizeof(__bam_split_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -563,11 +563,11 @@ __bam_split_read(recbuf, argpp)
|
||||
/*
|
||||
* PUBLIC: int __bam_rsplit_log
|
||||
* PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
|
||||
* PUBLIC: u_int32_t, db_pgno_t, DBT *, DBT *,
|
||||
* PUBLIC: DB_LSN *));
|
||||
* PUBLIC: u_int32_t, db_pgno_t, DBT *, db_pgno_t,
|
||||
* PUBLIC: DBT *, DB_LSN *));
|
||||
*/
|
||||
int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
|
||||
fileid, pgno, pgdbt, rootent, rootlsn)
|
||||
fileid, pgno, pgdbt, nrec, rootent, rootlsn)
|
||||
DB_LOG *logp;
|
||||
DB_TXN *txnid;
|
||||
DB_LSN *ret_lsnp;
|
||||
@ -575,6 +575,7 @@ int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
|
||||
u_int32_t fileid;
|
||||
db_pgno_t pgno;
|
||||
DBT *pgdbt;
|
||||
db_pgno_t nrec;
|
||||
DBT *rootent;
|
||||
DB_LSN * rootlsn;
|
||||
{
|
||||
@ -597,9 +598,10 @@ int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
|
||||
+ 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 ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -623,6 +625,8 @@ int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
|
||||
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));
|
||||
@ -645,7 +649,7 @@ int __bam_rsplit_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -692,6 +696,7 @@ __bam_rsplit_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("%#x ", c);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\tnrec: %lu\n", (u_long)argp->nrec);
|
||||
printf("\trootent: ");
|
||||
for (i = 0; i < argp->rootent.size; i++) {
|
||||
c = ((char *)argp->rootent.data)[i];
|
||||
@ -704,7 +709,7 @@ __bam_rsplit_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\trootlsn: [%lu][%lu]\n",
|
||||
(u_long)argp->rootlsn.file, (u_long)argp->rootlsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -719,7 +724,7 @@ __bam_rsplit_read(recbuf, argpp)
|
||||
__bam_rsplit_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_rsplit_args *)malloc(sizeof(__bam_rsplit_args) +
|
||||
argp = (__bam_rsplit_args *)__db_malloc(sizeof(__bam_rsplit_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -739,6 +744,8 @@ __bam_rsplit_read(recbuf, argpp)
|
||||
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;
|
||||
@ -789,7 +796,7 @@ int __bam_adj_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(indx)
|
||||
+ sizeof(indx_copy)
|
||||
+ sizeof(is_insert);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -821,7 +828,7 @@ int __bam_adj_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -865,7 +872,7 @@ __bam_adj_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tindx_copy: %lu\n", (u_long)argp->indx_copy);
|
||||
printf("\tis_insert: %lu\n", (u_long)argp->is_insert);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -880,7 +887,7 @@ __bam_adj_read(recbuf, argpp)
|
||||
__bam_adj_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_adj_args *)malloc(sizeof(__bam_adj_args) +
|
||||
argp = (__bam_adj_args *)__db_malloc(sizeof(__bam_adj_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -948,7 +955,7 @@ int __bam_cadjust_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(indx)
|
||||
+ sizeof(adjust)
|
||||
+ sizeof(total);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -980,7 +987,7 @@ int __bam_cadjust_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1024,7 +1031,7 @@ __bam_cadjust_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tadjust: %ld\n", (long)argp->adjust);
|
||||
printf("\ttotal: %ld\n", (long)argp->total);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1039,7 +1046,7 @@ __bam_cadjust_read(recbuf, argpp)
|
||||
__bam_cadjust_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_cadjust_args *)malloc(sizeof(__bam_cadjust_args) +
|
||||
argp = (__bam_cadjust_args *)__db_malloc(sizeof(__bam_cadjust_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1102,7 +1109,7 @@ int __bam_cdel_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(pgno)
|
||||
+ sizeof(*lsn)
|
||||
+ sizeof(indx);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -1130,7 +1137,7 @@ int __bam_cdel_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1172,7 +1179,7 @@ __bam_cdel_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
(u_long)argp->lsn.file, (u_long)argp->lsn.offset);
|
||||
printf("\tindx: %lu\n", (u_long)argp->indx);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1187,7 +1194,7 @@ __bam_cdel_read(recbuf, argpp)
|
||||
__bam_cdel_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__bam_cdel_args *)malloc(sizeof(__bam_cdel_args) +
|
||||
argp = (__bam_cdel_args *)__db_malloc(sizeof(__bam_cdel_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1211,6 +1218,225 @@ __bam_cdel_read(recbuf, argpp)
|
||||
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, DBT *, 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;
|
||||
DBT *orig;
|
||||
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) {
|
||||
null_lsn.file = 0;
|
||||
null_lsn.offset = 0;
|
||||
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 ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
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 DEBUG
|
||||
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;
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* PUBLIC: int __bam_repl_print
|
||||
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
*/
|
||||
|
||||
int
|
||||
__bam_repl_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
DB_LOG *notused1;
|
||||
DBT *dbtp;
|
||||
DB_LSN *lsnp;
|
||||
int notused3;
|
||||
void *notused4;
|
||||
{
|
||||
__bam_repl_args *argp;
|
||||
u_int32_t i;
|
||||
int c, ret;
|
||||
|
||||
i = 0;
|
||||
c = 0;
|
||||
notused1 = NULL;
|
||||
notused3 = 0;
|
||||
notused4 = 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++) {
|
||||
c = ((char *)argp->orig.data)[i];
|
||||
if (isprint(c) || c == 0xa)
|
||||
putchar(c);
|
||||
else
|
||||
printf("%#x ", c);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\trepl: ");
|
||||
for (i = 0; i < argp->repl.size; i++) {
|
||||
c = ((char *)argp->repl.data)[i];
|
||||
if (isprint(c) || c == 0xa)
|
||||
putchar(c);
|
||||
else
|
||||
printf("%#x ", c);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\tprefix: %lu\n", (u_long)argp->prefix);
|
||||
printf("\tsuffix: %lu\n", (u_long)argp->suffix);
|
||||
printf("\n");
|
||||
__db_free(argp);
|
||||
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;
|
||||
|
||||
argp = (__bam_repl_args *)__db_malloc(sizeof(__bam_repl_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
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 *));
|
||||
*/
|
||||
@ -1241,6 +1467,9 @@ __bam_init_print(dbenv)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1274,6 +1503,9 @@ __bam_init_recover(dbenv)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_appinit.c 10.33 (Sleepycat) 8/28/97";
|
||||
static const char sccsid[] = "@(#)db_appinit.c 10.36 (Sleepycat) 10/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -93,6 +93,10 @@ db_appinit(db_home, db_config, dbenv, flags)
|
||||
LF_ISSET(RECOVERY_FLAGS) != RECOVERY_FLAGS)
|
||||
return (__db_ferr(dbenv, "db_appinit", 1));
|
||||
|
||||
/* Convert the db_appinit(3) flags. */
|
||||
if (LF_ISSET(DB_THREAD))
|
||||
F_SET(dbenv, DB_ENV_THREAD);
|
||||
|
||||
fp = NULL;
|
||||
|
||||
/* Set the database home. */
|
||||
@ -126,7 +130,7 @@ db_appinit(db_home, db_config, dbenv, flags)
|
||||
goto err;
|
||||
|
||||
/* Indicate that the path names have been set. */
|
||||
F_SET(dbenv, DB_APP_INIT);
|
||||
F_SET(dbenv, DB_ENV_APPINIT);
|
||||
|
||||
/*
|
||||
* If we are doing recovery, remove all the regions.
|
||||
@ -300,7 +304,8 @@ __db_appname(dbenv, appname, dir, file, fdp, namep)
|
||||
* return.
|
||||
*/
|
||||
if (file != NULL && __db_abspath(file))
|
||||
return ((*namep = (char *)strdup(file)) == NULL ? ENOMEM : 0);
|
||||
return ((*namep =
|
||||
(char *)__db_strdup(file)) == NULL ? ENOMEM : 0);
|
||||
if (dir != NULL && __db_abspath(dir)) {
|
||||
a = dir;
|
||||
goto done;
|
||||
@ -335,7 +340,7 @@ __db_appname(dbenv, appname, dir, file, fdp, namep)
|
||||
*/
|
||||
retry: switch (appname) {
|
||||
case DB_APP_NONE:
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_APP_INIT)) {
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
|
||||
if (dir == NULL)
|
||||
goto tmp;
|
||||
a = dir;
|
||||
@ -355,7 +360,7 @@ retry: switch (appname) {
|
||||
tmp_create = 1;
|
||||
goto tmp;
|
||||
}
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_APP_INIT))
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT))
|
||||
a = PATH_DOT;
|
||||
else {
|
||||
a = dbenv->db_home;
|
||||
@ -367,7 +372,7 @@ retry: switch (appname) {
|
||||
}
|
||||
break;
|
||||
case DB_APP_LOG:
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_APP_INIT)) {
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
|
||||
if (dir == NULL)
|
||||
goto tmp;
|
||||
a = dir;
|
||||
@ -385,7 +390,7 @@ retry: switch (appname) {
|
||||
}
|
||||
|
||||
tmp_create = 1;
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_APP_INIT))
|
||||
if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT))
|
||||
goto tmp;
|
||||
else {
|
||||
a = dbenv->db_home;
|
||||
@ -396,7 +401,7 @@ retry: switch (appname) {
|
||||
|
||||
/* Reference a file from the appropriate temporary directory. */
|
||||
if (0) {
|
||||
tmp: if (dbenv == NULL || !F_ISSET(dbenv, DB_APP_INIT)) {
|
||||
tmp: if (dbenv == NULL || !F_ISSET(dbenv, DB_ENV_APPINIT)) {
|
||||
memset(&etmp, 0, sizeof(etmp));
|
||||
if ((ret = __db_tmp_dir(&etmp, DB_USE_ENVIRON)) != 0)
|
||||
return (ret);
|
||||
@ -412,7 +417,7 @@ done: len =
|
||||
(c == NULL ? 0 : strlen(c) + 1) +
|
||||
(file == NULL ? 0 : strlen(file) + 1);
|
||||
|
||||
if ((start = (char *)malloc(len)) == NULL) {
|
||||
if ((start = (char *)__db_malloc(len)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
if (tmp_free)
|
||||
FREES(etmp.db_tmp_dir);
|
||||
@ -484,7 +489,7 @@ __db_home(dbenv, db_home, flags)
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
|
||||
if ((dbenv->db_home = (char *)strdup(p)) == NULL) {
|
||||
if ((dbenv->db_home = (char *)__db_strdup(p)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -509,7 +514,7 @@ __db_parse(dbenv, s)
|
||||
* We need to strdup the argument in case the caller passed us
|
||||
* static data.
|
||||
*/
|
||||
if ((local_s = (char *)strdup(s)) == NULL)
|
||||
if ((local_s = (char *)__db_strdup(s)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
tp = local_s;
|
||||
@ -526,14 +531,15 @@ illegal: ret = EINVAL;
|
||||
#define DATA_INIT_CNT 20 /* Start with 20 data slots. */
|
||||
if (!strcmp(name, "DB_DATA_DIR")) {
|
||||
if (dbenv->db_data_dir == NULL) {
|
||||
if ((dbenv->db_data_dir = (char **)calloc(DATA_INIT_CNT,
|
||||
if ((dbenv->db_data_dir =
|
||||
(char **)__db_calloc(DATA_INIT_CNT,
|
||||
sizeof(char **))) == NULL)
|
||||
goto nomem;
|
||||
dbenv->data_cnt = DATA_INIT_CNT;
|
||||
} else if (dbenv->data_next == dbenv->data_cnt - 1) {
|
||||
dbenv->data_cnt *= 2;
|
||||
if ((dbenv->db_data_dir =
|
||||
(char **)realloc(dbenv->db_data_dir,
|
||||
(char **)__db_realloc(dbenv->db_data_dir,
|
||||
dbenv->data_cnt * sizeof(char **))) == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
@ -549,7 +555,7 @@ illegal: ret = EINVAL;
|
||||
} else
|
||||
goto err;
|
||||
|
||||
if ((*p = (char *)strdup(value)) == NULL) {
|
||||
if ((*p = (char *)__db_strdup(value)) == NULL) {
|
||||
nomem: ret = ENOMEM;
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
}
|
||||
@ -623,7 +629,7 @@ __db_tmp_dir(dbenv, flags)
|
||||
if (!Special2FSSpec(kTemporaryFolderType,
|
||||
kOnSystemDisk, 0, &spec)) {
|
||||
p = FSp2FullPath(&spec);
|
||||
sTempFolder = malloc(strlen(p) + 1);
|
||||
sTempFolder = __db_malloc(strlen(p) + 1);
|
||||
strcpy(sTempFolder, p);
|
||||
p = sTempFolder;
|
||||
}
|
||||
@ -639,7 +645,7 @@ __db_tmp_dir(dbenv, flags)
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
|
||||
if ((dbenv->db_tmp_dir = (char *)strdup(p)) == NULL) {
|
||||
if ((dbenv->db_tmp_dir = (char *)__db_strdup(p)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -722,7 +728,7 @@ __db_tmp_open(dbenv, dir, fdp)
|
||||
(void)sigprocmask(SIG_BLOCK, &set, &oset);
|
||||
#endif
|
||||
#define DB_TEMPOPEN DB_CREATE | DB_EXCL | DB_TEMPORARY
|
||||
if ((ret = __db_fdopen(buf,
|
||||
if ((ret = __db_open(buf,
|
||||
DB_TEMPOPEN, DB_TEMPOPEN, S_IRUSR | S_IWUSR, fdp)) == 0) {
|
||||
#ifdef HAVE_SIGFILLSET
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
@ -11,7 +11,7 @@
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1997\n\
|
||||
Sleepycat Software Inc. All rights reserved.\n";
|
||||
static const char sccsid[] = "@(#)db_apprec.c 10.16 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)db_apprec.c 10.18 (Sleepycat) 9/30/97";
|
||||
#endif
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -31,12 +31,6 @@ static const char sccsid[] = "@(#)db_apprec.c 10.16 (Sleepycat) 8/27/97";
|
||||
#include "txn.h"
|
||||
#include "common_ext.h"
|
||||
|
||||
#define FREE_DBT(L, D) { \
|
||||
if (F_ISSET((L), DB_AM_THREAD) && (D).data != NULL) \
|
||||
free((D).data); \
|
||||
(D).data = NULL; \
|
||||
} \
|
||||
|
||||
/*
|
||||
* __db_apprec --
|
||||
* Perform recovery.
|
||||
@ -52,13 +46,22 @@ __db_apprec(dbenv, flags)
|
||||
DB_LOG *lp;
|
||||
DB_LSN ckp_lsn, first_lsn, lsn, tmp_lsn;
|
||||
time_t now;
|
||||
int first_flag, ret;
|
||||
int first_flag, is_thread, 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);
|
||||
|
||||
/*
|
||||
* Read forward through the log, opening the appropriate files so that
|
||||
* we can call recovery routines. In general, we start at the last
|
||||
@ -66,20 +69,18 @@ __db_apprec(dbenv, flags)
|
||||
* recovery, we begin at the first LSN that appears in any log file
|
||||
* (log_get figures this out for us when we pass it the DB_FIRST flag).
|
||||
*/
|
||||
lp = dbenv->lg_info;
|
||||
if (LF_ISSET(DB_RECOVER_FATAL))
|
||||
first_flag = DB_FIRST;
|
||||
else {
|
||||
if ((ret = __log_findckp(lp, &lsn)) == DB_NOTFOUND)
|
||||
if ((ret = __log_findckp(lp, &lsn)) == DB_NOTFOUND) {
|
||||
F_SET(lp, is_thread);
|
||||
return (0);
|
||||
}
|
||||
first_flag = DB_SET;
|
||||
}
|
||||
|
||||
/* If we're a threaded application, we have to allocate space. */
|
||||
memset(&data, 0, sizeof(data));
|
||||
if (F_ISSET(lp, DB_AM_THREAD))
|
||||
F_SET(&data, DB_DBT_MALLOC);
|
||||
|
||||
if ((ret = log_get(lp, &lsn, &data, first_flag)) != 0) {
|
||||
__db_err(dbenv, "Failure: unable to get log record");
|
||||
if (first_flag == DB_SET)
|
||||
@ -93,7 +94,6 @@ __db_apprec(dbenv, flags)
|
||||
first_lsn = lsn;
|
||||
for (;;) {
|
||||
ret = __db_dispatch(lp, &data, &lsn, TXN_OPENFILES, txninfo);
|
||||
FREE_DBT(lp, data);
|
||||
if (ret != 0 && ret != DB_TXN_CKP)
|
||||
goto msgerr;
|
||||
if ((ret =
|
||||
@ -103,7 +103,6 @@ __db_apprec(dbenv, flags)
|
||||
break;
|
||||
}
|
||||
}
|
||||
FREE_DBT(lp, data);
|
||||
|
||||
/*
|
||||
* Initialize the ckp_lsn to 0,0. If we never find a valid
|
||||
@ -116,7 +115,6 @@ __db_apprec(dbenv, flags)
|
||||
tmp_lsn = lsn;
|
||||
ret = __db_dispatch(lp,
|
||||
&data, &lsn, TXN_BACKWARD_ROLL, txninfo);
|
||||
FREE_DBT(lp, data);
|
||||
if (ret == DB_TXN_CKP) {
|
||||
if (IS_ZERO_LSN(ckp_lsn))
|
||||
ckp_lsn = tmp_lsn;
|
||||
@ -124,20 +122,17 @@ __db_apprec(dbenv, flags)
|
||||
} else if (ret != 0)
|
||||
goto msgerr;
|
||||
}
|
||||
FREE_DBT(lp, data);
|
||||
if (ret != 0 && ret != DB_NOTFOUND)
|
||||
goto err;
|
||||
|
||||
for (ret = log_get(lp, &lsn, &data, DB_NEXT);
|
||||
ret == 0; ret = log_get(lp, &lsn, &data, DB_NEXT)) {
|
||||
ret = __db_dispatch(lp, &data, &lsn, TXN_FORWARD_ROLL, txninfo);
|
||||
FREE_DBT(lp, data);
|
||||
if (ret == DB_TXN_CKP)
|
||||
ret = 0;
|
||||
else if (ret != 0)
|
||||
goto msgerr;
|
||||
}
|
||||
FREE_DBT(lp, data);
|
||||
if (ret != DB_NOTFOUND)
|
||||
goto err;
|
||||
|
||||
@ -165,11 +160,12 @@ __db_apprec(dbenv, flags)
|
||||
(u_long)dbenv->tx_info->region->last_ckp.offset);
|
||||
}
|
||||
|
||||
F_SET(lp, is_thread);
|
||||
return (0);
|
||||
|
||||
msgerr: __db_err(dbenv, "Recovery function for LSN %lu %lu failed",
|
||||
(u_long)lsn.file, (u_long)lsn.offset);
|
||||
|
||||
err: FREE_DBT(lp, data);
|
||||
err: F_SET(lp, is_thread);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -8,20 +8,20 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_byteorder.c 10.3 (Sleepycat) 6/21/97";
|
||||
static const char sccsid[] = "@(#)db_byteorder.c 10.4 (Sleepycat) 9/4/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define WORDS_BIGENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
# if BYTE_ORDER == BIG_ENDIAN
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_region.c 10.13 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)db_region.c 10.15 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -114,7 +114,7 @@ __db_rcreate(dbenv, appname, path, file, mode, size, fdp, retp)
|
||||
* attempts to create the region will return failure in one of the
|
||||
* attempts.
|
||||
*/
|
||||
if (fd == -1 && (ret = __db_fdopen(name,
|
||||
if (fd == -1 && (ret = __db_open(name,
|
||||
DB_CREATE | DB_EXCL, DB_CREATE | DB_EXCL, mode, &fd)) != 0) {
|
||||
if (ret != EEXIST)
|
||||
__db_err(dbenv,
|
||||
@ -131,6 +131,42 @@ __db_rcreate(dbenv, appname, path, file, mode, size, fdp, retp)
|
||||
if ((ret = __db_rmap(dbenv, fd, size, &rp)) != 0)
|
||||
goto err;
|
||||
|
||||
/* Initialize the region. */
|
||||
if ((ret = __db_rinit(dbenv, rp, fd, size, 1)) != 0)
|
||||
goto err;
|
||||
|
||||
if (name != NULL)
|
||||
FREES(name);
|
||||
|
||||
*(void **)retp = rp;
|
||||
return (0);
|
||||
|
||||
err: if (fd != -1) {
|
||||
if (rp != NULL)
|
||||
(void)__db_unmap(rp, rp->size);
|
||||
(void)__db_unlink(name);
|
||||
(void)__db_close(fd);
|
||||
}
|
||||
if (name != NULL)
|
||||
FREES(name);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_rinit --
|
||||
* Initialize the region.
|
||||
*
|
||||
* PUBLIC: int __db_rinit __P((DB_ENV *, RLAYOUT *, int, size_t, int));
|
||||
*/
|
||||
int
|
||||
__db_rinit(dbenv, rp, fd, size, lock_region)
|
||||
DB_ENV *dbenv;
|
||||
RLAYOUT *rp;
|
||||
size_t size;
|
||||
int fd, lock_region;
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Initialize the common information.
|
||||
*
|
||||
@ -141,9 +177,12 @@ __db_rcreate(dbenv, appname, path, file, mode, size, fdp, retp)
|
||||
* file permissions games, but we can't because WNT filesystems won't
|
||||
* open a file mode 0.
|
||||
*
|
||||
* So, the process that's creating the region always acquires the lock
|
||||
* before the setting the version number. Any process joining always
|
||||
* checks the version number before attempting to acquire the lock.
|
||||
* If the lock_region flag is set, the process creating the region
|
||||
* acquires the lock before the setting the version number. Any
|
||||
* process joining the region checks the version number before
|
||||
* attempting to acquire the lock. (The lock_region flag may not be
|
||||
* set -- the mpool code sometimes malloc's private regions but still
|
||||
* needs to initialize them, specifically, the mutex for threads.)
|
||||
*
|
||||
* We have to check the version number first, because if the version
|
||||
* number has not been written, it's possible that the mutex has not
|
||||
@ -151,30 +190,16 @@ __db_rcreate(dbenv, appname, path, file, mode, size, fdp, retp)
|
||||
* random behavior. If the version number isn't there (the file size
|
||||
* is too small) or it's 0, we know that the region is being created.
|
||||
*/
|
||||
(void)__db_mutex_init(&rp->lock, MUTEX_LOCK_OFFSET(rp, &rp->lock));
|
||||
(void)__db_mutex_lock(&rp->lock,
|
||||
fd, dbenv == NULL ? NULL : dbenv->db_yield);
|
||||
__db_mutex_init(&rp->lock, MUTEX_LOCK_OFFSET(rp, &rp->lock));
|
||||
if (lock_region && (ret = __db_mutex_lock(&rp->lock, fd)) != 0)
|
||||
return (ret);
|
||||
|
||||
rp->refcnt = 1;
|
||||
rp->size = size;
|
||||
rp->flags = 0;
|
||||
db_version(&rp->majver, &rp->minver, &rp->patch);
|
||||
|
||||
if (name != NULL)
|
||||
FREES(name);
|
||||
|
||||
*(void **)retp = rp;
|
||||
return (0);
|
||||
|
||||
err: if (fd != -1) {
|
||||
if (rp != NULL)
|
||||
(void)__db_munmap(rp, rp->size);
|
||||
(void)__db_unlink(name);
|
||||
(void)__db_close(fd);
|
||||
}
|
||||
if (name != NULL)
|
||||
FREES(name);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -205,7 +230,7 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
|
||||
return (ret);
|
||||
|
||||
/* Open the file. */
|
||||
if ((ret = __db_fdopen(name, flags, DB_MUTEXDEBUG, 0, &fd)) != 0) {
|
||||
if ((ret = __db_open(name, flags, DB_MUTEXDEBUG, 0, &fd)) != 0) {
|
||||
__db_err(dbenv, "region open: %s: %s", name, strerror(ret));
|
||||
goto err2;
|
||||
}
|
||||
@ -225,8 +250,10 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
|
||||
* flatly impossible. Hope that mmap fails if the file is too large.
|
||||
*
|
||||
*/
|
||||
if ((ret = __db_stat(dbenv, name, fd, &size1, NULL)) != 0)
|
||||
if ((ret = __db_ioinfo(name, fd, &size1, NULL)) != 0) {
|
||||
__db_err(dbenv, "%s: %s", name, strerror(ret));
|
||||
goto err2;
|
||||
}
|
||||
|
||||
/* Check to make sure the first block has been written. */
|
||||
if ((size_t)size1 < sizeof(RLAYOUT)) {
|
||||
@ -249,16 +276,17 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
|
||||
|
||||
/* Get the region lock. */
|
||||
if (!LF_ISSET(DB_MUTEXDEBUG))
|
||||
(void)__db_mutex_lock(&rp->lock,
|
||||
fd, dbenv == NULL ? NULL : dbenv->db_yield);
|
||||
(void)__db_mutex_lock(&rp->lock, fd);
|
||||
|
||||
/*
|
||||
* The file may have been half-written if we were descheduled between
|
||||
* getting the size of the file and checking the major version. Check
|
||||
* to make sure we got the entire file.
|
||||
*/
|
||||
if ((ret = __db_stat(dbenv, name, fd, &size2, NULL)) != 0)
|
||||
if ((ret = __db_ioinfo(name, fd, &size2, NULL)) != 0) {
|
||||
__db_err(dbenv, "%s: %s", name, strerror(ret));
|
||||
goto err1;
|
||||
}
|
||||
if (size1 != size2) {
|
||||
ret = EAGAIN;
|
||||
goto err1;
|
||||
@ -285,7 +313,7 @@ __db_ropen(dbenv, appname, path, file, flags, fdp, retp)
|
||||
err1: if (!LF_ISSET(DB_MUTEXDEBUG))
|
||||
(void)__db_mutex_unlock(&rp->lock, fd);
|
||||
err2: if (rp != NULL)
|
||||
(void)__db_munmap(rp, rp->size);
|
||||
(void)__db_unmap(rp, rp->size);
|
||||
if (fd != -1)
|
||||
(void)__db_close(fd);
|
||||
FREES(name);
|
||||
@ -312,8 +340,7 @@ __db_rclose(dbenv, fd, ptr)
|
||||
fail = NULL;
|
||||
|
||||
/* Get the lock. */
|
||||
if ((ret = __db_mutex_lock(&rp->lock,
|
||||
fd, dbenv == NULL ? NULL : dbenv->db_yield)) != 0) {
|
||||
if ((ret = __db_mutex_lock(&rp->lock, fd)) != 0) {
|
||||
fail = "lock get";
|
||||
goto err;
|
||||
}
|
||||
@ -328,7 +355,7 @@ __db_rclose(dbenv, fd, ptr)
|
||||
}
|
||||
|
||||
/* Discard the region. */
|
||||
if ((t_ret = __db_munmap(ptr, rp->size)) != 0 && fail == NULL) {
|
||||
if ((t_ret = __db_unmap(ptr, rp->size)) != 0 && fail == NULL) {
|
||||
ret = t_ret;
|
||||
fail = "munmap";
|
||||
}
|
||||
@ -392,8 +419,7 @@ __db_runlink(dbenv, appname, path, file, force)
|
||||
/* Open and lock the region. */
|
||||
if ((ret = __db_ropen(dbenv, appname, path, file, 0, &fd, &rp)) != 0)
|
||||
goto err1;
|
||||
(void)__db_mutex_lock(&rp->lock,
|
||||
fd, dbenv == NULL ? NULL : dbenv->db_yield);
|
||||
(void)__db_mutex_lock(&rp->lock, fd);
|
||||
|
||||
/* If the region is currently being deleted, fail. */
|
||||
if (F_ISSET(rp, DB_R_DELETED)) {
|
||||
@ -434,8 +460,7 @@ __db_runlink(dbenv, appname, path, file, force)
|
||||
/* Not a clue. Try to clear the DB_R_DELETED flag. */
|
||||
if ((ret = __db_ropen(dbenv, appname, path, file, 0, &fd, &rp)) != 0)
|
||||
goto err1;
|
||||
(void)__db_mutex_lock(&rp->lock,
|
||||
fd, dbenv == NULL ? NULL : dbenv->db_yield);
|
||||
(void)__db_mutex_lock(&rp->lock, fd);
|
||||
F_CLR(rp, DB_R_DELETED);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
@ -472,7 +497,7 @@ __db_rgrow(dbenv, fd, incr)
|
||||
char buf[__DB_VMPAGESIZE];
|
||||
|
||||
/* Seek to the end of the region. */
|
||||
if ((ret = __db_lseek(fd, 0, 0, 0, SEEK_END)) != 0)
|
||||
if ((ret = __db_seek(fd, 0, 0, 0, SEEK_END)) != 0)
|
||||
goto err;
|
||||
|
||||
/* Write nuls to the new bytes. */
|
||||
@ -500,7 +525,7 @@ __db_rgrow(dbenv, fd, incr)
|
||||
incr -= incr % __DB_VMPAGESIZE;
|
||||
|
||||
/* Write the last page, not the page after the last. */
|
||||
if ((ret = __db_lseek(fd, 0, 0, incr - __DB_VMPAGESIZE, SEEK_CUR)) != 0)
|
||||
if ((ret = __db_seek(fd, 0, 0, incr - __DB_VMPAGESIZE, SEEK_CUR)) != 0)
|
||||
goto err;
|
||||
if ((ret = __db_write(fd, buf, sizeof(buf), &nw)) != 0)
|
||||
goto err;
|
||||
@ -531,7 +556,7 @@ __db_rremap(dbenv, ptr, oldsize, newsize, fd, retp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = __db_munmap(ptr, oldsize)) != 0) {
|
||||
if ((ret = __db_unmap(ptr, oldsize)) != 0) {
|
||||
__db_err(dbenv, "region remap: munmap: %s", strerror(ret));
|
||||
return (ret);
|
||||
}
|
||||
@ -553,7 +578,7 @@ __db_rmap(dbenv, fd, size, retp)
|
||||
RLAYOUT *rp;
|
||||
int ret;
|
||||
|
||||
if ((ret = __db_mmap(fd, size, 0, 0, &rp)) != 0) {
|
||||
if ((ret = __db_map(fd, size, 0, 0, (void **)&rp)) != 0) {
|
||||
__db_err(dbenv, "region map: mmap %s", strerror(ret));
|
||||
return (ret);
|
||||
}
|
||||
|
135
db2/db.h
135
db2/db.h
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db.h.src 10.77 (Sleepycat) 9/24/97
|
||||
* @(#)db.h.src 10.91 (Sleepycat) 11/3/97
|
||||
*/
|
||||
|
||||
#ifndef _DB_H_
|
||||
@ -28,9 +28,15 @@
|
||||
* 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)
|
||||
#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
|
||||
#define __P(protos) protos /* ANSI C prototypes */
|
||||
#else
|
||||
#define const
|
||||
@ -67,8 +73,8 @@
|
||||
|
||||
#define DB_VERSION_MAJOR 2
|
||||
#define DB_VERSION_MINOR 3
|
||||
#define DB_VERSION_PATCH 10
|
||||
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.10: (9/24/97)"
|
||||
#define DB_VERSION_PATCH 12
|
||||
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.12: (11/3/97)"
|
||||
|
||||
typedef u_int32_t db_pgno_t; /* Page number type. */
|
||||
typedef u_int16_t db_indx_t; /* Page offset type. */
|
||||
@ -93,6 +99,7 @@ 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_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT;
|
||||
@ -121,6 +128,31 @@ struct __db_dbt {
|
||||
u_int32_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* DB configuration. There are a set of functions which the application
|
||||
* can replace with its own versions.
|
||||
*/
|
||||
#define DB_FUNC_CALLOC 1 /* ANSI C calloc. */
|
||||
#define DB_FUNC_CLOSE 2 /* POSIX 1003.1 close. */
|
||||
#define DB_FUNC_DIRFREE 3 /* DB: free directory list. */
|
||||
#define DB_FUNC_DIRLIST 4 /* DB: create directory list. */
|
||||
#define DB_FUNC_EXISTS 5 /* DB: return if file exists. */
|
||||
#define DB_FUNC_FREE 6 /* ANSI C free. */
|
||||
#define DB_FUNC_FSYNC 7 /* POSIX 1003.1 fsync. */
|
||||
#define DB_FUNC_IOINFO 8 /* DB: return file I/O information. */
|
||||
#define DB_FUNC_MALLOC 9 /* ANSI C malloc. */
|
||||
#define DB_FUNC_MAP 10 /* DB: map file into shared memory. */
|
||||
#define DB_FUNC_OPEN 11 /* POSIX 1003.1 open. */
|
||||
#define DB_FUNC_READ 12 /* POSIX 1003.1 read. */
|
||||
#define DB_FUNC_REALLOC 13 /* ANSI C realloc. */
|
||||
#define DB_FUNC_SEEK 14 /* POSIX 1003.1 lseek. */
|
||||
#define DB_FUNC_SLEEP 15 /* DB: sleep secs/usecs. */
|
||||
#define DB_FUNC_STRDUP 16 /* ANSI C strdup. */
|
||||
#define DB_FUNC_UNLINK 17 /* POSIX 1003.1 unlink. */
|
||||
#define DB_FUNC_UNMAP 18 /* DB: unmap shared memory file. */
|
||||
#define DB_FUNC_WRITE 19 /* POSIX 1003.1 write. */
|
||||
#define DB_FUNC_YIELD 20 /* DB: yield thread to scheduler. */
|
||||
|
||||
/*
|
||||
* Database configuration and initialization.
|
||||
*/
|
||||
@ -134,21 +166,20 @@ struct __db_dbt {
|
||||
/*
|
||||
* Flags understood by db_appinit(3).
|
||||
*
|
||||
* DB_APP_INIT and DB_MUTEXDEBUG are internal only, and not documented.
|
||||
* DB_MUTEXDEBUG is internal only, and not documented.
|
||||
*/
|
||||
/* 0x00007 COMMON MASK. */
|
||||
#define DB_APP_INIT 0x00008 /* Appinit called, paths initialized. */
|
||||
#define DB_INIT_LOCK 0x00010 /* Initialize locking. */
|
||||
#define DB_INIT_LOG 0x00020 /* Initialize logging. */
|
||||
#define DB_INIT_MPOOL 0x00040 /* Initialize mpool. */
|
||||
#define DB_INIT_TXN 0x00080 /* Initialize transactions. */
|
||||
#define DB_MPOOL_PRIVATE 0x00100 /* Mpool: private memory pool. */
|
||||
#define DB_MUTEXDEBUG 0x00200 /* Do not get/set mutexes in regions. */
|
||||
#define DB_RECOVER 0x00400 /* Run normal recovery. */
|
||||
#define DB_RECOVER_FATAL 0x00800 /* Run catastrophic recovery. */
|
||||
#define DB_TXN_NOSYNC 0x01000 /* Do not sync log on commit. */
|
||||
#define DB_USE_ENVIRON 0x02000 /* Use the environment. */
|
||||
#define DB_USE_ENVIRON_ROOT 0x04000 /* Use the environment if root. */
|
||||
#define DB_INIT_LOCK 0x00008 /* Initialize locking. */
|
||||
#define DB_INIT_LOG 0x00010 /* Initialize logging. */
|
||||
#define DB_INIT_MPOOL 0x00020 /* Initialize mpool. */
|
||||
#define DB_INIT_TXN 0x00040 /* Initialize transactions. */
|
||||
#define DB_MPOOL_PRIVATE 0x00080 /* Mpool: private memory pool. */
|
||||
#define DB_MUTEXDEBUG 0x00100 /* Do not get/set mutexes in regions. */
|
||||
#define DB_RECOVER 0x00200 /* Run normal recovery. */
|
||||
#define DB_RECOVER_FATAL 0x00400 /* Run catastrophic recovery. */
|
||||
#define DB_TXN_NOSYNC 0x00800 /* Do not sync log on commit. */
|
||||
#define DB_USE_ENVIRON 0x01000 /* Use the environment. */
|
||||
#define DB_USE_ENVIRON_ROOT 0x02000 /* Use the environment if root. */
|
||||
|
||||
/* CURRENTLY UNUSED LOCK FLAGS. */
|
||||
#define DB_TXN_LOCK_2PL 0x00000 /* Two-phase locking. */
|
||||
@ -209,7 +240,6 @@ struct __db_env {
|
||||
int lk_modes; /* Number of lock modes in table. */
|
||||
unsigned int lk_max; /* Maximum number of locks. */
|
||||
u_int32_t lk_detect; /* Deadlock detect on every conflict. */
|
||||
int (*db_yield) __P((void)); /* Yield function for threads. */
|
||||
|
||||
/* Logging. */
|
||||
DB_LOG *lg_info; /* Return from log_open(). */
|
||||
@ -226,6 +256,9 @@ struct __db_env {
|
||||
int (*tx_recover) /* Dispatch function for recovery. */
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
|
||||
#define DB_ENV_APPINIT 0x01 /* Paths initialized by db_appinit(). */
|
||||
#define DB_ENV_STANDALONE 0x02 /* Test: freestanding environment. */
|
||||
#define DB_ENV_THREAD 0x04 /* DB_ENV is multi-threaded. */
|
||||
u_int32_t flags; /* Flags. */
|
||||
};
|
||||
|
||||
@ -301,7 +334,7 @@ struct __db_info {
|
||||
#define DB_CURRENT 0x000010 /* c_get(), c_put(), log_get() */
|
||||
#define DB_FIRST 0x000020 /* c_get(), log_get() */
|
||||
#define DB_FLUSH 0x000040 /* log_put() */
|
||||
#define DB_GET_RECNO 0x000080 /* c_get() */
|
||||
#define DB_GET_RECNO 0x000080 /* get(), c_get() */
|
||||
#define DB_KEYFIRST 0x000100 /* c_put() */
|
||||
#define DB_KEYLAST 0x000200 /* c_put() */
|
||||
#define DB_LAST 0x000400 /* c_get(), log_get() */
|
||||
@ -312,7 +345,7 @@ struct __db_info {
|
||||
#define DB_RECORDCOUNT 0x008000 /* stat() */
|
||||
#define DB_SET 0x010000 /* c_get(), log_get() */
|
||||
#define DB_SET_RANGE 0x020000 /* c_get() */
|
||||
#define DB_SET_RECNO 0x040000 /* get(), c_get() */
|
||||
#define DB_SET_RECNO 0x040000 /* c_get() */
|
||||
|
||||
/* DB (user visible) error return codes. */
|
||||
#define DB_INCOMPLETE ( -1) /* Sync didn't finish. */
|
||||
@ -472,6 +505,8 @@ struct __db_bt_stat {
|
||||
u_int32_t bt_get; /* Items retrieved. */
|
||||
u_int32_t bt_cache_hit; /* Hits in fast-insert code. */
|
||||
u_int32_t bt_cache_miss; /* Misses in fast-insert code. */
|
||||
u_int32_t bt_magic; /* Magic number. */
|
||||
u_int32_t bt_version; /* Version number. */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -479,6 +514,7 @@ extern "C" {
|
||||
#endif
|
||||
int db_appinit __P((const char *, char * const *, DB_ENV *, int));
|
||||
int db_appexit __P((DB_ENV *));
|
||||
int db_jump_set __P((void *, int));
|
||||
int db_open __P((const char *, DBTYPE, int, int, DB_ENV *, DB_INFO *, DB **));
|
||||
char *db_version __P((int *, int *, int *));
|
||||
#if defined(__cplusplus)
|
||||
@ -576,6 +612,22 @@ struct __db_lsn {
|
||||
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. */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -588,6 +640,7 @@ int log_get __P((DB_LOG *, DB_LSN *, DBT *, int));
|
||||
int log_open __P((const char *, int, int, DB_ENV *, DB_LOG **));
|
||||
int log_put __P((DB_LOG *, DB_LSN *, const DBT *, int));
|
||||
int log_register __P((DB_LOG *, DB *, const char *, DBTYPE, u_int32_t *));
|
||||
int log_stat __P((DB_LOG *, DB_LOG_STAT **, void *(*)(size_t)));
|
||||
int log_unlink __P((const char *, int, DB_ENV *));
|
||||
int log_unregister __P((DB_LOG *, u_int32_t));
|
||||
#if defined(__cplusplus)
|
||||
@ -610,30 +663,35 @@ int log_unregister __P((DB_LOG *, u_int32_t));
|
||||
/* Mpool statistics structure. */
|
||||
struct __db_mpool_stat {
|
||||
size_t st_cachesize; /* Cache size. */
|
||||
unsigned long st_cache_hit; /* Pages found in the cache. */
|
||||
unsigned long st_cache_miss; /* Pages not found in the cache. */
|
||||
unsigned long st_map; /* Pages from mapped files. */
|
||||
unsigned long st_page_create; /* Pages created in the cache. */
|
||||
unsigned long st_page_in; /* Pages read in. */
|
||||
unsigned long st_page_out; /* Pages written out. */
|
||||
unsigned long st_ro_evict; /* Read-only pages evicted. */
|
||||
unsigned long st_rw_evict; /* Read-write pages evicted. */
|
||||
unsigned long st_hash_buckets; /* Number of hash buckets. */
|
||||
unsigned long st_hash_searches; /* Total hash chain searches. */
|
||||
unsigned long st_hash_longest; /* Longest hash chain searched. */
|
||||
unsigned long st_hash_examined; /* Total hash entries searched. */
|
||||
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. */
|
||||
};
|
||||
|
||||
/* Mpool file statistics structure. */
|
||||
struct __db_mpool_fstat {
|
||||
char *file_name; /* File name. */
|
||||
size_t st_pagesize; /* Page size. */
|
||||
unsigned long st_cache_hit; /* Pages found in the cache. */
|
||||
unsigned long st_cache_miss; /* Pages not found in the cache. */
|
||||
unsigned long st_map; /* Pages from mapped files. */
|
||||
unsigned long st_page_create; /* Pages created in the cache. */
|
||||
unsigned long st_page_in; /* Pages read in. */
|
||||
unsigned long st_page_out; /* Pages written out. */
|
||||
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)
|
||||
@ -654,6 +712,7 @@ int memp_register __P((DB_MPOOL *, int,
|
||||
int memp_stat __P((DB_MPOOL *,
|
||||
DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, void *(*)(size_t)));
|
||||
int memp_sync __P((DB_MPOOL *, DB_LSN *));
|
||||
int memp_trickle __P((DB_MPOOL *, int, int *));
|
||||
int memp_unlink __P((const char *, int, DB_ENV *));
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
|
30
db2/db/db.c
30
db2/db/db.c
@ -44,7 +44,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db.c 10.41 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)db.c 10.44 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -125,13 +125,19 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
|
||||
if ((ret = __db_fchk(dbenv, "db_open", flags, OKFLAGS)) != 0)
|
||||
return (ret);
|
||||
|
||||
if (dbenv != NULL &&
|
||||
LF_ISSET(DB_THREAD) && !F_ISSET(dbenv, DB_ENV_THREAD)) {
|
||||
__db_err(dbenv, "environment not created using DB_THREAD");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Initialize for error return. */
|
||||
fd = -1;
|
||||
need_fileid = 1;
|
||||
real_name = NULL;
|
||||
|
||||
/* Allocate the DB structure, reference the DB_ENV structure. */
|
||||
if ((dbp = (DB *)calloc(1, sizeof(DB))) == NULL) {
|
||||
if ((dbp = (DB *)__db_calloc(1, sizeof(DB))) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -239,7 +245,7 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
|
||||
*/
|
||||
retry_cnt = 0;
|
||||
open_retry: if (LF_ISSET(DB_CREATE)) {
|
||||
if ((ret = __db_fdopen(real_name, flags | DB_EXCL,
|
||||
if ((ret = __db_open(real_name, flags | DB_EXCL,
|
||||
OKFLAGS | DB_EXCL, mode, &fd)) != 0)
|
||||
if (ret == EEXIST) {
|
||||
LF_CLR(DB_CREATE);
|
||||
@ -250,7 +256,7 @@ open_retry: if (LF_ISSET(DB_CREATE)) {
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
if ((ret = __db_fdopen(real_name,
|
||||
if ((ret = __db_open(real_name,
|
||||
flags, OKFLAGS, mode, &fd)) != 0) {
|
||||
__db_err(dbenv, "%s: %s", fname, strerror(ret));
|
||||
goto err;
|
||||
@ -264,8 +270,11 @@ open_retry: if (LF_ISSET(DB_CREATE)) {
|
||||
*/
|
||||
if (dbp->pgsize == 0) {
|
||||
if ((ret =
|
||||
__db_stat(dbenv, real_name, fd, NULL, &io)) != 0)
|
||||
__db_ioinfo(real_name, fd, NULL, &io)) != 0) {
|
||||
__db_err(dbenv,
|
||||
"%s: %s", real_name, strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
if (io < 512)
|
||||
io = 512;
|
||||
if (io > 16 * 1024)
|
||||
@ -477,7 +486,7 @@ empty: /*
|
||||
|
||||
if (dbenv == NULL) {
|
||||
if ((dbp->mp_dbenv =
|
||||
(DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
|
||||
(DB_ENV *)__db_calloc(sizeof(DB_ENV), 1)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -491,9 +500,9 @@ empty: /*
|
||||
restore = 1;
|
||||
}
|
||||
envp->mp_size = cachesize;
|
||||
F_SET(envp, DB_MPOOL_PRIVATE);
|
||||
if ((ret = memp_open(NULL,
|
||||
DB_CREATE, S_IRUSR | S_IWUSR, envp, &dbp->mp)) != 0)
|
||||
if ((ret = memp_open(NULL, DB_CREATE | DB_MPOOL_PRIVATE |
|
||||
(F_ISSET(dbp, DB_AM_THREAD) ? DB_THREAD : 0),
|
||||
S_IRUSR | S_IWUSR, envp, &dbp->mp)) != 0)
|
||||
goto err;
|
||||
if (restore)
|
||||
*dbenv = t_dbenv;
|
||||
@ -725,7 +734,8 @@ db_close(dbp, flags)
|
||||
}
|
||||
|
||||
/* Sync the memory pool. */
|
||||
if ((t_ret = memp_fsync(dbp->mpf)) != 0 && ret == 0)
|
||||
if ((t_ret = memp_fsync(dbp->mpf)) != 0 &&
|
||||
t_ret != DB_INCOMPLETE && ret == 0)
|
||||
ret = t_ret;
|
||||
|
||||
/* Close the memory pool file. */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
* @(#)db.src 10.3 (Sleepycat) 8/18/97
|
||||
* @(#)db.src 10.4 (Sleepycat) 11/2/97
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
@ -81,15 +81,17 @@ POINTER nextlsn DB_LSN * lu
|
||||
END
|
||||
|
||||
/*
|
||||
* ovref -- Handles increment of overflow page reference count.
|
||||
* ovref -- Handles increment/decrement of overflow page reference count.
|
||||
*
|
||||
* fileid: identifies the file being modified.
|
||||
* pgno: page number being incremented.
|
||||
* lsn the page's original lsn.
|
||||
* pgno: page number whose ref count is being incremented/decremented.
|
||||
* adjust: the adjustment being made.
|
||||
* lsn: the page's original lsn.
|
||||
*/
|
||||
BEGIN ovref
|
||||
ARG fileid u_int32_t lu
|
||||
ARG pgno db_pgno_t lu
|
||||
ARG adjust int32_t ld
|
||||
POINTER lsn DB_LSN * lu
|
||||
END
|
||||
|
||||
|
@ -62,7 +62,7 @@ int __db_addrem_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size)
|
||||
+ sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size)
|
||||
+ sizeof(*pagelsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -114,7 +114,7 @@ int __db_addrem_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ __db_addrem_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tpagelsn: [%lu][%lu]\n",
|
||||
(u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -191,7 +191,7 @@ __db_addrem_read(recbuf, argpp)
|
||||
__db_addrem_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_addrem_args *)malloc(sizeof(__db_addrem_args) +
|
||||
argp = (__db_addrem_args *)__db_malloc(sizeof(__db_addrem_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -266,7 +266,7 @@ int __db_split_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(pgno)
|
||||
+ sizeof(u_int32_t) + (pageimage == NULL ? 0 : pageimage->size)
|
||||
+ sizeof(*pagelsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -304,7 +304,7 @@ int __db_split_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ __db_split_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tpagelsn: [%lu][%lu]\n",
|
||||
(u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ __db_split_read(recbuf, argpp)
|
||||
__db_split_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_split_args *)malloc(sizeof(__db_split_args) +
|
||||
argp = (__db_split_args *)__db_malloc(sizeof(__db_split_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -447,7 +447,7 @@ int __db_big_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*pagelsn)
|
||||
+ sizeof(*prevlsn)
|
||||
+ sizeof(*nextlsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -499,7 +499,7 @@ int __db_big_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -556,7 +556,7 @@ __db_big_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tnextlsn: [%lu][%lu]\n",
|
||||
(u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -571,7 +571,7 @@ __db_big_read(recbuf, argpp)
|
||||
__db_big_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_big_args *)malloc(sizeof(__db_big_args) +
|
||||
argp = (__db_big_args *)__db_malloc(sizeof(__db_big_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -610,16 +610,17 @@ __db_big_read(recbuf, argpp)
|
||||
/*
|
||||
* PUBLIC: int __db_ovref_log
|
||||
* PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
|
||||
* PUBLIC: u_int32_t, db_pgno_t, DB_LSN *));
|
||||
* PUBLIC: u_int32_t, db_pgno_t, int32_t, DB_LSN *));
|
||||
*/
|
||||
int __db_ovref_log(logp, txnid, ret_lsnp, flags,
|
||||
fileid, pgno, lsn)
|
||||
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;
|
||||
@ -639,8 +640,9 @@ int __db_ovref_log(logp, txnid, ret_lsnp, flags,
|
||||
logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
|
||||
+ sizeof(fileid)
|
||||
+ sizeof(pgno)
|
||||
+ sizeof(adjust)
|
||||
+ sizeof(*lsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -654,6 +656,8 @@ int __db_ovref_log(logp, txnid, ret_lsnp, flags,
|
||||
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
|
||||
@ -666,7 +670,7 @@ int __db_ovref_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -704,10 +708,11 @@ __db_ovref_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
(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");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -722,7 +727,7 @@ __db_ovref_read(recbuf, argpp)
|
||||
__db_ovref_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_ovref_args *)malloc(sizeof(__db_ovref_args) +
|
||||
argp = (__db_ovref_args *)__db_malloc(sizeof(__db_ovref_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -738,6 +743,8 @@ __db_ovref_read(recbuf, argpp)
|
||||
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;
|
||||
@ -787,7 +794,7 @@ int __db_relink_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*lsn_prev)
|
||||
+ sizeof(next)
|
||||
+ sizeof(*lsn_next);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -827,7 +834,7 @@ int __db_relink_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -874,7 +881,7 @@ __db_relink_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tlsn_next: [%lu][%lu]\n",
|
||||
(u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -889,7 +896,7 @@ __db_relink_read(recbuf, argpp)
|
||||
__db_relink_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_relink_args *)malloc(sizeof(__db_relink_args) +
|
||||
argp = (__db_relink_args *)__db_malloc(sizeof(__db_relink_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -957,7 +964,7 @@ int __db_addpage_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*lsn)
|
||||
+ sizeof(nextpgno)
|
||||
+ sizeof(*nextlsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -990,7 +997,7 @@ int __db_addpage_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1034,7 +1041,7 @@ __db_addpage_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tnextlsn: [%lu][%lu]\n",
|
||||
(u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1049,7 +1056,7 @@ __db_addpage_read(recbuf, argpp)
|
||||
__db_addpage_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_addpage_args *)malloc(sizeof(__db_addpage_args) +
|
||||
argp = (__db_addpage_args *)__db_malloc(sizeof(__db_addpage_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1114,7 +1121,7 @@ int __db_debug_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(u_int32_t) + (key == NULL ? 0 : key->size)
|
||||
+ sizeof(u_int32_t) + (data == NULL ? 0 : data->size)
|
||||
+ sizeof(arg_flags);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -1165,7 +1172,7 @@ int __db_debug_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1231,7 +1238,7 @@ __db_debug_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\n");
|
||||
printf("\targ_flags: %lu\n", (u_long)argp->arg_flags);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1246,7 +1253,7 @@ __db_debug_read(recbuf, argpp)
|
||||
__db_debug_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_debug_args *)malloc(sizeof(__db_debug_args) +
|
||||
argp = (__db_debug_args *)__db_malloc(sizeof(__db_debug_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1303,7 +1310,7 @@ int __db_noop_log(logp, txnid, ret_lsnp, flags)
|
||||
} else
|
||||
lsnp = &txnid->last_lsn;
|
||||
logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -1320,7 +1327,7 @@ int __db_noop_log(logp, txnid, ret_lsnp, flags)
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1357,7 +1364,7 @@ __db_noop_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
(u_long)argp->prev_lsn.file,
|
||||
(u_long)argp->prev_lsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1372,7 +1379,7 @@ __db_noop_read(recbuf, argpp)
|
||||
__db_noop_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__db_noop_args *)malloc(sizeof(__db_noop_args) +
|
||||
argp = (__db_noop_args *)__db_malloc(sizeof(__db_noop_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_dispatch.c 10.5 (Sleepycat) 7/2/97";
|
||||
static const char sccsid[] = "@(#)db_dispatch.c 10.6 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -155,12 +155,12 @@ __db_add_recovery(dbenv, func, ndx)
|
||||
if (ndx >= dispatch_size) {
|
||||
if (dispatch_table == NULL)
|
||||
dispatch_table = (int (**)
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *)))
|
||||
malloc(DB_user_BEGIN * sizeof(dispatch_table[0]));
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *)))
|
||||
__db_malloc(DB_user_BEGIN * sizeof(dispatch_table[0]));
|
||||
else
|
||||
dispatch_table = (int (**)
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *)))
|
||||
realloc(dispatch_table, (DB_user_BEGIN +
|
||||
__db_realloc(dispatch_table, (DB_user_BEGIN +
|
||||
dispatch_size) * sizeof(dispatch_table[0]));
|
||||
if (dispatch_table == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
@ -187,8 +187,8 @@ __db_txnlist_init(retp)
|
||||
{
|
||||
__db_txnhead *headp;
|
||||
|
||||
if ((headp =
|
||||
(struct __db_txnhead *)malloc(sizeof(struct __db_txnhead))) == NULL)
|
||||
if ((headp = (struct __db_txnhead *)
|
||||
__db_malloc(sizeof(struct __db_txnhead))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
LIST_INIT(&headp->head);
|
||||
@ -212,7 +212,7 @@ __db_txnlist_add(listp, txnid)
|
||||
__db_txnhead *hp;
|
||||
__db_txnlist *elp;
|
||||
|
||||
if ((elp = (__db_txnlist *)malloc(sizeof(__db_txnlist))) == NULL)
|
||||
if ((elp = (__db_txnlist *)__db_malloc(sizeof(__db_txnlist))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
elp->txnid = txnid;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_dup.c 10.9 (Sleepycat) 9/3/97";
|
||||
static const char sccsid[] = "@(#)db_dup.c 10.10 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -217,7 +217,7 @@ __db_dsplit(dbp, hp, indxp, size, newfunc)
|
||||
indx = *indxp;
|
||||
|
||||
/* Create a temporary page to do compaction onto. */
|
||||
if ((tp = (PAGE *)malloc(dbp->pgsize)) == NULL)
|
||||
if ((tp = (PAGE *)__db_malloc(dbp->pgsize)) == NULL)
|
||||
return (ENOMEM);
|
||||
#ifdef DEBUG
|
||||
memset(tp, 0xff, dbp->pgsize);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_overflow.c 10.4 (Sleepycat) 7/2/97";
|
||||
static const char sccsid[] = "@(#)db_overflow.c 10.7 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -121,14 +121,14 @@ __db_goff(dbp, dbt, tlen, pgno, bpp, bpsz)
|
||||
}
|
||||
} else if (F_ISSET(dbt, DB_DBT_MALLOC)) {
|
||||
dbt->data = dbp->db_malloc == NULL ?
|
||||
(void *)malloc(needed + 1) :
|
||||
(void *)__db_malloc(needed + 1) :
|
||||
(void *)dbp->db_malloc(needed + 1);
|
||||
if (dbt->data == NULL)
|
||||
return (ENOMEM);
|
||||
} else if (*bpsz == 0 || *bpsz < needed) {
|
||||
*bpp = (*bpp == NULL ?
|
||||
(void *)malloc(needed + 1) :
|
||||
(void *)realloc(*bpp, needed + 1));
|
||||
(void *)__db_malloc(needed + 1) :
|
||||
(void *)__db_realloc(*bpp, needed + 1));
|
||||
if (*bpp == NULL)
|
||||
return (ENOMEM);
|
||||
*bpsz = needed + 1;
|
||||
@ -256,15 +256,16 @@ __db_poff(dbp, dbt, pgnop, newfunc)
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_ioff --
|
||||
* Increment the reference count on an overflow page.
|
||||
* __db_ovref --
|
||||
* Increment/decrement the reference count on an overflow page.
|
||||
*
|
||||
* PUBLIC: int __db_ioff __P((DB *, db_pgno_t));
|
||||
* PUBLIC: int __db_ovref __P((DB *, db_pgno_t, int));
|
||||
*/
|
||||
int
|
||||
__db_ioff(dbp, pgno)
|
||||
__db_ovref(dbp, pgno, adjust)
|
||||
DB *dbp;
|
||||
db_pgno_t pgno;
|
||||
int adjust;
|
||||
{
|
||||
PAGE *h;
|
||||
int ret;
|
||||
@ -274,10 +275,12 @@ __db_ioff(dbp, pgno)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
++OV_REF(h);
|
||||
if (DB_LOGGING(dbp) && (ret = __db_ovref_log(dbp->dbenv->lg_info,
|
||||
dbp->txn, &LSN(h), 0, dbp->log_fileid, h->pgno, &LSN(h))) != 0)
|
||||
return (ret);
|
||||
if (DB_LOGGING(dbp))
|
||||
if ((ret = __db_ovref_log(dbp->dbenv->lg_info, dbp->txn,
|
||||
&LSN(h), 0, dbp->log_fileid, h->pgno, (int32_t)adjust,
|
||||
&LSN(h))) != 0)
|
||||
return (ret);
|
||||
OV_REF(h) += adjust;
|
||||
|
||||
(void)memp_fput(dbp->mpf, h, DB_MPOOL_DIRTY);
|
||||
return (0);
|
||||
@ -311,9 +314,8 @@ __db_doff(dbp, pgno, freefunc)
|
||||
* one key/data item, decrement the reference count and return.
|
||||
*/
|
||||
if (TYPE(pagep) == P_OVERFLOW && OV_REF(pagep) > 1) {
|
||||
--OV_REF(pagep);
|
||||
(void)memp_fput(dbp->mpf, pagep, DB_MPOOL_DIRTY);
|
||||
return (0);
|
||||
(void)memp_fput(dbp->mpf, pagep, 0);
|
||||
return (__db_ovref(dbp, pgno, -1));
|
||||
}
|
||||
|
||||
if (DB_LOGGING(dbp)) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_pr.c 10.17 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)db_pr.c 10.19 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -183,7 +183,6 @@ __db_prbtree(dbp)
|
||||
};
|
||||
BTMETA *mp;
|
||||
BTREE *t;
|
||||
DB_LOCK lock;
|
||||
EPG *epg;
|
||||
FILE *fp;
|
||||
RECNO *rp;
|
||||
@ -195,8 +194,6 @@ __db_prbtree(dbp)
|
||||
|
||||
(void)fprintf(fp, "%s\nOn-page metadata:\n", DB_LINE);
|
||||
i = PGNO_METADATA;
|
||||
if ((ret = __bam_lget(dbp, 0, PGNO_METADATA, DB_LOCK_READ, &lock)) != 0)
|
||||
return (ret);
|
||||
|
||||
if ((ret = __bam_pget(dbp, (PAGE **)&mp, &i, 0)) != 0)
|
||||
return (ret);
|
||||
@ -211,7 +208,6 @@ __db_prbtree(dbp)
|
||||
__db_prflags(mp->flags, mfn);
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)memp_fput(dbp->mpf, mp, 0);
|
||||
(void)__bam_lput(dbp, lock);
|
||||
|
||||
(void)fprintf(fp, "%s\nDB_INFO:\n", DB_LINE);
|
||||
(void)fprintf(fp, "bt_maxkey: %lu bt_minkey: %lu\n",
|
||||
@ -416,7 +412,8 @@ __db_prpage(h, all)
|
||||
(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_LBTREE || TYPE(h) == P_LRECNO)
|
||||
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LRECNO ||
|
||||
TYPE(h) == P_DUPLICATE || TYPE(h) == P_OVERFLOW)
|
||||
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)
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_rec.c 10.8 (Sleepycat) 8/22/97";
|
||||
static const char sccsid[] = "@(#)db_rec.c 10.10 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -330,7 +330,7 @@ out: REC_CLOSE;
|
||||
|
||||
/*
|
||||
* __db_ovref_recover --
|
||||
* Recovery function for __db_ioff().
|
||||
* Recovery function for __db_ovref().
|
||||
*
|
||||
* PUBLIC: int __db_ovref_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
*/
|
||||
@ -357,22 +357,21 @@ __db_ovref_recover(logp, dbtp, lsnp, redo, info)
|
||||
}
|
||||
|
||||
modified = 0;
|
||||
if (log_compare(lsnp, &argp->lsn) == 0 && redo) {
|
||||
if (log_compare(&LSN(pagep), &argp->lsn) == 0 && redo) {
|
||||
/* Need to redo update described. */
|
||||
++OV_REF(pagep);
|
||||
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);
|
||||
OV_REF(pagep) -= argp->adjust;
|
||||
|
||||
pagep->lsn = argp->lsn;
|
||||
modified = 1;
|
||||
}
|
||||
ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0);
|
||||
|
||||
*lsnp = argp->prev_lsn;
|
||||
if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) == 0)
|
||||
*lsnp = argp->prev_lsn;
|
||||
|
||||
out: REC_CLOSE;
|
||||
}
|
||||
@ -413,7 +412,7 @@ __db_relink_recover(logp, dbtp, lsnp, redo, info)
|
||||
goto next;
|
||||
}
|
||||
modified = 0;
|
||||
if (log_compare(lsnp, &argp->lsn) == 0 && redo) {
|
||||
if (log_compare(&LSN(pagep), &argp->lsn) == 0 && redo) {
|
||||
/* Redo the relink. */
|
||||
pagep->lsn = *lsnp;
|
||||
modified = 1;
|
||||
@ -438,7 +437,7 @@ next: if ((ret = memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
|
||||
goto prev;
|
||||
}
|
||||
modified = 0;
|
||||
if (log_compare(lsnp, &argp->lsn_next) == 0 && redo) {
|
||||
if (log_compare(&LSN(pagep), &argp->lsn_next) == 0 && redo) {
|
||||
/* Redo the relink. */
|
||||
pagep->prev_pgno = argp->prev;
|
||||
|
||||
@ -464,7 +463,7 @@ prev: if ((ret = memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
|
||||
goto done;
|
||||
}
|
||||
modified = 0;
|
||||
if (log_compare(lsnp, &argp->lsn_prev) == 0 && redo) {
|
||||
if (log_compare(&LSN(pagep), &argp->lsn_prev) == 0 && redo) {
|
||||
/* Redo the relink. */
|
||||
pagep->next_pgno = argp->next;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_ret.c 10.7 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)db_ret.c 10.8 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -122,7 +122,7 @@ __db_retcopy(dbt, data, len, memp, memsize, db_malloc)
|
||||
*/
|
||||
if (F_ISSET(dbt, DB_DBT_MALLOC)) {
|
||||
dbt->data = db_malloc == NULL ?
|
||||
(void *)malloc(len + 1) :
|
||||
(void *)__db_malloc(len + 1) :
|
||||
(void *)db_malloc(len + 1);
|
||||
if (dbt->data == NULL)
|
||||
return (ENOMEM);
|
||||
@ -134,8 +134,8 @@ __db_retcopy(dbt, data, len, memp, memsize, db_malloc)
|
||||
} else {
|
||||
if (*memsize == 0 || *memsize < len) {
|
||||
*memp = *memp == NULL ?
|
||||
(void *)malloc(len + 1) :
|
||||
(void *)realloc(*memp, len + 1);
|
||||
(void *)__db_malloc(len + 1) :
|
||||
(void *)__db_realloc(*memp, len + 1);
|
||||
if (*memp == NULL) {
|
||||
*memsize = 0;
|
||||
return (ENOMEM);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_thread.c 8.12 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)db_thread.c 8.13 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -42,8 +42,7 @@ __db_gethandle(dbp, am_func, dbpp)
|
||||
DB *ret_dbp;
|
||||
int ret, t_ret;
|
||||
|
||||
if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutexp, -1,
|
||||
dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
|
||||
if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutexp, -1)) != 0)
|
||||
return (ret);
|
||||
|
||||
if ((ret_dbp = LIST_FIRST(&dbp->handleq)) != NULL)
|
||||
@ -51,7 +50,7 @@ __db_gethandle(dbp, am_func, dbpp)
|
||||
LIST_REMOVE(ret_dbp, links);
|
||||
else {
|
||||
/* Allocate a new handle. */
|
||||
if ((ret_dbp = (DB *)malloc(sizeof(*dbp))) == NULL) {
|
||||
if ((ret_dbp = (DB *)__db_malloc(sizeof(*dbp))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -94,8 +93,7 @@ __db_puthandle(dbp)
|
||||
int ret;
|
||||
|
||||
master = dbp->master;
|
||||
if ((ret = __db_mutex_lock((db_mutex_t *)master->mutexp, -1,
|
||||
dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
|
||||
if ((ret = __db_mutex_lock((db_mutex_t *)master->mutexp, -1)) != 0)
|
||||
return (ret);
|
||||
|
||||
LIST_INSERT_HEAD(&master->handleq, dbp, links);
|
||||
|
@ -11,7 +11,7 @@
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1997\n\
|
||||
Sleepycat Software Inc. All rights reserved.\n";
|
||||
static const char sccsid[] = "@(#)db185.c 8.13 (Sleepycat) 8/24/97";
|
||||
static const char sccsid[] = "@(#)db185.c 8.14 (Sleepycat) 10/25/97";
|
||||
#endif
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -52,7 +52,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
DB_INFO dbinfo, *dbinfop;
|
||||
int s_errno;
|
||||
|
||||
if ((db185p = (DB185 *)calloc(1, sizeof(DB185))) == NULL)
|
||||
if ((db185p = (DB185 *)__db_calloc(1, sizeof(DB185))) == NULL)
|
||||
return (NULL);
|
||||
dbinfop = NULL;
|
||||
memset(&dbinfo, 0, sizeof(dbinfo));
|
||||
@ -119,7 +119,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
*/
|
||||
if (file != NULL) {
|
||||
if (oflags & O_CREAT && __db_exists(file, NULL) != 0)
|
||||
(void)close(open(file, oflags, mode));
|
||||
(void)__os_close(open(file, oflags, mode));
|
||||
dbinfop->re_source = (char *)file;
|
||||
file = NULL;
|
||||
}
|
||||
@ -131,7 +131,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
*/
|
||||
#define BFMSG "DB: DB 1.85's recno bfname field is not supported.\n"
|
||||
if (ri->bfname != NULL) {
|
||||
(void)write(2, BFMSG, sizeof(BFMSG) - 1);
|
||||
(void)__os_write(2, BFMSG, sizeof(BFMSG) - 1);
|
||||
goto einval;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
*/
|
||||
if ((__set_errno(db_open(file,
|
||||
type, __db_oflags(oflags), mode, NULL, dbinfop, &dbp))) != 0) {
|
||||
free(db185p);
|
||||
__db_free(db185p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
!= 0) {
|
||||
s_errno = errno;
|
||||
(void)dbp->close(dbp, 0);
|
||||
free(db185p);
|
||||
__db_free(db185p);
|
||||
__set_errno(s_errno);
|
||||
return (NULL);
|
||||
}
|
||||
@ -200,7 +200,7 @@ __dbopen(file, oflags, mode, type, openinfo)
|
||||
db185p->internal = dbp;
|
||||
return (db185p);
|
||||
|
||||
einval: free(db185p);
|
||||
einval: __db_free(db185p);
|
||||
__set_errno(EINVAL);
|
||||
return (NULL);
|
||||
}
|
||||
@ -216,7 +216,7 @@ db185_close(db185p)
|
||||
|
||||
__set_errno(dbp->close(dbp, 0));
|
||||
|
||||
free(db185p);
|
||||
__db_free(db185p);
|
||||
|
||||
return (errno == 0 ? 0 : -1);
|
||||
}
|
||||
@ -461,7 +461,7 @@ db185_sync(db185p, flags)
|
||||
* We can't support the R_RECNOSYNC flag.
|
||||
*/
|
||||
#define RSMSG "DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n"
|
||||
(void)write(2, RSMSG, sizeof(RSMSG) - 1);
|
||||
(void)__os_write(2, RSMSG, sizeof(RSMSG) - 1);
|
||||
goto einval;
|
||||
default:
|
||||
goto einval;
|
||||
|
28
db2/db_int.h
28
db2/db_int.h
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db_int.h.src 10.30 (Sleepycat) 9/23/97
|
||||
* @(#)db_int.h.src 10.36 (Sleepycat) 10/31/97
|
||||
*/
|
||||
|
||||
#ifndef _DB_INTERNAL_H_
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "db.h" /* Standard DB include file. */
|
||||
#include "queue.h"
|
||||
#include "os_func.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*******************************************************
|
||||
@ -64,12 +65,16 @@
|
||||
#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)
|
||||
|
||||
/* Free and free-string macros that overwrite memory during debugging. */
|
||||
#ifdef DEBUG
|
||||
#undef FREE
|
||||
#define FREE(p, len) { \
|
||||
memset(p, 0xff, len); \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#undef FREES
|
||||
#define FREES(p) { \
|
||||
@ -78,17 +83,17 @@
|
||||
#else
|
||||
#undef FREE
|
||||
#define FREE(p, len) { \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#undef FREES
|
||||
#define FREES(p) { \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Structure used to print flag values. */
|
||||
typedef struct __fn {
|
||||
u_int32_t mask; /* Flag value. */
|
||||
u_int32_t mask; /* Flag value. */
|
||||
const char *name; /* Flag name. */
|
||||
} FN;
|
||||
|
||||
@ -163,10 +168,8 @@ typedef struct _db_mutex_t {
|
||||
off_t off; /* Backing file offset. */
|
||||
u_long pid; /* Lock holder: 0 or process pid. */
|
||||
#endif
|
||||
#ifdef MUTEX_STATISTICS
|
||||
u_long mutex_set_wait; /* Blocking mutex: required waiting. */
|
||||
u_long mutex_set_nowait; /* Blocking mutex: without waiting. */
|
||||
#endif
|
||||
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"
|
||||
@ -177,11 +180,10 @@ typedef struct _db_mutex_t {
|
||||
/* Lock/unlock a DB thread. */
|
||||
#define DB_THREAD_LOCK(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_THREAD) ? \
|
||||
__db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1, \
|
||||
(dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
|
||||
__db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
#define DB_THREAD_UNLOCK(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_THREAD) ? \
|
||||
__db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
__db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
|
||||
/* Btree/recno local statistics structure. */
|
||||
struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT;
|
||||
@ -260,7 +262,7 @@ typedef struct __dbpginfo {
|
||||
#define IS_ZERO_LSN(LSN) ((LSN).file == 0)
|
||||
|
||||
/* Test if we need to log a change. */
|
||||
#define DB_LOGGING(dbp) \
|
||||
#define DB_LOGGING(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_LOGGING) && !F_ISSET(dbp, DB_AM_RECOVER))
|
||||
|
||||
#ifdef DEBUG
|
||||
|
143
db2/hash/hash.c
143
db2/hash/hash.c
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)hash.c 10.27 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)hash.c 10.33 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -79,7 +79,7 @@ static int __ham_cursor __P((DB *, DB_TXN *, DBC **));
|
||||
static int __ham_delete __P((DB *, DB_TXN *, DBT *, int));
|
||||
static int __ham_dup_return __P((HTAB *, HASH_CURSOR *, DBT *, int));
|
||||
static int __ham_get __P((DB *, DB_TXN *, DBT *, DBT *, int));
|
||||
static void __ham_init_htab __P((HTAB *));
|
||||
static void __ham_init_htab __P((HTAB *, u_int));
|
||||
static int __ham_lookup __P((HTAB *,
|
||||
HASH_CURSOR *, const DBT *, u_int32_t, db_lockmode_t));
|
||||
static int __ham_overwrite __P((HTAB *, HASH_CURSOR *, DBT *));
|
||||
@ -106,7 +106,7 @@ __ham_open(dbp, dbinfo)
|
||||
|
||||
dbenv = dbp->dbenv;
|
||||
|
||||
if ((hashp = (HTAB *)calloc(1, sizeof(HTAB))) == NULL)
|
||||
if ((hashp = (HTAB *)__db_calloc(1, sizeof(HTAB))) == NULL)
|
||||
return (ENOMEM);
|
||||
hashp->dbp = dbp;
|
||||
|
||||
@ -175,10 +175,9 @@ __ham_open(dbp, dbinfo)
|
||||
goto out;
|
||||
}
|
||||
|
||||
hashp->hdr->nelem = dbinfo != NULL ? dbinfo->h_nelem : 0;
|
||||
hashp->hdr->ffactor =
|
||||
dbinfo != NULL && dbinfo->h_ffactor ? dbinfo->h_ffactor : 0;
|
||||
__ham_init_htab(hashp);
|
||||
__ham_init_htab(hashp, dbinfo != NULL ? dbinfo->h_nelem : 0);
|
||||
if (F_ISSET(dbp, DB_AM_DUP))
|
||||
F_SET(hashp->hdr, DB_HASH_DUP);
|
||||
if ((ret = __ham_dirty_page(hashp, (PAGE *)hashp->hdr)) != 0)
|
||||
@ -190,7 +189,7 @@ __ham_open(dbp, dbinfo)
|
||||
TAILQ_INSERT_TAIL(&dbp->curs_queue, curs, links);
|
||||
|
||||
/* Allocate memory for our split buffer. */
|
||||
if ((hashp->split_buf = (PAGE *)malloc(dbp->pgsize)) == NULL) {
|
||||
if ((hashp->split_buf = (PAGE *)__db_malloc(dbp->pgsize)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -265,13 +264,13 @@ __ham_close(dbp)
|
||||
* Returns 0 on No Error
|
||||
*/
|
||||
static void
|
||||
__ham_init_htab(hashp)
|
||||
__ham_init_htab(hashp, nelem)
|
||||
HTAB *hashp;
|
||||
u_int nelem;
|
||||
{
|
||||
u_int32_t nelem;
|
||||
int32_t l2, nbuckets;
|
||||
|
||||
nelem = hashp->hdr->nelem;
|
||||
hashp->hdr->nelem = 0;
|
||||
hashp->hdr->pagesize = hashp->dbp->pgsize;
|
||||
ZERO_LSN(hashp->hdr->lsn);
|
||||
hashp->hdr->magic = DB_HASHMAGIC;
|
||||
@ -502,11 +501,11 @@ __ham_c_init(dbp, txnid, dbcp)
|
||||
DBC *db_curs;
|
||||
HASH_CURSOR *new_curs;
|
||||
|
||||
if ((db_curs = (DBC *)calloc(sizeof(DBC), 1)) == NULL)
|
||||
if ((db_curs = (DBC *)__db_calloc(sizeof(DBC), 1)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if ((new_curs =
|
||||
(HASH_CURSOR *)calloc(sizeof(struct cursor_t), 1)) == NULL) {
|
||||
(HASH_CURSOR *)__db_calloc(sizeof(struct cursor_t), 1)) == NULL) {
|
||||
FREE(db_curs, sizeof(DBC));
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -555,7 +554,7 @@ __ham_delete(dbp, txn, key, flags)
|
||||
hashp->hash_accesses++;
|
||||
if ((ret = __ham_lookup(hashp, hcp, key, 0, DB_LOCK_WRITE)) == 0)
|
||||
if (F_ISSET(hcp, H_OK))
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
ret = __ham_del_pair(hashp, hcp, 1);
|
||||
else
|
||||
ret = DB_NOTFOUND;
|
||||
|
||||
@ -669,7 +668,34 @@ __ham_c_del(cursor, flags)
|
||||
if ((ret = __ham_get_cpage(hashp, hcp, 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;
|
||||
@ -677,22 +703,6 @@ __ham_c_del(cursor, flags)
|
||||
&hcp->dpagep, hcp->dndx, __ham_del_page)) != 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* There are 4 cases.
|
||||
* 1. We removed an item on a page, but nothing else changed.
|
||||
* 2. We removed the last item on a page, but there is a
|
||||
* following page of duplicates.
|
||||
* 3. We removed the last item on a page, this page was the
|
||||
* last page in a duplicate set, but there were dups before
|
||||
* it.
|
||||
* 4. We removed 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.
|
||||
*/
|
||||
if (hcp->dpagep == NULL) {
|
||||
if (ppgno != PGNO_INVALID) { /* Case 3 */
|
||||
hcp->dpgno = ppgno;
|
||||
@ -702,7 +712,7 @@ __ham_c_del(cursor, flags)
|
||||
hcp->dndx = NUM_ENT(hcp->dpagep);
|
||||
F_SET(hcp, H_DELETED);
|
||||
} else { /* Case 4 */
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
ret = __ham_del_pair(hashp, hcp, 1);
|
||||
hcp->dpgno = PGNO_INVALID;
|
||||
/*
|
||||
* Delpair updated the cursor queue, so we
|
||||
@ -718,14 +728,14 @@ __ham_c_del(cursor, flags)
|
||||
H_DATAINDEX(hcp->bndx))),
|
||||
&hcp->dpgno, sizeof(db_pgno_t));
|
||||
F_SET(hcp, H_DELETED);
|
||||
} else /* Case 1 */
|
||||
} else /* Case 1 */
|
||||
F_SET(hcp, H_DELETED);
|
||||
if (chg_pgno != PGNO_INVALID)
|
||||
__ham_c_update(hashp, 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, hashp->hdr->pagesize, hcp->bndx))
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
ret = __ham_del_pair(hashp, hcp, 1);
|
||||
else {
|
||||
DBT repldbt;
|
||||
|
||||
@ -736,14 +746,14 @@ __ham_c_del(cursor, flags)
|
||||
repldbt.size = 0;
|
||||
ret = __ham_replpair(hashp, hcp, &repldbt, 0);
|
||||
hcp->dup_tlen -= DUP_SIZE(hcp->dup_len);
|
||||
F_SET(hcp, H_DELETED);
|
||||
__ham_c_update(hashp, hcp, hcp->pgno,
|
||||
DUP_SIZE(hcp->dup_len), 0, 1);
|
||||
F_SET(hcp, H_DELETED);
|
||||
}
|
||||
|
||||
} else
|
||||
/* Not a duplicate */
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
normal: ret = __ham_del_pair(hashp, hcp, 1);
|
||||
|
||||
out: if ((t_ret = __ham_item_done(hashp, hcp, ret == 0)) != 0 && ret == 0)
|
||||
t_ret = ret;
|
||||
@ -975,8 +985,8 @@ int
|
||||
__ham_expand_table(hashp)
|
||||
HTAB *hashp;
|
||||
{
|
||||
u_int32_t old_bucket, new_bucket;
|
||||
u_int32_t spare_ndx;
|
||||
DB_LSN new_lsn;
|
||||
u_int32_t old_bucket, new_bucket, spare_ndx;
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
@ -984,9 +994,30 @@ __ham_expand_table(hashp)
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
if (DB_LOGGING(hashp->dbp)) {
|
||||
DB_LSN new_lsn;
|
||||
/*
|
||||
* 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(hashp->hdr->max_bucket + 2) > hashp->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 (hashp->hdr->max_bucket + 1 >= 8 &&
|
||||
hashp->hdr->spares[hashp->hdr->ovfl_point] <
|
||||
hashp->hdr->spares[hashp->hdr->ovfl_point - 1] +
|
||||
hashp->hdr->ovfl_point + 1)
|
||||
__ham_init_ovflpages(hashp);
|
||||
}
|
||||
|
||||
/* Now we can log the meta-data split. */
|
||||
if (DB_LOGGING(hashp->dbp)) {
|
||||
if ((ret = __ham_splitmeta_log(hashp->dbp->dbenv->lg_info,
|
||||
(DB_TXN *)hashp->dbp->txn, &new_lsn, 0,
|
||||
hashp->dbp->log_fileid,
|
||||
@ -1003,22 +1034,11 @@ __ham_expand_table(hashp)
|
||||
old_bucket = (hashp->hdr->max_bucket & hashp->hdr->low_mask);
|
||||
|
||||
/*
|
||||
* If the split point is increasing (hdr.max_bucket's log base 2
|
||||
* increases), max sure that we have enough extra pages, then
|
||||
* copy the current contents of the spare split bucket to the
|
||||
* next bucket.
|
||||
* If the split point is increasing, copy the current contents
|
||||
* of the spare split bucket to the next bucket.
|
||||
*/
|
||||
spare_ndx = __db_log2(hashp->hdr->max_bucket + 1);
|
||||
if (spare_ndx > hashp->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 (hashp->hdr->spares[hashp->hdr->ovfl_point] == 0 &&
|
||||
new_bucket >= 8)
|
||||
__ham_init_ovflpages(hashp);
|
||||
|
||||
hashp->hdr->spares[spare_ndx] =
|
||||
hashp->hdr->spares[hashp->hdr->ovfl_point];
|
||||
hashp->hdr->ovfl_point = spare_ndx;
|
||||
@ -1306,7 +1326,7 @@ __ham_init_dbt(dbt, size, bufp, sizep)
|
||||
memset(dbt, 0, sizeof(*dbt));
|
||||
if (*sizep < size) {
|
||||
if ((*bufp = (void *)(*bufp == NULL ?
|
||||
malloc(size) : realloc(*bufp, size))) == NULL) {
|
||||
__db_malloc(size) : __db_realloc(*bufp, size))) == NULL) {
|
||||
*sizep = 0;
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -1352,9 +1372,20 @@ __ham_c_update(hashp, hcp, chg_pgno, len, add, dup)
|
||||
if (!dup && add)
|
||||
return;
|
||||
|
||||
page_deleted = chg_pgno != PGNO_INVALID &&
|
||||
((!dup && chg_pgno != hcp->pgno) ||
|
||||
(dup && chg_pgno != hcp->dpgno));
|
||||
/*
|
||||
* Determine if a page was deleted. If this is a regular update
|
||||
* (i.e., not 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 (!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;
|
||||
|
||||
hp = hcp->db_cursor->dbp->master->internal;
|
||||
DB_THREAD_LOCK(hp->dbp);
|
||||
@ -1432,7 +1463,7 @@ __ham_hdup(orig, new)
|
||||
DBC *curs;
|
||||
int ret;
|
||||
|
||||
if ((hashp = (HTAB *)malloc(sizeof(HTAB))) == NULL)
|
||||
if ((hashp = (HTAB *)__db_malloc(sizeof(HTAB))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
new->internal = hashp;
|
||||
@ -1441,7 +1472,7 @@ __ham_hdup(orig, new)
|
||||
hashp->hlock = 0;
|
||||
hashp->hdr = NULL;
|
||||
hashp->hash = ((HTAB *)orig->internal)->hash;
|
||||
if ((hashp->split_buf = (PAGE *)malloc(orig->pgsize)) == NULL)
|
||||
if ((hashp->split_buf = (PAGE *)__db_malloc(orig->pgsize)) == NULL)
|
||||
return (ENOMEM);
|
||||
hashp->local_errno = 0;
|
||||
hashp->hash_accesses = 0;
|
||||
|
@ -43,7 +43,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)hash.src 10.1 (Sleepycat) 4/12/97
|
||||
* @(#)hash.src 10.2 (Sleepycat) 11/2/97
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -207,5 +207,27 @@ 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
|
||||
|
@ -61,7 +61,7 @@ int __ham_insdel_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*pagelsn)
|
||||
+ sizeof(u_int32_t) + (key == NULL ? 0 : key->size)
|
||||
+ sizeof(u_int32_t) + (data == NULL ? 0 : data->size);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -111,7 +111,7 @@ int __ham_insdel_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ __ham_insdel_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ __ham_insdel_read(recbuf, argpp)
|
||||
__ham_insdel_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_insdel_args *)malloc(sizeof(__ham_insdel_args) +
|
||||
argp = (__ham_insdel_args *)__db_malloc(sizeof(__ham_insdel_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -266,7 +266,7 @@ int __ham_newpage_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(*pagelsn)
|
||||
+ sizeof(next_pgno)
|
||||
+ sizeof(*nextlsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -308,7 +308,7 @@ int __ham_newpage_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ __ham_newpage_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tnextlsn: [%lu][%lu]\n",
|
||||
(u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -371,7 +371,7 @@ __ham_newpage_read(recbuf, argpp)
|
||||
__ham_newpage_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_newpage_args *)malloc(sizeof(__ham_newpage_args) +
|
||||
argp = (__ham_newpage_args *)__db_malloc(sizeof(__ham_newpage_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -441,7 +441,7 @@ int __ham_splitmeta_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(ovflpoint)
|
||||
+ sizeof(spares)
|
||||
+ sizeof(*metalsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -471,7 +471,7 @@ int __ham_splitmeta_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ __ham_splitmeta_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tmetalsn: [%lu][%lu]\n",
|
||||
(u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -529,7 +529,7 @@ __ham_splitmeta_read(recbuf, argpp)
|
||||
__ham_splitmeta_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_splitmeta_args *)malloc(sizeof(__ham_splitmeta_args) +
|
||||
argp = (__ham_splitmeta_args *)__db_malloc(sizeof(__ham_splitmeta_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -594,7 +594,7 @@ int __ham_splitdata_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(pgno)
|
||||
+ sizeof(u_int32_t) + (pageimage == NULL ? 0 : pageimage->size)
|
||||
+ sizeof(*pagelsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -632,7 +632,7 @@ int __ham_splitdata_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -683,7 +683,7 @@ __ham_splitdata_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tpagelsn: [%lu][%lu]\n",
|
||||
(u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -698,7 +698,7 @@ __ham_splitdata_read(recbuf, argpp)
|
||||
__ham_splitdata_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_splitdata_args *)malloc(sizeof(__ham_splitdata_args) +
|
||||
argp = (__ham_splitdata_args *)__db_malloc(sizeof(__ham_splitdata_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -772,7 +772,7 @@ int __ham_replace_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(u_int32_t) + (olditem == NULL ? 0 : olditem->size)
|
||||
+ sizeof(u_int32_t) + (newitem == NULL ? 0 : newitem->size)
|
||||
+ sizeof(makedup);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -824,7 +824,7 @@ int __ham_replace_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -886,7 +886,7 @@ __ham_replace_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\n");
|
||||
printf("\tmakedup: %lu\n", (u_long)argp->makedup);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -901,7 +901,7 @@ __ham_replace_read(recbuf, argpp)
|
||||
__ham_replace_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_replace_args *)malloc(sizeof(__ham_replace_args) +
|
||||
argp = (__ham_replace_args *)__db_malloc(sizeof(__ham_replace_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -985,7 +985,7 @@ int __ham_newpgno_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(new_type)
|
||||
+ sizeof(*pagelsn)
|
||||
+ sizeof(*metalsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -1026,7 +1026,7 @@ int __ham_newpgno_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1074,7 +1074,7 @@ __ham_newpgno_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tmetalsn: [%lu][%lu]\n",
|
||||
(u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1089,7 +1089,7 @@ __ham_newpgno_read(recbuf, argpp)
|
||||
__ham_newpgno_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_newpgno_args *)malloc(sizeof(__ham_newpgno_args) +
|
||||
argp = (__ham_newpgno_args *)__db_malloc(sizeof(__ham_newpgno_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1127,10 +1127,10 @@ __ham_newpgno_read(recbuf, argpp)
|
||||
* 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: DB_LSN *));
|
||||
* PUBLIC: u_int32_t, DB_LSN *));
|
||||
*/
|
||||
int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
|
||||
fileid, start_pgno, npages, free_pgno, metalsn)
|
||||
fileid, start_pgno, npages, free_pgno, ovflpoint, metalsn)
|
||||
DB_LOG *logp;
|
||||
DB_TXN *txnid;
|
||||
DB_LSN *ret_lsnp;
|
||||
@ -1139,6 +1139,7 @@ int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
|
||||
db_pgno_t start_pgno;
|
||||
u_int32_t npages;
|
||||
db_pgno_t free_pgno;
|
||||
u_int32_t ovflpoint;
|
||||
DB_LSN * metalsn;
|
||||
{
|
||||
DBT logrec;
|
||||
@ -1160,8 +1161,9 @@ int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(start_pgno)
|
||||
+ sizeof(npages)
|
||||
+ sizeof(free_pgno)
|
||||
+ sizeof(ovflpoint)
|
||||
+ sizeof(*metalsn);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -1179,6 +1181,8 @@ int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
|
||||
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
|
||||
@ -1191,7 +1195,7 @@ int __ham_ovfl_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1231,10 +1235,11 @@ __ham_ovfl_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
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");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1249,7 +1254,7 @@ __ham_ovfl_read(recbuf, argpp)
|
||||
__ham_ovfl_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__ham_ovfl_args *)malloc(sizeof(__ham_ovfl_args) +
|
||||
argp = (__ham_ovfl_args *)__db_malloc(sizeof(__ham_ovfl_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -1269,12 +1274,215 @@ __ham_ovfl_read(recbuf, argpp)
|
||||
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 *, 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;
|
||||
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) {
|
||||
null_lsn.file = 0;
|
||||
null_lsn.offset = 0;
|
||||
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 ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
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 DEBUG
|
||||
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;
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* PUBLIC: int __ham_copypage_print
|
||||
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
*/
|
||||
|
||||
int
|
||||
__ham_copypage_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
DB_LOG *notused1;
|
||||
DBT *dbtp;
|
||||
DB_LSN *lsnp;
|
||||
int notused3;
|
||||
void *notused4;
|
||||
{
|
||||
__ham_copypage_args *argp;
|
||||
u_int32_t i;
|
||||
int c, ret;
|
||||
|
||||
i = 0;
|
||||
c = 0;
|
||||
notused1 = NULL;
|
||||
notused3 = 0;
|
||||
notused4 = 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++) {
|
||||
c = ((char *)argp->page.data)[i];
|
||||
if (isprint(c) || c == 0xa)
|
||||
putchar(c);
|
||||
else
|
||||
printf("%#x ", c);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
__db_free(argp);
|
||||
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;
|
||||
|
||||
argp = (__ham_copypage_args *)__db_malloc(sizeof(__ham_copypage_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
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 *));
|
||||
*/
|
||||
@ -1305,6 +1513,9 @@ __ham_init_print(dbenv)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1338,6 +1549,9 @@ __ham_init_recover(dbenv)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)hash_dup.c 10.7 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)hash_dup.c 10.8 (Sleepycat) 10/14/97";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -480,7 +480,7 @@ __ham_check_move(hashp, hcp, add_len)
|
||||
__ham_copy_item(hashp, hcp->pagep, H_DATAINDEX(hcp->bndx), next_pagep);
|
||||
|
||||
/* Now delete the pair from the current page. */
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
ret = __ham_del_pair(hashp, hcp, 0);
|
||||
|
||||
(void)__ham_put_page(hashp->dbp, hcp->pagep, 1);
|
||||
hcp->pagep = next_pagep;
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)hash_page.c 10.24 (Sleepycat) 9/17/97";
|
||||
static const char sccsid[] = "@(#)hash_page.c 10.29 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -489,19 +489,20 @@ __ham_putitem(p, dbt, type)
|
||||
|
||||
|
||||
/*
|
||||
* PUBLIC: int __ham_del_pair __P((HTAB *, HASH_CURSOR *));
|
||||
* PUBLIC: int __ham_del_pair __P((HTAB *, HASH_CURSOR *, int));
|
||||
* XXX TODO: if the item is an offdup, delete the other pages and
|
||||
* then remove the pair. If the offpage page is 0, then you can
|
||||
* just remove the pair.
|
||||
*/
|
||||
int
|
||||
__ham_del_pair(hashp, cursorp)
|
||||
__ham_del_pair(hashp, cursorp, reclaim_page)
|
||||
HTAB *hashp;
|
||||
HASH_CURSOR *cursorp;
|
||||
int reclaim_page;
|
||||
{
|
||||
DBT data_dbt, key_dbt;
|
||||
DB_ENV *dbenv;
|
||||
DB_LSN new_lsn, *n_lsn;
|
||||
DB_LSN new_lsn, *n_lsn, tmp_lsn;
|
||||
PAGE *p;
|
||||
db_indx_t ndx;
|
||||
db_pgno_t chg_pgno, pgno;
|
||||
@ -542,6 +543,15 @@ __ham_del_pair(hashp, cursorp)
|
||||
HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
|
||||
sizeof(db_pgno_t));
|
||||
ret = __db_ddup(hashp->dbp, pgno, __ham_del_page);
|
||||
F_CLR(cursorp, 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(cursorp, H_ISDUP);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -578,13 +588,13 @@ __ham_del_pair(hashp, cursorp)
|
||||
--hashp->hdr->nelem;
|
||||
|
||||
/*
|
||||
* Check if the page is empty. There are two cases. If it's
|
||||
* empty and it's not the first chain 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 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 (NUM_ENT(p) == 0 && PREV_PGNO(p) == PGNO_INVALID &&
|
||||
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;
|
||||
@ -592,7 +602,6 @@ __ham_del_pair(hashp, cursorp)
|
||||
/*
|
||||
* First page in chain is empty and we know that there
|
||||
* are more pages in the chain.
|
||||
* XXX Need to log this.
|
||||
*/
|
||||
if ((ret =
|
||||
__ham_get_page(hashp->dbp, NEXT_PGNO(p), &n_pagep)) != 0)
|
||||
@ -605,13 +614,35 @@ __ham_del_pair(hashp, cursorp)
|
||||
(void) __ham_put_page(hashp->dbp, n_pagep, 0);
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (DB_LOGGING(hashp->dbp)) {
|
||||
key_dbt.data = n_pagep;
|
||||
key_dbt.size = hashp->hdr->pagesize;
|
||||
if ((ret = __ham_copypage_log(dbenv->lg_info,
|
||||
(DB_TXN *)hashp->dbp->txn, &new_lsn, 0,
|
||||
hashp->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(hashp->dbp, nn_pagep, 1);
|
||||
}
|
||||
|
||||
tmp_pgno = PGNO(p);
|
||||
tmp_lsn = LSN(p);
|
||||
memcpy(p, n_pagep, hashp->hdr->pagesize);
|
||||
PGNO(p) = tmp_pgno;
|
||||
LSN(p) = tmp_lsn;
|
||||
PREV_PGNO(p) = PGNO_INVALID;
|
||||
|
||||
/*
|
||||
@ -623,7 +654,8 @@ __ham_del_pair(hashp, cursorp)
|
||||
if ((ret = __ham_dirty_page(hashp, p)) != 0 ||
|
||||
(ret = __ham_del_page(hashp->dbp, n_pagep)) != 0)
|
||||
return (ret);
|
||||
} else if (NUM_ENT(p) == 0 && PREV_PGNO(p) != PGNO_INVALID) {
|
||||
} else if (reclaim_page &&
|
||||
NUM_ENT(p) == 0 && PREV_PGNO(p) != PGNO_INVALID) {
|
||||
PAGE *n_pagep, *p_pagep;
|
||||
|
||||
if ((ret =
|
||||
@ -690,13 +722,22 @@ __ham_del_pair(hashp, cursorp)
|
||||
}
|
||||
__ham_c_update(hashp, cursorp, chg_pgno, 0, 0, 0);
|
||||
|
||||
/*
|
||||
* Since we just deleted a pair from the master page, anything
|
||||
* in cursorp->dpgno should be cleared.
|
||||
*/
|
||||
cursorp->dpgno = PGNO_INVALID;
|
||||
|
||||
F_CLR(cursorp, 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((HTAB *, HASH_CURSOR *, DBT *, u_int32_t));
|
||||
* Given the key data indicated by the cursor, replace part/all of it
|
||||
* according to the fields in the dbt.
|
||||
*/
|
||||
int
|
||||
__ham_replpair(hashp, hcp, dbt, make_dup)
|
||||
@ -768,7 +809,7 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
|
||||
return (ret);
|
||||
|
||||
if (dbt->doff == 0 && dbt->dlen == len) {
|
||||
ret = __ham_del_pair(hashp, hcp);
|
||||
ret = __ham_del_pair(hashp, hcp, 0);
|
||||
if (ret == 0)
|
||||
ret = __ham_add_el(hashp,
|
||||
hcp, &tmp, dbt, H_KEYDATA);
|
||||
@ -784,15 +825,15 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
|
||||
goto err;
|
||||
|
||||
/* Now we can delete the item. */
|
||||
if ((ret = __ham_del_pair(hashp, hcp)) != 0) {
|
||||
free(tdata.data);
|
||||
if ((ret = __ham_del_pair(hashp, hcp, 0)) != 0) {
|
||||
__db_free(tdata.data);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now shift old data around to make room for new. */
|
||||
if (change > 0) {
|
||||
tdata.data = (void *)
|
||||
realloc(tdata.data, tdata.size + change);
|
||||
tdata.data = (void *)__db_realloc(tdata.data,
|
||||
tdata.size + change);
|
||||
memset((u_int8_t *)tdata.data + tdata.size,
|
||||
0, change);
|
||||
}
|
||||
@ -812,9 +853,9 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
|
||||
|
||||
/* Now add the pair. */
|
||||
ret = __ham_add_el(hashp, hcp, &tmp, &tdata, type);
|
||||
free(tdata.data);
|
||||
__db_free(tdata.data);
|
||||
}
|
||||
err: free(tmp.data);
|
||||
err: __db_free(tmp.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1025,7 +1066,7 @@ __ham_split_page(hashp, obucket, nbucket)
|
||||
}
|
||||
}
|
||||
if (big_buf != NULL)
|
||||
free(big_buf);
|
||||
__db_free(big_buf);
|
||||
|
||||
/*
|
||||
* If the original bucket spanned multiple pages, then we've got
|
||||
@ -1549,17 +1590,20 @@ __ham_init_ovflpages(hp)
|
||||
{
|
||||
DB_LSN new_lsn;
|
||||
PAGE *p;
|
||||
db_pgno_t last_pgno;
|
||||
u_int32_t i, numpages;
|
||||
db_pgno_t last_pgno, new_pgno;
|
||||
u_int32_t i, curpages, numpages;
|
||||
|
||||
numpages = hp->hdr->ovfl_point + 1;
|
||||
curpages = hp->hdr->spares[hp->hdr->ovfl_point] -
|
||||
hp->hdr->spares[hp->hdr->ovfl_point - 1];
|
||||
numpages = hp->hdr->ovfl_point + 1 - curpages;
|
||||
|
||||
last_pgno = hp->hdr->last_freed;
|
||||
new_pgno = PGNO_OF(hp, hp->hdr->ovfl_point, curpages + 1);
|
||||
if (DB_LOGGING(hp->dbp)) {
|
||||
(void)__ham_ovfl_log(hp->dbp->dbenv->lg_info,
|
||||
(DB_TXN *)hp->dbp->txn, &new_lsn, 0,
|
||||
hp->dbp->log_fileid, PGNO_OF(hp, hp->hdr->ovfl_point, 1),
|
||||
numpages, last_pgno, &hp->hdr->lsn);
|
||||
hp->dbp->log_fileid, new_pgno,
|
||||
numpages, last_pgno, hp->hdr->ovfl_point, &hp->hdr->lsn);
|
||||
hp->hdr->lsn = new_lsn;
|
||||
} else
|
||||
ZERO_LSN(new_lsn);
|
||||
@ -1567,7 +1611,8 @@ __ham_init_ovflpages(hp)
|
||||
hp->hdr->spares[hp->hdr->ovfl_point] += numpages;
|
||||
for (i = numpages; i > 0; i--) {
|
||||
if (__ham_new_page(hp,
|
||||
PGNO_OF(hp, hp->hdr->ovfl_point, i), P_INVALID, &p) != 0)
|
||||
PGNO_OF(hp, hp->hdr->ovfl_point, curpages + i),
|
||||
P_INVALID, &p) != 0)
|
||||
break;
|
||||
LSN(p) = new_lsn;
|
||||
NEXT_PGNO(p) = last_pgno;
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)hash_rec.c 10.13 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)hash_rec.c 10.14 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -756,7 +756,6 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
|
||||
hashp = (HTAB *)file_dbp->internal;
|
||||
GET_META(file_dbp, hashp);
|
||||
getmeta = 1;
|
||||
file_dbp = NULL;
|
||||
|
||||
cmp_n = log_compare(lsnp, &hashp->hdr->lsn);
|
||||
cmp_p = log_compare(&hashp->hdr->lsn, &argp->metalsn);
|
||||
@ -764,12 +763,12 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
|
||||
if (cmp_p == 0 && redo) {
|
||||
/* Redo the allocation. */
|
||||
hashp->hdr->last_freed = argp->start_pgno;
|
||||
hashp->hdr->spares[argp->npages - 1] += argp->npages;
|
||||
hashp->hdr->spares[argp->ovflpoint] += argp->npages;
|
||||
hashp->hdr->lsn = *lsnp;
|
||||
F_SET(file_dbp, DB_HS_DIRTYMETA);
|
||||
} else if (cmp_n == 0 && !redo) {
|
||||
hashp->hdr->last_freed = argp->free_pgno;
|
||||
hashp->hdr->spares[argp->npages - 1] -= argp->npages;
|
||||
hashp->hdr->spares[argp->ovflpoint] -= argp->npages;
|
||||
hashp->hdr->lsn = argp->metalsn;
|
||||
F_SET(file_dbp, DB_HS_DIRTYMETA);
|
||||
}
|
||||
@ -808,3 +807,142 @@ out: if (getmeta)
|
||||
RELEASE_META(file_dbp, hashp);
|
||||
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, *mdbp;
|
||||
DB_MPOOLFILE *mpf;
|
||||
HTAB *hashp;
|
||||
PAGE *pagep;
|
||||
int cmp_n, cmp_p, getmeta, modified, ret;
|
||||
|
||||
getmeta = 0;
|
||||
hashp = NULL; /* XXX: shut the compiler up. */
|
||||
REC_PRINT(__ham_copypage_print);
|
||||
REC_INTRO(__ham_copypage_read);
|
||||
|
||||
hashp = (HTAB *)file_dbp->internal;
|
||||
GET_META(file_dbp, hashp);
|
||||
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, hashp->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) {
|
||||
*lsnp = argp->prev_lsn;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
ret = 0;
|
||||
*lsnp = argp->prev_lsn;
|
||||
goto out;
|
||||
} 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;
|
||||
|
||||
*lsnp = argp->prev_lsn;
|
||||
|
||||
out: if (getmeta)
|
||||
RELEASE_META(file_dbp, hashp);
|
||||
REC_CLOSE;
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ typedef struct _bam_rsplit_args {
|
||||
u_int32_t fileid;
|
||||
db_pgno_t pgno;
|
||||
DBT pgdbt;
|
||||
db_pgno_t nrec;
|
||||
DBT rootent;
|
||||
DB_LSN rootlsn;
|
||||
} __bam_rsplit_args;
|
||||
@ -105,4 +106,22 @@ typedef struct _bam_cdel_args {
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __bam_close __P((DB *));
|
||||
int __bam_sync __P((DB *, int));
|
||||
int __bam_cmp __P((DB *, const DBT *, EPG *));
|
||||
@ -35,6 +35,7 @@ int __bam_pget __P((DB *, PAGE **, db_pgno_t *, int));
|
||||
int __bam_put __P((DB *, DB_TXN *, DBT *, DBT *, int));
|
||||
int __bam_iitem __P((DB *,
|
||||
PAGE **, db_indx_t *, DBT *, DBT *, int, int));
|
||||
int __bam_ritem __P((DB *, PAGE *, u_int32_t, DBT *));
|
||||
int __bam_pg_alloc_recover
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
int __bam_pg_free_recover
|
||||
@ -49,6 +50,8 @@ 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 *, DBTYPE, DB_INFO *));
|
||||
int __ram_cursor __P((DB *, DB_TXN *, DBC **));
|
||||
int __ram_close __P((DB *));
|
||||
@ -94,8 +97,8 @@ int __bam_split_print
|
||||
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, DBT *, DBT *,
|
||||
DB_LSN *));
|
||||
u_int32_t, db_pgno_t, DBT *, db_pgno_t,
|
||||
DBT *, DB_LSN *));
|
||||
int __bam_rsplit_print
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
int __bam_rsplit_read __P((void *, __bam_rsplit_args **));
|
||||
@ -119,5 +122,13 @@ int __bam_cdel_log
|
||||
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, DBT *, 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 *));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
#ifdef __STDC__
|
||||
void err __P((int eval, const char *, ...));
|
||||
#else
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __db_appname __P((DB_ENV *,
|
||||
APPNAME, const char *, const char *, int *, char **));
|
||||
int __db_apprec __P((DB_ENV *, int));
|
||||
@ -24,6 +24,7 @@ int __db_ferr __P((const DB_ENV *, const char *, int));
|
||||
u_int32_t __db_log2 __P((u_int32_t));
|
||||
int __db_rcreate __P((DB_ENV *, APPNAME,
|
||||
const char *, const char *, int, size_t, int *, void *));
|
||||
int __db_rinit __P((DB_ENV *, RLAYOUT *, int, size_t, int));
|
||||
int __db_ropen __P((DB_ENV *,
|
||||
APPNAME, const char *, const char *, int, int *, void *));
|
||||
int __db_rclose __P((DB_ENV *, int, void *));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db.h.src 10.77 (Sleepycat) 9/24/97
|
||||
* @(#)db.h.src 10.91 (Sleepycat) 11/3/97
|
||||
*/
|
||||
|
||||
#ifndef _DB_H_
|
||||
@ -28,9 +28,15 @@
|
||||
* 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)
|
||||
#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
|
||||
#define __P(protos) protos /* ANSI C prototypes */
|
||||
#else
|
||||
#define const
|
||||
@ -67,8 +73,8 @@
|
||||
|
||||
#define DB_VERSION_MAJOR 2
|
||||
#define DB_VERSION_MINOR 3
|
||||
#define DB_VERSION_PATCH 10
|
||||
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.10: (9/24/97)"
|
||||
#define DB_VERSION_PATCH 12
|
||||
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.12: (11/3/97)"
|
||||
|
||||
typedef u_int32_t db_pgno_t; /* Page number type. */
|
||||
typedef u_int16_t db_indx_t; /* Page offset type. */
|
||||
@ -93,6 +99,7 @@ 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_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT;
|
||||
@ -121,6 +128,31 @@ struct __db_dbt {
|
||||
u_int32_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* DB configuration. There are a set of functions which the application
|
||||
* can replace with its own versions.
|
||||
*/
|
||||
#define DB_FUNC_CALLOC 1 /* ANSI C calloc. */
|
||||
#define DB_FUNC_CLOSE 2 /* POSIX 1003.1 close. */
|
||||
#define DB_FUNC_DIRFREE 3 /* DB: free directory list. */
|
||||
#define DB_FUNC_DIRLIST 4 /* DB: create directory list. */
|
||||
#define DB_FUNC_EXISTS 5 /* DB: return if file exists. */
|
||||
#define DB_FUNC_FREE 6 /* ANSI C free. */
|
||||
#define DB_FUNC_FSYNC 7 /* POSIX 1003.1 fsync. */
|
||||
#define DB_FUNC_IOINFO 8 /* DB: return file I/O information. */
|
||||
#define DB_FUNC_MALLOC 9 /* ANSI C malloc. */
|
||||
#define DB_FUNC_MAP 10 /* DB: map file into shared memory. */
|
||||
#define DB_FUNC_OPEN 11 /* POSIX 1003.1 open. */
|
||||
#define DB_FUNC_READ 12 /* POSIX 1003.1 read. */
|
||||
#define DB_FUNC_REALLOC 13 /* ANSI C realloc. */
|
||||
#define DB_FUNC_SEEK 14 /* POSIX 1003.1 lseek. */
|
||||
#define DB_FUNC_SLEEP 15 /* DB: sleep secs/usecs. */
|
||||
#define DB_FUNC_STRDUP 16 /* ANSI C strdup. */
|
||||
#define DB_FUNC_UNLINK 17 /* POSIX 1003.1 unlink. */
|
||||
#define DB_FUNC_UNMAP 18 /* DB: unmap shared memory file. */
|
||||
#define DB_FUNC_WRITE 19 /* POSIX 1003.1 write. */
|
||||
#define DB_FUNC_YIELD 20 /* DB: yield thread to scheduler. */
|
||||
|
||||
/*
|
||||
* Database configuration and initialization.
|
||||
*/
|
||||
@ -134,21 +166,20 @@ struct __db_dbt {
|
||||
/*
|
||||
* Flags understood by db_appinit(3).
|
||||
*
|
||||
* DB_APP_INIT and DB_MUTEXDEBUG are internal only, and not documented.
|
||||
* DB_MUTEXDEBUG is internal only, and not documented.
|
||||
*/
|
||||
/* 0x00007 COMMON MASK. */
|
||||
#define DB_APP_INIT 0x00008 /* Appinit called, paths initialized. */
|
||||
#define DB_INIT_LOCK 0x00010 /* Initialize locking. */
|
||||
#define DB_INIT_LOG 0x00020 /* Initialize logging. */
|
||||
#define DB_INIT_MPOOL 0x00040 /* Initialize mpool. */
|
||||
#define DB_INIT_TXN 0x00080 /* Initialize transactions. */
|
||||
#define DB_MPOOL_PRIVATE 0x00100 /* Mpool: private memory pool. */
|
||||
#define DB_MUTEXDEBUG 0x00200 /* Do not get/set mutexes in regions. */
|
||||
#define DB_RECOVER 0x00400 /* Run normal recovery. */
|
||||
#define DB_RECOVER_FATAL 0x00800 /* Run catastrophic recovery. */
|
||||
#define DB_TXN_NOSYNC 0x01000 /* Do not sync log on commit. */
|
||||
#define DB_USE_ENVIRON 0x02000 /* Use the environment. */
|
||||
#define DB_USE_ENVIRON_ROOT 0x04000 /* Use the environment if root. */
|
||||
#define DB_INIT_LOCK 0x00008 /* Initialize locking. */
|
||||
#define DB_INIT_LOG 0x00010 /* Initialize logging. */
|
||||
#define DB_INIT_MPOOL 0x00020 /* Initialize mpool. */
|
||||
#define DB_INIT_TXN 0x00040 /* Initialize transactions. */
|
||||
#define DB_MPOOL_PRIVATE 0x00080 /* Mpool: private memory pool. */
|
||||
#define DB_MUTEXDEBUG 0x00100 /* Do not get/set mutexes in regions. */
|
||||
#define DB_RECOVER 0x00200 /* Run normal recovery. */
|
||||
#define DB_RECOVER_FATAL 0x00400 /* Run catastrophic recovery. */
|
||||
#define DB_TXN_NOSYNC 0x00800 /* Do not sync log on commit. */
|
||||
#define DB_USE_ENVIRON 0x01000 /* Use the environment. */
|
||||
#define DB_USE_ENVIRON_ROOT 0x02000 /* Use the environment if root. */
|
||||
|
||||
/* CURRENTLY UNUSED LOCK FLAGS. */
|
||||
#define DB_TXN_LOCK_2PL 0x00000 /* Two-phase locking. */
|
||||
@ -209,7 +240,6 @@ struct __db_env {
|
||||
int lk_modes; /* Number of lock modes in table. */
|
||||
unsigned int lk_max; /* Maximum number of locks. */
|
||||
u_int32_t lk_detect; /* Deadlock detect on every conflict. */
|
||||
int (*db_yield) __P((void)); /* Yield function for threads. */
|
||||
|
||||
/* Logging. */
|
||||
DB_LOG *lg_info; /* Return from log_open(). */
|
||||
@ -226,6 +256,9 @@ struct __db_env {
|
||||
int (*tx_recover) /* Dispatch function for recovery. */
|
||||
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
|
||||
|
||||
#define DB_ENV_APPINIT 0x01 /* Paths initialized by db_appinit(). */
|
||||
#define DB_ENV_STANDALONE 0x02 /* Test: freestanding environment. */
|
||||
#define DB_ENV_THREAD 0x04 /* DB_ENV is multi-threaded. */
|
||||
u_int32_t flags; /* Flags. */
|
||||
};
|
||||
|
||||
@ -301,7 +334,7 @@ struct __db_info {
|
||||
#define DB_CURRENT 0x000010 /* c_get(), c_put(), log_get() */
|
||||
#define DB_FIRST 0x000020 /* c_get(), log_get() */
|
||||
#define DB_FLUSH 0x000040 /* log_put() */
|
||||
#define DB_GET_RECNO 0x000080 /* c_get() */
|
||||
#define DB_GET_RECNO 0x000080 /* get(), c_get() */
|
||||
#define DB_KEYFIRST 0x000100 /* c_put() */
|
||||
#define DB_KEYLAST 0x000200 /* c_put() */
|
||||
#define DB_LAST 0x000400 /* c_get(), log_get() */
|
||||
@ -312,7 +345,7 @@ struct __db_info {
|
||||
#define DB_RECORDCOUNT 0x008000 /* stat() */
|
||||
#define DB_SET 0x010000 /* c_get(), log_get() */
|
||||
#define DB_SET_RANGE 0x020000 /* c_get() */
|
||||
#define DB_SET_RECNO 0x040000 /* get(), c_get() */
|
||||
#define DB_SET_RECNO 0x040000 /* c_get() */
|
||||
|
||||
/* DB (user visible) error return codes. */
|
||||
#define DB_INCOMPLETE ( -1) /* Sync didn't finish. */
|
||||
@ -472,6 +505,8 @@ struct __db_bt_stat {
|
||||
u_int32_t bt_get; /* Items retrieved. */
|
||||
u_int32_t bt_cache_hit; /* Hits in fast-insert code. */
|
||||
u_int32_t bt_cache_miss; /* Misses in fast-insert code. */
|
||||
u_int32_t bt_magic; /* Magic number. */
|
||||
u_int32_t bt_version; /* Version number. */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -479,6 +514,7 @@ extern "C" {
|
||||
#endif
|
||||
int db_appinit __P((const char *, char * const *, DB_ENV *, int));
|
||||
int db_appexit __P((DB_ENV *));
|
||||
int db_jump_set __P((void *, int));
|
||||
int db_open __P((const char *, DBTYPE, int, int, DB_ENV *, DB_INFO *, DB **));
|
||||
char *db_version __P((int *, int *, int *));
|
||||
#if defined(__cplusplus)
|
||||
@ -576,6 +612,22 @@ struct __db_lsn {
|
||||
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. */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -588,6 +640,7 @@ int log_get __P((DB_LOG *, DB_LSN *, DBT *, int));
|
||||
int log_open __P((const char *, int, int, DB_ENV *, DB_LOG **));
|
||||
int log_put __P((DB_LOG *, DB_LSN *, const DBT *, int));
|
||||
int log_register __P((DB_LOG *, DB *, const char *, DBTYPE, u_int32_t *));
|
||||
int log_stat __P((DB_LOG *, DB_LOG_STAT **, void *(*)(size_t)));
|
||||
int log_unlink __P((const char *, int, DB_ENV *));
|
||||
int log_unregister __P((DB_LOG *, u_int32_t));
|
||||
#if defined(__cplusplus)
|
||||
@ -610,30 +663,35 @@ int log_unregister __P((DB_LOG *, u_int32_t));
|
||||
/* Mpool statistics structure. */
|
||||
struct __db_mpool_stat {
|
||||
size_t st_cachesize; /* Cache size. */
|
||||
unsigned long st_cache_hit; /* Pages found in the cache. */
|
||||
unsigned long st_cache_miss; /* Pages not found in the cache. */
|
||||
unsigned long st_map; /* Pages from mapped files. */
|
||||
unsigned long st_page_create; /* Pages created in the cache. */
|
||||
unsigned long st_page_in; /* Pages read in. */
|
||||
unsigned long st_page_out; /* Pages written out. */
|
||||
unsigned long st_ro_evict; /* Read-only pages evicted. */
|
||||
unsigned long st_rw_evict; /* Read-write pages evicted. */
|
||||
unsigned long st_hash_buckets; /* Number of hash buckets. */
|
||||
unsigned long st_hash_searches; /* Total hash chain searches. */
|
||||
unsigned long st_hash_longest; /* Longest hash chain searched. */
|
||||
unsigned long st_hash_examined; /* Total hash entries searched. */
|
||||
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. */
|
||||
};
|
||||
|
||||
/* Mpool file statistics structure. */
|
||||
struct __db_mpool_fstat {
|
||||
char *file_name; /* File name. */
|
||||
size_t st_pagesize; /* Page size. */
|
||||
unsigned long st_cache_hit; /* Pages found in the cache. */
|
||||
unsigned long st_cache_miss; /* Pages not found in the cache. */
|
||||
unsigned long st_map; /* Pages from mapped files. */
|
||||
unsigned long st_page_create; /* Pages created in the cache. */
|
||||
unsigned long st_page_in; /* Pages read in. */
|
||||
unsigned long st_page_out; /* Pages written out. */
|
||||
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)
|
||||
@ -654,6 +712,7 @@ int memp_register __P((DB_MPOOL *, int,
|
||||
int memp_stat __P((DB_MPOOL *,
|
||||
DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, void *(*)(size_t)));
|
||||
int memp_sync __P((DB_MPOOL *, DB_LSN *));
|
||||
int memp_trickle __P((DB_MPOOL *, int, int *));
|
||||
int memp_unlink __P((const char *, int, DB_ENV *));
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db_am.h 10.6 (Sleepycat) 8/27/97
|
||||
* @(#)db_am.h 10.7 (Sleepycat) 10/25/97
|
||||
*/
|
||||
#ifndef _DB_AM_H
|
||||
#define _DB_AM_H
|
||||
@ -49,7 +49,7 @@
|
||||
}
|
||||
#define REC_CLOSE { \
|
||||
if (argp != NULL) \
|
||||
free (argp); \
|
||||
__db_free(argp); \
|
||||
if (file_dbp != NULL) { \
|
||||
F_CLR(file_dbp, DB_AM_RECOVER); \
|
||||
if (F_ISSET(file_dbp, DB_AM_THREAD)) \
|
||||
@ -67,7 +67,7 @@
|
||||
}
|
||||
#define REC_NOOP_CLOSE { \
|
||||
if (argp != NULL) \
|
||||
free (argp); \
|
||||
__db_free(argp); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ typedef struct _db_ovref_args {
|
||||
DB_LSN prev_lsn;
|
||||
u_int32_t fileid;
|
||||
db_pgno_t pgno;
|
||||
int32_t adjust;
|
||||
DB_LSN lsn;
|
||||
} __db_ovref_args;
|
||||
|
||||
|
@ -4,12 +4,11 @@
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db_cxx.h 10.8 (Sleepycat) 9/20/97
|
||||
* @(#)db_cxx.h 10.12 (Sleepycat) 10/25/97
|
||||
*/
|
||||
|
||||
#ifndef _DB_CXX_H_
|
||||
#define _DB_CXX_H_
|
||||
|
||||
//
|
||||
// C++ assumptions:
|
||||
//
|
||||
@ -264,7 +263,7 @@ public:
|
||||
// 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, u_int32_t *fidp);
|
||||
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
|
||||
@ -353,6 +352,7 @@ public:
|
||||
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
|
||||
//
|
||||
@ -598,6 +598,11 @@ public:
|
||||
//
|
||||
int appinit(const char *homeDir, char *const *db_config, int flags);
|
||||
|
||||
// Called automatically when DbEnv is destroyed, or can be
|
||||
// called at any time to shut down Db.
|
||||
//
|
||||
int appexit();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// simple get/set access methods
|
||||
//
|
||||
@ -675,11 +680,6 @@ public:
|
||||
u_int32_t get_lk_detect() const;
|
||||
void set_lk_detect(u_int32_t);
|
||||
|
||||
// Yield function for threads.
|
||||
typedef int (*db_yield_fcn) (void);
|
||||
db_yield_fcn get_yield() const;
|
||||
void set_yield(db_yield_fcn);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Logging.
|
||||
@ -783,7 +783,7 @@ class _exported Db
|
||||
public:
|
||||
int close(int flags);
|
||||
int cursor(DbTxn *txnid, Dbc **cursorp);
|
||||
int del(Dbt *key, DbTxn *txnid);
|
||||
int del(DbTxn *txnid, Dbt *key, int flags);
|
||||
int fd(int *fdp);
|
||||
int get(DbTxn *txnid, Dbt *key, Dbt *data, int flags);
|
||||
int put(DbTxn *txnid, Dbt *key, Dbt *data, int flags);
|
||||
@ -884,5 +884,4 @@ private:
|
||||
Dbc(const Dbc &);
|
||||
Dbc &operator = (const Dbc &);
|
||||
};
|
||||
|
||||
#endif /* !_DB_CXX_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __db_pgerr __P((DB *, db_pgno_t));
|
||||
int __db_pgfmt __P((DB *, db_pgno_t));
|
||||
int __db_addrem_log
|
||||
@ -25,7 +25,7 @@ int __db_big_print
|
||||
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, DB_LSN *));
|
||||
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 **));
|
||||
@ -79,7 +79,7 @@ int __db_goff __P((DB *, DBT *,
|
||||
u_int32_t, db_pgno_t, void **, u_int32_t *));
|
||||
int __db_poff __P((DB *, const DBT *, db_pgno_t *,
|
||||
int (*)(DB *, u_int32_t, PAGE **)));
|
||||
int __db_ioff __P((DB *, db_pgno_t));
|
||||
int __db_ovref __P((DB *, db_pgno_t, int));
|
||||
int __db_doff __P((DB *, db_pgno_t, int (*)(DB *, PAGE *)));
|
||||
int __db_moff __P((DB *, const DBT *, db_pgno_t));
|
||||
void __db_loadme __P((void));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)db_int.h.src 10.30 (Sleepycat) 9/23/97
|
||||
* @(#)db_int.h.src 10.36 (Sleepycat) 10/31/97
|
||||
*/
|
||||
|
||||
#ifndef _DB_INTERNAL_H_
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "db.h" /* Standard DB include file. */
|
||||
#include "queue.h"
|
||||
#include "os_func.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*******************************************************
|
||||
@ -64,12 +65,16 @@
|
||||
#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)
|
||||
|
||||
/* Free and free-string macros that overwrite memory during debugging. */
|
||||
#ifdef DEBUG
|
||||
#undef FREE
|
||||
#define FREE(p, len) { \
|
||||
memset(p, 0xff, len); \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#undef FREES
|
||||
#define FREES(p) { \
|
||||
@ -78,18 +83,18 @@
|
||||
#else
|
||||
#undef FREE
|
||||
#define FREE(p, len) { \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#undef FREES
|
||||
#define FREES(p) { \
|
||||
free(p); \
|
||||
__db_free(p); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Structure used to print flag values. */
|
||||
typedef struct __fn {
|
||||
u_int32_t mask; /* Flag value. */
|
||||
char *name; /* Flag name. */
|
||||
const char *name; /* Flag name. */
|
||||
} FN;
|
||||
|
||||
/* Set, clear and test flags. */
|
||||
@ -163,10 +168,8 @@ typedef struct _db_mutex_t {
|
||||
off_t off; /* Backing file offset. */
|
||||
u_long pid; /* Lock holder: 0 or process pid. */
|
||||
#endif
|
||||
#ifdef MUTEX_STATISTICS
|
||||
u_long mutex_set_wait; /* Blocking mutex: required waiting. */
|
||||
u_long mutex_set_nowait; /* Blocking mutex: without waiting. */
|
||||
#endif
|
||||
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"
|
||||
@ -177,11 +180,10 @@ typedef struct _db_mutex_t {
|
||||
/* Lock/unlock a DB thread. */
|
||||
#define DB_THREAD_LOCK(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_THREAD) ? \
|
||||
__db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1, \
|
||||
(dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
|
||||
__db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
#define DB_THREAD_UNLOCK(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_THREAD) ? \
|
||||
__db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
__db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0)
|
||||
|
||||
/* Btree/recno local statistics structure. */
|
||||
struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT;
|
||||
@ -260,7 +262,7 @@ typedef struct __dbpginfo {
|
||||
#define IS_ZERO_LSN(LSN) ((LSN).file == 0)
|
||||
|
||||
/* Test if we need to log a change. */
|
||||
#define DB_LOGGING(dbp) \
|
||||
#define DB_LOGGING(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_LOGGING) && !F_ISSET(dbp, DB_AM_RECOVER))
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -43,7 +43,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)hash.h 10.6 (Sleepycat) 8/18/97
|
||||
* @(#)hash.h 10.7 (Sleepycat) 11/1/97
|
||||
*/
|
||||
|
||||
/* Cursor structure definitions. */
|
||||
@ -179,8 +179,8 @@ typedef struct htab { /* Memory resident data structure. */
|
||||
/* Constraints about number of pages and how much data goes on a page. */
|
||||
|
||||
#define MAX_PAGES(H) UINT32_T_MAX
|
||||
#define MINFILL 0.25
|
||||
#define ISBIG(H, N) (((N) > ((H)->hdr->pagesize * MINFILL)) ? 1 : 0)
|
||||
#define MINFILL 4
|
||||
#define ISBIG(H, N) (((N) > ((H)->hdr->pagesize / MINFILL)) ? 1 : 0)
|
||||
|
||||
/* Shorthands for accessing structure */
|
||||
#define NDX_INVALID 0xFFFF
|
||||
|
@ -108,7 +108,25 @@ typedef struct _ham_ovfl_args {
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __ham_open __P((DB *, DB_INFO *));
|
||||
int __ham_close __P((DB *));
|
||||
int __ham_c_iclose __P((DB *, DBC *));
|
||||
@ -54,10 +54,17 @@ 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,
|
||||
DB_LSN *));
|
||||
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 *, 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 *));
|
||||
@ -81,7 +88,7 @@ int __ham_item_first __P((HTAB *, HASH_CURSOR *, db_lockmode_t));
|
||||
int __ham_item_prev __P((HTAB *, HASH_CURSOR *, db_lockmode_t));
|
||||
int __ham_item_next __P((HTAB *, HASH_CURSOR *, db_lockmode_t));
|
||||
void __ham_putitem __P((PAGE *p, const DBT *, int));
|
||||
int __ham_del_pair __P((HTAB *, HASH_CURSOR *));
|
||||
int __ham_del_pair __P((HTAB *, HASH_CURSOR *, int));
|
||||
int __ham_replpair __P((HTAB *, HASH_CURSOR *, DBT *, u_int32_t));
|
||||
void __ham_onpage_replace __P((PAGE *, size_t, u_int32_t, int32_t,
|
||||
int32_t, DBT *));
|
||||
@ -118,4 +125,6 @@ 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 *, FILE *));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)lock.h 10.8 (Sleepycat) 9/23/97
|
||||
* @(#)lock.h 10.9 (Sleepycat) 10/25/97
|
||||
*/
|
||||
|
||||
typedef struct __db_lockobj DB_LOCKOBJ;
|
||||
@ -54,8 +54,7 @@ struct __db_lockregion {
|
||||
|
||||
/* Macros to lock/unlock the region. */
|
||||
#define LOCK_LOCKREGION(lt) \
|
||||
(void)__db_mutex_lock(&(lt)->region->hdr.lock,(lt)->fd, \
|
||||
(lt)->dbenv == NULL ? NULL : (lt)->dbenv->db_yield)
|
||||
(void)__db_mutex_lock(&(lt)->region->hdr.lock, (lt)->fd)
|
||||
#define UNLOCK_LOCKREGION(lt) \
|
||||
(void)__db_mutex_unlock(&(lt)->region->hdr.lock, (lt)->fd)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __lock_getobj __P((DB_LOCKTAB *,
|
||||
u_int32_t, DBT *, u_int32_t type, DB_LOCKOBJ **));
|
||||
int __lock_cmp __P((DBT *, DB_LOCKOBJ *));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)log.h 10.9 (Sleepycat) 9/23/97
|
||||
* @(#)log.h 10.15 (Sleepycat) 11/2/97
|
||||
*/
|
||||
|
||||
#ifndef _LOG_H_
|
||||
@ -15,6 +15,8 @@ struct __hdr; typedef struct __hdr HDR;
|
||||
struct __log; typedef struct __log LOG;
|
||||
struct __log_persist; typedef struct __log_persist LOGP;
|
||||
|
||||
#define MEGABYTE (1024 * 1024)
|
||||
|
||||
#define MAXLFNAME 99999 /* Maximum log file name. */
|
||||
#define LFNAME "log.%05d" /* Log file name template. */
|
||||
|
||||
@ -23,21 +25,15 @@ struct __log_persist; typedef struct __log_persist LOGP;
|
||||
|
||||
#define DEFAULT_MAX (10 * 1048576) /* 10 Mb. */
|
||||
|
||||
/* Macros to return per-process address, offsets. */
|
||||
#define ADDR(base, offset) ((void *)((u_int8_t *)((base)->addr) + offset))
|
||||
#define OFFSET(base, p) ((u_int8_t *)(p) - (u_int8_t *)(base)->addr)
|
||||
|
||||
/* 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, \
|
||||
(dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
|
||||
(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)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
|
||||
(void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock, (dblp)->fd)
|
||||
#define UNLOCK_LOGREGION(dblp) \
|
||||
(void)__db_mutex_unlock(&((RLAYOUT *)(dblp)->lp)->lock, (dblp)->fd)
|
||||
|
||||
@ -124,7 +120,7 @@ struct __log {
|
||||
DB_LSN lsn; /* LSN at current file offset. */
|
||||
DB_LSN c_lsn; /* LSN of the last checkpoint. */
|
||||
DB_LSN s_lsn; /* LSN of the last sync. */
|
||||
DB_LSN span_lsn; /* LSN spanning buffer write. */
|
||||
DB_LSN uw_lsn; /* LSN of 1st rec not fully on disk. */
|
||||
|
||||
u_int32_t len; /* Length of the last record. */
|
||||
|
||||
@ -132,7 +128,8 @@ struct __log {
|
||||
u_int32_t w_off; /* Current write offset in the file. */
|
||||
|
||||
time_t chkpt; /* Time of the last checkpoint. */
|
||||
u_int32_t written; /* Bytes written since checkpoint. */
|
||||
|
||||
DB_LOG_STAT stat; /* Log statistics. */
|
||||
|
||||
u_int8_t buf[4 * 1024]; /* Log buffer. */
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __log_find __P((DB_LOG *, int *));
|
||||
int __log_valid __P((DB_LOG *, LOG *, int));
|
||||
int __log_register_log
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)mp.h 10.16 (Sleepycat) 9/23/97
|
||||
* @(#)mp.h 10.19 (Sleepycat) 10/25/97
|
||||
*/
|
||||
|
||||
struct __bh; typedef struct __bh BH;
|
||||
@ -22,30 +22,36 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
|
||||
#define DB_CACHESIZE_DEF (128 * 1024)
|
||||
#define DB_CACHESIZE_MIN ( 20 * 1024)
|
||||
|
||||
/* Macro to return per-process address, offsets. */
|
||||
#define ADDR(base, offset) ((void *)((u_int8_t *)((base)->addr) + offset))
|
||||
#define OFFSET(base, p) ((u_int8_t *)(p) - (u_int8_t *)(base)->addr)
|
||||
|
||||
#define INVALID 0 /* Invalid shared memory offset. */
|
||||
#define TEMPORARY "<tmp>" /* Temporary file name. */
|
||||
|
||||
/*
|
||||
* There are two kinds of locks in the mpool code. The first is the region
|
||||
* lock, used to serialize modifications to all data structures. The second
|
||||
* is a per-buffer header lock. The locking order is as follows:
|
||||
* There are three ways we do locking in the mpool code:
|
||||
*
|
||||
* Process searching for a buffer:
|
||||
* 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).
|
||||
* If the BH_LOCKED flag is set:
|
||||
* If the BH_LOCKED flag is set (I/O is going on):
|
||||
* Release the region lock.
|
||||
* Request the buffer lock.
|
||||
* The I/O will complete...
|
||||
* Acquire the buffer lock.
|
||||
* Release the buffer lock.
|
||||
* Acquire the region lock.
|
||||
* Return the buffer.
|
||||
*
|
||||
* Process reading/writing a buffer:
|
||||
* Reading/writing a buffer:
|
||||
* Acquire the region lock.
|
||||
* Find/create the buffer header.
|
||||
* If reading, increment the reference count (guarantee the buffer stays).
|
||||
@ -69,8 +75,7 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
|
||||
|
||||
#define LOCKHANDLE(dbmp, mutexp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKHANDLE)) \
|
||||
(void)__db_mutex_lock(mutexp, (dbmp)->fd, \
|
||||
(dbmp)->dbenv == NULL ? NULL : (dbmp)->dbenv->db_yield)
|
||||
(void)__db_mutex_lock(mutexp, (dbmp)->fd)
|
||||
#define UNLOCKHANDLE(dbmp, mutexp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKHANDLE)) \
|
||||
(void)__db_mutex_unlock(mutexp, (dbmp)->fd)
|
||||
@ -78,8 +83,7 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
|
||||
#define LOCKREGION(dbmp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKREGION)) \
|
||||
(void)__db_mutex_lock(&((RLAYOUT *)(dbmp)->mp)->lock, \
|
||||
(dbmp)->fd, \
|
||||
(dbmp)->dbenv == NULL ? NULL : (dbmp)->dbenv->db_yield)
|
||||
(dbmp)->fd)
|
||||
#define UNLOCKREGION(dbmp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKREGION)) \
|
||||
(void)__db_mutex_unlock(&((RLAYOUT *)(dbmp)->mp)->lock, \
|
||||
@ -87,8 +91,7 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
|
||||
|
||||
#define LOCKBUFFER(dbmp, bhp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKREGION)) \
|
||||
(void)__db_mutex_lock(&(bhp)->mutex, (dbmp)->fd, \
|
||||
(dbmp)->dbenv == NULL ? NULL : (dbmp)->dbenv->db_yield)
|
||||
(void)__db_mutex_lock(&(bhp)->mutex, (dbmp)->fd)
|
||||
#define UNLOCKBUFFER(dbmp, bhp) \
|
||||
if (F_ISSET(dbmp, MP_LOCKREGION)) \
|
||||
(void)__db_mutex_unlock(&(bhp)->mutex, (dbmp)->fd)
|
||||
@ -250,8 +253,8 @@ struct __bh {
|
||||
#define BH_WRITE 0x020 /* Page scheduled for writing. */
|
||||
u_int16_t flags;
|
||||
|
||||
SH_TAILQ_ENTRY q; /* LRU list of bucket headers. */
|
||||
SH_TAILQ_ENTRY mq; /* MPOOLFILE list of bucket headers. */
|
||||
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. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __memp_bhwrite
|
||||
__P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
|
||||
int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
void __db_mutex_init __P((db_mutex_t *, off_t));
|
||||
int __db_mutex_lock __P((db_mutex_t *, int, int (*)(void)));
|
||||
int __db_mutex_lock __P((db_mutex_t *, int));
|
||||
int __db_mutex_unlock __P((db_mutex_t *, int));
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __db_abspath __P((const char *));
|
||||
char *__db_rpath __P((const char *));
|
||||
int __db_dir __P((DB_ENV *, const char *, char ***, int *));
|
||||
void __db_dirf __P((DB_ENV *, char **, int));
|
||||
int __os_dirlist __P((const char *, char ***, int *));
|
||||
void __os_dirfree __P((char **, int));
|
||||
int __db_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
|
||||
int __db_lseek __P((int, size_t, db_pgno_t, u_long, int));
|
||||
int __db_mmap __P((int, size_t, int, int, void *));
|
||||
int __db_munmap __P((void *, size_t));
|
||||
int __db_oflags __P((int));
|
||||
int __db_fdopen __P((const char *, int, int, int, int *));
|
||||
int __db_fsync __P((int));
|
||||
int __os_map __P((int, size_t, int, int, void **));
|
||||
int __os_unmap __P((void *, size_t));
|
||||
int __db_oflags __P((int));
|
||||
int __db_open __P((const char *, int, int, int, int *));
|
||||
int __db_close __P((int));
|
||||
char *__db_rpath __P((const char *));
|
||||
int __db_read __P((int, void *, size_t, ssize_t *));
|
||||
int __db_write __P((int, void *, size_t, ssize_t *));
|
||||
int __db_sleep __P((u_long, u_long));
|
||||
int __db_exists __P((const char *, int *));
|
||||
int __db_stat __P((DB_ENV *, const char *, int, off_t *, off_t *));
|
||||
int __os_seek __P((int, size_t, db_pgno_t, u_long, int));
|
||||
int __os_sleep __P((u_long, u_long));
|
||||
int __os_exists __P((const char *, int *));
|
||||
int __os_ioinfo __P((const char *, int, off_t *, off_t *));
|
||||
int __db_unlink __P((const char *));
|
||||
|
76
db2/include/os_func.h
Normal file
76
db2/include/os_func.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)os_func.h 10.2 (Sleepycat) 10/28/97
|
||||
*/
|
||||
|
||||
/* Calls which can be replaced by the application. */
|
||||
struct __db_jumptab {
|
||||
void *(*db_calloc) __P((size_t, size_t)); /* DB_FUNC_CALLOC */
|
||||
int (*db_close) __P((int)); /* DB_FUNC_CLOSE */
|
||||
void (*db_dirfree) __P((char **, int)); /* DB_FUNC_DIRFREE */
|
||||
int (*db_dirlist) /* DB_FUNC_DIRLIST */
|
||||
__P((const char *, char ***, int *));
|
||||
int (*db_exists) /* DB_FUNC_EXISTS */
|
||||
__P((const char *, int *));
|
||||
void (*db_free) __P((void *)); /* DB_FUNC_FREE */
|
||||
int (*db_fsync) __P((int)); /* DB_FUNC_FSYNC */
|
||||
int (*db_ioinfo) /* DB_FUNC_IOINFO */
|
||||
__P((const char *, int, off_t *, off_t *));
|
||||
void *(*db_malloc) __P((size_t)); /* DB_FUNC_MALLOC */
|
||||
int (*db_map) /* DB_FUNC_MAP */
|
||||
__P((int, size_t, int, int, void **));
|
||||
int (*db_open) /* DB_FUNC_OPEN */
|
||||
__P((const char *, int, ...));
|
||||
ssize_t (*db_read) __P((int, void *, size_t)); /* DB_FUNC_READ */
|
||||
void *(*db_realloc) __P((void *, size_t)); /* DB_FUNC_REALLOC */
|
||||
int (*db_seek) /* DB_FUNC_SEEK */
|
||||
__P((int, size_t, db_pgno_t, u_long, int));
|
||||
int (*db_sleep) __P((u_long, u_long)); /* DB_FUNC_SLEEP */
|
||||
char *(*db_strdup) __P((const char *)); /* DB_FUNC_STRDUP */
|
||||
int (*db_unlink) __P((const char *)); /* DB_FUNC_UNLINK */
|
||||
int (*db_unmap) __P((void *, size_t)); /* DB_FUNC_UNMAP */
|
||||
ssize_t (*db_write) /* DB_FUNC_WRITE */
|
||||
__P((int, const void *, size_t));
|
||||
int (*db_yield) __P((void)); /* DB_FUNC_YIELD */
|
||||
};
|
||||
|
||||
extern struct __db_jumptab __db_jump;
|
||||
|
||||
/*
|
||||
* Names used by DB to call through the jump table.
|
||||
*
|
||||
* The naming scheme goes like this: if the functionality the application can
|
||||
* replace is the same as the DB functionality, e.g., calloc, or dirlist, then
|
||||
* we use the name __db_XXX, and the application is expected to replace the
|
||||
* complete functionality, which may or may not map directly to an ANSI C or
|
||||
* POSIX 1003.1 interface. If the functionality that the aplication replaces
|
||||
* only underlies what the DB os directory exports to other parts of DB, e.g.,
|
||||
* read, then the name __os_XXX is used, and the application can only replace
|
||||
* the underlying functionality. Under most circumstances, the os directory
|
||||
* part of DB is the only code that should use the __os_XXX names, all other
|
||||
* parts of DB should be calling __db_XXX functions.
|
||||
*/
|
||||
#define __db_calloc __db_jump.db_calloc
|
||||
#define __os_close __db_jump.db_close /* __db_close is a wrapper. */
|
||||
#define __db_dirfree __db_jump.db_dirfree
|
||||
#define __db_dirlist __db_jump.db_dirlist
|
||||
#define __db_exists __db_jump.db_exists
|
||||
#define __db_free __db_jump.db_free
|
||||
#define __os_fsync __db_jump.db_fsync /* __db_fsync is a wrapper. */
|
||||
#define __db_ioinfo __db_jump.db_ioinfo
|
||||
#define __db_malloc __db_jump.db_malloc
|
||||
#define __db_map __db_jump.db_map
|
||||
#define __os_open __db_jump.db_open /* __db_open is a wrapper. */
|
||||
#define __os_read __db_jump.db_read /* __db_read is a wrapper. */
|
||||
#define __db_realloc __db_jump.db_realloc
|
||||
#define __db_seek __db_jump.db_seek
|
||||
#define __db_sleep __db_jump.db_sleep
|
||||
#define __db_strdup __db_jump.db_strdup
|
||||
#define __os_unlink __db_jump.db_unlink /* __db_unlink is a wrapper. */
|
||||
#define __db_unmap __db_jump.db_unmap
|
||||
#define __os_write __db_jump.db_write /* __db_write is a wrapper. */
|
||||
#define __db_yield __db_jump.db_yield
|
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*
|
||||
* @(#)txn.h 10.10 (Sleepycat) 9/23/97
|
||||
* @(#)txn.h 10.11 (Sleepycat) 10/25/97
|
||||
*/
|
||||
#ifndef _TXN_H_
|
||||
#define _TXN_H_
|
||||
@ -96,15 +96,13 @@ struct __db_txnregion {
|
||||
/* 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, \
|
||||
(tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield)
|
||||
(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)->fd, \
|
||||
(tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield)
|
||||
(void)__db_mutex_lock(&(tmgrp)->region->hdr.lock, (tmgrp)->fd)
|
||||
#define UNLOCK_TXNREGION(tmgrp) \
|
||||
(void)__db_mutex_unlock(&(tmgrp)->region->hdr.lock, (tmgrp)->fd)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Do not edit: automatically built by dist/distrib. */
|
||||
/* DO NOT EDIT: automatically built by dist/distrib. */
|
||||
int __txn_regop_log
|
||||
__P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
|
||||
u_int32_t));
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)lock.c 10.36 (Sleepycat) 9/24/97";
|
||||
static const char sccsid[] = "@(#)lock.c 10.38 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -200,7 +200,7 @@ lock_open(path, flags, mode, dbenv, ltp)
|
||||
/*
|
||||
* Create the lock table structure.
|
||||
*/
|
||||
if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) {
|
||||
if ((lt = (DB_LOCKTAB *)__db_calloc(1, sizeof(DB_LOCKTAB))) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -269,7 +269,7 @@ out: if (lt->region != NULL)
|
||||
(void)__db_rclose(lt->dbenv, lt->fd, lt->region);
|
||||
if (LF_ISSET(DB_CREATE))
|
||||
(void)lock_unlink(path, 1, lt->dbenv);
|
||||
free(lt);
|
||||
__db_free(lt);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -505,7 +505,7 @@ lock_close(lt)
|
||||
return (ret);
|
||||
|
||||
/* Free lock table. */
|
||||
free(lt);
|
||||
__db_free(lt);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -728,8 +728,7 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp)
|
||||
*/
|
||||
(void)__db_mutex_init(&newl->mutex,
|
||||
MUTEX_LOCK_OFFSET(lt->region, &newl->mutex));
|
||||
(void)__db_mutex_lock(&newl->mutex, lt->fd,
|
||||
lt->dbenv == NULL ? NULL : lt->dbenv->db_yield);
|
||||
(void)__db_mutex_lock(&newl->mutex, lt->fd);
|
||||
|
||||
/*
|
||||
* Now, insert the lock onto its locker's list.
|
||||
@ -760,8 +759,7 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp)
|
||||
if (lrp->detect != DB_LOCK_NORUN)
|
||||
ret = lock_detect(lt, 0, lrp->detect);
|
||||
|
||||
(void)__db_mutex_lock(&newl->mutex,
|
||||
lt->fd, lt->dbenv == NULL ? NULL : lt->dbenv->db_yield);
|
||||
(void)__db_mutex_lock(&newl->mutex, lt->fd);
|
||||
|
||||
LOCK_LOCKREGION(lt);
|
||||
if (newl->status != DB_LSTAT_PENDING) {
|
||||
@ -975,11 +973,9 @@ __lock_dump_region(lt, flags)
|
||||
#ifndef HAVE_SPINLOCKS
|
||||
printf("Mutex: off %lu", (u_long)lrp->hdr.lock.off);
|
||||
#endif
|
||||
#ifdef MUTEX_STATISTICS
|
||||
printf(" waits %lu nowaits %lu",
|
||||
(u_long)lrp->hdr.lock.mutex_set_wait,
|
||||
(u_long)lrp->hdr.lock.mutex_set_nowait);
|
||||
#endif
|
||||
printf("\n%s:%lu\t%s:%lu\t%s:%lu\t%s:%lu\n",
|
||||
"nconflicts ", (u_long)lrp->nconflicts,
|
||||
"nrequests ", (u_long)lrp->nrequests,
|
||||
|
@ -11,7 +11,7 @@
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1997\n\
|
||||
Sleepycat Software Inc. All rights reserved.\n";
|
||||
static const char sccsid[] = "@(#)lock_deadlock.c 10.21 (Sleepycat) 9/6/97";
|
||||
static const char sccsid[] = "@(#)lock_deadlock.c 10.25 (Sleepycat) 11/1/97";
|
||||
#endif
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -50,16 +50,19 @@ 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 **, int *, locker_info **));
|
||||
#ifdef DEBUG
|
||||
static void __dd_debug __P((DB_ENV *, locker_info *, u_int32_t *, int));
|
||||
#endif
|
||||
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 DEBUG
|
||||
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;
|
||||
@ -68,8 +71,8 @@ lock_detect(lt, flags, atype)
|
||||
{
|
||||
DB_ENV *dbenv;
|
||||
locker_info *idmap;
|
||||
u_int32_t *bitmap, *deadlock, killid;
|
||||
int do_pass, i, nlockers, nentries, ret;
|
||||
u_int32_t *bitmap, *deadlock, i, killid, nentries, nlockers;
|
||||
int do_pass, ret;
|
||||
|
||||
/* Validate arguments. */
|
||||
if ((ret =
|
||||
@ -77,17 +80,16 @@ lock_detect(lt, flags, atype)
|
||||
return (ret);
|
||||
|
||||
/* Check if a detector run is necessary. */
|
||||
do_pass = 1;
|
||||
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);
|
||||
if (!do_pass)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Build the waits-for bitmap. */
|
||||
if ((ret = __dd_build(dbenv, &bitmap, &nlockers, &idmap)) != 0)
|
||||
@ -118,8 +120,7 @@ lock_detect(lt, flags, atype)
|
||||
|
||||
if (killid == BAD_KILLID) {
|
||||
__db_err(dbenv,
|
||||
"warning: could not find %s",
|
||||
"locker to abort");
|
||||
"warning: could not find locker to abort");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -137,11 +138,8 @@ lock_detect(lt, flags, atype)
|
||||
/*
|
||||
* We are trying to calculate the id of the
|
||||
* locker whose entry is indicated by deadlock.
|
||||
* We know that this is less than nlockers, so
|
||||
* the cast below is valid.
|
||||
*/
|
||||
killid =
|
||||
(u_int32_t)((deadlock - bitmap) / nentries);
|
||||
killid = (deadlock - bitmap) / nentries;
|
||||
break;
|
||||
case DB_LOCK_YOUNGEST:
|
||||
/*
|
||||
@ -155,8 +153,7 @@ lock_detect(lt, flags, atype)
|
||||
|
||||
if (killid == BAD_KILLID) {
|
||||
__db_err(dbenv,
|
||||
"warning: could not find %s",
|
||||
"locker to abort");
|
||||
"warning: could not find locker to abort");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@ -184,8 +181,8 @@ lock_detect(lt, flags, atype)
|
||||
"warning: unable to abort locker %lx",
|
||||
(u_long)idmap[killid].id);
|
||||
}
|
||||
free(bitmap);
|
||||
free(idmap);
|
||||
__db_free(bitmap);
|
||||
__db_free(idmap);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -197,15 +194,15 @@ lock_detect(lt, flags, atype)
|
||||
static int
|
||||
__dd_build(dbenv, bmp, nlockers, idmap)
|
||||
DB_ENV *dbenv;
|
||||
u_int32_t **bmp;
|
||||
int *nlockers;
|
||||
u_int32_t **bmp, *nlockers;
|
||||
locker_info **idmap;
|
||||
{
|
||||
DB_LOCKTAB *lt;
|
||||
DB_LOCKOBJ *op, *lockerp;
|
||||
struct __db_lock *lp;
|
||||
u_int32_t *bitmap, count, *entryp, i, id, nentries, *tmpmap;
|
||||
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;
|
||||
@ -238,24 +235,24 @@ retry: count = lt->region->nlockers;
|
||||
* We can probably save the malloc's between iterations just
|
||||
* reallocing if necessary because count grew by too much.
|
||||
*/
|
||||
if ((bitmap = (u_int32_t *)calloc((size_t)count,
|
||||
if ((bitmap = (u_int32_t *)__db_calloc((size_t)count,
|
||||
sizeof(u_int32_t) * nentries)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
if ((tmpmap =
|
||||
(u_int32_t *)calloc(sizeof(u_int32_t), nentries)) == NULL) {
|
||||
(u_int32_t *)__db_calloc(sizeof(u_int32_t), nentries)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
free(bitmap);
|
||||
__db_free(bitmap);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
if ((id_array = (locker_info *)calloc((size_t)count,
|
||||
if ((id_array = (locker_info *)__db_calloc((size_t)count,
|
||||
sizeof(locker_info))) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
free(bitmap);
|
||||
free(tmpmap);
|
||||
__db_free(bitmap);
|
||||
__db_free(tmpmap);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -264,9 +261,9 @@ retry: count = lt->region->nlockers;
|
||||
*/
|
||||
LOCK_LOCKREGION(lt);
|
||||
if (lt->region->nlockers > count) {
|
||||
free(bitmap);
|
||||
free(tmpmap);
|
||||
free(id_array);
|
||||
__db_free(bitmap);
|
||||
__db_free(tmpmap);
|
||||
__db_free(id_array);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@ -326,9 +323,8 @@ retry: count = lt->region->nlockers;
|
||||
lp != NULL;
|
||||
is_first = 0,
|
||||
lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
|
||||
if ((ret = __lock_getobj(lt,
|
||||
lp->holder, NULL, DB_LOCK_LOCKER, &lockerp))
|
||||
!= 0) {
|
||||
if ((ret = __lock_getobj(lt, lp->holder,
|
||||
NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {
|
||||
__db_err(dbenv,
|
||||
"warning unable to find object");
|
||||
continue;
|
||||
@ -369,8 +365,16 @@ retry: count = lt->region->nlockers;
|
||||
continue;
|
||||
}
|
||||
lp = SH_LIST_FIRST(&lockerp->heldby, __db_lock);
|
||||
if (lp != NULL)
|
||||
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. */
|
||||
@ -384,21 +388,20 @@ retry: count = lt->region->nlockers;
|
||||
*nlockers = id;
|
||||
*idmap = id_array;
|
||||
*bmp = bitmap;
|
||||
free(tmpmap);
|
||||
__db_free(tmpmap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static u_int32_t *
|
||||
__dd_find(bmp, idmap, nlockers)
|
||||
u_int32_t *bmp;
|
||||
u_int32_t *bmp, nlockers;
|
||||
locker_info *idmap;
|
||||
u_int32_t nlockers;
|
||||
{
|
||||
u_int32_t i, j, nentries, *mymap, *tmpmap;
|
||||
|
||||
/*
|
||||
* For each locker, or in the bits from the lockers
|
||||
* on which that locker is waiting.
|
||||
* 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) {
|
||||
@ -422,9 +425,9 @@ __dd_abort(dbenv, info)
|
||||
DB_ENV *dbenv;
|
||||
locker_info *info;
|
||||
{
|
||||
struct __db_lock *lockp;
|
||||
DB_LOCKTAB *lt;
|
||||
DB_LOCKOBJ *lockerp, *sh_obj;
|
||||
struct __db_lock *lockp;
|
||||
int ret;
|
||||
|
||||
lt = dbenv->lk_info;
|
||||
@ -459,19 +462,17 @@ static void
|
||||
__dd_debug(dbenv, idmap, bitmap, nlockers)
|
||||
DB_ENV *dbenv;
|
||||
locker_info *idmap;
|
||||
u_int32_t *bitmap;
|
||||
int nlockers;
|
||||
u_int32_t *bitmap, nlockers;
|
||||
{
|
||||
u_int32_t *mymap;
|
||||
int i, j, nentries;
|
||||
u_int32_t i, j, *mymap, nentries;
|
||||
char *msgbuf;
|
||||
|
||||
__db_err(dbenv, "Waitsfor array");
|
||||
__db_err(dbenv, "waiter\twaiting on");
|
||||
/*
|
||||
* Alloc space to print 10 bytes per item waited on.
|
||||
* Allocate space to print 10 bytes per item waited on.
|
||||
*/
|
||||
if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
|
||||
if ((msgbuf = (char *)__db_malloc((nlockers + 1) * 10 + 64)) == NULL) {
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return;
|
||||
}
|
||||
@ -480,7 +481,8 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
|
||||
for (mymap = bitmap, i = 0; i < nlockers; i++, mymap += nentries) {
|
||||
if (!idmap[i].valid)
|
||||
continue;
|
||||
sprintf(msgbuf, "%lx\t\t", (u_long)idmap[i].id);/* Waiter. */
|
||||
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,
|
||||
@ -490,6 +492,6 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
|
||||
__db_err(dbenv, msgbuf);
|
||||
}
|
||||
|
||||
free(msgbuf);
|
||||
__db_free(msgbuf);
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log.c 10.27 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)log.c 10.33 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -67,11 +67,11 @@ log_open(path, flags, mode, dbenv, lpp)
|
||||
}
|
||||
|
||||
/* Create and initialize the DB_LOG structure. */
|
||||
if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL)
|
||||
if ((dblp = (DB_LOG *)__db_calloc(1, sizeof(DB_LOG))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if (path != NULL && (dblp->dir = strdup(path)) == NULL) {
|
||||
free(dblp);
|
||||
if (path != NULL && (dblp->dir = __db_strdup(path)) == NULL) {
|
||||
__db_free(dblp);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -329,10 +329,12 @@ __log_find(dblp, valp)
|
||||
}
|
||||
|
||||
/* Get the list of file names. */
|
||||
ret = __db_dir(dblp->dbenv, dir, &names, &fcnt);
|
||||
ret = __db_dirlist(dir, &names, &fcnt);
|
||||
FREES(p);
|
||||
if (ret != 0)
|
||||
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
|
||||
@ -350,7 +352,7 @@ __log_find(dblp, valp)
|
||||
}
|
||||
|
||||
/* Discard the list. */
|
||||
__db_dirf(dblp->dbenv, names, fcnt);
|
||||
__db_dirfree(names, fcnt);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -376,10 +378,10 @@ __log_valid(dblp, lp, cnt)
|
||||
return (ret);
|
||||
|
||||
fd = -1;
|
||||
if ((ret = __db_fdopen(p,
|
||||
if ((ret = __db_open(p,
|
||||
DB_RDONLY | DB_SEQUENTIAL,
|
||||
DB_RDONLY | DB_SEQUENTIAL, 0, &fd)) != 0 ||
|
||||
(ret = __db_lseek(fd, 0, 0, sizeof(HDR), SEEK_SET)) != 0 ||
|
||||
(ret = __db_seek(fd, 0, 0, sizeof(HDR), SEEK_SET)) != 0 ||
|
||||
(ret = __db_read(fd, &persist, sizeof(LOGP), &nw)) != 0 ||
|
||||
nw != sizeof(LOGP)) {
|
||||
if (ret == 0)
|
||||
@ -474,3 +476,39 @@ log_unlink(path, force, dbenv)
|
||||
return (__db_runlink(dbenv,
|
||||
DB_APP_LOG, path, DB_DEFAULT_LOG_FILE, force));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
*gspp = NULL;
|
||||
lp = dblp->lp;
|
||||
|
||||
if ((*gspp = db_malloc == NULL ?
|
||||
(DB_LOG_STAT *)__db_malloc(sizeof(**gspp)) :
|
||||
(DB_LOG_STAT *)db_malloc(sizeof(**gspp))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* 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;
|
||||
UNLOCK_LOGREGION(dblp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_archive.c 10.26 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)log_archive.c 10.28 (Sleepycat) 10/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -68,7 +68,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
* but that's just not possible.
|
||||
*/
|
||||
if (LF_ISSET(DB_ARCH_ABS)) {
|
||||
__set_errno (0);
|
||||
errno = 0;
|
||||
if ((pref = getcwd(buf, sizeof(buf))) == NULL)
|
||||
return (errno == 0 ? ENOMEM : errno);
|
||||
} else
|
||||
@ -84,7 +84,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0)
|
||||
return (ret);
|
||||
if (F_ISSET(dblp, DB_AM_THREAD))
|
||||
free(rec.data);
|
||||
__db_free(rec.data);
|
||||
fnum = stable_lsn.file;
|
||||
break;
|
||||
case 0:
|
||||
@ -102,7 +102,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
#define LIST_INCREMENT 64
|
||||
/* Get some initial space. */
|
||||
if ((array =
|
||||
(char **)malloc(sizeof(char *) * (array_size = 10))) == NULL)
|
||||
(char **)__db_malloc(sizeof(char *) * (array_size = 10))) == NULL)
|
||||
return (ENOMEM);
|
||||
array[0] = NULL;
|
||||
|
||||
@ -115,7 +115,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
|
||||
if (n >= array_size - 1) {
|
||||
array_size += LIST_INCREMENT;
|
||||
if ((array = (char **)realloc(array,
|
||||
if ((array = (char **)__db_realloc(array,
|
||||
sizeof(char *) * array_size)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
@ -127,7 +127,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
goto err;
|
||||
FREES(name);
|
||||
} else if ((p = __db_rpath(name)) != NULL) {
|
||||
if ((array[n] = (char *)strdup(p + 1)) == NULL) {
|
||||
if ((array[n] = (char *)__db_strdup(p + 1)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -158,7 +158,7 @@ log_archive(dblp, listp, flags, db_malloc)
|
||||
err: if (array != NULL) {
|
||||
for (arrayp = array; *arrayp != NULL; ++arrayp)
|
||||
FREES(*arrayp);
|
||||
free(array);
|
||||
__db_free(array);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -182,7 +182,7 @@ __build_data(dblp, pref, listp, db_malloc)
|
||||
|
||||
/* Get some initial space. */
|
||||
if ((array =
|
||||
(char **)malloc(sizeof(char *) * (array_size = 10))) == NULL)
|
||||
(char **)__db_malloc(sizeof(char *) * (array_size = 10))) == NULL)
|
||||
return (ENOMEM);
|
||||
array[0] = NULL;
|
||||
|
||||
@ -200,7 +200,7 @@ __build_data(dblp, pref, listp, db_malloc)
|
||||
memcpy(&rectype, rec.data, sizeof(rectype));
|
||||
if (rectype != DB_log_register) {
|
||||
if (F_ISSET(dblp, DB_AM_THREAD)) {
|
||||
free(rec.data);
|
||||
__db_free(rec.data);
|
||||
rec.data = NULL;
|
||||
}
|
||||
continue;
|
||||
@ -214,25 +214,25 @@ __build_data(dblp, pref, listp, db_malloc)
|
||||
|
||||
if (n >= array_size - 1) {
|
||||
array_size += LIST_INCREMENT;
|
||||
if ((array = (char **)realloc(array,
|
||||
if ((array = (char **)__db_realloc(array,
|
||||
sizeof(char *) * array_size)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto lg_free;
|
||||
}
|
||||
}
|
||||
|
||||
if ((array[n] = (char *)strdup(argp->name.data)) == NULL) {
|
||||
if ((array[n] = (char *)__db_strdup(argp->name.data)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
|
||||
free(rec.data);
|
||||
__db_free(rec.data);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
array[++n] = NULL;
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
|
||||
if (F_ISSET(dblp, DB_AM_THREAD)) {
|
||||
free(rec.data);
|
||||
__db_free(rec.data);
|
||||
rec.data = NULL;
|
||||
}
|
||||
}
|
||||
@ -289,7 +289,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
|
||||
if (ret != 0)
|
||||
goto err2;
|
||||
} else if ((p = __db_rpath(real_name)) != NULL) {
|
||||
array[last] = (char *)strdup(p + 1);
|
||||
array[last] = (char *)__db_strdup(p + 1);
|
||||
FREES(real_name);
|
||||
if (array[last] == NULL)
|
||||
goto err2;
|
||||
@ -321,7 +321,7 @@ err2: /*
|
||||
err1: if (array != NULL) {
|
||||
for (arrayp = array; *arrayp != NULL; ++arrayp)
|
||||
FREES(*arrayp);
|
||||
free(array);
|
||||
__db_free(array);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -341,7 +341,7 @@ __absname(pref, name, newnamep)
|
||||
l_name = strlen(name);
|
||||
|
||||
/* Malloc space for concatenating the two. */
|
||||
if ((newname = (char *)malloc(l_pref + l_name + 2)) == NULL)
|
||||
if ((newname = (char *)__db_malloc(l_pref + l_name + 2)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Build the name. */
|
||||
@ -379,7 +379,7 @@ __usermem(listp, func)
|
||||
* Don't simplify this expression, SunOS compilers don't like it.
|
||||
*/
|
||||
if (func == NULL)
|
||||
array = (char **)malloc(len);
|
||||
array = (char **)__db_malloc(len);
|
||||
else
|
||||
array = (char **)func(len);
|
||||
if (array == NULL)
|
||||
@ -399,7 +399,7 @@ __usermem(listp, func)
|
||||
/* NULL-terminate the list. */
|
||||
*arrayp = NULL;
|
||||
|
||||
free(*listp);
|
||||
__db_free(*listp);
|
||||
*listp = array;
|
||||
|
||||
return (0);
|
||||
|
@ -53,7 +53,7 @@ int __log_register_log(logp, txnid, ret_lsnp, flags,
|
||||
+ sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size)
|
||||
+ sizeof(id)
|
||||
+ sizeof(ftype);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -94,7 +94,7 @@ int __log_register_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = __log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ __log_register_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
printf("\tid: %lu\n", (u_long)argp->id);
|
||||
printf("\tftype: 0x%lx\n", (u_long)argp->ftype);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ __log_register_read(recbuf, argpp)
|
||||
__log_register_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__log_register_args *)malloc(sizeof(__log_register_args) +
|
||||
argp = (__log_register_args *)__db_malloc(sizeof(__log_register_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
@ -223,7 +223,7 @@ int __log_unregister_log(logp, txnid, ret_lsnp, flags,
|
||||
lsnp = &txnid->last_lsn;
|
||||
logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
|
||||
+ sizeof(id);
|
||||
if ((logrec.data = (void *)malloc(logrec.size)) == NULL)
|
||||
if ((logrec.data = (void *)__db_malloc(logrec.size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
bp = logrec.data;
|
||||
@ -242,7 +242,7 @@ int __log_unregister_log(logp, txnid, ret_lsnp, flags,
|
||||
ret = __log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
|
||||
if (txnid != NULL)
|
||||
txnid->last_lsn = *ret_lsnp;
|
||||
free(logrec.data);
|
||||
__db_free(logrec.data);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ __log_unregister_print(notused1, dbtp, lsnp, notused3, notused4)
|
||||
(u_long)argp->prev_lsn.offset);
|
||||
printf("\tid: %lu\n", (u_long)argp->id);
|
||||
printf("\n");
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ __log_unregister_read(recbuf, argpp)
|
||||
__log_unregister_args *argp;
|
||||
u_int8_t *bp;
|
||||
|
||||
argp = (__log_unregister_args *)malloc(sizeof(__log_unregister_args) +
|
||||
argp = (__log_unregister_args *)__db_malloc(sizeof(__log_unregister_args) +
|
||||
sizeof(DB_TXN));
|
||||
if (argp == NULL)
|
||||
return (ENOMEM);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_findckp.c 10.11 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)log_findckp.c 10.12 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -77,13 +77,13 @@ __log_findckp(lp, lsnp)
|
||||
next_lsn = last_ckp;
|
||||
do {
|
||||
if (F_ISSET(lp, DB_AM_THREAD))
|
||||
free(data.data);
|
||||
__db_free(data.data);
|
||||
|
||||
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))
|
||||
free(data.data);
|
||||
__db_free(data.data);
|
||||
return (ret);
|
||||
}
|
||||
if (IS_ZERO_LSN(ckp_lsn))
|
||||
@ -100,12 +100,12 @@ __log_findckp(lp, lsnp)
|
||||
}
|
||||
last_ckp = next_lsn;
|
||||
next_lsn = ckp_args->last_ckp;
|
||||
free(ckp_args);
|
||||
__db_free(ckp_args);
|
||||
} while (!IS_ZERO_LSN(next_lsn) &&
|
||||
log_compare(&last_ckp, &ckp_lsn) > 0);
|
||||
|
||||
if (F_ISSET(lp, DB_AM_THREAD))
|
||||
free(data.data);
|
||||
__db_free(data.data);
|
||||
|
||||
/*
|
||||
* At this point, either, next_lsn is ZERO or ckp_lsn is the
|
||||
@ -118,7 +118,7 @@ __log_findckp(lp, lsnp)
|
||||
if ((ret = log_get(lp, &last_ckp, &data, DB_FIRST)) != 0)
|
||||
return (ret);
|
||||
if (F_ISSET(lp, DB_AM_THREAD))
|
||||
free(data.data);
|
||||
__db_free(data.data);
|
||||
}
|
||||
*lsnp = last_ckp;
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_get.c 10.19 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)log_get.c 10.21 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -170,7 +170,8 @@ __log_get(dblp, alsn, dbt, flags, silent)
|
||||
if (!IS_ZERO_LSN(nlsn)) {
|
||||
/* If at start-of-file, move to the previous file. */
|
||||
if (nlsn.offset == 0) {
|
||||
if (nlsn.file == 1)
|
||||
if (nlsn.file == 1 ||
|
||||
__log_valid(dblp, NULL, nlsn.file - 1) != 0)
|
||||
return (DB_NOTFOUND);
|
||||
|
||||
--nlsn.file;
|
||||
@ -215,27 +216,21 @@ retry:
|
||||
goto cksum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the file descriptor to the page that has the hdr. We dealt
|
||||
* with moving to a previous log file in the flags switch code, but
|
||||
* we don't yet know if we'll need to move to a subsequent file.
|
||||
*
|
||||
* Acquire a file descriptor.
|
||||
*/
|
||||
/* Acquire a file descriptor. */
|
||||
if (dblp->c_fd == -1) {
|
||||
if ((ret = __log_name(dblp, nlsn.file, &np)) != 0)
|
||||
goto err1;
|
||||
if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL,
|
||||
if ((ret = __db_open(np, DB_RDONLY | DB_SEQUENTIAL,
|
||||
DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) {
|
||||
fail = np;
|
||||
goto err1;
|
||||
}
|
||||
free(np);
|
||||
__db_free(np);
|
||||
np = NULL;
|
||||
}
|
||||
|
||||
/* Seek to the header offset and read the header. */
|
||||
if ((ret = __db_lseek(dblp->c_fd, 0, 0, nlsn.offset, SEEK_SET)) != 0) {
|
||||
if ((ret = __db_seek(dblp->c_fd, 0, 0, nlsn.offset, SEEK_SET)) != 0) {
|
||||
fail = "seek";
|
||||
goto err1;
|
||||
}
|
||||
@ -289,7 +284,7 @@ retry:
|
||||
}
|
||||
|
||||
/* Allocate temporary memory to hold the record. */
|
||||
if ((tbuf = (char *)malloc(len)) == NULL) {
|
||||
if ((tbuf = (char *)__db_malloc(len)) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
@ -318,7 +313,7 @@ retry:
|
||||
if ((ret = __db_retcopy(dbt, tbuf, len,
|
||||
&dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
|
||||
goto err1;
|
||||
free(tbuf);
|
||||
__db_free(tbuf);
|
||||
tbuf = NULL;
|
||||
|
||||
cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
|
||||
@ -349,8 +344,8 @@ err1: if (!silent)
|
||||
__db_err(dblp->dbenv,
|
||||
"log_get: %s: %s", fail, strerror(ret));
|
||||
err2: if (np != NULL)
|
||||
free(np);
|
||||
__db_free(np);
|
||||
if (tbuf != NULL)
|
||||
free(tbuf);
|
||||
__db_free(tbuf);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_put.c 10.14 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)log_put.c 10.20 (Sleepycat) 11/2/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -29,9 +29,10 @@ static const char sccsid[] = "@(#)log_put.c 10.14 (Sleepycat) 9/23/97";
|
||||
#include "common_ext.h"
|
||||
|
||||
static int __log_fill __P((DB_LOG *, void *, u_int32_t));
|
||||
static int __log_flush __P((DB_LOG *, const DB_LSN *));
|
||||
static int __log_newfd __P((DB_LOG *));
|
||||
static int __log_write __P((DB_LOG *, void *, u_int32_t));
|
||||
static int __log_putr __P((DB_LOG *, const DBT *, u_int32_t));
|
||||
static int __log_write __P((DB_LOG *, void *, u_int32_t));
|
||||
|
||||
/*
|
||||
* log_put --
|
||||
@ -63,11 +64,8 @@ log_put(dblp, lsn, dbt, flags)
|
||||
}
|
||||
|
||||
LOCK_LOGREGION(dblp);
|
||||
|
||||
ret = __log_put(dblp, lsn, dbt, flags);
|
||||
|
||||
UNLOCK_LOGREGION(dblp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -102,14 +100,10 @@ __log_put(dblp, lsn, dbt, flags)
|
||||
"log_put: record larger than maximum file size");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (lp->b_off != 0) {
|
||||
if ((ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
|
||||
return (ret);
|
||||
if ((ret = __db_fsync(dblp->lfd)) != 0)
|
||||
return (ret);
|
||||
lp->s_lsn.file = lp->lsn.file;
|
||||
lp->s_lsn.offset = lp->lsn.offset - 1;
|
||||
}
|
||||
|
||||
/* Flush the log. */
|
||||
if ((ret = __log_flush(dblp, NULL)) != 0)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Save the last known offset from the previous file, we'll
|
||||
@ -117,9 +111,15 @@ __log_put(dblp, lsn, dbt, flags)
|
||||
*/
|
||||
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;
|
||||
|
||||
/* Reset the first-unwritten LSN for the buffer. */
|
||||
lp->uw_lsn = lp->lsn;
|
||||
} else
|
||||
lastoff = 0;
|
||||
|
||||
@ -149,56 +149,54 @@ __log_put(dblp, lsn, dbt, flags)
|
||||
* 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.
|
||||
* Flush the current buffer contents to disk.
|
||||
* Sync the log to disk.
|
||||
* Save the time the checkpoint was written.
|
||||
* Reset the bytes written since the last checkpoint.
|
||||
*/
|
||||
if (flags == DB_CHECKPOINT) {
|
||||
lp->c_lsn = *lsn;
|
||||
|
||||
for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
|
||||
fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
|
||||
t.data = ADDR(dblp, fnp->name_off);
|
||||
t.data = R_ADDR(dblp, fnp->name_off);
|
||||
t.size = strlen(t.data) + 1;
|
||||
memset(&fid_dbt, 0, sizeof(fid_dbt));
|
||||
fid_dbt.data = ADDR(dblp, fnp->fileid_off);
|
||||
fid_dbt.data = R_ADDR(dblp, fnp->fileid_off);
|
||||
fid_dbt.size = DB_FILE_ID_LEN;
|
||||
if ((ret = __log_register_log(dblp, NULL, &r_unused,
|
||||
0, &t, &fid_dbt, fnp->id, fnp->s_type)) != 0)
|
||||
return (ret);
|
||||
}
|
||||
if (lp->b_off != 0 &&
|
||||
(ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
|
||||
return (ret);
|
||||
(void)time(&lp->chkpt);
|
||||
lp->written = 0;
|
||||
|
||||
if ((ret = __db_fsync(dblp->lfd)) != 0)
|
||||
return (ret);
|
||||
lp->s_lsn.file = lp->lsn.file;
|
||||
lp->s_lsn.offset = lp->lsn.offset - 1;
|
||||
}
|
||||
|
||||
/* We always flush on a checkpoint. */
|
||||
if (flags == DB_FLUSH || flags == DB_CHECKPOINT) {
|
||||
if (lp->b_off != 0 &&
|
||||
(ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
|
||||
return (ret);
|
||||
|
||||
if ((ret = __db_fsync(dblp->lfd)) != 0)
|
||||
return (ret);
|
||||
lp->s_lsn.file = lp->lsn.file;
|
||||
lp->s_lsn.offset = lp->lsn.offset - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we just did I/O, i.e., this LSN could have spanned the start of
|
||||
* the in-core buffer, we remember it so that we can flush correctly
|
||||
* during a sync.
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* When an application calls the log_flush routine, we need to figure
|
||||
* out if the current buffer needs to be flushed. The problem is that
|
||||
* if a record spans buffers, it's possible for the record continued
|
||||
* in the current buffer to have begun in a previous buffer. Each time
|
||||
* we write a buffer, we update the first-unwritten LSN to point to the
|
||||
* first LSN after that written buffer. If we have a spanning record,
|
||||
* correct that value to be the LSN that started it all, here.
|
||||
*/
|
||||
if (lsn->offset < lp->w_off && lsn->offset + lp->len > lp->w_off)
|
||||
lp->span_lsn = *lsn;
|
||||
lp->uw_lsn = *lsn;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -247,6 +245,24 @@ int
|
||||
log_flush(dblp, lsn)
|
||||
DB_LOG *dblp;
|
||||
const DB_LSN *lsn;
|
||||
{
|
||||
int ret;
|
||||
|
||||
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;
|
||||
@ -255,60 +271,64 @@ log_flush(dblp, lsn)
|
||||
ret = 0;
|
||||
lp = dblp->lp;
|
||||
|
||||
LOCK_LOGREGION(dblp);
|
||||
|
||||
/* If no LSN specified, flush the entire log. */
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* If it's a non-existent record, it's an error. */
|
||||
if (lsn->file > lp->lsn.file ||
|
||||
(lsn->file == lp->lsn.file && lsn->offset > lp->lsn.offset)) {
|
||||
__db_err(dblp->dbenv, "log_flush: LSN past current end-of-log");
|
||||
ret = EINVAL;
|
||||
goto ret1;
|
||||
}
|
||||
} 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 it's from a previous file, we're done because we sync each
|
||||
* file when we move to a new one.
|
||||
* 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
|
||||
* that has not yet been written to disk, so the test is <, not <=.
|
||||
*/
|
||||
if (lsn->file < lp->lsn.file)
|
||||
goto ret1;
|
||||
|
||||
/*
|
||||
* If it's less than the last-sync'd offset, we've already sync'd
|
||||
* this LSN.
|
||||
*/
|
||||
if (lsn->offset <= lp->s_lsn.offset)
|
||||
goto ret1;
|
||||
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 sync LSN is greater than or equal to the
|
||||
* saved spanning-LSN.
|
||||
* current buffer if the flush LSN is greater than or equal to the
|
||||
* first-unwritten LSN (uw_lsn). If we write the buffer, then we
|
||||
* update the first-unwritten LSN.
|
||||
*/
|
||||
if (lsn->file >= lp->span_lsn.file &&
|
||||
lsn->offset >= lp->span_lsn.offset)
|
||||
if (lp->b_off != 0 &&
|
||||
lsn->file >= lp->uw_lsn.file && lsn->offset >= lp->uw_lsn.offset)
|
||||
if ((ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
|
||||
goto ret1;
|
||||
return (ret);
|
||||
|
||||
/* Acquire a file descriptor if we don't have one. */
|
||||
if (dblp->lfname != dblp->lp->lsn.file &&
|
||||
(ret = __log_newfd(dblp)) != 0)
|
||||
goto ret1;
|
||||
/*
|
||||
* 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 = __db_fsync(dblp->lfd)) != 0)
|
||||
goto ret1;
|
||||
return (ret);
|
||||
++lp->stat.st_scount;
|
||||
|
||||
lp->s_lsn.file = lp->lsn.file;
|
||||
lp->s_lsn.offset = lsn->offset;
|
||||
/*
|
||||
* Set the last-synced LSN, the first LSN after the last record
|
||||
* that we know is on disk.
|
||||
*/
|
||||
lp->s_lsn = lp->uw_lsn;
|
||||
|
||||
ret1: UNLOCK_LOGREGION(dblp);
|
||||
return (ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -385,17 +405,32 @@ __log_write(dblp, addr, len)
|
||||
* Seek to the offset in the file (someone may have written it
|
||||
* since we last did).
|
||||
*/
|
||||
if ((ret = __db_lseek(dblp->lfd, 0, 0, lp->w_off, SEEK_SET)) != 0)
|
||||
if ((ret = __db_seek(dblp->lfd, 0, 0, lp->w_off, SEEK_SET)) != 0)
|
||||
return (ret);
|
||||
if ((ret = __db_write(dblp->lfd, addr, len, &nw)) != 0)
|
||||
return (ret);
|
||||
if (nw != (int32_t)len)
|
||||
return (EIO);
|
||||
|
||||
/* Update the seek offset and reset the buffer offset. */
|
||||
/*
|
||||
* Reset the buffer offset, update the seek offset, and update the
|
||||
* first-unwritten LSN.
|
||||
*/
|
||||
lp->b_off = 0;
|
||||
lp->w_off += len;
|
||||
lp->written += len;
|
||||
lp->uw_lsn.file = lp->lsn.file;
|
||||
lp->uw_lsn.offset = lp->w_off;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
@ -415,11 +450,8 @@ log_file(dblp, lsn, namep, len)
|
||||
char *p;
|
||||
|
||||
LOCK_LOGREGION(dblp);
|
||||
|
||||
ret = __log_name(dblp, lsn->file, &p);
|
||||
|
||||
UNLOCK_LOGREGION(dblp);
|
||||
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
@ -429,7 +461,7 @@ log_file(dblp, lsn, namep, len)
|
||||
return (ENOMEM);
|
||||
}
|
||||
(void)strcpy(namep, p);
|
||||
free(p);
|
||||
__db_free(p);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -455,7 +487,7 @@ __log_newfd(dblp)
|
||||
dblp->lfname = dblp->lp->lsn.file;
|
||||
if ((ret = __log_name(dblp, dblp->lfname, &p)) != 0)
|
||||
return (ret);
|
||||
if ((ret = __db_fdopen(p,
|
||||
if ((ret = __db_open(p,
|
||||
DB_CREATE | DB_SEQUENTIAL,
|
||||
DB_CREATE | DB_SEQUENTIAL,
|
||||
dblp->lp->persist.mode, &dblp->lfd)) != 0)
|
||||
@ -472,14 +504,14 @@ __log_newfd(dblp)
|
||||
* PUBLIC: int __log_name __P((DB_LOG *, int, char **));
|
||||
*/
|
||||
int
|
||||
__log_name(dblp, fileno, namep)
|
||||
__log_name(dblp, filenumber, namep)
|
||||
DB_LOG *dblp;
|
||||
char **namep;
|
||||
int fileno;
|
||||
int filenumber;
|
||||
{
|
||||
char name[sizeof(LFNAME) + 10];
|
||||
|
||||
(void)snprintf(name, sizeof(name), LFNAME, fileno);
|
||||
(void)snprintf(name, sizeof(name), LFNAME, filenumber);
|
||||
return (__db_appname(dblp->dbenv,
|
||||
DB_APP_LOG, dblp->dir, name, NULL, namep));
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_rec.c 10.13 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)log_rec.c 10.14 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -99,7 +99,7 @@ __log_register_recover(logp, dbtp, lsnp, redo, info)
|
||||
|
||||
out: F_CLR(logp, DB_AM_RECOVER);
|
||||
if (argp != NULL)
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ __log_unregister_recover(logp, dbtp, lsnp, redo, info)
|
||||
|
||||
out: F_CLR(logp, DB_AM_RECOVER);
|
||||
if (argp != NULL)
|
||||
free(argp);
|
||||
__db_free(argp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -227,14 +227,14 @@ __log_add_logid(logp, dbp, ndx)
|
||||
*/
|
||||
if (logp->dbentry_cnt <= ndx) {
|
||||
if (logp->dbentry_cnt == 0) {
|
||||
logp->dbentry =
|
||||
(DB_ENTRY *)malloc(DB_GROW_SIZE * sizeof(DB_ENTRY));
|
||||
logp->dbentry = (DB_ENTRY *)
|
||||
__db_malloc(DB_GROW_SIZE * sizeof(DB_ENTRY));
|
||||
if (logp->dbentry == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
temp_entryp = (DB_ENTRY *)realloc(logp->dbentry,
|
||||
temp_entryp = (DB_ENTRY *)__db_realloc(logp->dbentry,
|
||||
(DB_GROW_SIZE + logp->dbentry_cnt) *
|
||||
sizeof(DB_ENTRY));
|
||||
if (temp_entryp == NULL) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)log_register.c 10.11 (Sleepycat) 9/15/97";
|
||||
static const char sccsid[] = "@(#)log_register.c 10.12 (Sleepycat) 9/29/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -72,7 +72,7 @@ log_register(dblp, dbp, name, type, idp)
|
||||
if (fid <= fnp->id)
|
||||
fid = fnp->id + 1;
|
||||
if (!memcmp(dbp->lock.fileid,
|
||||
ADDR(dblp, fnp->fileid_off), DB_FILE_ID_LEN)) {
|
||||
R_ADDR(dblp, fnp->fileid_off), DB_FILE_ID_LEN)) {
|
||||
++fnp->ref;
|
||||
fid = fnp->id;
|
||||
if (!F_ISSET(dblp, DB_AM_RECOVER) &&
|
||||
@ -95,13 +95,13 @@ log_register(dblp, dbp, name, type, idp)
|
||||
* XXX Now that uids are fixed size, we can put them in the fnp
|
||||
* structure.
|
||||
*/
|
||||
fnp->fileid_off = OFFSET(dblp, fidp);
|
||||
fnp->fileid_off = R_OFFSET(dblp, fidp);
|
||||
memcpy(fidp, dbp->lock.fileid, DB_FILE_ID_LEN);
|
||||
|
||||
len = strlen(name) + 1;
|
||||
if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0)
|
||||
goto err;
|
||||
fnp->name_off = OFFSET(dblp, namep);
|
||||
fnp->name_off = R_OFFSET(dblp, namep);
|
||||
memcpy(namep, name, len);
|
||||
|
||||
SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
|
||||
@ -185,8 +185,8 @@ log_unregister(dblp, fid)
|
||||
}
|
||||
|
||||
/* Free the unique file information, name and structure. */
|
||||
__db_shalloc_free(dblp->addr, ADDR(dblp, fnp->fileid_off));
|
||||
__db_shalloc_free(dblp->addr, ADDR(dblp, fnp->name_off));
|
||||
__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->fileid_off));
|
||||
__db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
|
||||
SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
|
||||
__db_shalloc_free(dblp->addr, fnp);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_bh.c 10.16 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mp_bh.c 10.21 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -94,10 +94,10 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
|
||||
* files that we have previously tried (and failed) to open.
|
||||
*/
|
||||
dbt.size = mfp->pgcookie_len;
|
||||
dbt.data = ADDR(dbmp, mfp->pgcookie_off);
|
||||
if (__memp_fopen(dbmp, ADDR(dbmp, mfp->path_off),
|
||||
dbt.data = R_ADDR(dbmp, mfp->pgcookie_off);
|
||||
if (__memp_fopen(dbmp, R_ADDR(dbmp, mfp->path_off),
|
||||
mfp->ftype, 0, 0, mfp->stat.st_pagesize,
|
||||
mfp->lsn_off, &dbt, ADDR(dbmp, mfp->fileid_off), 0, &dbmfp) != 0)
|
||||
mfp->lsn_off, &dbt, R_ADDR(dbmp, mfp->fileid_off), 0, &dbmfp) != 0)
|
||||
return (0);
|
||||
|
||||
found: return (__memp_pgwrite(dbmfp, bhp, restartp, wrotep));
|
||||
@ -137,7 +137,7 @@ __memp_pgread(dbmfp, bhp, can_create)
|
||||
ret = 0;
|
||||
LOCKHANDLE(dbmp, dbmfp->mutexp);
|
||||
if (dbmfp->fd == -1 || (ret =
|
||||
__db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) {
|
||||
__db_seek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) {
|
||||
if (!can_create) {
|
||||
if (dbmfp->fd == -1)
|
||||
ret = EINVAL;
|
||||
@ -230,6 +230,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
|
||||
|
||||
dbmp = dbmfp->dbmp;
|
||||
dbenv = dbmp->dbenv;
|
||||
mp = dbmp->mp;
|
||||
mfp = dbmfp->mfp;
|
||||
|
||||
if (restartp != NULL)
|
||||
@ -277,8 +278,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
|
||||
}
|
||||
|
||||
/* Write the page out. */
|
||||
if ((ret =
|
||||
__db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0)
|
||||
if ((ret = __db_seek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0)
|
||||
fail = "seek";
|
||||
else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)
|
||||
fail = "write";
|
||||
@ -309,15 +309,23 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
|
||||
/* Clean up the flags based on a successful write. */
|
||||
F_SET(bhp, BH_CALLPGIN);
|
||||
F_CLR(bhp, BH_DIRTY | BH_LOCKED);
|
||||
|
||||
++mp->stat.st_page_clean;
|
||||
--mp->stat.st_page_dirty;
|
||||
|
||||
UNLOCKBUFFER(dbmp, bhp);
|
||||
|
||||
/*
|
||||
* If we wrote a buffer which a checkpoint is waiting for, update
|
||||
* 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 sync to
|
||||
* be retried later.
|
||||
@ -325,21 +333,15 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
|
||||
* If the buffer we wrote has a LSN larger than the current largest
|
||||
* we've written for this checkpoint, update the saved value.
|
||||
*/
|
||||
mp = dbmp->mp;
|
||||
if (F_ISSET(bhp, BH_WRITE)) {
|
||||
if (log_compare(&lsn, &mp->lsn) > 0)
|
||||
mp->lsn = lsn;
|
||||
F_CLR(bhp, BH_WRITE);
|
||||
|
||||
--mp->lsn_cnt;
|
||||
if (--mfp->lsn_cnt == 0) {
|
||||
/*
|
||||
* Don't lock -- there are no atomicity issues for
|
||||
* fsync(2).
|
||||
*/
|
||||
if (__db_fsync(dbmfp->fd) != 0)
|
||||
F_SET(mp, MP_LSN_RETRY);
|
||||
}
|
||||
|
||||
if (--mfp->lsn_cnt == 0 && __db_fsync(dbmfp->fd) != 0)
|
||||
F_SET(mp, MP_LSN_RETRY);
|
||||
}
|
||||
|
||||
/* Update I/O statistics. */
|
||||
@ -391,7 +393,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
|
||||
dbtp = NULL;
|
||||
else {
|
||||
dbt.size = mfp->pgcookie_len;
|
||||
dbt.data = ADDR(dbmp, mfp->pgcookie_off);
|
||||
dbt.data = R_ADDR(dbmp, mfp->pgcookie_off);
|
||||
dbtp = &dbt;
|
||||
}
|
||||
UNLOCKHANDLE(dbmp, dbmp->mutexp);
|
||||
@ -433,19 +435,21 @@ __memp_bhfree(dbmp, mfp, bhp, free_mem)
|
||||
{
|
||||
size_t off;
|
||||
|
||||
/* Delete the buffer header from the MPOOL hash list. */
|
||||
off = BUCKET(dbmp->mp, OFFSET(dbmp, mfp), bhp->pgno);
|
||||
SH_TAILQ_REMOVE(&dbmp->htab[off], bhp, mq, __bh);
|
||||
/* 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 chain. */
|
||||
/* 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)
|
||||
if (free_mem) {
|
||||
__db_shalloc_free(dbmp->addr, bhp);
|
||||
--dbmp->mp->stat.st_page_clean;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -474,13 +478,13 @@ __memp_upgrade(dbmp, dbmfp, mfp)
|
||||
return (1);
|
||||
|
||||
/* Try the open. */
|
||||
if (__db_fdopen(ADDR(dbmp, mfp->path_off), 0, 0, 0, &fd) != 0) {
|
||||
if (__db_open(R_ADDR(dbmp, mfp->path_off), 0, 0, 0, &fd) != 0) {
|
||||
F_SET(dbmfp, MP_UPGRADE_FAIL);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Swap the descriptors and set the upgrade flag. */
|
||||
(void)close(dbmfp->fd);
|
||||
(void)__db_close(dbmfp->fd);
|
||||
dbmfp->fd = fd;
|
||||
F_SET(dbmfp, MP_UPGRADE);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_fget.c 10.25 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mp_fget.c 10.30 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -87,14 +87,14 @@ memp_fget(dbmfp, pgnoaddr, flags, addrp)
|
||||
* We want to switch threads as often as possible. Sleep every time
|
||||
* we get a new page to make it more likely.
|
||||
*/
|
||||
if (__sleep_on_every_page_get && (dbmp->dbenv == NULL ||
|
||||
dbmp->dbenv->db_yield == NULL || dbmp->dbenv->db_yield() != 0))
|
||||
if (__sleep_on_every_page_get &&
|
||||
(__db_yield == NULL || __db_yield() != 0))
|
||||
__db_sleep(0, 1);
|
||||
#endif
|
||||
|
||||
mp = dbmp->mp;
|
||||
mfp = dbmfp->mfp;
|
||||
mf_offset = OFFSET(dbmp, mfp);
|
||||
mf_offset = R_OFFSET(dbmp, mfp);
|
||||
addr = NULL;
|
||||
bhp = NULL;
|
||||
b_incr = b_inserted = readonly_alloc = ret = 0;
|
||||
@ -137,7 +137,7 @@ memp_fget(dbmfp, pgnoaddr, flags, addrp)
|
||||
}
|
||||
}
|
||||
if (!readonly_alloc) {
|
||||
addr = ADDR(dbmfp, *pgnoaddr * mfp->stat.st_pagesize);
|
||||
addr = R_ADDR(dbmfp, *pgnoaddr * mfp->stat.st_pagesize);
|
||||
|
||||
++mp->stat.st_map;
|
||||
++mfp->stat.st_map;
|
||||
@ -159,9 +159,12 @@ memp_fget(dbmfp, pgnoaddr, flags, addrp)
|
||||
*/
|
||||
if (dbmfp->fd == -1)
|
||||
size = 0;
|
||||
else if ((ret = __db_stat(dbmp->dbenv,
|
||||
dbmfp->path, dbmfp->fd, &size, NULL)) != 0)
|
||||
else if ((ret =
|
||||
__db_ioinfo(dbmfp->path, dbmfp->fd, &size, NULL)) != 0) {
|
||||
__db_err(dbmp->dbenv,
|
||||
"%s: %s", dbmfp->path, strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pgnoaddr = size == 0 ? 0 : (size - 1) / mfp->stat.st_pagesize;
|
||||
|
||||
@ -190,26 +193,29 @@ memp_fget(dbmfp, pgnoaddr, flags, addrp)
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* If we haven't checked the BH list yet, do the search. */
|
||||
/* If we haven't checked the BH hash bucket queue, do the search. */
|
||||
if (!LF_ISSET(DB_MPOOL_LAST | DB_MPOOL_NEW)) {
|
||||
++mp->stat.st_hash_searches;
|
||||
bucket = BUCKET(mp, mf_offset, *pgnoaddr);
|
||||
for (cnt = 0,
|
||||
bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
|
||||
bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, mq, __bh)) {
|
||||
bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) {
|
||||
++cnt;
|
||||
if (bhp->pgno == *pgnoaddr &&
|
||||
bhp->mf_offset == mf_offset) {
|
||||
addr = bhp->buf;
|
||||
++mp->stat.st_hash_searches;
|
||||
if (cnt > mp->stat.st_hash_longest)
|
||||
mp->stat.st_hash_longest = cnt;
|
||||
mp->stat.st_hash_examined += cnt;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
if (cnt > mp->stat.st_hash_longest)
|
||||
mp->stat.st_hash_longest = cnt;
|
||||
mp->stat.st_hash_examined += cnt;
|
||||
if (cnt != 0) {
|
||||
++mp->stat.st_hash_searches;
|
||||
if (cnt > mp->stat.st_hash_longest)
|
||||
mp->stat.st_hash_longest = cnt;
|
||||
mp->stat.st_hash_examined += cnt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -239,8 +245,9 @@ memp_fget(dbmfp, pgnoaddr, flags, addrp)
|
||||
* our region lock without screwing up the world.
|
||||
*/
|
||||
bucket = BUCKET(mp, mf_offset, *pgnoaddr);
|
||||
SH_TAILQ_INSERT_HEAD(&dbmp->htab[bucket], bhp, mq, __bh);
|
||||
SH_TAILQ_INSERT_HEAD(&dbmp->htab[bucket], bhp, hq, __bh);
|
||||
SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
|
||||
++mp->stat.st_page_clean;
|
||||
b_inserted = 1;
|
||||
|
||||
/* Set the page number, and associated MPOOLFILE. */
|
||||
@ -281,7 +288,8 @@ reread: if ((ret = __memp_pgread(dbmfp,
|
||||
* !!!
|
||||
* The __memp_pgread call discarded and reacquired the region
|
||||
* lock. Because the buffer reference count was incremented
|
||||
* before the region lock was discarded the buffer didn't move.
|
||||
* before the region lock was discarded the buffer can't move
|
||||
* and its contents can't change.
|
||||
*/
|
||||
++mp->stat.st_cache_miss;
|
||||
++mfp->stat.st_cache_miss;
|
||||
@ -305,7 +313,8 @@ found: /* Increment the reference count. */
|
||||
* BH_LOCKED --
|
||||
* I/O in progress, wait for it to finish. Because the buffer
|
||||
* reference count was incremented before the region lock was
|
||||
* discarded we know the buffer didn't move.
|
||||
* discarded we know the buffer can't move and its contents
|
||||
* can't change.
|
||||
*/
|
||||
if (F_ISSET(bhp, BH_LOCKED)) {
|
||||
UNLOCKREGION(dbmp);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_fopen.c 10.27 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mp_fopen.c 10.30 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -92,7 +92,7 @@ __memp_fopen(dbmp, path,
|
||||
|
||||
/* Allocate and initialize the per-process structure. */
|
||||
if ((dbmfp =
|
||||
(DB_MPOOLFILE *)calloc(1, sizeof(DB_MPOOLFILE))) == NULL) {
|
||||
(DB_MPOOLFILE *)__db_calloc(1, sizeof(DB_MPOOLFILE))) == NULL) {
|
||||
__db_err(dbenv, "%s: %s",
|
||||
path == NULL ? TEMPORARY : path, strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
@ -120,7 +120,7 @@ __memp_fopen(dbmp, path,
|
||||
|
||||
|
||||
/* Open the file. */
|
||||
if ((ret = __db_fdopen(dbmfp->path,
|
||||
if ((ret = __db_open(dbmfp->path,
|
||||
LF_ISSET(DB_CREATE | DB_RDONLY), DB_CREATE | DB_RDONLY,
|
||||
mode, &dbmfp->fd)) != 0) {
|
||||
__db_err(dbenv, "%s: %s", dbmfp->path, strerror(ret));
|
||||
@ -128,9 +128,11 @@ __memp_fopen(dbmp, path,
|
||||
}
|
||||
|
||||
/* Don't permit files that aren't a multiple of the pagesize. */
|
||||
if ((ret = __db_stat(dbenv,
|
||||
dbmfp->path, dbmfp->fd, &size, NULL)) != 0)
|
||||
if ((ret =
|
||||
__db_ioinfo(dbmfp->path, dbmfp->fd, &size, NULL)) != 0) {
|
||||
__db_err(dbenv, "%s: %s", dbmfp->path, strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
if (size % pagesize) {
|
||||
__db_err(dbenv,
|
||||
"%s: file size not a multiple of the pagesize",
|
||||
@ -198,7 +200,7 @@ __memp_fopen(dbmp, path,
|
||||
dbmfp->addr = NULL;
|
||||
if (mfp->can_mmap) {
|
||||
dbmfp->len = size;
|
||||
if (__db_mmap(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) {
|
||||
if (__db_map(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) {
|
||||
mfp->can_mmap = 0;
|
||||
dbmfp->addr = NULL;
|
||||
}
|
||||
@ -264,7 +266,7 @@ __memp_mf_open(dbmp, dbmfp,
|
||||
for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
|
||||
mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
|
||||
if (!memcmp(fileid,
|
||||
ADDR(dbmp, mfp->fileid_off), DB_FILE_ID_LEN)) {
|
||||
R_ADDR(dbmp, mfp->fileid_off), DB_FILE_ID_LEN)) {
|
||||
if (ftype != mfp->ftype ||
|
||||
pagesize != mfp->stat.st_pagesize) {
|
||||
__db_err(dbmp->dbenv,
|
||||
@ -325,10 +327,10 @@ alloc: if ((ret = __memp_ralloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
|
||||
if (0) {
|
||||
err: if (mfp->path_off != 0)
|
||||
__db_shalloc_free(dbmp->addr,
|
||||
ADDR(dbmp, mfp->path_off));
|
||||
R_ADDR(dbmp, mfp->path_off));
|
||||
if (!istemp)
|
||||
__db_shalloc_free(dbmp->addr,
|
||||
ADDR(dbmp, mfp->fileid_off));
|
||||
R_ADDR(dbmp, mfp->fileid_off));
|
||||
if (mfp != NULL)
|
||||
__db_shalloc_free(dbmp->addr, mfp);
|
||||
mfp = NULL;
|
||||
@ -367,7 +369,7 @@ memp_fclose(dbmfp)
|
||||
|
||||
/* Discard any mmap information. */
|
||||
if (dbmfp->addr != NULL &&
|
||||
(ret = __db_munmap(dbmfp->addr, dbmfp->len)) != 0)
|
||||
(ret = __db_unmap(dbmfp->addr, dbmfp->len)) != 0)
|
||||
__db_err(dbmp->dbenv, "%s: %s", dbmfp->path, strerror(ret));
|
||||
|
||||
/* Close the file; temporary files may not yet have been created. */
|
||||
@ -423,7 +425,7 @@ __memp_mf_close(dbmp, dbmfp)
|
||||
* fairly expensive to reintegrate the buffers back into the region for
|
||||
* no purpose.
|
||||
*/
|
||||
mf_offset = OFFSET(dbmp, mfp);
|
||||
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);
|
||||
|
||||
@ -436,6 +438,10 @@ __memp_mf_close(dbmp, dbmfp)
|
||||
#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);
|
||||
}
|
||||
@ -446,11 +452,11 @@ __memp_mf_close(dbmp, dbmfp)
|
||||
|
||||
/* Free the space. */
|
||||
__db_shalloc_free(dbmp->addr, mfp);
|
||||
__db_shalloc_free(dbmp->addr, ADDR(dbmp, mfp->path_off));
|
||||
__db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->path_off));
|
||||
if (mfp->fileid_off != 0)
|
||||
__db_shalloc_free(dbmp->addr, ADDR(dbmp, mfp->fileid_off));
|
||||
__db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->fileid_off));
|
||||
if (mfp->pgcookie_off != 0)
|
||||
__db_shalloc_free(dbmp->addr, ADDR(dbmp, mfp->pgcookie_off));
|
||||
__db_shalloc_free(dbmp->addr, R_ADDR(dbmp, mfp->pgcookie_off));
|
||||
|
||||
ret1: UNLOCKREGION(dbmp);
|
||||
return (0);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_fput.c 10.12 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mp_fput.c 10.14 (Sleepycat) 10/5/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -35,10 +35,12 @@ memp_fput(dbmfp, pgaddr, flags)
|
||||
{
|
||||
BH *bhp;
|
||||
DB_MPOOL *dbmp;
|
||||
MPOOL *mp;
|
||||
MPOOLFILE *mfp;
|
||||
int wrote, ret;
|
||||
|
||||
dbmp = dbmfp->dbmp;
|
||||
mp = dbmp->mp;
|
||||
|
||||
/* Validate arguments. */
|
||||
if (flags) {
|
||||
@ -82,10 +84,16 @@ memp_fput(dbmfp, pgaddr, flags)
|
||||
LOCKREGION(dbmp);
|
||||
|
||||
/* Set/clear the page bits. */
|
||||
if (LF_ISSET(DB_MPOOL_CLEAN))
|
||||
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))
|
||||
}
|
||||
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);
|
||||
|
||||
@ -108,11 +116,11 @@ memp_fput(dbmfp, pgaddr, flags)
|
||||
}
|
||||
|
||||
/* Move the buffer to the head/tail of the LRU chain. */
|
||||
SH_TAILQ_REMOVE(&dbmp->mp->bhq, bhp, q, __bh);
|
||||
SH_TAILQ_REMOVE(&mp->bhq, bhp, q, __bh);
|
||||
if (F_ISSET(bhp, BH_DISCARD))
|
||||
SH_TAILQ_INSERT_HEAD(&dbmp->mp->bhq, bhp, q, __bh);
|
||||
SH_TAILQ_INSERT_HEAD(&mp->bhq, bhp, q, __bh);
|
||||
else
|
||||
SH_TAILQ_INSERT_TAIL(&dbmp->mp->bhq, bhp, q);
|
||||
SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
|
||||
|
||||
/*
|
||||
* If this buffer is scheduled for writing because of a checkpoint,
|
||||
@ -125,14 +133,14 @@ memp_fput(dbmfp, pgaddr, flags)
|
||||
if (F_ISSET(bhp, BH_DIRTY)) {
|
||||
if (__memp_bhwrite(dbmp,
|
||||
dbmfp->mfp, bhp, NULL, &wrote) != 0 || !wrote)
|
||||
F_SET(dbmp->mp, MP_LSN_RETRY);
|
||||
F_SET(mp, MP_LSN_RETRY);
|
||||
} else {
|
||||
F_CLR(bhp, BH_WRITE);
|
||||
|
||||
mfp = ADDR(dbmp, bhp->mf_offset);
|
||||
mfp = R_ADDR(dbmp, bhp->mf_offset);
|
||||
--mfp->lsn_cnt;
|
||||
|
||||
--dbmp->mp->lsn_cnt;
|
||||
--mp->lsn_cnt;
|
||||
}
|
||||
|
||||
UNLOCKREGION(dbmp);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_fset.c 10.9 (Sleepycat) 9/20/97";
|
||||
static const char sccsid[] = "@(#)mp_fset.c 10.10 (Sleepycat) 10/5/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -34,9 +34,13 @@ memp_fset(dbmfp, pgaddr, flags)
|
||||
{
|
||||
BH *bhp;
|
||||
DB_MPOOL *dbmp;
|
||||
MPOOL *mp;
|
||||
MPOOLFILE *mfp;
|
||||
int ret;
|
||||
|
||||
dbmp = dbmfp->dbmp;
|
||||
mfp = dbmfp->mfp;
|
||||
mp = dbmp->mp;
|
||||
|
||||
/* Validate arguments. */
|
||||
if (flags != 0) {
|
||||
@ -60,10 +64,16 @@ memp_fset(dbmfp, pgaddr, flags)
|
||||
|
||||
LOCKREGION(dbmp);
|
||||
|
||||
if (LF_ISSET(DB_MPOOL_DIRTY))
|
||||
F_SET(bhp, BH_DIRTY);
|
||||
if (LF_ISSET(DB_MPOOL_CLEAN))
|
||||
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);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_open.c 10.13 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mp_open.c 10.15 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -54,7 +54,7 @@ memp_open(path, flags, mode, dbenv, retp)
|
||||
cachesize = dbenv == NULL ? 0 : dbenv->mp_size;
|
||||
|
||||
/* Create and initialize the DB_MPOOL structure. */
|
||||
if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL)
|
||||
if ((dbmp = (DB_MPOOL *)__db_calloc(1, sizeof(DB_MPOOL))) == NULL)
|
||||
return (ENOMEM);
|
||||
LIST_INIT(&dbmp->dbregq);
|
||||
TAILQ_INIT(&dbmp->dbmfq);
|
||||
@ -62,8 +62,7 @@ memp_open(path, flags, mode, dbenv, retp)
|
||||
dbmp->dbenv = dbenv;
|
||||
|
||||
/* Decide if it's possible for anyone else to access the pool. */
|
||||
if ((dbenv == NULL && path == NULL) ||
|
||||
(dbenv != NULL && F_ISSET(dbenv, DB_MPOOL_PRIVATE)))
|
||||
if ((dbenv == NULL && path == NULL) || LF_ISSET(DB_MPOOL_PRIVATE))
|
||||
F_SET(dbmp, MP_ISPRIVATE);
|
||||
|
||||
/*
|
||||
@ -183,7 +182,7 @@ memp_register(dbmp, ftype, pgin, pgout)
|
||||
{
|
||||
DB_MPREG *mpr;
|
||||
|
||||
if ((mpr = (DB_MPREG *)malloc(sizeof(DB_MPREG))) == NULL)
|
||||
if ((mpr = (DB_MPREG *)__db_malloc(sizeof(DB_MPREG))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
mpr->ftype = ftype;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_pr.c 10.13 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)mp_pr.c 10.18 (Sleepycat) 11/1/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -53,7 +53,7 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
|
||||
*gspp = NULL;
|
||||
|
||||
if ((*gspp = db_malloc == NULL ?
|
||||
(DB_MPOOL_STAT *)malloc(sizeof(**gspp)) :
|
||||
(DB_MPOOL_STAT *)__db_malloc(sizeof(**gspp)) :
|
||||
(DB_MPOOL_STAT *)db_malloc(sizeof(**gspp))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
@ -62,6 +62,10 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
|
||||
/* 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;
|
||||
|
||||
UNLOCKREGION(dbmp);
|
||||
}
|
||||
@ -85,7 +89,7 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
|
||||
/* Allocate space for the pointers. */
|
||||
len = (len + 1) * sizeof(DB_MPOOL_FSTAT *);
|
||||
if ((*fspp = db_malloc == NULL ?
|
||||
(DB_MPOOL_FSTAT **)malloc(len) :
|
||||
(DB_MPOOL_FSTAT **)__db_malloc(len) :
|
||||
(DB_MPOOL_FSTAT **)db_malloc(len)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
@ -96,11 +100,11 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
|
||||
mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
|
||||
mfp != NULL;
|
||||
++tfsp, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
|
||||
name = ADDR(dbmp, mfp->path_off);
|
||||
name = R_ADDR(dbmp, mfp->path_off);
|
||||
nlen = strlen(name);
|
||||
len = sizeof(DB_MPOOL_FSTAT) + nlen + 1;
|
||||
if ((*tfsp = db_malloc == NULL ?
|
||||
(DB_MPOOL_FSTAT *)malloc(len) :
|
||||
(DB_MPOOL_FSTAT *)__db_malloc(len) :
|
||||
(DB_MPOOL_FSTAT *)db_malloc(len)) == NULL)
|
||||
return (ENOMEM);
|
||||
**tfsp = mfp->stat;
|
||||
@ -200,18 +204,19 @@ __memp_pmp(fp, dbmp, mp, data)
|
||||
(void)fprintf(fp, "references: %lu; cachesize: %lu\n",
|
||||
(u_long)mp->rlayout.refcnt, (u_long)mp->stat.st_cachesize);
|
||||
(void)fprintf(fp,
|
||||
" %lu pages created\n", mp->stat.st_page_create);
|
||||
" %lu pages created\n", (u_long)mp->stat.st_page_create);
|
||||
(void)fprintf(fp,
|
||||
" %lu mmap pages returned\n", mp->stat.st_map);
|
||||
" %lu mmap pages returned\n", (u_long)mp->stat.st_map);
|
||||
(void)fprintf(fp, " %lu I/O's (%lu read, %lu written)\n",
|
||||
mp->stat.st_page_in + mp->stat.st_page_out,
|
||||
mp->stat.st_page_in, mp->stat.st_page_out);
|
||||
(u_long)mp->stat.st_page_in + mp->stat.st_page_out,
|
||||
(u_long)mp->stat.st_page_in, (u_long)mp->stat.st_page_out);
|
||||
if (mp->stat.st_cache_hit + mp->stat.st_cache_miss != 0)
|
||||
(void)fprintf(fp,
|
||||
" %.0f%% cache hit rate (%lu hit, %lu miss)\n",
|
||||
((double)mp->stat.st_cache_hit /
|
||||
(mp->stat.st_cache_hit + mp->stat.st_cache_miss)) * 100,
|
||||
mp->stat.st_cache_hit, mp->stat.st_cache_miss);
|
||||
(u_long)mp->stat.st_cache_hit,
|
||||
(u_long)mp->stat.st_cache_miss);
|
||||
|
||||
/* Display the MPOOLFILE structures. */
|
||||
for (cnt = 0, mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
|
||||
@ -230,17 +235,18 @@ __memp_pmp(fp, dbmp, mp, data)
|
||||
(void)fprintf(fp, "%s\nHASH table of BH's (%lu buckets):\n",
|
||||
DB_LINE, (u_long)mp->htab_buckets);
|
||||
(void)fprintf(fp,
|
||||
"longest chain searched %lu\n", mp->stat.st_hash_longest);
|
||||
"longest chain searched %lu\n", (u_long)mp->stat.st_hash_longest);
|
||||
(void)fprintf(fp, "average chain searched %lu (total/calls: %lu/%lu)\n",
|
||||
mp->stat.st_hash_examined /
|
||||
(u_long)mp->stat.st_hash_examined /
|
||||
(mp->stat.st_hash_searches ? mp->stat.st_hash_searches : 1),
|
||||
mp->stat.st_hash_examined, mp->stat.st_hash_searches);
|
||||
(u_long)mp->stat.st_hash_examined,
|
||||
(u_long)mp->stat.st_hash_searches);
|
||||
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, mq, __bh))
|
||||
bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
|
||||
__memp_pbh(fp, dbmp, bhp, data);
|
||||
}
|
||||
|
||||
@ -249,7 +255,7 @@ __memp_pmp(fp, dbmp, mp, data)
|
||||
for (sep = "\n ", bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
|
||||
bhp != NULL; sep = ", ", bhp = SH_TAILQ_NEXT(bhp, q, __bh))
|
||||
(void)fprintf(fp, "%s%lu/%lu", sep,
|
||||
(u_long)bhp->pgno, (u_long)OFFSET(dbmp, bhp));
|
||||
(u_long)bhp->pgno, (u_long)R_OFFSET(dbmp, bhp));
|
||||
(void)fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
@ -263,16 +269,18 @@ __memp_pmf(fp, mfp, data)
|
||||
MPOOLFILE *mfp;
|
||||
int data;
|
||||
{
|
||||
(void)fprintf(fp, " %lu pages created\n", mfp->stat.st_page_create);
|
||||
(void)fprintf(fp, " %lu pages created\n",
|
||||
(u_long)mfp->stat.st_page_create);
|
||||
(void)fprintf(fp, " %lu I/O's (%lu read, %lu written)\n",
|
||||
mfp->stat.st_page_in + mfp->stat.st_page_out,
|
||||
mfp->stat.st_page_in, mfp->stat.st_page_out);
|
||||
(u_long)mfp->stat.st_page_in + mfp->stat.st_page_out,
|
||||
(u_long)mfp->stat.st_page_in, (u_long)mfp->stat.st_page_out);
|
||||
if (mfp->stat.st_cache_hit + mfp->stat.st_cache_miss != 0)
|
||||
(void)fprintf(fp,
|
||||
" %.0f%% cache hit rate (%lu hit, %lu miss)\n",
|
||||
((double)mfp->stat.st_cache_hit /
|
||||
(mfp->stat.st_cache_hit + mfp->stat.st_cache_miss)) * 100,
|
||||
mfp->stat.st_cache_hit, mfp->stat.st_cache_miss);
|
||||
(u_long)mfp->stat.st_cache_hit,
|
||||
(u_long)mfp->stat.st_cache_miss);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
@ -298,7 +306,7 @@ __memp_pbh(fp, dbmp, bhp, data)
|
||||
return;
|
||||
|
||||
(void)fprintf(fp, " BH @ %lu (mf: %lu): page %lu; ref %lu",
|
||||
(u_long)OFFSET(dbmp, bhp),
|
||||
(u_long)R_OFFSET(dbmp, bhp),
|
||||
(u_long)bhp->mf_offset, (u_long)bhp->pgno, (u_long)bhp->ref);
|
||||
sep = "; ";
|
||||
if (F_ISSET(bhp, BH_DIRTY)) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_region.c 10.11 (Sleepycat) 8/2/97";
|
||||
static const char sccsid[] = "@(#)mp_region.c 10.16 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -51,7 +51,7 @@ __memp_ralloc(dbmp, len, offsetp, retp)
|
||||
nomore = 0;
|
||||
alloc: if ((ret = __db_shalloc(dbmp->addr, len, MUTEX_ALIGNMENT, &p)) == 0) {
|
||||
if (offsetp != NULL)
|
||||
*offsetp = OFFSET(dbmp, p);
|
||||
*offsetp = R_OFFSET(dbmp, p);
|
||||
*(void **)retp = p;
|
||||
return (0);
|
||||
}
|
||||
@ -68,7 +68,7 @@ alloc: if ((ret = __db_shalloc(dbmp->addr, len, MUTEX_ALIGNMENT, &p)) == 0) {
|
||||
if (__db_shsizeof(bhp) == len) {
|
||||
SH_TAILQ_REMOVE(&mp->bhfq, bhp, q, __bh);
|
||||
if (offsetp != NULL)
|
||||
*offsetp = OFFSET(dbmp, bhp);
|
||||
*offsetp = R_OFFSET(dbmp, bhp);
|
||||
*(void **)retp = bhp;
|
||||
return (0);
|
||||
}
|
||||
@ -82,6 +82,7 @@ alloc: if ((ret = __db_shalloc(dbmp->addr, len, MUTEX_ALIGNMENT, &p)) == 0) {
|
||||
|
||||
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
|
||||
@ -104,7 +105,7 @@ retry: /* Find a buffer we can flush; pure LRU. */
|
||||
continue;
|
||||
|
||||
/* Find the associated MPOOLFILE. */
|
||||
mfp = ADDR(dbmp, bhp->mf_offset);
|
||||
mfp = R_ADDR(dbmp, bhp->mf_offset);
|
||||
|
||||
/*
|
||||
* Write the page if it's dirty.
|
||||
@ -135,8 +136,7 @@ retry: /* Find a buffer we can flush; pure LRU. */
|
||||
else {
|
||||
if (restart)
|
||||
goto retry;
|
||||
else
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
++mp->stat.st_ro_evict;
|
||||
@ -150,7 +150,7 @@ retry: /* Find a buffer we can flush; pure LRU. */
|
||||
__memp_bhfree(dbmp, mfp, bhp, 0);
|
||||
|
||||
if (offsetp != NULL)
|
||||
*offsetp = OFFSET(dbmp, bhp);
|
||||
*offsetp = R_OFFSET(dbmp, bhp);
|
||||
*(void **)retp = bhp;
|
||||
return (0);
|
||||
}
|
||||
@ -225,9 +225,13 @@ retry: if (LF_ISSET(DB_CREATE)) {
|
||||
* be possible for DB_THREAD to be set if HAVE_SPINLOCKS aren't
|
||||
* defined.
|
||||
*/
|
||||
if (F_ISSET(dbmp, MP_ISPRIVATE))
|
||||
ret = (dbmp->maddr = malloc(rlen)) == NULL ? ENOMEM : 0;
|
||||
else
|
||||
if (F_ISSET(dbmp, MP_ISPRIVATE)) {
|
||||
if ((dbmp->maddr = __db_malloc(rlen)) == NULL)
|
||||
ret = ENOMEM;
|
||||
else
|
||||
ret = __db_rinit(dbmp->dbenv,
|
||||
dbmp->maddr, 0, rlen, 0);
|
||||
} else
|
||||
ret = __db_rcreate(dbmp->dbenv, DB_APP_NONE, path,
|
||||
DB_DEFAULT_MPOOL_FILE, mode, rlen, &fd,
|
||||
&dbmp->maddr);
|
||||
@ -259,7 +263,10 @@ retry: if (LF_ISSET(DB_CREATE)) {
|
||||
0, &dbmp->htab)) != 0)
|
||||
goto err;
|
||||
__db_hashinit(dbmp->htab, mp->htab_buckets);
|
||||
mp->htab = OFFSET(dbmp, dbmp->htab);
|
||||
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;
|
||||
@ -303,7 +310,7 @@ retry: if (LF_ISSET(DB_CREATE)) {
|
||||
* Get the hash table address; it's on the shared page, so we have
|
||||
* to lock first.
|
||||
*/
|
||||
dbmp->htab = ADDR(dbmp, dbmp->mp->htab);
|
||||
dbmp->htab = R_ADDR(dbmp, dbmp->mp->htab);
|
||||
|
||||
dbmp->fd = fd;
|
||||
|
||||
@ -333,7 +340,7 @@ __memp_rclose(dbmp)
|
||||
DB_MPOOL *dbmp;
|
||||
{
|
||||
if (F_ISSET(dbmp, MP_ISPRIVATE)) {
|
||||
free(dbmp->maddr);
|
||||
__db_free(dbmp->maddr);
|
||||
return (0);
|
||||
}
|
||||
return (__db_rclose(dbmp->dbenv, dbmp->fd, dbmp->maddr));
|
||||
|
395
db2/mp/mp_sync.c
395
db2/mp/mp_sync.c
@ -7,13 +7,14 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mp_sync.c 10.9 (Sleepycat) 8/29/97";
|
||||
static const char sccsid[] = "@(#)mp_sync.c 10.15 (Sleepycat) 11/1/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
@ -23,6 +24,8 @@ static const char sccsid[] = "@(#)mp_sync.c 10.9 (Sleepycat) 8/29/97";
|
||||
#include "mp.h"
|
||||
#include "common_ext.h"
|
||||
|
||||
static int __bhcmp __P((const void *, const void *));
|
||||
|
||||
/*
|
||||
* memp_sync --
|
||||
* Mpool sync function.
|
||||
@ -32,27 +35,40 @@ memp_sync(dbmp, lsnp)
|
||||
DB_MPOOL *dbmp;
|
||||
DB_LSN *lsnp;
|
||||
{
|
||||
BH *bhp;
|
||||
BH *bhp, **bharray;
|
||||
DB_ENV *dbenv;
|
||||
MPOOL *mp;
|
||||
MPOOLFILE *mfp;
|
||||
int can_write, wrote, lsn_cnt, restart, ret;
|
||||
int ar_cnt, cnt, nalloc, next, notused, ret, wrote;
|
||||
|
||||
dbenv = dbmp->dbenv;
|
||||
|
||||
if (dbmp->dbenv->lg_info == NULL) {
|
||||
__db_err(dbenv, "memp_sync requires logging");
|
||||
if (dbenv->lg_info == NULL) {
|
||||
__db_err(dbenv, "memp_sync: requires logging");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* We try and write the buffers in page order so that the underlying
|
||||
* filesystem doesn't have to seek and can write contiguous blocks,
|
||||
* plus, we don't want to hold the region lock while we write the
|
||||
* buffers. Get memory to hold the buffer pointers. Get a good-size
|
||||
* block, too, because we realloc while holding the region lock if we
|
||||
* run out.
|
||||
*/
|
||||
if ((bharray =
|
||||
(BH **)__db_malloc((nalloc = 1024) * sizeof(BH *))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
LOCKREGION(dbmp);
|
||||
|
||||
/*
|
||||
* If the application is asking about a previous call, 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, then we return based on the count for that LSN.
|
||||
* 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.
|
||||
*/
|
||||
mp = dbmp->mp;
|
||||
if (!F_ISSET(mp, MP_LSN_RETRY) && log_compare(lsnp, &mp->lsn) <= 0) {
|
||||
@ -61,9 +77,7 @@ memp_sync(dbmp, lsnp)
|
||||
ret = 0;
|
||||
} else
|
||||
ret = DB_INCOMPLETE;
|
||||
|
||||
UNLOCKREGION(dbmp);
|
||||
return (ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Else, it's a new checkpoint. */
|
||||
@ -74,7 +88,7 @@ memp_sync(dbmp, lsnp)
|
||||
* 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.
|
||||
* 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
|
||||
@ -93,64 +107,127 @@ memp_sync(dbmp, lsnp)
|
||||
|
||||
/*
|
||||
* Walk the list of buffers and mark all dirty buffers to be written
|
||||
* and all pinned buffers to be potentially written. We do this in
|
||||
* single fell swoop 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.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
can_write = lsn_cnt = 0;
|
||||
for (lsn_cnt = 0, bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
|
||||
ar_cnt = 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->ref != 0) {
|
||||
F_SET(bhp, BH_WRITE);
|
||||
|
||||
if (bhp->ref == 0)
|
||||
can_write = 1;
|
||||
++mp->lsn_cnt;
|
||||
|
||||
mfp = ADDR(dbmp, bhp->mf_offset);
|
||||
mfp = R_ADDR(dbmp, bhp->mf_offset);
|
||||
++mfp->lsn_cnt;
|
||||
|
||||
++lsn_cnt;
|
||||
/*
|
||||
* If the buffer isn't in use, we should be able to
|
||||
* write it immediately, so save a reference to it.
|
||||
*/
|
||||
if (bhp->ref == 0) {
|
||||
if (ar_cnt == nalloc) {
|
||||
nalloc *= 2;
|
||||
if ((bharray =
|
||||
(BH **)__db_realloc(bharray,
|
||||
nalloc * sizeof(BH *))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
bharray[ar_cnt++] = bhp;
|
||||
}
|
||||
} else
|
||||
F_CLR(bhp, BH_WRITE);
|
||||
|
||||
mp->lsn_cnt = lsn_cnt;
|
||||
|
||||
/* If there no buffers we can write, we're done. */
|
||||
if (!can_write) {
|
||||
UNLOCKREGION(dbmp);
|
||||
return (mp->lsn_cnt ? DB_INCOMPLETE : 0);
|
||||
/* If there no buffers we can write immediately, we're done. */
|
||||
if (ar_cnt == 0) {
|
||||
ret = mp->lsn_cnt ? DB_INCOMPLETE : 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write any buffers that we can. Restart the walk after each write,
|
||||
* __memp_pgwrite() discards and reacquires the region lock during I/O.
|
||||
*/
|
||||
retry: for (bhp = SH_TAILQ_FIRST(&mp->bhq, __bh);
|
||||
bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {
|
||||
/* Ignore pinned or locked buffers. */
|
||||
if (!F_ISSET(bhp, BH_WRITE) ||
|
||||
bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED))
|
||||
continue;
|
||||
/* Lock down the buffers and their contents. */
|
||||
for (cnt = 0; cnt < ar_cnt; ++cnt)
|
||||
++bharray[cnt]->ref;
|
||||
|
||||
mfp = ADDR(dbmp, bhp->mf_offset);
|
||||
if ((ret =
|
||||
__memp_bhwrite(dbmp, mfp, bhp, &restart, &wrote)) != 0)
|
||||
goto err;
|
||||
if (wrote) {
|
||||
if (restart)
|
||||
goto retry;
|
||||
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;
|
||||
}
|
||||
__db_err(dbenv, "%s: unable to flush page: %lu",
|
||||
ADDR(dbmp, mfp->path_off), (u_long)bhp->pgno);
|
||||
ret = EPERM;
|
||||
goto err;
|
||||
|
||||
/* Write the buffer. */
|
||||
mfp = R_ADDR(dbmp, bharray[next]->mf_offset);
|
||||
ret =
|
||||
__memp_bhwrite(dbmp, mfp, bharray[next], ¬used, &wrote);
|
||||
|
||||
/* Release the buffer. */
|
||||
--bharray[next]->ref;
|
||||
|
||||
/* If there's an error, release the rest of the buffers. */
|
||||
if (ret != 0 || !wrote) {
|
||||
while (++next < ar_cnt)
|
||||
--bharray[next]->ref;
|
||||
|
||||
if (ret != 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(dbenv, "%s: unable to flush page: %lu",
|
||||
R_ADDR(dbmp, mfp->path_off),
|
||||
(u_long)bharray[next]->pgno);
|
||||
ret = EPERM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = mp->lsn_cnt ? DB_INCOMPLETE : 0;
|
||||
|
||||
err: UNLOCKREGION(dbmp);
|
||||
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);
|
||||
__db_free(bharray);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -162,10 +239,10 @@ int
|
||||
memp_fsync(dbmfp)
|
||||
DB_MPOOLFILE *dbmfp;
|
||||
{
|
||||
BH *bhp;
|
||||
BH *bhp, **bharray;
|
||||
DB_MPOOL *dbmp;
|
||||
size_t mf_offset;
|
||||
int pincnt, restart, ret, wrote;
|
||||
int ar_cnt, cnt, nalloc, next, pincnt, notused, ret, wrote;
|
||||
|
||||
/*
|
||||
* If this handle doesn't have a file descriptor that's open for
|
||||
@ -175,35 +252,205 @@ memp_fsync(dbmfp)
|
||||
if (F_ISSET(dbmfp, MP_READONLY | MP_PATH_TEMP))
|
||||
return (0);
|
||||
|
||||
dbmp = dbmfp->dbmp;
|
||||
ret = 0;
|
||||
dbmp = dbmfp->dbmp;
|
||||
mf_offset = R_OFFSET(dbmp, dbmfp->mfp);
|
||||
|
||||
mf_offset = OFFSET(dbmp, dbmfp->mfp);
|
||||
/*
|
||||
* We try and write the buffers in page order so that the underlying
|
||||
* filesystem doesn't have to seek and can write contiguous blocks,
|
||||
* plus, we don't want to hold the region lock while we write the
|
||||
* buffers. Get memory to hold the buffer pointers. Get a good-size
|
||||
* block, too, because we realloc while holding the region lock if we
|
||||
* run out.
|
||||
*/
|
||||
nalloc = 1024;
|
||||
if ((bharray =
|
||||
(BH **)__db_malloc((size_t)nalloc * sizeof(BH *))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
LOCKREGION(dbmp);
|
||||
|
||||
/*
|
||||
* Walk the list of buffer headers for the MPOOLFILE, and write out any
|
||||
* dirty buffers that we can.
|
||||
* Walk the LRU list of buffer headers, and get a list of buffers to
|
||||
* write for this MPOOLFILE.
|
||||
*/
|
||||
retry: pincnt = 0;
|
||||
ar_cnt = pincnt = 0;
|
||||
for (bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
|
||||
bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh))
|
||||
if (F_ISSET(bhp, BH_DIRTY) && bhp->mf_offset == mf_offset) {
|
||||
if (bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED)) {
|
||||
++pincnt;
|
||||
continue;
|
||||
}
|
||||
if ((ret =
|
||||
__memp_pgwrite(dbmfp, bhp, &restart, &wrote)) != 0)
|
||||
goto err;
|
||||
if (!wrote)
|
||||
++pincnt;
|
||||
if (restart)
|
||||
goto retry;
|
||||
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)) {
|
||||
++pincnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ar_cnt == nalloc) {
|
||||
nalloc *= 2;
|
||||
if ((bharray = (BH **)__db_realloc(bharray,
|
||||
nalloc * sizeof(BH *))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
bharray[ar_cnt++] = bhp;
|
||||
}
|
||||
|
||||
/* Lock down the buffers and their contents. */
|
||||
for (cnt = 0; cnt < ar_cnt; ++cnt)
|
||||
++bharray[cnt]->ref;
|
||||
|
||||
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) {
|
||||
++pincnt;
|
||||
|
||||
--bharray[next]->ref;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Write the buffer. */
|
||||
ret = __memp_pgwrite(dbmfp, bharray[next], ¬used, &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 (!wrote)
|
||||
++pincnt;
|
||||
}
|
||||
|
||||
err: UNLOCKREGION(dbmp);
|
||||
|
||||
return (ret == 0 ? (pincnt ? DB_INCOMPLETE : 0) : ret);
|
||||
__db_free(bharray);
|
||||
|
||||
/*
|
||||
* 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 (pincnt == 0 ? __db_fsync(dbmfp->fd) : DB_INCOMPLETE);
|
||||
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 notused, ret, wrote;
|
||||
|
||||
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);
|
||||
if ((ret =
|
||||
__memp_bhwrite(dbmp, mfp, bhp, ¬used, &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",
|
||||
R_ADDR(dbmp, mfp->path_off), (u_long)bhp->pgno);
|
||||
ret = EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
++mp->stat.st_page_trickle;
|
||||
if (nwrotep != NULL)
|
||||
++*nwrotep;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/* No more buffers to write. */
|
||||
return (0);
|
||||
|
||||
err: UNLOCKREGION(dbmp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
__bhcmp(p1, p2)
|
||||
const void *p1, *p2;
|
||||
{
|
||||
BH *bhp1, *bhp2;
|
||||
|
||||
bhp1 = *(BH **)p1;
|
||||
bhp2 = *(BH **)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);
|
||||
|
||||
/* Sort by page in file. */
|
||||
return (bhp1->pgno < bhp2->pgno ? -1 : 1);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)mutex.c 10.25 (Sleepycat) 9/23/97";
|
||||
static const char sccsid[] = "@(#)mutex.c 10.28 (Sleepycat) 10/31/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -67,6 +67,10 @@ static const char sccsid[] = "@(#)mutex.c 10.25 (Sleepycat) 9/23/97";
|
||||
#define TSL_UNSET(x) _lock_clear(x)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ASSEM_SCO_CC
|
||||
#include "sco.cc"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ASSEM_SPARC_GCC
|
||||
#include "sparc.gcc"
|
||||
#endif
|
||||
@ -138,13 +142,12 @@ __db_mutex_init(mp, off)
|
||||
* __db_mutex_lock
|
||||
* Lock on a mutex, logically blocking if necessary.
|
||||
*
|
||||
* PUBLIC: int __db_mutex_lock __P((db_mutex_t *, int, int (*)(void)));
|
||||
* PUBLIC: int __db_mutex_lock __P((db_mutex_t *, int));
|
||||
*/
|
||||
int
|
||||
__db_mutex_lock(mp, fd, yield)
|
||||
__db_mutex_lock(mp, fd)
|
||||
db_mutex_t *mp;
|
||||
int fd;
|
||||
int (*yield) __P((void));
|
||||
{
|
||||
u_long usecs;
|
||||
|
||||
@ -166,17 +169,15 @@ __db_mutex_lock(mp, fd, yield)
|
||||
}
|
||||
mp->pid = getpid();
|
||||
#endif
|
||||
#ifdef MUTEX_STATISTICS
|
||||
if (usecs == MS(10))
|
||||
++mp->mutex_set_nowait;
|
||||
else
|
||||
++mp->mutex_set_wait;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Yield the processor; wait 10ms initially, up to 1 second. */
|
||||
if (yield == NULL || yield() != 0) {
|
||||
if (__db_yield == NULL || __db_yield() != 0) {
|
||||
(void)__db_sleep(0, usecs);
|
||||
if ((usecs <<= 1) > SECOND)
|
||||
usecs = SECOND;
|
||||
@ -200,7 +201,7 @@ __db_mutex_lock(mp, fd, yield)
|
||||
* up to 1 second.
|
||||
*/
|
||||
for (usecs = MS(10); mp->pid != 0;)
|
||||
if (yield == NULL || yield() != 0) {
|
||||
if (__db_yield == NULL || __db_yield() != 0) {
|
||||
(void)__db_sleep(0, usecs);
|
||||
if ((usecs <<= 1) > SECOND)
|
||||
usecs = SECOND;
|
||||
@ -234,10 +235,6 @@ __db_mutex_lock(mp, fd, yield)
|
||||
if (locked)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef MUTEX_STATISTICS
|
||||
++mp->mutex_set_wait;
|
||||
#endif
|
||||
return (0);
|
||||
#endif /* !HAVE_SPINLOCKS */
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_abs.c 10.5 (Sleepycat) 7/5/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*
|
||||
* __db_abspath --
|
||||
* Return if a path is an absolute path.
|
||||
*
|
||||
* PUBLIC: int __db_abspath __P((const char *));
|
||||
*/
|
||||
int
|
||||
__db_abspath(path)
|
||||
const char *path;
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* !!!
|
||||
* Check for drive specifications, e.g., "C:". In addition, the path
|
||||
* separator used by the win32 DB (PATH_SEPARATOR) is \; look for both
|
||||
* / and \ since these are user-input paths.
|
||||
*/
|
||||
if (isalpha(path[0]) && path[1] == ':')
|
||||
path += 2;
|
||||
return (path[0] == '/' || path[0] == '\\');
|
||||
#else
|
||||
#ifdef macintosh
|
||||
/*
|
||||
* !!!
|
||||
* Absolute pathnames always start with a volume name, which must be
|
||||
* followed by a colon, thus they are of the form:
|
||||
* volume: or volume:dir1:dir2:file
|
||||
*
|
||||
* Relative pathnames are either a single name without colons or a
|
||||
* path starting with a colon, thus of the form:
|
||||
* file or :file or :dir1:dir2:file
|
||||
*/
|
||||
return (strchr(path, ':') != NULL && path[0] != ':');
|
||||
#else
|
||||
return (path[0] == '/');
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* __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);
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_dir.c 10.10 (Sleepycat) 9/17/97";
|
||||
#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>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "os_ext.h"
|
||||
#include "common_ext.h"
|
||||
|
||||
/*
|
||||
* __db_dir --
|
||||
* Return a list of the files in a directory.
|
||||
*
|
||||
* PUBLIC: int __db_dir __P((DB_ENV *, const char *, char ***, int *));
|
||||
*/
|
||||
int
|
||||
__db_dir(dbenv, dir, namesp, cntp)
|
||||
DB_ENV *dbenv;
|
||||
const char *dir;
|
||||
char ***namesp;
|
||||
int *cntp;
|
||||
{
|
||||
int arraysz, cnt;
|
||||
char **names;
|
||||
#ifdef _WIN32
|
||||
struct _finddata_t fdata;
|
||||
long dirhandle;
|
||||
int finished;
|
||||
char filespec[MAX_PATH];
|
||||
|
||||
(void)snprintf(filespec, sizeof(filespec), "%s/*", dir);
|
||||
if ((dirhandle = _findfirst(filespec, &fdata)) == -1) {
|
||||
__db_err(dbenv, "%s: %s", filespec, strerror(errno));
|
||||
return (errno);
|
||||
}
|
||||
|
||||
names = NULL;
|
||||
finished = 0;
|
||||
for (arraysz = cnt = 0; finished != 1; ++cnt) {
|
||||
if (cnt >= arraysz) {
|
||||
arraysz += 100;
|
||||
names = (char **)(names == NULL ?
|
||||
malloc(arraysz * sizeof(names[0])) :
|
||||
realloc(names, arraysz * sizeof(names[0])));
|
||||
if (names == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
if ((names[cnt] = (char *)strdup(fdata.name)) == NULL)
|
||||
goto nomem;
|
||||
if (_findnext(dirhandle,&fdata) != 0)
|
||||
finished = 1;
|
||||
}
|
||||
_findclose(dirhandle);
|
||||
#else /* !_WIN32 */
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
|
||||
if ((dirp = opendir(dir)) == NULL) {
|
||||
__db_err(dbenv, "%s: %s", dir, strerror(errno));
|
||||
return (errno);
|
||||
}
|
||||
names = NULL;
|
||||
for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL; ++cnt) {
|
||||
if (cnt >= arraysz) {
|
||||
arraysz += 100;
|
||||
names = (char **)(names == NULL ?
|
||||
malloc(arraysz * sizeof(names[0])) :
|
||||
realloc(names, arraysz * sizeof(names[0])));
|
||||
if (names == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
if ((names[cnt] = (char *)strdup(dp->d_name)) == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
(void)closedir(dirp);
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
*namesp = names;
|
||||
*cntp = cnt;
|
||||
return (0);
|
||||
|
||||
nomem: if (names != NULL)
|
||||
__db_dirf(dbenv, names, cnt);
|
||||
__db_err(dbenv, "%s", strerror(ENOMEM));
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_dirf --
|
||||
* Free the list of files.
|
||||
*
|
||||
* PUBLIC: void __db_dirf __P((DB_ENV *, char **, int));
|
||||
*/
|
||||
void
|
||||
__db_dirf(dbenv, names, cnt)
|
||||
DB_ENV *dbenv;
|
||||
char **names;
|
||||
int cnt;
|
||||
{
|
||||
dbenv = dbenv; /* XXX: Shut the compiler up. */
|
||||
while (cnt > 0)
|
||||
free(names[--cnt]);
|
||||
free (names);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_lseek.c 10.3 (Sleepycat) 6/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*
|
||||
* __db_lseek --
|
||||
* Seek to a page/byte offset in the file.
|
||||
*
|
||||
* PUBLIC: int __db_lseek __P((int, size_t, db_pgno_t, u_long, int));
|
||||
*/
|
||||
int
|
||||
__db_lseek(fd, pgsize, pageno, relative, whence)
|
||||
int fd;
|
||||
size_t pgsize;
|
||||
db_pgno_t pageno;
|
||||
u_long relative;
|
||||
int whence;
|
||||
{
|
||||
/* 64-bit offsets are done differently by different vendors. */
|
||||
#undef __LSEEK_SET
|
||||
#ifdef HAVE_LLSEEK
|
||||
#define __LSEEK_SET
|
||||
offset_t offset; /* Solaris. */
|
||||
|
||||
offset = pgsize * pageno + relative;
|
||||
return (llseek(fd, offset, whence) == -1 ? errno : 0);
|
||||
#endif
|
||||
#ifdef HAVE_LSEEKI
|
||||
#define __LSEEK_SET
|
||||
__int64 offset; /* WNT */
|
||||
|
||||
offset = pgsize * pageno + relative;
|
||||
return (_lseeki64(fd, offset, whence) == -1 ? errno : 0);
|
||||
#endif
|
||||
#ifndef __LSEEK_SET
|
||||
off_t offset; /* Default. */
|
||||
|
||||
offset = pgsize * pageno + relative;
|
||||
return (lseek(fd, offset, whence) == -1 ? errno : 0);
|
||||
#endif
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_mmap.c 10.4 (Sleepycat) 6/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*
|
||||
* __db_mmap --
|
||||
* Map in some shared memory backed by a file descriptor.
|
||||
*
|
||||
* PUBLIC: int __db_mmap __P((int, size_t, int, int, void *));
|
||||
*/
|
||||
int
|
||||
__db_mmap(fd, len, is_private, rdonly, addr)
|
||||
int fd, is_private, rdonly;
|
||||
size_t len;
|
||||
void *addr;
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* We have not implemented copy-on-write here */
|
||||
void * pMemory = 0;
|
||||
HANDLE hFile = (HANDLE)_get_osfhandle(fd);
|
||||
HANDLE hMemory = CreateFileMapping(
|
||||
hFile,
|
||||
0,
|
||||
(rdonly ? PAGE_READONLY : PAGE_READWRITE),
|
||||
0,
|
||||
len, /* This code fails if the library is ever compiled on a 64-bit machine */
|
||||
0
|
||||
);
|
||||
if (NULL == hMemory)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
pMemory = MapViewOfFile(
|
||||
hMemory,
|
||||
(rdonly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS),
|
||||
0,
|
||||
0,
|
||||
len
|
||||
);
|
||||
CloseHandle(hMemory);
|
||||
*(void **)addr = pMemory;
|
||||
return 0;
|
||||
|
||||
#else /* !_WIN32 */
|
||||
|
||||
void *p;
|
||||
int flags, prot;
|
||||
|
||||
flags = is_private ? MAP_PRIVATE : MAP_SHARED;
|
||||
#ifdef MAP_HASSEMAPHORE
|
||||
flags += MAP_HASSEMAPHORE;
|
||||
#endif
|
||||
prot = PROT_READ | (rdonly ? 0 : PROT_WRITE);
|
||||
|
||||
#ifndef MAP_FAILED /* XXX: Mmap(2) failure return. */
|
||||
#define MAP_FAILED -1
|
||||
#endif
|
||||
if ((p =
|
||||
mmap(NULL, len, prot, flags, fd, (off_t)0)) == (void *)MAP_FAILED)
|
||||
return (errno);
|
||||
|
||||
*(void **)addr = p;
|
||||
return (0);
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_unmap --
|
||||
* Release the specified shared memory.
|
||||
*
|
||||
* PUBLIC: int __db_munmap __P((void *, size_t));
|
||||
*/
|
||||
int
|
||||
__db_munmap(addr, len)
|
||||
void *addr;
|
||||
size_t len;
|
||||
{
|
||||
/*
|
||||
* !!!
|
||||
* The argument len is always the same length as was mapped.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
return (!UnmapViewOfFile(addr) ? errno : 0);
|
||||
#else
|
||||
return (munmap(addr, len) ? errno : 0);
|
||||
#endif
|
||||
}
|
31
db2/os/os_abs.c
Normal file
31
db2/os/os_abs.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_abs.c 10.7 (Sleepycat) 10/24/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
||||
/*
|
||||
* __db_abspath --
|
||||
* Return if a path is an absolute path.
|
||||
*
|
||||
* PUBLIC: int __db_abspath __P((const char *));
|
||||
*/
|
||||
int
|
||||
__db_abspath(path)
|
||||
const char *path;
|
||||
{
|
||||
return (path[0] == '/');
|
||||
}
|
100
db2/os/os_dir.c
Normal file
100
db2/os/os_dir.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_dir.c 10.13 (Sleepycat) 10/28/97";
|
||||
#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>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "common_ext.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;
|
||||
char **names;
|
||||
|
||||
if ((dirp = opendir(dir)) == NULL)
|
||||
return (errno);
|
||||
names = NULL;
|
||||
for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL; ++cnt) {
|
||||
if (cnt >= arraysz) {
|
||||
arraysz += 100;
|
||||
names = (char **)(names == NULL ?
|
||||
__db_malloc(arraysz * sizeof(names[0])) :
|
||||
__db_realloc(names, arraysz * sizeof(names[0])));
|
||||
if (names == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
if ((names[cnt] = (char *)__db_strdup(dp->d_name)) == NULL)
|
||||
goto nomem;
|
||||
}
|
||||
(void)closedir(dirp);
|
||||
|
||||
*namesp = names;
|
||||
*cntp = cnt;
|
||||
return (0);
|
||||
|
||||
nomem: if (names != NULL)
|
||||
__os_dirfree(names, cnt);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* __os_dirfree --
|
||||
* Free the list of files.
|
||||
*
|
||||
* PUBLIC: void __os_dirfree __P((char **, int));
|
||||
*/
|
||||
void
|
||||
__os_dirfree(names, cnt)
|
||||
char **names;
|
||||
int cnt;
|
||||
{
|
||||
while (cnt > 0)
|
||||
__db_free(names[--cnt]);
|
||||
__db_free(names);
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_fid.c 10.8 (Sleepycat) 8/27/97";
|
||||
static const char sccsid[] = "@(#)os_fid.c 10.9 (Sleepycat) 10/24/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -22,8 +22,6 @@ static const char sccsid[] = "@(#)db_os_fid.c 10.8 (Sleepycat) 8/27/97";
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "db_page.h"
|
||||
#include "os_ext.h"
|
||||
#include "common_ext.h"
|
||||
|
||||
/*
|
||||
@ -39,58 +37,11 @@ __db_fileid(dbenv, fname, timestamp, fidp)
|
||||
int timestamp;
|
||||
u_int8_t *fidp;
|
||||
{
|
||||
struct stat sb;
|
||||
size_t i;
|
||||
time_t now;
|
||||
u_int8_t *p;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* The documentation for GetFileInformationByHandle() states that the
|
||||
* inode-type numbers are not constant between processes. Actually,
|
||||
* they are, they're the NTFS MFT indexes. So, this works on NTFS,
|
||||
* but perhaps not on other platforms, and perhaps not over a network.
|
||||
* Can't think of a better solution right now.
|
||||
*/
|
||||
int fd = 0;
|
||||
HANDLE fh = 0;
|
||||
BY_HANDLE_FILE_INFORMATION fi;
|
||||
BOOL retval = FALSE;
|
||||
|
||||
/* Clear the buffer. */
|
||||
memset(fidp, 0, DB_FILE_ID_LEN);
|
||||
|
||||
/* first we open the file, because we're not given a handle to it */
|
||||
fd = open(fname,_O_RDONLY,_S_IREAD);
|
||||
if (-1 == fd) {
|
||||
/* If we can't open it, we're in trouble */
|
||||
return (errno);
|
||||
}
|
||||
|
||||
/* File open, get its info */
|
||||
fh = (HANDLE)_get_osfhandle(fd);
|
||||
if ((HANDLE)(-1) != fh) {
|
||||
retval = GetFileInformationByHandle(fh,&fi);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* We want the three 32-bit words which tell us the volume ID and
|
||||
* the file ID. We make a crude attempt to copy the bytes over to
|
||||
* the callers buffer.
|
||||
*
|
||||
* DBDB: really we should ensure that the bytes get packed the same
|
||||
* way on all compilers, platforms etc.
|
||||
*/
|
||||
if ( ((HANDLE)(-1) != fh) && (TRUE == retval) ) {
|
||||
memcpy(fidp, &fi.nFileIndexLow, sizeof(u_int32_t));
|
||||
fidp += sizeof(u_int32_t);
|
||||
memcpy(fidp, &fi.nFileIndexHigh, sizeof(u_int32_t));
|
||||
fidp += sizeof(u_int32_t);
|
||||
memcpy(fidp, &fi.dwVolumeSerialNumber, sizeof(u_int32_t));
|
||||
}
|
||||
#else
|
||||
struct stat sb;
|
||||
|
||||
/* Clear the buffer. */
|
||||
memset(fidp, 0, DB_FILE_ID_LEN);
|
||||
|
||||
@ -115,7 +66,7 @@ __db_fileid(dbenv, fname, timestamp, fidp)
|
||||
for (p = (u_int8_t *)&sb.st_dev +
|
||||
sizeof(sb.st_dev), i = 0; i < sizeof(sb.st_dev); ++i)
|
||||
*fidp++ = *--p;
|
||||
#endif
|
||||
|
||||
if (timestamp) {
|
||||
(void)time(&now);
|
||||
for (p = (u_int8_t *)&now +
|
34
db2/os/os_fsync.c
Normal file
34
db2/os/os_fsync.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_fsync.c 10.3 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
||||
/*
|
||||
* __db_fsync --
|
||||
* Flush a file descriptor.
|
||||
*
|
||||
* PUBLIC: int __db_fsync __P((int));
|
||||
*/
|
||||
int
|
||||
__db_fsync(fd)
|
||||
int fd;
|
||||
{
|
||||
return (__os_fsync(fd) ? errno : 0);
|
||||
}
|
153
db2/os/os_func.c
Normal file
153
db2/os/os_func.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_func.c 10.4 (Sleepycat) 10/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* We provide our own extern declarations so that we don't collide with
|
||||
* systems that get them wrong, e.g., SunOS.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define fsync _commit
|
||||
#define imported __declspec(dllimport)
|
||||
#else
|
||||
#define imported
|
||||
#endif
|
||||
|
||||
imported extern void *calloc __P((size_t, size_t));
|
||||
imported extern int close __P((int));
|
||||
imported extern void free __P((void *));
|
||||
imported extern int fsync __P((int));
|
||||
imported extern void *malloc __P((size_t));
|
||||
imported extern int open __P((const char *, int, ...));
|
||||
imported extern ssize_t read __P((int, void *, size_t));
|
||||
imported extern char *strdup __P((const char *));
|
||||
imported extern void *realloc __P((void *, size_t));
|
||||
imported extern int unlink __P((const char *));
|
||||
imported extern ssize_t write __P((int, const void *, size_t));
|
||||
|
||||
/*
|
||||
* __db_jump --
|
||||
* This list of interfaces that applications can replace. In some
|
||||
* cases, the user is permitted to replace the standard ANSI C or
|
||||
* POSIX 1003.1 call, e.g., calloc or read. In others, we provide
|
||||
* a local interface to the functionality, e.g., __os_map.
|
||||
*/
|
||||
struct __db_jumptab __db_jump = {
|
||||
calloc, /* DB_FUNC_CALLOC */
|
||||
close, /* DB_FUNC_CLOSE */
|
||||
__os_dirfree, /* DB_FUNC_DIRFREE */
|
||||
__os_dirlist, /* DB_FUNC_DIRLIST */
|
||||
__os_exists, /* DB_FUNC_EXISTS */
|
||||
free, /* DB_FUNC_FREE */
|
||||
fsync, /* DB_FUNC_FSYNC */
|
||||
__os_ioinfo, /* DB_FUNC_IOINFO */
|
||||
malloc, /* DB_FUNC_MALLOC */
|
||||
__os_map, /* DB_FUNC_MAP */
|
||||
open, /* DB_FUNC_OPEN */
|
||||
read, /* DB_FUNC_READ */
|
||||
realloc, /* DB_FUNC_REALLOC */
|
||||
__os_seek, /* DB_FUNC_SEEK */
|
||||
__os_sleep, /* DB_FUNC_SLEEP */
|
||||
strdup, /* DB_FUNC_STRDUP */
|
||||
unlink, /* DB_FUNC_UNLINK */
|
||||
__os_unmap, /* DB_FUNC_UNMAP */
|
||||
write, /* DB_FUNC_WRITE */
|
||||
NULL /* DB_FUNC_YIELD */
|
||||
};
|
||||
|
||||
/*
|
||||
* db_jump_set --
|
||||
* Replace an interface.
|
||||
*/
|
||||
int
|
||||
db_jump_set(func, which)
|
||||
void *func;
|
||||
int which;
|
||||
{
|
||||
switch (which) {
|
||||
case DB_FUNC_CALLOC:
|
||||
__db_calloc = (void *(*) __P((size_t, size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_CLOSE:
|
||||
__os_close = (int (*) __P((int)))func;
|
||||
break;
|
||||
case DB_FUNC_DIRFREE:
|
||||
__db_dirfree = (void (*) __P((char **, int)))func;
|
||||
break;
|
||||
case DB_FUNC_DIRLIST:
|
||||
__db_dirlist =
|
||||
(int (*) __P((const char *, char ***, int *)))func;
|
||||
break;
|
||||
case DB_FUNC_EXISTS:
|
||||
__db_exists = (int (*) __P((const char *, int *)))func;
|
||||
break;
|
||||
case DB_FUNC_FREE:
|
||||
__db_free = (void (*) __P((void *)))func;
|
||||
break;
|
||||
case DB_FUNC_FSYNC:
|
||||
__os_fsync = (int (*) __P((int)))func;
|
||||
break;
|
||||
case DB_FUNC_IOINFO:
|
||||
__db_ioinfo =
|
||||
(int (*) __P((const char *, int, off_t *, off_t *)))func;
|
||||
break;
|
||||
case DB_FUNC_MALLOC:
|
||||
__db_malloc = (void *(*) __P((size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_MAP:
|
||||
__db_map = (int (*) __P((int, size_t, int, int, void **)))func;
|
||||
break;
|
||||
case DB_FUNC_OPEN:
|
||||
__os_open = (int (*) __P((const char *, int, ...)))func;
|
||||
break;
|
||||
case DB_FUNC_READ:
|
||||
__os_read = (ssize_t (*) __P((int, void *, size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_REALLOC:
|
||||
__db_realloc = (void *(*) __P((void *, size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_SEEK:
|
||||
__db_seek =
|
||||
(int (*) __P((int, size_t, db_pgno_t, u_long, int)))func;
|
||||
break;
|
||||
case DB_FUNC_SLEEP:
|
||||
__db_sleep = (int (*) __P((u_long, u_long)))func;
|
||||
break;
|
||||
case DB_FUNC_STRDUP:
|
||||
__db_strdup = (char *(*) __P((const char *)))func;
|
||||
break;
|
||||
case DB_FUNC_UNLINK:
|
||||
__os_unlink = (int (*) __P((const char *)))func;
|
||||
break;
|
||||
case DB_FUNC_UNMAP:
|
||||
__db_unmap = (int (*) __P((void *, size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_WRITE:
|
||||
__os_write = (ssize_t (*) __P((int, const void *, size_t)))func;
|
||||
break;
|
||||
case DB_FUNC_YIELD:
|
||||
__db_yield = (int (*) __P((void)))func;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
71
db2/os/os_map.c
Normal file
71
db2/os/os_map.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1996, 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_map.c 10.7 (Sleepycat) 10/25/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
||||
/*
|
||||
* __os_map --
|
||||
* Map in some shared memory backed by a file descriptor.
|
||||
*
|
||||
* PUBLIC: int __os_map __P((int, size_t, int, int, void **));
|
||||
*/
|
||||
int
|
||||
__os_map(fd, len, is_private, is_rdonly, addr)
|
||||
int fd, is_private, is_rdonly;
|
||||
size_t len;
|
||||
void **addr;
|
||||
{
|
||||
void *p;
|
||||
int flags, prot;
|
||||
|
||||
flags = is_private ? MAP_PRIVATE : MAP_SHARED;
|
||||
#ifdef MAP_HASSEMAPHORE
|
||||
flags |= MAP_HASSEMAPHORE;
|
||||
#endif
|
||||
prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);
|
||||
|
||||
#ifndef MAP_FAILED /* XXX: Mmap(2) failure return. */
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
* __os_unmap --
|
||||
* Release the specified shared memory.
|
||||
*
|
||||
* PUBLIC: int __os_unmap __P((void *, size_t));
|
||||
*/
|
||||
int
|
||||
__os_unmap(addr, len)
|
||||
void *addr;
|
||||
size_t len;
|
||||
{
|
||||
/*
|
||||
* !!!
|
||||
* The argument len is always the same length as was mapped.
|
||||
*/
|
||||
return (munmap(addr, len) ? errno : 0);
|
||||
}
|
48
db2/os/os_oflags.c
Normal file
48
db2/os/os_oflags.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1997
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)os_oflags.c 10.2 (Sleepycat) 10/24/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
|
||||
/*
|
||||
* __db_oflags --
|
||||
* Convert open(2) flags to DB flags.
|
||||
*
|
||||
* PUBLIC: int __db_oflags __P((int));
|
||||
*/
|
||||
int
|
||||
__db_oflags(oflags)
|
||||
int oflags;
|
||||
{
|
||||
int dbflags;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Convert POSIX 1003.1 open(2) flags to DB flags. Not an exact
|
||||
* science as most POSIX implementations don't have a flag value
|
||||
* for O_RDONLY, it's simply the lack of a write flag.
|
||||
*/
|
||||
dbflags = 0;
|
||||
if (oflags & O_CREAT)
|
||||
dbflags |= DB_CREATE;
|
||||
if (!(oflags & (O_RDWR | O_WRONLY)) || oflags & O_RDONLY)
|
||||
dbflags |= DB_RDONLY;
|
||||
if (oflags & O_TRUNC)
|
||||
dbflags |= DB_TRUNCATE;
|
||||
return (dbflags);
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)db_os_open.c 10.14 (Sleepycat) 7/5/97";
|
||||
static const char sccsid[] = "@(#)os_open.c 10.19 (Sleepycat) 10/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -20,44 +20,15 @@ static const char sccsid[] = "@(#)db_os_open.c 10.14 (Sleepycat) 7/5/97";
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "os_ext.h"
|
||||
|
||||
/*
|
||||
* __db_oflags --
|
||||
* Convert open(2) flags to DB flags.
|
||||
*
|
||||
* PUBLIC: int __db_oflags __P((int));
|
||||
*/
|
||||
int
|
||||
__db_oflags(oflags)
|
||||
int oflags;
|
||||
{
|
||||
int dbflags;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Convert POSIX 1003.1 open(2) flags to DB flags. Not an exact
|
||||
* science as most POSIX implementations don't have a flag value
|
||||
* for O_RDONLY, it's simply the lack of a write flag.
|
||||
*/
|
||||
dbflags = 0;
|
||||
if (oflags & O_CREAT)
|
||||
dbflags |= DB_CREATE;
|
||||
if (!(oflags & (O_RDWR | O_WRONLY)) || oflags & O_RDONLY)
|
||||
dbflags |= DB_RDONLY;
|
||||
if (oflags & O_TRUNC)
|
||||
dbflags |= DB_TRUNCATE;
|
||||
return (dbflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_fdopen --
|
||||
* __db_open --
|
||||
* Open a file descriptor.
|
||||
*
|
||||
* PUBLIC: int __db_fdopen __P((const char *, int, int, int, int *));
|
||||
* PUBLIC: int __db_open __P((const char *, int, int, int, int *));
|
||||
*/
|
||||
int
|
||||
__db_fdopen(name, arg_flags, ok_flags, mode, fdp)
|
||||
__db_open(name, arg_flags, ok_flags, mode, fdp)
|
||||
const char *name;
|
||||
int arg_flags, ok_flags, mode, *fdp;
|
||||
{
|
||||
@ -95,13 +66,13 @@ __db_fdopen(name, arg_flags, ok_flags, mode, fdp)
|
||||
flags |= O_TRUNC;
|
||||
|
||||
/* Open the file. */
|
||||
if ((fd = open(name, flags, mode)) == -1)
|
||||
if ((fd = __os_open(name, flags, mode)) == -1)
|
||||
return (errno);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Delete any temporary file; done for Win32 by _O_TEMPORARY. */
|
||||
if (arg_flags & DB_TEMPORARY)
|
||||
(void)unlink(name);
|
||||
(void)__os_unlink(name);
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(macintosh)
|
||||
@ -112,7 +83,7 @@ __db_fdopen(name, arg_flags, ok_flags, mode, fdp)
|
||||
if (fcntl(fd, F_SETFD, 1) == -1) {
|
||||
int ret = errno;
|
||||
|
||||
(void)__db_close(fd);
|
||||
(void)__os_close(fd);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
@ -120,19 +91,6 @@ __db_fdopen(name, arg_flags, ok_flags, mode, fdp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_fsync --
|
||||
* Flush a file descriptor.
|
||||
*
|
||||
* PUBLIC: int __db_fsync __P((int));
|
||||
*/
|
||||
int
|
||||
__db_fsync(fd)
|
||||
int fd;
|
||||
{
|
||||
return (fsync(fd) ? errno : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __db_close --
|
||||
* Close a file descriptor.
|
||||
@ -143,5 +101,5 @@ int
|
||||
__db_close(fd)
|
||||
int fd;
|
||||
{
|
||||
return (close(fd) ? errno : 0);
|
||||
return (__os_close(fd) ? errno : 0);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user