1 /* DO NOT EDIT: automatically built by dist/s_windows. */
3 * See the file LICENSE for redistribution information.
5 * Copyright (c) 1996-2009 Oracle. All rights reserved.
13 /*******************************************************
14 * Berkeley DB ANSI/POSIX include files.
15 *******************************************************/
16 #ifdef HAVE_SYSTEM_INCLUDE_FILES
17 #include <sys/types.h>
23 #if defined(__INCLUDE_SELECT_H)
24 #ifdef HAVE_SYS_SELECT_H
25 #include <sys/select.h>
28 #include <selectLib.h>
32 #if TIME_WITH_SYS_TIME
49 #if defined(__INCLUDE_NETWORKING)
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h>
53 #include <netinet/in.h>
55 #include <arpa/inet.h>
58 #if defined(STDC_HEADERS) || defined(__cplusplus)
75 #if defined(__INCLUDE_DIRECTORY)
78 # define NAMLEN(dirent) strlen((dirent)->d_name)
80 # define dirent direct
81 # define NAMLEN(dirent) (dirent)->d_namlen
83 # include <sys/ndir.h>
92 #endif /* __INCLUDE_DIRECTORY */
94 #endif /* !HAVE_SYSTEM_INCLUDE_FILES */
97 #include "dbinc/win_db.h"
101 #include "clib_port.h"
103 #include "dbinc/queue.h"
104 #include "dbinc/shqueue.h"
106 #if defined(__cplusplus)
110 /*******************************************************
111 * Forward structure declarations.
112 *******************************************************/
113 struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO;
114 struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD;
115 struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST;
116 struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
117 struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO;
118 struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
120 typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
122 /*******************************************************
123 * General purpose constants and macros.
124 *******************************************************/
128 #define TRUE (!FALSE)
130 #define MEGABYTE 1048576
131 #define GIGABYTE 1073741824
133 #define NS_PER_MS 1000000 /* Nanoseconds in a millisecond */
134 #define NS_PER_US 1000 /* Nanoseconds in a microsecond */
135 #define NS_PER_SEC 1000000000 /* Nanoseconds in a second */
136 #define US_PER_MS 1000 /* Microseconds in a millisecond */
137 #define US_PER_SEC 1000000 /* Microseconds in a second */
138 #define MS_PER_SEC 1000 /* Milliseconds in a second */
140 #define RECNO_OOB 0 /* Illegal record number. */
142 /* Test for a power-of-two (tests true for zero, which doesn't matter here). */
143 #define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
145 /* Test for valid page sizes. */
146 #define DB_MIN_PGSIZE 0x000200 /* Minimum page size (512). */
147 #define DB_MAX_PGSIZE 0x010000 /* Maximum page size (65536). */
148 #define IS_VALID_PAGESIZE(x) \
149 (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE))
151 /* Minimum number of pages cached, by default. */
152 #define DB_MINPAGECACHE 16
155 * If we are unable to determine the underlying filesystem block size, use
156 * 8K on the grounds that most OS's use less than 8K for a VM page size.
158 #define DB_DEF_IOSIZE (8 * 1024)
160 /* Align an integer to a specific boundary. */
162 #define DB_ALIGN(v, bound) \
163 (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1))
165 /* Increment a pointer to a specific boundary. */
167 #define ALIGNP_INC(p, bound) \
168 (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1))
171 * Print an address as a u_long (a u_long is the largest type we can print
172 * portably). Most 64-bit systems have made longs 64-bits, so this should
175 #define P_TO_ULONG(p) ((u_long)(uintptr_t)(p))
178 * Convert a pointer to a small integral value.
180 * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
181 * converts the value to an integral type, and the (u_int16_t) cast converts
182 * it to a small integral type so we don't get complaints when we assign the
183 * final result to an integral type smaller than uintptr_t.
185 #define P_TO_UINT32(p) ((u_int32_t)(uintptr_t)(p))
186 #define P_TO_UINT16(p) ((u_int16_t)(uintptr_t)(p))
189 * There are several on-page structures that are declared to have a number of
190 * fields followed by a variable length array of items. The structure size
191 * without including the variable length array or the address of the first of
192 * those elements can be found using SSZ.
194 * This macro can also be used to find the offset of a structure element in a
195 * structure. This is used in various places to copy structure elements from
196 * unaligned memory references, e.g., pointers into a packed page.
198 * There are two versions because compilers object if you take the address of
202 #define SSZ(name, field) P_TO_UINT16(&(((name *)0)->field))
205 #define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0]))
207 /* Structure used to print flag values. */
208 typedef struct __fn {
209 u_int32_t mask; /* Flag value. */
210 const char *name; /* Flag name. */
213 /* Set, clear and test flags. */
214 #define FLD_CLR(fld, f) (fld) &= ~(f)
215 #define FLD_ISSET(fld, f) ((fld) & (f))
216 #define FLD_SET(fld, f) (fld) |= (f)
217 #define F_CLR(p, f) (p)->flags &= ~(f)
218 #define F_ISSET(p, f) ((p)->flags & (f))
219 #define F_SET(p, f) (p)->flags |= (f)
220 #define LF_CLR(f) ((flags) &= ~(f))
221 #define LF_ISSET(f) ((flags) & (f))
222 #define LF_SET(f) ((flags) |= (f))
225 * Calculate a percentage. The values can overflow 32-bit integer arithmetic
226 * so we use floating point.
228 * When calculating a bytes-vs-page size percentage, we're getting the inverse
229 * of the percentage in all cases, that is, we want 100 minus the percentage we
232 #define DB_PCT(v, total) \
233 ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total)))
234 #define DB_PCT_PG(v, total, pgsize) \
235 ((int)((total) == 0 ? 0 : \
236 100 - ((double)(v) * 100) / (((double)total) * (pgsize))))
239 * Statistics update shared memory and so are expensive -- don't update the
240 * values unless we're going to display the results.
243 #ifdef HAVE_STATISTICS
250 * Structure used for callback message aggregation.
252 * Display values in XXX_stat_print calls.
254 typedef struct __db_msgbuf {
255 char *buf; /* Heap allocated buffer. */
256 char *cur; /* Current end of message. */
257 size_t len; /* Allocated length of buffer. */
259 #define DB_MSGBUF_INIT(a) do { \
260 (a)->buf = (a)->cur = NULL; \
263 #define DB_MSGBUF_FLUSH(env, a) do { \
264 if ((a)->buf != NULL) { \
265 if ((a)->cur != (a)->buf) \
266 __db_msg(env, "%s", (a)->buf); \
267 __os_free(env, (a)->buf); \
271 #define STAT_FMT(msg, fmt, type, v) do { \
273 DB_MSGBUF_INIT(&__mb); \
274 __db_msgadd(env, &__mb, fmt, (type)(v)); \
275 __db_msgadd(env, &__mb, "\t%s", msg); \
276 DB_MSGBUF_FLUSH(env, &__mb); \
278 #define STAT_HEX(msg, v) \
279 __db_msg(env, "%#lx\t%s", (u_long)(v), msg)
280 #define STAT_ISSET(msg, p) \
281 __db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg)
282 #define STAT_LONG(msg, v) \
283 __db_msg(env, "%ld\t%s", (long)(v), msg)
284 #define STAT_LSN(msg, lsnp) \
285 __db_msg(env, "%lu/%lu\t%s", \
286 (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg)
287 #define STAT_POINTER(msg, v) \
288 __db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg)
289 #define STAT_STRING(msg, p) do { \
290 const char *__p = p; /* p may be a function call. */ \
291 __db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg); \
293 #define STAT_ULONG(msg, v) \
294 __db_msg(env, "%lu\t%s", (u_long)(v), msg)
297 * There are quite a few places in Berkeley DB where we want to initialize
298 * a DBT from a string or other random pointer type, using a length typed
299 * to size_t in most cases. This macro avoids a lot of casting. The macro
300 * comes in two flavors because we often want to clear the DBT first.
302 #define DB_SET_DBT(dbt, d, s) do { \
303 (dbt).data = (void *)(d); \
304 (dbt).size = (u_int32_t)(s); \
306 #define DB_INIT_DBT(dbt, d, s) do { \
307 memset(&(dbt), 0, sizeof(dbt)); \
308 DB_SET_DBT(dbt, d, s); \
311 /*******************************************************
313 *******************************************************/
315 * Return values that are OK for each different call. Most calls have a
316 * standard 'return of 0 is only OK value', but some, like db->get have
317 * DB_NOTFOUND as a return value, but it really isn't an error.
319 #define DB_RETOK_STD(ret) ((ret) == 0)
320 #define DB_RETOK_DBCDEL(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \
321 (ret) == DB_NOTFOUND)
322 #define DB_RETOK_DBCGET(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \
323 (ret) == DB_NOTFOUND)
324 #define DB_RETOK_DBCPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST || \
325 (ret) == DB_NOTFOUND)
326 #define DB_RETOK_DBDEL(ret) DB_RETOK_DBCDEL(ret)
327 #define DB_RETOK_DBGET(ret) DB_RETOK_DBCGET(ret)
328 #define DB_RETOK_DBPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST)
329 #define DB_RETOK_EXISTS(ret) DB_RETOK_DBCGET(ret)
330 #define DB_RETOK_LGGET(ret) ((ret) == 0 || (ret) == DB_NOTFOUND)
331 #define DB_RETOK_MPGET(ret) ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND)
332 #define DB_RETOK_REPPMSG(ret) ((ret) == 0 || \
333 (ret) == DB_REP_IGNORE || \
334 (ret) == DB_REP_ISPERM || \
335 (ret) == DB_REP_NEWMASTER || \
336 (ret) == DB_REP_NEWSITE || \
337 (ret) == DB_REP_NOTPERM)
338 #define DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE)
340 /* Find a reasonable operation-not-supported error. */
342 #define DB_OPNOTSUP EOPNOTSUPP
345 #define DB_OPNOTSUP ENOTSUP
347 #define DB_OPNOTSUP EINVAL
351 /*******************************************************
353 *******************************************************/
355 * We use 1024 as the maximum path length. It's too hard to figure out what
356 * the real path length is, as it was traditionally stored in <sys/param.h>,
357 * and that file isn't always available.
359 #define DB_MAXPATHLEN 1024
361 #define PATH_DOT "." /* Current working directory. */
362 /* Path separator character(s). */
363 #define PATH_SEPARATOR "\\/:"
365 /*******************************************************
367 *******************************************************/
368 /* Type passed to __db_appname(). */
370 DB_APP_NONE=0, /* No type (region). */
371 DB_APP_DATA, /* Data file. */
372 DB_APP_LOG, /* Log file. */
373 DB_APP_TMP, /* Temporary file. */
374 DB_APP_RECOVER /* We are in recovery. */
378 * A set of macros to check if various functionality has been configured.
380 * ALIVE_ON The is_alive function is configured.
381 * CDB_LOCKING CDB product locking.
382 * CRYPTO_ON Security has been configured.
383 * LOCKING_ON Locking has been configured.
384 * LOGGING_ON Logging has been configured.
385 * MUTEX_ON Mutexes have been configured.
386 * MPOOL_ON Memory pool has been configured.
387 * REP_ON Replication has been configured.
388 * RPC_ON RPC has been configured.
389 * TXN_ON Transactions have been configured.
391 * REP_ON is more complex than most: if the BDB library was compiled without
392 * replication support, ENV->rep_handle will be NULL; if the BDB library has
393 * replication support, but it was not configured, the region reference will
396 #define ALIVE_ON(env) ((env)->dbenv->is_alive != NULL)
397 #define CDB_LOCKING(env) F_ISSET(env, ENV_CDB)
398 #define CRYPTO_ON(env) ((env)->crypto_handle != NULL)
399 #define LOCKING_ON(env) ((env)->lk_handle != NULL)
400 #define LOGGING_ON(env) ((env)->lg_handle != NULL)
401 #define MPOOL_ON(env) ((env)->mp_handle != NULL)
402 #define MUTEX_ON(env) ((env)->mutex_handle != NULL)
403 #define REP_ON(env) \
404 ((env)->rep_handle != NULL && (env)->rep_handle->region != NULL)
405 #define RPC_ON(dbenv) ((dbenv)->cl_handle != NULL)
406 #define TXN_ON(env) ((env)->tx_handle != NULL)
409 * STD_LOCKING Standard locking, that is, locking was configured and CDB
410 * was not. We do not do locking in off-page duplicate trees,
411 * so we check for that in the cursor first.
413 #define STD_LOCKING(dbc) \
414 (!F_ISSET(dbc, DBC_OPD) && \
415 !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env))
418 * IS_RECOVERING: The system is running recovery.
420 #define IS_RECOVERING(env) \
421 (LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER))
423 /* Initialization methods are often illegal before/after open is called. */
424 #define ENV_ILLEGAL_AFTER_OPEN(env, name) \
425 if (F_ISSET((env), ENV_OPEN_CALLED)) \
426 return (__db_mi_open(env, name, 1));
427 #define ENV_ILLEGAL_BEFORE_OPEN(env, name) \
428 if (!F_ISSET((env), ENV_OPEN_CALLED)) \
429 return (__db_mi_open(env, name, 0));
431 /* We're not actually user hostile, honest. */
432 #define ENV_REQUIRES_CONFIG(env, handle, i, flags) \
433 if (handle == NULL) \
434 return (__env_not_config(env, i, flags));
435 #define ENV_REQUIRES_CONFIG_XX(env, handle, i, flags) \
436 if ((env)->handle->region == NULL) \
437 return (__env_not_config(env, i, flags));
438 #define ENV_NOT_CONFIGURED(env, handle, i, flags) \
439 if (F_ISSET((env), ENV_OPEN_CALLED)) \
440 ENV_REQUIRES_CONFIG(env, handle, i, flags)
442 #define ENV_ENTER(env, ip) do { \
445 if ((env)->thr_hashtab == NULL) \
449 __env_set_state(env, &(ip), THREAD_ACTIVE)) != 0) \
454 #define FAILCHK_THREAD(env, ip) do { \
456 (ip)->dbth_state = THREAD_FAILCHK; \
459 #define ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip)
462 #define ENV_LEAVE(env, ip) do { \
463 if ((ip) != NULL) { \
464 DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE || \
465 (ip)->dbth_state == THREAD_FAILCHK)); \
466 (ip)->dbth_state = THREAD_OUT; \
470 #define ENV_LEAVE(env, ip) do { \
472 (ip)->dbth_state = THREAD_OUT; \
476 #define CHECK_THREAD(env) do { \
477 if ((env)->thr_hashtab != NULL) \
478 (void)__env_set_state(env, NULL, THREAD_VERIFY); \
480 #ifdef HAVE_STATISTICS
481 #define CHECK_MTX_THREAD(env, mtx) do { \
482 if (mtx->alloc_id != MTX_MUTEX_REGION && \
483 mtx->alloc_id != MTX_ENV_REGION && \
484 mtx->alloc_id != MTX_APPLICATION) \
488 #define CHECK_MTX_THREAD(env, mtx)
491 #define CHECK_THREAD(env)
492 #define CHECK_MTX_THREAD(env, mtx)
496 THREAD_SLOT_NOT_IN_USE=0,
505 typedef struct __pin_list {
506 roff_t b_ref; /* offset to buffer. */
507 int region; /* region containing buffer. */
511 struct __db_thread_info {
513 db_threadid_t dbth_tid;
514 DB_THREAD_STATE dbth_state;
515 SH_TAILQ_ENTRY dbth_links;
517 * The following fields track which buffers this thread of
518 * control has pinned in the mpool buffer cache.
520 u_int16_t dbth_pincount; /* Number of pins for this thread. */
521 u_int16_t dbth_pinmax; /* Number of slots allocated. */
522 roff_t dbth_pinlist; /* List of pins. */
523 PIN_LIST dbth_pinarray[PINMAX]; /* Initial array of slots. */
526 typedef struct __env_thread_info {
529 u_int32_t thr_nbucket;
533 #define DB_EVENT(env, e, einfo) do { \
534 DB_ENV *__dbenv = (env)->dbenv; \
535 if (__dbenv->db_event_func != NULL) \
536 __dbenv->db_event_func(__dbenv, e, einfo); \
539 typedef struct __flag_map {
540 u_int32_t inflag, outflag;
544 * Internal database environment structure.
546 * This is the private database environment handle. The public environment
547 * handle is the DB_ENV structure. The library owns this structure, the user
548 * owns the DB_ENV structure. The reason there are two structures is because
549 * the user's configuration outlives any particular DB_ENV->open call, and
550 * separate structures allows us to easily discard internal information without
551 * discarding the user's configuration.
554 DB_ENV *dbenv; /* Linked DB_ENV structure */
557 * The ENV structure can be used concurrently, so field access is
560 db_mutex_t mtx_env; /* ENV structure mutex */
563 * Some fields are included in the ENV structure rather than in the
564 * DB_ENV structure because they are only set as arguments to the
565 * DB_ENV->open method. In other words, because of the historic API,
566 * not for any rational reason.
568 * Arguments to DB_ENV->open.
570 char *db_home; /* Database home */
571 u_int32_t open_flags; /* Flags */
572 int db_mode; /* Default open permissions */
574 pid_t pid_cache; /* Cached process ID */
576 DB_FH *lockfhp; /* fcntl(2) locking file handle */
578 DB_LOCKER *env_lref; /* Locker in non-threaded handles */
580 DB_DISTAB recover_dtab; /* Dispatch table for recover funcs */
582 int dir_mode; /* Intermediate directory perms. */
584 /* Thread tracking */
585 u_int32_t thr_nbucket; /* Number of hash buckets */
586 DB_HASHTAB *thr_hashtab; /* Hash table of DB_THREAD_INFO */
588 /* Mutex allocation */
590 int alloc_id; /* Allocation ID argument */
591 u_int32_t flags; /* Flags argument */
592 } *mutex_iq; /* Initial mutexes queue */
593 u_int mutex_iq_next; /* Count of initial mutexes */
594 u_int mutex_iq_max; /* Maximum initial mutexes */
597 * List of open DB handles for this ENV, used for cursor
598 * adjustment. Must be protected for multi-threaded support.
600 db_mutex_t mtx_dblist;
601 int db_ref; /* DB handle reference count */
602 TAILQ_HEAD(__dblist, __db) dblist;
605 * List of open file handles for this ENV. Must be protected
606 * for multi-threaded support.
608 TAILQ_HEAD(__fdlist, __fh_t) fdlist;
610 db_mutex_t mtx_mt; /* Mersenne Twister mutex */
611 int mti; /* Mersenne Twister index */
612 u_long *mt; /* Mersenne Twister state vector */
614 DB_CIPHER *crypto_handle; /* Crypto handle */
615 DB_LOCKTAB *lk_handle; /* Lock handle */
616 DB_LOG *lg_handle; /* Log handle */
617 DB_MPOOL *mp_handle; /* Mpool handle */
618 DB_MUTEXMGR *mutex_handle; /* Mutex handle */
619 DB_REP *rep_handle; /* Replication handle */
620 DB_TXNMGR *tx_handle; /* Txn handle */
622 /* Application callback to copy data to/from a custom data source */
623 #define DB_USERCOPY_GETDATA 0x0001
624 #define DB_USERCOPY_SETDATA 0x0002
626 __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
628 REGINFO *reginfo; /* REGINFO structure reference */
630 #define DB_TEST_ELECTINIT 1 /* after __rep_elect_init */
631 #define DB_TEST_ELECTVOTE1 2 /* after sending VOTE1 */
632 #define DB_TEST_POSTDESTROY 3 /* after destroy op */
633 #define DB_TEST_POSTLOG 4 /* after logging all pages */
634 #define DB_TEST_POSTLOGMETA 5 /* after logging meta in btree */
635 #define DB_TEST_POSTOPEN 6 /* after __os_open */
636 #define DB_TEST_POSTSYNC 7 /* after syncing the log */
637 #define DB_TEST_PREDESTROY 8 /* before destroy op */
638 #define DB_TEST_PREOPEN 9 /* before __os_open */
639 #define DB_TEST_SUBDB_LOCKS 10 /* subdb locking tests */
640 int test_abort; /* Abort value for testing */
641 int test_check; /* Checkpoint value for testing */
642 int test_copy; /* Copy value for testing */
644 #define ENV_CDB 0x00000001 /* DB_INIT_CDB */
645 #define ENV_DBLOCAL 0x00000002 /* Environment for a private DB */
646 #define ENV_LITTLEENDIAN 0x00000004 /* Little endian system. */
647 #define ENV_LOCKDOWN 0x00000008 /* DB_LOCKDOWN set */
648 #define ENV_NO_OUTPUT_SET 0x00000010 /* No output channel set */
649 #define ENV_OPEN_CALLED 0x00000020 /* DB_ENV->open called */
650 #define ENV_PRIVATE 0x00000040 /* DB_PRIVATE set */
651 #define ENV_RECOVER_FATAL 0x00000080 /* Doing fatal recovery in env */
652 #define ENV_REF_COUNTED 0x00000100 /* Region references this handle */
653 #define ENV_SYSTEM_MEM 0x00000200 /* DB_SYSTEM_MEM set */
654 #define ENV_THREAD 0x00000400 /* DB_THREAD set */
658 /*******************************************************
659 * Database Access Methods.
660 *******************************************************/
663 * The database handle is free-threaded (was opened with DB_THREAD).
665 #define DB_IS_THREADED(dbp) \
666 ((dbp)->mutex != MUTEX_INVALID)
668 /* Initialization methods are often illegal before/after open is called. */
669 #define DB_ILLEGAL_AFTER_OPEN(dbp, name) \
670 if (F_ISSET((dbp), DB_AM_OPEN_CALLED)) \
671 return (__db_mi_open((dbp)->env, name, 1));
672 #define DB_ILLEGAL_BEFORE_OPEN(dbp, name) \
673 if (!F_ISSET((dbp), DB_AM_OPEN_CALLED)) \
674 return (__db_mi_open((dbp)->env, name, 0));
675 /* Some initialization methods are illegal if environment isn't local. */
676 #define DB_ILLEGAL_IN_ENV(dbp, name) \
677 if (!F_ISSET((dbp)->env, ENV_DBLOCAL)) \
678 return (__db_mi_env((dbp)->env, name));
679 #define DB_ILLEGAL_METHOD(dbp, flags) { \
681 if ((__ret = __dbh_am_chk(dbp, flags)) != 0) \
686 * Common DBC->internal fields. Each access method adds additional fields
687 * to this list, but the initial fields are common.
689 #define __DBC_INTERNAL \
690 DBC *opd; /* Off-page duplicate cursor. */\
691 DBC *pdbc; /* Pointer to parent cursor. */ \
693 void *page; /* Referenced page. */ \
694 u_int32_t part; /* Partition number. */ \
695 db_pgno_t root; /* Tree root. */ \
696 db_pgno_t pgno; /* Referenced page number. */ \
697 db_indx_t indx; /* Referenced key item index. */\
699 /* Streaming -- cache last position. */ \
700 db_pgno_t stream_start_pgno; /* Last start pgno. */ \
701 u_int32_t stream_off; /* Current offset. */ \
702 db_pgno_t stream_curr_pgno; /* Current overflow page. */ \
704 DB_LOCK lock; /* Cursor lock. */ \
705 db_lockmode_t lock_mode; /* Lock mode. */
707 struct __dbc_internal {
711 /* Actions that __db_master_update can take. */
712 typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action;
715 * Access-method-common macro for determining whether a cursor
716 * has been initialized.
718 #ifdef HAVE_PARTITION
719 #define IS_INITIALIZED(dbc) (DB_IS_PARTITIONED((dbc)->dbp) ? \
720 ((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \
721 ((PART_CURSOR *)(dbc)->internal)->sub_cursor-> \
722 internal->pgno != PGNO_INVALID : \
723 (dbc)->internal->pgno != PGNO_INVALID)
725 #define IS_INITIALIZED(dbc) ((dbc)->internal->pgno != PGNO_INVALID)
728 /* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
729 #define FREE_IF_NEEDED(env, dbt) \
730 if (F_ISSET((dbt), DB_DBT_APPMALLOC)) { \
731 __os_ufree((env), (dbt)->data); \
732 F_CLR((dbt), DB_DBT_APPMALLOC); \
736 * Use memory belonging to object "owner" to return the results of
737 * any no-DBT-flag get ops on cursor "dbc".
739 #define SET_RET_MEM(dbc, owner) \
741 (dbc)->rskey = &(owner)->my_rskey; \
742 (dbc)->rkey = &(owner)->my_rkey; \
743 (dbc)->rdata = &(owner)->my_rdata; \
746 /* Use the return-data memory src is currently set to use in dest as well. */
747 #define COPY_RET_MEM(src, dest) \
749 (dest)->rskey = (src)->rskey; \
750 (dest)->rkey = (src)->rkey; \
751 (dest)->rdata = (src)->rdata; \
754 /* Reset the returned-memory pointers to their defaults. */
755 #define RESET_RET_MEM(dbc) \
757 (dbc)->rskey = &(dbc)->my_rskey; \
758 (dbc)->rkey = &(dbc)->my_rkey; \
759 (dbc)->rdata = &(dbc)->my_rdata; \
762 /*******************************************************
764 *******************************************************/
766 * File types for DB access methods. Negative numbers are reserved to DB.
768 #define DB_FTYPE_SET -1 /* Call pgin/pgout functions. */
769 #define DB_FTYPE_NOTSET 0 /* Don't call... */
770 #define DB_LSN_OFF_NOTSET -1 /* Not yet set. */
771 #define DB_CLEARLEN_NOTSET UINT32_MAX /* Not yet set. */
773 /* Structure used as the DB pgin/pgout pgcookie. */
774 typedef struct __dbpginfo {
775 size_t db_pagesize; /* Underlying page size. */
776 u_int32_t flags; /* Some DB_AM flags needed. */
777 DBTYPE type; /* DB type */
780 /*******************************************************
782 *******************************************************/
783 /* Initialize an LSN to 'zero'. */
784 #define ZERO_LSN(LSN) do { \
788 #define IS_ZERO_LSN(LSN) ((LSN).file == 0 && (LSN).offset == 0)
790 #define IS_INIT_LSN(LSN) ((LSN).file == 1 && (LSN).offset == 0)
791 #define INIT_LSN(LSN) do { \
796 #define MAX_LSN(LSN) do { \
797 (LSN).file = UINT32_MAX; \
798 (LSN).offset = UINT32_MAX; \
800 #define IS_MAX_LSN(LSN) \
801 ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX)
803 /* If logging is turned off, smash the lsn. */
804 #define LSN_NOT_LOGGED(LSN) do { \
808 #define IS_NOT_LOGGED_LSN(LSN) \
809 ((LSN).file == 0 && (LSN).offset == 1)
812 * LOG_COMPARE -- compare two LSNs.
815 #define LOG_COMPARE(lsn0, lsn1) \
816 ((lsn0)->file != (lsn1)->file ? \
817 ((lsn0)->file < (lsn1)->file ? -1 : 1) : \
818 ((lsn0)->offset != (lsn1)->offset ? \
819 ((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0))
821 /*******************************************************
823 *******************************************************/
824 #define DB_NONBLOCK(C) ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT))
825 #define NOWAIT_FLAG(txn) \
826 ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0)
827 #define IS_REAL_TXN(txn) \
828 ((txn) != NULL && !F_ISSET(txn, TXN_CDSGROUP))
829 #define IS_SUBTRANSACTION(txn) \
830 ((txn) != NULL && (txn)->parent != NULL)
832 /*******************************************************
834 *******************************************************/
835 #define DB_IV_BYTES 16 /* Bytes per IV */
836 #define DB_MAC_KEY 20 /* Bytes per MAC checksum */
838 /*******************************************************
840 *******************************************************/
841 #define CMP_INT_SPARE_VAL 0xFC /* Smallest byte value that the integer
842 compression algorithm doesn't use */
844 /*******************************************************
845 * Secondaries over RPC.
846 *******************************************************/
849 * These are flags passed to DB->associate calls by the Tcl API if running
850 * over RPC. The RPC server will mask out these flags before making the real
851 * DB->associate call.
853 * These flags must coexist with the valid flags to DB->associate (currently
854 * DB_AUTO_COMMIT and DB_CREATE). DB_AUTO_COMMIT is in the group of
855 * high-order shared flags (0xff000000), and DB_CREATE is in the low-order
856 * group (0x00000fff), so we pick a range in between.
858 #define DB_RPC2ND_MASK 0x00f00000 /* Reserved bits. */
860 #define DB_RPC2ND_REVERSEDATA 0x00100000 /* callback_n(0) _s_reversedata. */
861 #define DB_RPC2ND_NOOP 0x00200000 /* callback_n(1) _s_noop */
862 #define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */
863 #define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */
864 #define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */
865 #define DB_RPC2ND_TRUNCDATA 0x00600000 /* callback_n(5) _s_truncdata */
866 #define DB_RPC2ND_CONSTANT 0x00700000 /* callback_n(6) _s_constant */
867 #define DB_RPC2ND_GETZIP 0x00800000 /* sj_getzip */
868 #define DB_RPC2ND_GETNAME 0x00900000 /* sj_getname */
871 #if defined(__cplusplus)
875 /*******************************************************
876 * Remaining general DB includes.
877 *******************************************************/
880 #include "dbinc/globals.h"
881 #include "dbinc/clock.h"
882 #include "dbinc/debug.h"
883 #include "dbinc/region.h"
884 #include "dbinc_auto/env_ext.h"
885 #include "dbinc/mutex.h"
886 #ifdef HAVE_REPLICATION_THREADS
887 #include "dbinc/repmgr.h"
889 #include "dbinc/rep.h"
890 #include "dbinc/os.h"
891 #include "dbinc_auto/clib_ext.h"
892 #include "dbinc_auto/common_ext.h"
894 /*******************************************************
896 * These need to be defined after the general includes
897 * because they need rep.h from above.
898 *******************************************************/
900 * Test if the environment is currently logging changes. If we're in recovery
901 * or we're a replication client, we don't need to log changes because they're
902 * already in the log, even though we have a fully functional log system.
904 #define DBENV_LOGGING(env) \
905 (LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env)))
908 * Test if we need to log a change. By default, we don't log operations without
909 * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
910 * This is because we want to get log records for read/write operations, and, if
911 * we are trying to debug something, more information is always better.
913 * The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
914 * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
917 * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
918 * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
919 * because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
921 * If we're not in recovery (master - doing an abort or a client applying
922 * a txn), then a client's only path through here is on an internal
923 * operation, and a master's only path through here is a transactional
924 * operation. Detect if either is not the case.
926 #if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP)
927 #define DBC_LOGGING(dbc) __dbc_logging(dbc)
929 #define DBC_LOGGING(dbc) \
930 ((dbc)->txn != NULL && LOGGING_ON((dbc)->env) && \
931 !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env))
934 #endif /* !_DB_INT_H_ */