📄 db_page.h
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 * Sleepycat Software. All rights reserved. * * $Id: db_page.h,v 11.52 2002/09/13 21:24:04 bostic Exp $ */#ifndef _DB_PAGE_H_#define _DB_PAGE_H_#if defined(__cplusplus)extern "C" {#endif/* * DB page formats. * * !!! * This implementation requires that values within the following structures * NOT be padded -- note, ANSI C permits random padding within structures. * If your compiler pads randomly you can just forget ever making DB run on * your system. In addition, no data type can require larger alignment than * its own size, e.g., a 4-byte data element may not require 8-byte alignment. * * Note that key/data lengths are often stored in db_indx_t's -- this is * not accidental, nor does it limit the key/data size. If the key/data * item fits on a page, it's guaranteed to be small enough to fit into a * db_indx_t, and storing it in one saves space. */#define PGNO_INVALID 0 /* Invalid page number in any database. */#define PGNO_BASE_MD 0 /* Base database: metadata page number. *//* Page types. */#define P_INVALID 0 /* Invalid page type. */#define __P_DUPLICATE 1 /* Duplicate. DEPRECATED in 3.1 */#define P_HASH 2 /* Hash. */#define P_IBTREE 3 /* Btree internal. */#define P_IRECNO 4 /* Recno internal. */#define P_LBTREE 5 /* Btree leaf. */#define P_LRECNO 6 /* Recno leaf. */#define P_OVERFLOW 7 /* Overflow. */#define P_HASHMETA 8 /* Hash metadata page. */#define P_BTREEMETA 9 /* Btree metadata page. */#define P_QAMMETA 10 /* Queue metadata page. */#define P_QAMDATA 11 /* Queue data page. */#define P_LDUP 12 /* Off-page duplicate leaf. */#define P_PAGETYPE_MAX 13/* * When we create pages in mpool, we ask mpool to clear some number of bytes * in the header. This number must be at least as big as the regular page * headers and cover enough of the btree and hash meta-data pages to obliterate * the page type. */#define DB_PAGE_DB_LEN 32#define DB_PAGE_QUEUE_LEN 0/************************************************************************ GENERIC METADATA PAGE HEADER * * !!! * The magic and version numbers have to be in the same place in all versions * of the metadata page as the application may not have upgraded the database. ************************************************************************/typedef struct _dbmeta33 { DB_LSN lsn; /* 00-07: LSN. */ db_pgno_t pgno; /* 08-11: Current page number. */ u_int32_t magic; /* 12-15: Magic number. */ u_int32_t version; /* 16-19: Version. */ u_int32_t pagesize; /* 20-23: Pagesize. */ u_int8_t encrypt_alg; /* 24: Encryption algorithm. */ u_int8_t type; /* 25: Page type. */#define DBMETA_CHKSUM 0x01 u_int8_t metaflags; /* 26: Meta-only flags */ u_int8_t unused1; /* 27: Unused. */ u_int32_t free; /* 28-31: Free list page number. */ db_pgno_t last_pgno; /* 32-35: Page number of last page in db. */ u_int32_t unused3; /* 36-39: Unused. */ u_int32_t key_count; /* 40-43: Cached key count. */ u_int32_t record_count; /* 44-47: Cached record count. */ u_int32_t flags; /* 48-51: Flags: unique to each AM. */ /* 52-71: Unique file ID. */ u_int8_t uid[DB_FILE_ID_LEN];} DBMETA33, DBMETA;/************************************************************************ BTREE METADATA PAGE LAYOUT ************************************************************************/typedef struct _btmeta33 {#define BTM_DUP 0x001 /* Duplicates. */#define BTM_RECNO 0x002 /* Recno tree. */#define BTM_RECNUM 0x004 /* Btree: maintain record count. */#define BTM_FIXEDLEN 0x008 /* Recno: fixed length records. */#define BTM_RENUMBER 0x010 /* Recno: renumber on insert/delete. */#define BTM_SUBDB 0x020 /* Subdatabases. */#define BTM_DUPSORT 0x040 /* Duplicates are sorted. */#define BTM_MASK 0x07f DBMETA dbmeta; /* 00-71: Generic meta-data header. */ u_int32_t maxkey; /* 72-75: Btree: Maxkey. */ u_int32_t minkey; /* 76-79: Btree: Minkey. */ u_int32_t re_len; /* 80-83: Recno: fixed-length record length. */ u_int32_t re_pad; /* 84-87: Recno: fixed-length record pad. */ u_int32_t root; /* 88-91: Root page. */ u_int32_t unused[92]; /* 92-459: Unused space */ u_int32_t crypto_magic; /* 460-463: Crypto magic number */ u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ /* * Minimum page size is 512. */} BTMETA33, BTMETA;/************************************************************************ HASH METADATA PAGE LAYOUT ************************************************************************/typedef struct _hashmeta33 {#define DB_HASH_DUP 0x01 /* Duplicates. */#define DB_HASH_SUBDB 0x02 /* Subdatabases. */#define DB_HASH_DUPSORT 0x04 /* Duplicates are sorted. */ DBMETA dbmeta; /* 00-71: Generic meta-data page header. */ u_int32_t max_bucket; /* 72-75: ID of Maximum bucket in use */ u_int32_t high_mask; /* 76-79: Modulo mask into table */ u_int32_t low_mask; /* 80-83: Modulo mask into table lower half */ u_int32_t ffactor; /* 84-87: Fill factor */ u_int32_t nelem; /* 88-91: Number of keys in hash table */ u_int32_t h_charkey; /* 92-95: Value of hash(CHARKEY) */#define NCACHED 32 /* number of spare points */ /* 96-223: Spare pages for overflow */ u_int32_t spares[NCACHED]; u_int32_t unused[59]; /* 224-459: Unused space */ u_int32_t crypto_magic; /* 460-463: Crypto magic number */ u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ /* * Minimum page size is 512. */} HMETA33, HMETA;/************************************************************************ QUEUE METADATA PAGE LAYOUT ************************************************************************//* * QAM Meta data page structure * */typedef struct _qmeta33 { DBMETA dbmeta; /* 00-71: Generic meta-data header. */ u_int32_t first_recno; /* 72-75: First not deleted record. */ u_int32_t cur_recno; /* 76-79: Next recno to be allocated. */ u_int32_t re_len; /* 80-83: Fixed-length record length. */ u_int32_t re_pad; /* 84-87: Fixed-length record pad. */ u_int32_t rec_page; /* 88-91: Records Per Page. */ u_int32_t page_ext; /* 92-95: Pages per extent */ u_int32_t unused[91]; /* 96-459: Unused space */ u_int32_t crypto_magic; /* 460-463: Crypto magic number */ u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ /* * Minimum page size is 512. */} QMETA33, QMETA;/* * DBMETASIZE is a constant used by __db_file_setup and DB->verify * as a buffer which is guaranteed to be larger than any possible * metadata page size and smaller than any disk sector. */#define DBMETASIZE 512/************************************************************************ BTREE/HASH MAIN PAGE LAYOUT ************************************************************************//* * +-----------------------------------+ * | lsn | pgno | prev pgno | * +-----------------------------------+ * | next pgno | entries | hf offset | * +-----------------------------------+ * | level | type | chksum | * +-----------------------------------+ * | iv | index | free --> | * +-----------+-----------------------+ * | F R E E A R E A | * +-----------------------------------+ * | <-- free | item | * +-----------------------------------+ * | item | item | item | * +-----------------------------------+ * * sizeof(PAGE) == 26 bytes + possibly 20 bytes of checksum and possibly * 16 bytes of IV (+ 2 bytes for alignment), and the following indices * are guaranteed to be two-byte aligned. If we aren't doing crypto or * checksumming the bytes are reclaimed for data storage. * * For hash and btree leaf pages, index items are paired, e.g., inp[0] is the * key for inp[1]'s data. All other types of pages only contain single items. */typedef struct __pg_chksum { u_int8_t unused[2]; /* 26-27: For alignment */ u_int8_t chksum[4]; /* 28-31: Checksum */} PG_CHKSUM;typedef struct __pg_crypto { u_int8_t unused[2]; /* 26-27: For alignment */ u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */ /* !!! * Must be 16-byte aligned for crypto */} PG_CRYPTO;typedef struct _db_page { DB_LSN lsn; /* 00-07: Log sequence number. */ db_pgno_t pgno; /* 08-11: Current page number. */ db_pgno_t prev_pgno; /* 12-15: Previous page number. */ db_pgno_t next_pgno; /* 16-19: Next page number. */ db_indx_t entries; /* 20-21: Number of items on the page. */ db_indx_t hf_offset; /* 22-23: High free byte page offset. */ /* * The btree levels are numbered from the leaf to the root, starting * with 1, so the leaf is level 1, its parent is level 2, and so on. * We maintain this level on all btree pages, but the only place that * we actually need it is on the root page. It would not be difficult * to hide the byte on the root page once it becomes an internal page, * so we could get this byte back if we needed it for something else. */#define LEAFLEVEL 1#define MAXBTREELEVEL 255 u_int8_t level; /* 24: Btree tree level. */ u_int8_t type; /* 25: Page type. */} PAGE;#define SIZEOF_PAGE 26/* * !!! * DB_AM_ENCRYPT always implies DB_AM_CHKSUM so that must come first. */#define P_INP(dbp, pg) \ ((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE + \ (F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) : \ (F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0))))#define P_IV(dbp, pg) \ (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ SIZEOF_PAGE + SSZA(PG_CRYPTO, iv)) \ : NULL)#define P_CHKSUM(dbp, pg) \ (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ SIZEOF_PAGE + SSZA(PG_CRYPTO, chksum)) : \ (F_ISSET((dbp), DB_AM_CHKSUM) ? ((u_int8_t *)(pg) + \ SIZEOF_PAGE + SSZA(PG_CHKSUM, chksum)) \ : NULL))/* PAGE element macros. */#define LSN(p) (((PAGE *)p)->lsn)#define PGNO(p) (((PAGE *)p)->pgno)#define PREV_PGNO(p) (((PAGE *)p)->prev_pgno)#define NEXT_PGNO(p) (((PAGE *)p)->next_pgno)#define NUM_ENT(p) (((PAGE *)p)->entries)#define HOFFSET(p) (((PAGE *)p)->hf_offset)#define LEVEL(p) (((PAGE *)p)->level)#define TYPE(p) (((PAGE *)p)->type)/************************************************************************ QUEUE MAIN PAGE LAYOUT ************************************************************************//* * Sizes of page below. Used to reclaim space if not doing * crypto or checksumming. If you change the QPAGE below you * MUST adjust this too. */#define QPAGE_NORMAL 28#define QPAGE_CHKSUM 48#define QPAGE_SEC 64typedef struct _qpage { DB_LSN lsn; /* 00-07: Log sequence number. */ db_pgno_t pgno; /* 08-11: Current page number. */ u_int32_t unused0[3]; /* 12-23: Unused. */ u_int8_t unused1[1]; /* 24: Unused. */ u_int8_t type; /* 25: Page type. */ u_int8_t unused2[2]; /* 26-27: Unused. */ u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */} QPAGE;#define QPAGE_SZ(dbp) \ (F_ISSET((dbp), DB_AM_ENCRYPT) ? QPAGE_SEC : \ F_ISSET((dbp), DB_AM_CHKSUM) ? QPAGE_CHKSUM : QPAGE_NORMAL)/* * !!! * The next_pgno and prev_pgno fields are not maintained for btree and recno * internal pages. Doing so only provides a minor performance improvement, * it's hard to do when deleting internal pages, and it increases the chance * of deadlock during deletes and splits because we have to re-link pages at * more than the leaf level. * * !!! * The btree/recno access method needs db_recno_t bytes of space on the root * page to specify how many records are stored in the tree. (The alternative * is to store the number of records in the meta-data page, which will create * a second hot spot in trees being actively modified, or recalculate it from * the BINTERNAL fields on each access.) Overload the PREV_PGNO field. */#define RE_NREC(p) \ ((TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) ? PREV_PGNO(p) : \ (db_pgno_t)(TYPE(p) == P_LBTREE ? NUM_ENT(p) / 2 : NUM_ENT(p)))#define RE_NREC_ADJ(p, adj) \ PREV_PGNO(p) += adj;#define RE_NREC_SET(p, num) \ PREV_PGNO(p) = num;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -