Import BSDDB 4.7.25 (as of svn r89086)
This commit is contained in:
292
dbinc/db_am.h
Normal file
292
dbinc/db_am.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1996,2008 Oracle. All rights reserved.
|
||||
*
|
||||
* $Id: db_am.h 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#ifndef _DB_AM_H_
|
||||
#define _DB_AM_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct __db_foreign_info; \
|
||||
typedef struct __db_foreign_info DB_FOREIGN_INFO;
|
||||
|
||||
/*
|
||||
* Keep track of information for foreign keys. Used to maintain a linked list
|
||||
* of 'primary' DBs which reference this 'foreign' DB.
|
||||
*/
|
||||
struct __db_foreign_info {
|
||||
DB *dbp;
|
||||
u_int32_t flags;
|
||||
int (*callback) __P((DB *, const DBT *, DBT *, const DBT *, int *));
|
||||
|
||||
/*
|
||||
* List entries for foreign key.
|
||||
*
|
||||
* !!!
|
||||
* Explicit representations of structures from queue.h.
|
||||
* LIST_ENTRY(__db) s_links;
|
||||
*/
|
||||
struct {
|
||||
struct __db_foreign_info *le_next;
|
||||
struct __db_foreign_info **le_prev;
|
||||
} f_links;
|
||||
};
|
||||
|
||||
/*
|
||||
* IS_ENV_AUTO_COMMIT --
|
||||
* Auto-commit test for enviroment operations: DbEnv::{open,remove,rename}
|
||||
*/
|
||||
#define IS_ENV_AUTO_COMMIT(env, txn, flags) \
|
||||
(LF_ISSET(DB_AUTO_COMMIT) || ((txn) == NULL && \
|
||||
F_ISSET((env)->dbenv, DB_ENV_AUTO_COMMIT) && \
|
||||
!LF_ISSET(DB_NO_AUTO_COMMIT)))
|
||||
|
||||
/*
|
||||
* IS_DB_AUTO_COMMIT --
|
||||
* Auto-commit test for database operations.
|
||||
*/
|
||||
#define IS_DB_AUTO_COMMIT(dbp, txn) \
|
||||
((txn) == NULL && F_ISSET((dbp), DB_AM_TXN))
|
||||
|
||||
/*
|
||||
* STRIP_AUTO_COMMIT --
|
||||
* Releases after 4.3 no longer requires DB operations to specify the
|
||||
* AUTO_COMMIT flag, but the API continues to allow it to be specified.
|
||||
*/
|
||||
#define STRIP_AUTO_COMMIT(f) FLD_CLR((f), DB_AUTO_COMMIT)
|
||||
|
||||
/* DB recovery operation codes. */
|
||||
#define DB_ADD_DUP 1
|
||||
#define DB_REM_DUP 2
|
||||
#define DB_ADD_BIG 3
|
||||
#define DB_REM_BIG 4
|
||||
#define DB_ADD_PAGE_COMPAT 5 /* Compatibility for 4.2 db_relink */
|
||||
#define DB_REM_PAGE_COMPAT 6 /* Compatibility for 4.2 db_relink */
|
||||
|
||||
/*
|
||||
* Standard initialization and shutdown macros for all recovery functions.
|
||||
*/
|
||||
#define REC_INTRO(func, ip, do_cursor) do { \
|
||||
argp = NULL; \
|
||||
dbc = NULL; \
|
||||
file_dbp = NULL; \
|
||||
COMPQUIET(mpf, NULL); /* Not all recovery routines use mpf. */\
|
||||
if ((ret = func(env, &file_dbp, \
|
||||
(info != NULL) ? ((DB_TXNHEAD *)info)->td : NULL, \
|
||||
dbtp->data, &argp)) != 0) { \
|
||||
if (ret == DB_DELETED) { \
|
||||
ret = 0; \
|
||||
goto done; \
|
||||
} \
|
||||
goto out; \
|
||||
} \
|
||||
if (do_cursor) { \
|
||||
if ((ret = \
|
||||
__db_cursor(file_dbp, ip, NULL, &dbc, 0)) != 0) \
|
||||
goto out; \
|
||||
F_SET(dbc, DBC_RECOVER); \
|
||||
} \
|
||||
mpf = file_dbp->mpf; \
|
||||
} while (0)
|
||||
|
||||
#define REC_CLOSE { \
|
||||
int __t_ret; \
|
||||
if (argp != NULL) \
|
||||
__os_free(env, argp); \
|
||||
if (dbc != NULL && \
|
||||
(__t_ret = __dbc_close(dbc)) != 0 && ret == 0) \
|
||||
ret = __t_ret; \
|
||||
} \
|
||||
return (ret)
|
||||
|
||||
/*
|
||||
* No-op versions of the same macros.
|
||||
*/
|
||||
#define REC_NOOP_INTRO(func) do { \
|
||||
argp = NULL; \
|
||||
if ((ret = func(env, dbtp->data, &argp)) != 0) \
|
||||
return (ret); \
|
||||
} while (0)
|
||||
#define REC_NOOP_CLOSE \
|
||||
if (argp != NULL) \
|
||||
__os_free(env, argp); \
|
||||
return (ret)
|
||||
|
||||
/*
|
||||
* Macro for reading pages during recovery. In most cases we
|
||||
* want to avoid an error if the page is not found during rollback.
|
||||
*/
|
||||
#define REC_FGET(mpf, ip, pgno, pagep, cont) \
|
||||
if ((ret = __memp_fget(mpf, \
|
||||
&(pgno), ip, NULL, 0, pagep)) != 0) { \
|
||||
if (ret != DB_PAGE_NOTFOUND) { \
|
||||
ret = __db_pgerr(file_dbp, pgno, ret); \
|
||||
goto out; \
|
||||
} else \
|
||||
goto cont; \
|
||||
}
|
||||
#define REC_DIRTY(mpf, ip, priority, pagep) \
|
||||
if ((ret = __memp_dirty(mpf, \
|
||||
pagep, ip, NULL, priority, DB_MPOOL_EDIT)) != 0) { \
|
||||
ret = __db_pgerr(file_dbp, PGNO(*(pagep)), ret); \
|
||||
goto out; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard debugging macro for all recovery functions.
|
||||
*/
|
||||
#ifdef DEBUG_RECOVER
|
||||
#define REC_PRINT(func) \
|
||||
(void)func(env, dbtp, lsnp, op, info);
|
||||
#else
|
||||
#define REC_PRINT(func)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Actions to __db_lget
|
||||
*/
|
||||
#define LCK_ALWAYS 1 /* Lock even for off page dup cursors */
|
||||
#define LCK_COUPLE 2 /* Lock Couple */
|
||||
#define LCK_COUPLE_ALWAYS 3 /* Lock Couple even in txn. */
|
||||
#define LCK_DOWNGRADE 4 /* Downgrade the lock. (internal) */
|
||||
#define LCK_ROLLBACK 5 /* Lock even if in rollback */
|
||||
|
||||
/*
|
||||
* If doing transactions we have to hold the locks associated with a data item
|
||||
* from a page for the entire transaction. However, we don't have to hold the
|
||||
* locks associated with walking the tree. Distinguish between the two so that
|
||||
* we don't tie up the internal pages of the tree longer than necessary.
|
||||
*/
|
||||
#define __LPUT(dbc, lock) \
|
||||
__ENV_LPUT((dbc)->env, lock)
|
||||
|
||||
#define __ENV_LPUT(env, lock) \
|
||||
(LOCK_ISSET(lock) ? __lock_put(env, &(lock)) : 0)
|
||||
|
||||
/*
|
||||
* __TLPUT -- transactional lock put
|
||||
* If the lock is valid then
|
||||
* If we are not in a transaction put the lock.
|
||||
* Else if the cursor is doing dirty reads and this was a read then
|
||||
* put the lock.
|
||||
* Else if the db is supporting dirty reads and this is a write then
|
||||
* downgrade it.
|
||||
* Else do nothing.
|
||||
*/
|
||||
#define __TLPUT(dbc, lock) \
|
||||
(LOCK_ISSET(lock) ? __db_lput(dbc, &(lock)) : 0)
|
||||
|
||||
/*
|
||||
* A database should be required to be readonly if it's been explicitly
|
||||
* specified as such or if we're a client in a replicated environment
|
||||
* and the user did not specify DB_TXN_NOT_DURABLE.
|
||||
*/
|
||||
#define DB_IS_READONLY(dbp) \
|
||||
(F_ISSET(dbp, DB_AM_RDONLY) || \
|
||||
(IS_REP_CLIENT((dbp)->env) && !F_ISSET((dbp), DB_AM_NOT_DURABLE)))
|
||||
|
||||
/*
|
||||
* We copy the key out if there's any chance the key in the database is not
|
||||
* the same as the user-specified key. If there is a custom comparator we
|
||||
* return a key, as the user-specified key might be a partial key, containing
|
||||
* only the unique identifier. [#13572] [#15770]
|
||||
*
|
||||
* The test for (flags != 0) is necessary for Db.{get,pget}, but it's not
|
||||
* legal to pass a non-zero flags value to Dbc.{get,pget}.
|
||||
*
|
||||
* We need to split out the hash component, since it is possible to build
|
||||
* without hash support enabled. Which would result in a null pointer access.
|
||||
*/
|
||||
#ifdef HAVE_HASH
|
||||
#define DB_RETURNS_A_KEY_HASH(dbp) \
|
||||
((HASH *)(dbp)->h_internal)->h_compare != NULL
|
||||
#else
|
||||
#define DB_RETURNS_A_KEY_HASH(dbp) 0
|
||||
#endif
|
||||
#define DB_RETURNS_A_KEY(dbp, flags) \
|
||||
(((flags) != 0 && (flags) != DB_GET_BOTH && \
|
||||
(flags) != DB_GET_BOTH_RANGE && (flags) != DB_SET) || \
|
||||
((BTREE *)(dbp)->bt_internal)->bt_compare != __bam_defcmp ||\
|
||||
DB_RETURNS_A_KEY_HASH(dbp))
|
||||
|
||||
/*
|
||||
* For portability, primary keys that are record numbers are stored in
|
||||
* secondaries in the same byte order as the secondary database. As a
|
||||
* consequence, we need to swap the byte order of these keys before attempting
|
||||
* to use them for lookups in the primary. We also need to swap user-supplied
|
||||
* primary keys that are used in secondary lookups (for example, with the
|
||||
* DB_GET_BOTH flag on a secondary get).
|
||||
*/
|
||||
#include "dbinc/db_swap.h"
|
||||
|
||||
#define SWAP_IF_NEEDED(sdbp, pkey) \
|
||||
do { \
|
||||
if (((sdbp)->s_primary->type == DB_QUEUE || \
|
||||
(sdbp)->s_primary->type == DB_RECNO) && \
|
||||
F_ISSET((sdbp), DB_AM_SWAP)) \
|
||||
P_32_SWAP((pkey)->data); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Cursor adjustment:
|
||||
* Return the first DB handle in the sorted ENV list of DB
|
||||
* handles that has a matching file ID.
|
||||
*/
|
||||
#define FIND_FIRST_DB_MATCH(env, dbp, tdbp) do { \
|
||||
for ((tdbp) = (dbp); \
|
||||
TAILQ_PREV((tdbp), __dblist, dblistlinks) != NULL && \
|
||||
TAILQ_PREV((tdbp), \
|
||||
__dblist, dblistlinks)->adj_fileid == (dbp)->adj_fileid;\
|
||||
(tdbp) = TAILQ_PREV((tdbp), __dblist, dblistlinks)) \
|
||||
; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Macros used to implement a binary search algorithm. Shared between the
|
||||
* btree and hash implementations.
|
||||
*/
|
||||
#define DB_BINARY_SEARCH_FOR(base, limit, page, adjust) \
|
||||
for (base = 0, limit = NUM_ENT(page) / (db_indx_t)(adjust); \
|
||||
(limit) != 0; (limit) >>= 1)
|
||||
|
||||
#define DB_BINARY_SEARCH_INCR(index, base, limit, adjust) \
|
||||
index = (base) + (((limit) >> 1) * (adjust))
|
||||
|
||||
#define DB_BINARY_SEARCH_SHIFT_BASE(index, base, limit, adjust) do { \
|
||||
base = (index) + (adjust); \
|
||||
--(limit); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Sequence macros, shared between sequence.c and seq_stat.c
|
||||
*/
|
||||
#define SEQ_IS_OPEN(seq) ((seq)->seq_key.data != NULL)
|
||||
|
||||
#define SEQ_ILLEGAL_AFTER_OPEN(seq, name) \
|
||||
if (SEQ_IS_OPEN(seq)) \
|
||||
return (__db_mi_open((seq)->seq_dbp->env, name, 1));
|
||||
|
||||
#define SEQ_ILLEGAL_BEFORE_OPEN(seq, name) \
|
||||
if (!SEQ_IS_OPEN(seq)) \
|
||||
return (__db_mi_open((seq)->seq_dbp->env, name, 0));
|
||||
|
||||
/*
|
||||
* Flags to __db_chk_meta.
|
||||
*/
|
||||
#define DB_CHK_META 0x01 /* Checksum the meta page. */
|
||||
#define DB_CHK_NOLSN 0x02 /* Don't check the LSN. */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "dbinc/db_dispatch.h"
|
||||
#include "dbinc_auto/db_auto.h"
|
||||
#include "dbinc_auto/crdel_auto.h"
|
||||
#include "dbinc_auto/db_ext.h"
|
||||
#endif /* !_DB_AM_H_ */
|
||||
Reference in New Issue
Block a user