📄 btreeint.h
字号:
/*** The in-memory image of a disk page has the auxiliary information appended** to the end. EXTRA_SIZE is the number of bytes of space needed to hold** that extra information.*/#define EXTRA_SIZE sizeof(MemPage)/* Btree handle */struct Btree { sqlite3 *pSqlite; BtShared *pBt; u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */};/*** Btree.inTrans may take one of the following values.**** If the shared-data extension is enabled, there may be multiple users** of the Btree structure. At most one of these may open a write transaction,** but any number may have active read transactions. Variable Btree.pDb ** points to the handle that owns any current write-transaction.*/#define TRANS_NONE 0#define TRANS_READ 1#define TRANS_WRITE 2/*** Everything we need to know about an open database*/struct BtShared { Pager *pPager; /* The page cache */ BtCursor *pCursor; /* A list of all open cursors */ MemPage *pPage1; /* First page of the database */ u8 inStmt; /* True if we are in a statement subtransaction */ u8 readOnly; /* True if the underlying file is readonly */ u8 maxEmbedFrac; /* Maximum payload as % of total page size */ u8 minEmbedFrac; /* Minimum payload as % of total page size */ u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 pageSizeFixed; /* True if the page size can no longer be changed */#ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ Pgno nTrunc; /* Non-zero if the db will be truncated (incr vacuum) */#endif u16 pageSize; /* Total number of bytes on a page */ u16 usableSize; /* Number of usable bytes on each page */ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ int minLocal; /* Minimum local payload in non-LEAFDATA tables */ int maxLeaf; /* Maximum local payload in a LEAFDATA table */ int minLeaf; /* Minimum local payload in a LEAFDATA table */ BusyHandler *pBusyHandler; /* Callback for when there is lock contention */ u8 inTransaction; /* Transaction state */ int nRef; /* Number of references to this structure */ int nTransaction; /* Number of open transactions (read + write) */ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */#ifndef SQLITE_OMIT_SHARED_CACHE BtLock *pLock; /* List of locks held on this shared-btree struct */ BtShared *pNext; /* Next in ThreadData.pBtree linked list */#endif};/*** An instance of the following structure is used to hold information** about a cell. The parseCellPtr() function fills in this structure** based on information extract from the raw disk page.*/typedef struct CellInfo CellInfo;struct CellInfo { u8 *pCell; /* Pointer to the start of cell content */ i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ u32 nData; /* Number of bytes of data */ u32 nPayload; /* Total amount of payload */ u16 nHeader; /* Size of the cell content header in bytes */ u16 nLocal; /* Amount of payload held locally */ u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ u16 nSize; /* Size of the cell content on the main b-tree page */};/*** A cursor is a pointer to a particular entry in the BTree.** The entry is identified by its MemPage and the index in** MemPage.aCell[] of the entry.*/struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */ void *pArg; /* First arg to xCompare() */ Pgno pgnoRoot; /* The root page of this tree */ MemPage *pPage; /* Page that contains the entry */ int idx; /* Index of the entry in pPage->aCell[] */ CellInfo info; /* A parse of the cell we are pointing at */ u8 wrFlag; /* True if writable */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ void *pKey; /* Saved key that was cursor's last known position */ i64 nKey; /* Size of pKey, or last integer key */ int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */#ifndef SQLITE_OMIT_INCRBLOB u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ Pgno *aOverflow; /* Cache of overflow page locations */#endif};/*** Potential values for BtCursor.eState.**** CURSOR_VALID:** Cursor points to a valid entry. getPayload() etc. may be called.**** CURSOR_INVALID:** Cursor does not point to a valid entry. This can happen (for example) ** because the table is empty or because BtreeCursorFirst() has not been** called.**** CURSOR_REQUIRESEEK:** The table that this cursor was opened on still exists, but has been ** modified since the cursor was last used. The cursor position is saved** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in ** this state, restoreOrClearCursorPosition() can be called to attempt to** seek the cursor to the saved position.*/#define CURSOR_INVALID 0#define CURSOR_VALID 1#define CURSOR_REQUIRESEEK 2/*** The TRACE macro will print high-level status information about the** btree operation when the global variable sqlite3_btree_trace is** enabled.*/#if SQLITE_TEST# define TRACE(X) if( sqlite3_btree_trace ){ printf X; fflush(stdout); }#else# define TRACE(X)#endif/*** Routines to read and write variable-length integers. These used to** be defined locally, but now we use the varint routines in the util.c** file.*/#define getVarint sqlite3GetVarint#define getVarint32(A,B) ((*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B))#define putVarint sqlite3PutVarint/* The database page the PENDING_BYTE occupies. This page is never used.** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They** should possibly be consolidated (presumably in pager.h).**** If disk I/O is omitted (meaning that the database is stored purely** in memory) then there is no pending byte.*/#ifdef SQLITE_OMIT_DISKIO# define PENDING_BYTE_PAGE(pBt) 0x7fffffff#else# define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)#endif/*** A linked list of the following structures is stored at BtShared.pLock.** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor ** is opened on the table with root page BtShared.iTable. Locks are removed** from this list when a transaction is committed or rolled back, or when** a btree handle is closed.*/struct BtLock { Btree *pBtree; /* Btree handle holding this lock */ Pgno iTable; /* Root page of table */ u8 eLock; /* READ_LOCK or WRITE_LOCK */ BtLock *pNext; /* Next in BtShared.pLock list */};/* Candidate values for BtLock.eLock */#define READ_LOCK 1#define WRITE_LOCK 2/*** These macros define the location of the pointer-map entry for a ** database page. The first argument to each is the number of usable** bytes on each page of the database (often 1024). The second is the** page number to look up in the pointer map.**** PTRMAP_PAGENO returns the database page number of the pointer-map** page that stores the required pointer. PTRMAP_PTROFFSET returns** the offset of the requested map entry.**** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements** this test.*/#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1))#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))/*** The pointer map is a lookup table that identifies the parent page for** each child page in the database file. The parent page is the page that** contains a pointer to the child. Every page in the database contains** 0 or 1 parent pages. (In this context 'database page' refers** to any page that is not part of the pointer map itself.) Each pointer map** entry consists of a single byte 'type' and a 4 byte parent page number.** The PTRMAP_XXX identifiers below are the valid types.**** The purpose of the pointer map is to facility moving pages from one** position in the file to another as part of autovacuum. When a page** is moved, the pointer in its parent must be updated to point to the** new location. The pointer map is used to locate the parent page quickly.**** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not** used in this case.**** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number ** is not used in this case.**** PTRMAP_OVERFLOW1: The database page is the first page in a list of ** overflow pages. The page number identifies the page that** contains the cell with a pointer to this overflow page.**** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of** overflow pages. The page-number identifies the previous** page in the overflow page list.**** PTRMAP_BTREE: The database page is a non-root btree page. The page number** identifies the parent page in the btree.*/#define PTRMAP_ROOTPAGE 1#define PTRMAP_FREEPAGE 2#define PTRMAP_OVERFLOW1 3#define PTRMAP_OVERFLOW2 4#define PTRMAP_BTREE 5/* A bunch of assert() statements to check the transaction state variables** of handle p (type Btree*) are internally consistent.*/#define btreeIntegrity(p) \ assert( p->inTrans!=TRANS_NONE || p->pBt->nTransaction<p->pBt->nRef ); \ assert( p->pBt->nTransaction<=p->pBt->nRef ); \ assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ assert( p->pBt->inTransaction>=p->inTrans ); /*** The ISAUTOVACUUM macro is used within balance_nonroot() to determine** if the database supports auto-vacuum or not. Because it is used** within an expression that is an argument to another macro ** (sqliteMallocRaw), it is not possible to use conditional compilation.** So, this macro is defined instead.*/#ifndef SQLITE_OMIT_AUTOVACUUM#define ISAUTOVACUUM (pBt->autoVacuum)#else#define ISAUTOVACUUM 0#endif/*** This structure is passed around through all the sanity checking routines** in order to keep track of some global state information.*/typedef struct IntegrityCk IntegrityCk;struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ int nPage; /* Number of pages in the database */ int *anRef; /* Number of times each page is referenced */ int mxErr; /* Stop accumulating errors when this reaches zero */ char *zErrMsg; /* An error message. NULL if no errors seen. */ int nErr; /* Number of messages written to zErrMsg so far */};/*** Read or write a two- and four-byte big-endian integer values.*/#define get2byte(x) ((x)[0]<<8 | (x)[1])#define put2byte(p,v) ((p)[0] = (v)>>8, (p)[1] = (v))#define get4byte sqlite3Get4byte#define put4byte sqlite3Put4byte/*** Internal routines that should be accessed by the btree layer only.*/int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);int sqlite3BtreeIsRootPage(MemPage *pPage);void sqlite3BtreeMoveToParent(BtCursor *pCur);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -