📄 btreeint.h
字号:
*/struct Btree { sqlite3 *db; /* The database connection holding this btree */ BtShared *pBt; /* Sharable content of this btree */ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ u8 sharable; /* True if we can share pBt with another db */ u8 locked; /* True if db currently has pBt locked */ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */};/*** 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.*/#define TRANS_NONE 0#define TRANS_READ 1#define TRANS_WRITE 2/*** An instance of this object represents a single database file.** ** A single database file can be in use as the same time by two** or more database connections. When two or more connections are** sharing the same database file, each connection has it own** private Btree object for the file and each of those Btrees points** to this one BtShared object. BtShared.nRef is the number of** connections currently sharing this database file.**** Fields in this structure are accessed under the BtShared.mutex** mutex, except for nRef and pNext which are accessed under the** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field** may not be modified once it is initially set as long as nRef>0.** The pSchema field may be set once under BtShared.mutex and** thereafter is unchanged as long as nRef>0.*/struct BtShared { Pager *pPager; /* The page cache */ sqlite3 *db; /* Database connection currently using this Btree */ 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 */ u8 inTransaction; /* Transaction state */ int nTransaction; /* Number of open transactions (read + write) */ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */ BusyHandler busyHdr; /* The busy handler for this btree */#ifndef SQLITE_OMIT_SHARED_CACHE int nRef; /* Number of references to this structure */ BtShared *pNext; /* Next on a list of sharable BtShared structs */ BtLock *pLock; /* List of locks held on this shared-btree struct */#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 within a particular** b-tree within a database file.**** The entry is identified by its MemPage and the index in** MemPage.aCell[] of the entry.**** When a single database file can shared by two more database connections,** but cursors cannot be shared. Each cursor is associated with a** particular database connection identified BtCursor.pBtree.db.**** Fields in this structure are accessed under the BtShared.mutex** found at self->pBt->mutex. */struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ 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.**** CURSOR_FAULT:** A unrecoverable error (an I/O error or a malloc failure) has occurred** on a different connection that shares the BtShared cache with this** cursor. The error has left the cache in an inconsistent state.** Do nothing else with this cursor. Any attempt to use the cursor** should return the error code stored in BtCursor.skip*/#define CURSOR_INVALID 0#define CURSOR_VALID 1#define CURSOR_REQUIRESEEK 2#define CURSOR_FAULT 3/*** 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->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*);#ifdef SQLITE_TESTu8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);#endifint 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 + -