bdb-fork-grimen
Version:
Berkeley DB(5.X) bindings for node
1,049 lines (933 loc) • 34.9 kB
Plain Text
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
/*******************************************************
* Berkeley DB ANSI/POSIX include files.
*******************************************************/
extern "C" {
/*
* The Windows compiler needs to be told about structures that are available
* outside a dll.
*/
/*******************************************************
* Forward structure declarations.
*******************************************************/
struct __db_commit_info; typedef struct __db_commit_info DB_COMMIT_INFO;
struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO;
struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD;
struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST;
struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO;
struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
struct __db_log_verify_info;
struct __txn_verify_info;
struct __lv_filereg_info;
struct __lv_ckp_info;
struct __lv_timestamp_info;
typedef struct __db_log_verify_info DB_LOG_VRFY_INFO;
typedef struct __txn_verify_info VRFY_TXN_INFO;
typedef struct __lv_filereg_info VRFY_FILEREG_INFO;
typedef struct __lv_filelife VRFY_FILELIFE;
typedef struct __lv_ckp_info VRFY_CKP_INFO;
typedef struct __lv_timestamp_info VRFY_TIMESTAMP_INFO;
/*
* TXNINFO_HANDLER --
* Callback function pointer type for __iterate_txninfo.
*/
typedef int (*TXNINFO_HANDLER) __P((DB_LOG_VRFY_INFO *, VRFY_TXN_INFO *, void *));
typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
/*******************************************************
* General purpose constants and macros.
*******************************************************/
/*
* Define a macro which has no runtime effect, yet avoids triggering empty
* statement compiler warnings. Use it as the text of conditionally-null macros.
*/
/* Test for a power-of-two (tests true for zero, which doesn't matter here). */
/* Test for valid page sizes. */
/* Minimum number of pages cached, by default. */
/*
* If we are unable to determine the underlying filesystem block size, use
* 8K on the grounds that most OS's use less than 8K for a VM page size.
*/
/* Align an integer to a specific boundary. */
/* Increment a pointer to a specific boundary. */
/*
* Berkeley DB uses the va_copy macro from C99, not all compilers include
* it, so add a dumb implementation compatible with pre C99 implementations.
*/
/*
* Print an address as a u_long (a u_long is the largest type we can print
* portably). Most 64-bit systems have made longs 64-bits, so this should
* work.
*/
/*
* Convert a pointer to a small integral value.
*
* The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
* converts the value to an integral type, and the (u_int16_t) cast converts
* it to a small integral type so we don't get complaints when we assign the
* final result to an integral type smaller than uintptr_t.
*/
/*
* There are several on-page structures that are declared to have a number of
* fields followed by a variable length array of items. The structure size
* without including the variable length array or the address of the first of
* those elements can be found using SSZ.
*
* This macro can also be used to find the offset of a structure element in a
* structure. This is used in various places to copy structure elements from
* unaligned memory references, e.g., pointers into a packed page.
*
* There are two versions because compilers object if you take the address of
* an array.
*/
/* Structure used to print flag values. */
typedef struct __fn {
u_int32_t mask; /* Flag value. */
const char *name; /* Flag name. */
} FN;
/* Set, clear and test flags. */
/*
* Calculate a percentage. The values can overflow 32-bit integer arithmetic
* so we use floating point.
*
* When calculating a bytes-vs-page size percentage, we're getting the inverse
* of the percentage in all cases, that is, we want 100 minus the percentage we
* calculate.
*/
/*
* Statistics update shared memory and so are expensive -- don't update the
* values unless we're going to display the results.
* When performance monitoring is enabled, the changed value can be published
* (via DTrace or SystemTap) along with another associated value or two.
*/
/*
* STAT_DEC() subtracts one rather than adding (-1) with STAT_ADJUST(); the
* latter might generate a compilation warning for an unsigned value.
*/
/* N.B.: Add a verbose version of STAT_DEC() when needed. */
/*
* These macros are used when an error condition is first noticed. They allow
* one to be notified (via e.g. DTrace, SystemTap, ...) when an error occurs
* deep inside DB, rather than when it is returned back through the API.
*
* The second actual argument to these is the second part of the error or
* warning event name. They work when 'errcode' is a symbolic name e.g.
* EINVAL or DB_LOCK_DEALOCK, not a variable. Noticing system call failures
* would be handled by tracing on syscall exit; when e.g., it returns < 0.
*/
/*
* Structure used for callback message aggregation.
*
* Display values in XXX_stat_print calls.
*/
typedef struct __db_msgbuf {
char *buf; /* Heap allocated buffer. */
char *cur; /* Current end of message. */
size_t len; /* Allocated length of buffer. */
} DB_MSGBUF;
/*
* There are quite a few places in Berkeley DB where we want to initialize
* a DBT from a string or other random pointer type, using a length typed
* to size_t in most cases. This macro avoids a lot of casting. The macro
* comes in two flavors because we often want to clear the DBT first.
*/
/*******************************************************
* API return values
*******************************************************/
/*
* Return values that are OK for each different call. Most calls have a
* standard 'return of 0 is only OK value', but some, like db->get have
* DB_NOTFOUND as a return value, but it really isn't an error.
*/
/* Find a reasonable operation-not-supported error. */
/*******************************************************
* Files.
*******************************************************/
/*
* We use 1024 as the maximum path length. It's too hard to figure out what
* the real path length is, as it was traditionally stored in <sys/param.h>,
* and that file isn't always available.
*/
/* Path separator character(s). */
/*******************************************************
* Environment.
*******************************************************/
/* Type passed to __db_appname(). */
typedef enum {
DB_APP_NONE=0, /* No type (region). */
DB_APP_DATA, /* Data file. */
DB_APP_LOG, /* Log file. */
DB_APP_TMP, /* Temporary file. */
DB_APP_RECOVER /* We are in recovery. */
} APPNAME;
/*
* A set of macros to check if various functionality has been configured.
*
* ALIVE_ON The is_alive function is configured.
* CDB_LOCKING CDB product locking.
* CRYPTO_ON Security has been configured.
* LOCKING_ON Locking has been configured.
* LOGGING_ON Logging has been configured.
* MUTEX_ON Mutexes have been configured.
* MPOOL_ON Memory pool has been configured.
* REP_ON Replication has been configured.
* TXN_ON Transactions have been configured.
*
* REP_ON is more complex than most: if the BDB library was compiled without
* replication support, ENV->rep_handle will be NULL; if the BDB library has
* replication support, but it was not configured, the region reference will
* be NULL.
*/
/*
* STD_LOCKING Standard locking, that is, locking was configured and CDB
* was not. We do not do locking in off-page duplicate trees,
* so we check for that in the cursor first.
*/
/*
* IS_RECOVERING: The system is running recovery.
*/
/* Initialization methods are often illegal before/after open is called. */
/* We're not actually user hostile, honest. */
typedef enum {
THREAD_SLOT_NOT_IN_USE=0,
THREAD_OUT,
THREAD_ACTIVE,
THREAD_BLOCKED,
THREAD_BLOCKED_DEAD,
THREAD_FAILCHK,
THREAD_VERIFY
} DB_THREAD_STATE;
typedef struct __pin_list {
roff_t b_ref; /* offset to buffer. */
int region; /* region containing buffer. */
} PIN_LIST;
struct __db_thread_info {
pid_t dbth_pid;
db_threadid_t dbth_tid;
DB_THREAD_STATE dbth_state;
SH_TAILQ_ENTRY dbth_links;
/*
* The following fields track which buffers this thread of
* control has pinned in the mpool buffer cache.
*/
u_int16_t dbth_pincount; /* Number of pins for this thread. */
u_int16_t dbth_pinmax; /* Number of slots allocated. */
roff_t dbth_pinlist; /* List of pins. */
PIN_LIST dbth_pinarray[PINMAX]; /* Initial array of slots. */
DB_LOCKER *dbth_locker; /* Current locker for this thread. */
u_int32_t dbth_check_off; /* Count of number of LOCK_OFF calls. */
};
typedef struct __env_thread_info {
u_int32_t thr_count;
u_int32_t thr_max;
u_int32_t thr_nbucket;
roff_t thr_hashoff;
} THREAD_INFO;
typedef struct __flag_map {
u_int32_t inflag, outflag;
} FLAG_MAP;
/*
* Internal database environment structure.
*
* This is the private database environment handle. The public environment
* handle is the DB_ENV structure. The library owns this structure, the user
* owns the DB_ENV structure. The reason there are two structures is because
* the user's configuration outlives any particular DB_ENV->open call, and
* separate structures allows us to easily discard internal information without
* discarding the user's configuration.
*/
struct __env {
DB_ENV *dbenv; /* Linked DB_ENV structure */
/*
* The ENV structure can be used concurrently, so field access is
* protected.
*/
db_mutex_t mtx_env; /* ENV structure mutex */
/*
* Some fields are included in the ENV structure rather than in the
* DB_ENV structure because they are only set as arguments to the
* DB_ENV->open method. In other words, because of the historic API,
* not for any rational reason.
*
* Arguments to DB_ENV->open.
*/
char *db_home; /* Database home */
u_int32_t open_flags; /* Flags */
int db_mode; /* Default open permissions */
pid_t pid_cache; /* Cached process ID */
DB_FH *lockfhp; /* fcntl(2) locking file handle */
DB_LOCKER *env_lref; /* Locker in non-threaded handles */
DB_DISTAB recover_dtab; /* Dispatch table for recover funcs */
int dir_mode; /* Intermediate directory perms. */
u_int32_t data_len; /* Data length in __db_prbytes. */
/* Thread tracking */
u_int32_t thr_nbucket; /* Number of hash buckets */
DB_HASHTAB *thr_hashtab; /* Hash table of DB_THREAD_INFO */
/* Mutex allocation */
struct {
int alloc_id; /* Allocation ID argument */
u_int32_t flags; /* Flags argument */
} *mutex_iq; /* Initial mutexes queue */
u_int mutex_iq_next; /* Count of initial mutexes */
u_int mutex_iq_max; /* Maximum initial mutexes */
/*
* List of open DB handles for this ENV, used for cursor
* adjustment. Must be protected for multi-threaded support.
*/
db_mutex_t mtx_dblist;
int db_ref; /* DB handle reference count */
TAILQ_HEAD(__dblist, __db) dblist;
/*
* List of open file handles for this ENV. Must be protected
* for multi-threaded support.
*/
TAILQ_HEAD(__fdlist, __fh_t) fdlist;
db_mutex_t mtx_mt; /* Mersenne Twister mutex */
int mti; /* Mersenne Twister index */
u_long *mt; /* Mersenne Twister state vector */
DB_CIPHER *crypto_handle; /* Crypto handle */
DB_LOCKTAB *lk_handle; /* Lock handle */
DB_LOG *lg_handle; /* Log handle */
DB_MPOOL *mp_handle; /* Mpool handle */
DB_MUTEXMGR *mutex_handle; /* Mutex handle */
DB_REP *rep_handle; /* Replication handle */
DB_TXNMGR *tx_handle; /* Txn handle */
/* Application callback to copy data to/from a custom data source */
int (*dbt_usercopy)
__P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
int (*log_verify_wrap) __P((ENV *, const char *, u_int32_t,
const char *, const char *, time_t, time_t, u_int32_t, u_int32_t,
u_int32_t, u_int32_t, int, int));
REGINFO *reginfo; /* REGINFO structure reference */
int test_abort; /* Abort value for testing */
int test_check; /* Checkpoint value for testing */
int test_copy; /* Copy value for testing */
u_int32_t flags;
};
/*******************************************************
* Database Access Methods.
*******************************************************/
/*
* DB_IS_THREADED --
* The database handle is free-threaded (was opened with DB_THREAD).
*/
/* Initialization methods are often illegal before/after open is called. */
/* Some initialization methods are illegal if environment isn't local. */
/*
* Common DBC->internal fields. Each access method adds additional fields
* to this list, but the initial fields are common.
*/
struct __dbc_internal {
__DBC_INTERNAL
};
/* Actions that __db_master_update can take. */
typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN, MU_MOVE } mu_action;
/*
* Access-method-common macro for determining whether a cursor
* has been initialized.
*/
/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
/*
* Use memory belonging to object "owner" to return the results of
* any no-DBT-flag get ops on cursor "dbc".
*/
/* Use the return-data memory src is currently set to use in dest as well. */
/* Reset the returned-memory pointers to their defaults. */
/*******************************************************
* Mpool.
*******************************************************/
/*
* File types for DB access methods. Negative numbers are reserved to DB.
*/
/* Structure used as the DB pgin/pgout pgcookie. */
typedef struct __dbpginfo {
u_int32_t db_pagesize; /* Underlying page size. */
u_int32_t flags; /* Some DB_AM flags needed. */
DBTYPE type; /* DB type */
} DB_PGINFO;
/*******************************************************
* Log.
*******************************************************/
/* Initialize an LSN to 'zero'. */
/* If logging is turned off, smash the lsn. */
/*
* LOG_COMPARE -- compare two LSNs.
*/
/*******************************************************
* Txn.
*******************************************************/
/*******************************************************
* Crypto.
*******************************************************/
/*******************************************************
* Compression
*******************************************************/
}
/*******************************************************
* Remaining general DB includes.
*******************************************************/
@db_int_def@
/*******************************************************
* Remaining Log.
* These need to be defined after the general includes
* because they need rep.h from above.
*******************************************************/
/*
* Test if the environment is currently logging changes. If we're in recovery
* or we're a replication client, we don't need to log changes because they're
* already in the log, even though we have a fully functional log system.
*/
/*
* Test if we need to log a change. By default, we don't log operations without
* associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
* This is because we want to get log records for read/write operations, and, if
* we are trying to debug something, more information is always better.
*
* The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
* thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
* is true.
*
* We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
* in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
* because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
*
* If we're not in recovery (master - doing an abort or a client applying
* a txn), then a client's only path through here is on an internal
* operation, and a master's only path through here is a transactional
* operation. Detect if either is not the case.
*/