extensions/sqlite/sqlite-source/btreeInt.h
changeset 1645 27307df4d711
parent 1203 633c25ce6405
     1.1 --- a/extensions/sqlite/sqlite-source/btreeInt.h	Sun Oct 28 05:06:12 2007 +0000
     1.2 +++ b/extensions/sqlite/sqlite-source/btreeInt.h	Sun Oct 28 05:48:06 2007 +0000
     1.3 @@ -248,7 +248,7 @@
     1.4  
     1.5  /*
     1.6  ** Page type flags.  An ORed combination of these flags appear as the
     1.7 -** first byte of every BTree page.
     1.8 +** first byte of on-disk image of every BTree page.
     1.9  */
    1.10  #define PTF_INTKEY    0x01
    1.11  #define PTF_ZERODATA  0x02
    1.12 @@ -264,6 +264,9 @@
    1.13  ** walk up the BTree from any leaf to the root.  Care must be taken to
    1.14  ** unref() the parent page pointer when this page is no longer referenced.
    1.15  ** The pageDestructor() routine handles that chore.
    1.16 +**
    1.17 +** Access to all fields of this structure is controlled by the mutex
    1.18 +** stored in MemPage.pBt->mutex.
    1.19  */
    1.20  struct MemPage {
    1.21    u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
    1.22 @@ -276,8 +279,8 @@
    1.23    u8 hasData;          /* True if this page stores data */
    1.24    u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
    1.25    u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
    1.26 -  u16 maxLocal;        /* Copy of Btree.maxLocal or Btree.maxLeaf */
    1.27 -  u16 minLocal;        /* Copy of Btree.minLocal or Btree.minLeaf */
    1.28 +  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
    1.29 +  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
    1.30    u16 cellOffset;      /* Index in aData of first cell pointer */
    1.31    u16 idxParent;       /* Index in parent of this node */
    1.32    u16 nFree;           /* Number of free bytes on the page */
    1.33 @@ -286,8 +289,8 @@
    1.34      u8 *pCell;          /* Pointers to the body of the overflow cell */
    1.35      u16 idx;            /* Insert this cell before idx-th non-overflow cell */
    1.36    } aOvfl[5];
    1.37 -  BtShared *pBt;       /* Pointer back to BTree structure */
    1.38 -  u8 *aData;           /* Pointer back to the start of the page */
    1.39 +  BtShared *pBt;       /* Pointer to BtShared that this page is part of */
    1.40 +  u8 *aData;           /* Pointer to disk image of the page data */
    1.41    DbPage *pDbPage;     /* Pager page handle */
    1.42    Pgno pgno;           /* Page number for this page */
    1.43    MemPage *pParent;    /* The parent of this page.  NULL for root */
    1.44 @@ -300,11 +303,36 @@
    1.45  */
    1.46  #define EXTRA_SIZE sizeof(MemPage)
    1.47  
    1.48 -/* Btree handle */
    1.49 +/* A Btree handle
    1.50 +**
    1.51 +** A database connection contains a pointer to an instance of
    1.52 +** this object for every database file that it has open.  This structure
    1.53 +** is opaque to the database connection.  The database connection cannot
    1.54 +** see the internals of this structure and only deals with pointers to
    1.55 +** this structure.
    1.56 +**
    1.57 +** For some database files, the same underlying database cache might be 
    1.58 +** shared between multiple connections.  In that case, each contection
    1.59 +** has it own pointer to this object.  But each instance of this object
    1.60 +** points to the same BtShared object.  The database cache and the
    1.61 +** schema associated with the database file are all contained within
    1.62 +** the BtShared object.
    1.63 +**
    1.64 +** All fields in this structure are accessed under sqlite3.mutex.
    1.65 +** The pBt pointer itself may not be changed while there exists cursors 
    1.66 +** in the referenced BtShared that point back to this Btree since those
    1.67 +** cursors have to do go through this Btree to find their BtShared and
    1.68 +** they often do so without holding sqlite3.mutex.
    1.69 +*/
    1.70  struct Btree {
    1.71 -  sqlite3 *pSqlite;
    1.72 -  BtShared *pBt;
    1.73 -  u8 inTrans;            /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
    1.74 +  sqlite3 *pSqlite;  /* The database connection holding this btree */
    1.75 +  BtShared *pBt;     /* Sharable content of this btree */
    1.76 +  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
    1.77 +  u8 sharable;       /* True if we can share pBt with other pSqlite */
    1.78 +  u8 locked;         /* True if pSqlite currently has pBt locked */
    1.79 +  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
    1.80 +  Btree *pNext;      /* List of other sharable Btrees from the same pSqlite */
    1.81 +  Btree *pPrev;      /* Back pointer of the same list */
    1.82  };
    1.83  
    1.84  /*
    1.85 @@ -312,15 +340,28 @@
    1.86  **
    1.87  ** If the shared-data extension is enabled, there may be multiple users
    1.88  ** of the Btree structure. At most one of these may open a write transaction,
    1.89 -** but any number may have active read transactions. Variable Btree.pDb 
    1.90 -** points to the handle that owns any current write-transaction.
    1.91 +** but any number may have active read transactions.
    1.92  */
    1.93  #define TRANS_NONE  0
    1.94  #define TRANS_READ  1
    1.95  #define TRANS_WRITE 2
    1.96  
    1.97  /*
    1.98 -** Everything we need to know about an open database
    1.99 +** An instance of this object represents a single database file.
   1.100 +** 
   1.101 +** A single database file can be in use as the same time by two
   1.102 +** or more database connections.  When two or more connections are
   1.103 +** sharing the same database file, each connection has it own
   1.104 +** private Btree object for the file and each of those Btrees points
   1.105 +** to this one BtShared object.  BtShared.nRef is the number of
   1.106 +** connections currently sharing this database file.
   1.107 +**
   1.108 +** Fields in this structure are accessed under the BtShared.mutex
   1.109 +** mutex, except for nRef and pNext which are accessed under the
   1.110 +** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
   1.111 +** may not be modified once it is initially set as long as nRef>0.
   1.112 +** The pSchema field may be set once under BtShared.mutex and
   1.113 +** thereafter is unchanged as long as nRef>0.
   1.114  */
   1.115  struct BtShared {
   1.116    Pager *pPager;        /* The page cache */
   1.117 @@ -345,13 +386,14 @@
   1.118    int minLeaf;          /* Minimum local payload in a LEAFDATA table */
   1.119    BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
   1.120    u8 inTransaction;     /* Transaction state */
   1.121 -  int nRef;             /* Number of references to this structure */
   1.122    int nTransaction;     /* Number of open transactions (read + write) */
   1.123    void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
   1.124    void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
   1.125 +  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
   1.126  #ifndef SQLITE_OMIT_SHARED_CACHE
   1.127 +  int nRef;             /* Number of references to this structure */
   1.128 +  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
   1.129    BtLock *pLock;        /* List of locks held on this shared-btree struct */
   1.130 -  BtShared *pNext;      /* Next in ThreadData.pBtree linked list */
   1.131  #endif
   1.132  };
   1.133  
   1.134 @@ -373,12 +415,22 @@
   1.135  };
   1.136  
   1.137  /*
   1.138 -** A cursor is a pointer to a particular entry in the BTree.
   1.139 +** A cursor is a pointer to a particular entry within a particular
   1.140 +** b-tree within a database file.
   1.141 +**
   1.142  ** The entry is identified by its MemPage and the index in
   1.143  ** MemPage.aCell[] of the entry.
   1.144 +**
   1.145 +** When a single database file can shared by two more database connections,
   1.146 +** but cursors cannot be shared.  Each cursor is associated with a
   1.147 +** particular database connection identified BtCursor.pBtree.pSqlite.
   1.148 +**
   1.149 +** Fields in this structure are accessed under the BtShared.mutex
   1.150 +** found at self->pBt->mutex. 
   1.151  */
   1.152  struct BtCursor {
   1.153    Btree *pBtree;            /* The Btree to which this cursor belongs */
   1.154 +  BtShared *pBt;            /* The BtShared this cursor points to */
   1.155    BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
   1.156    int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
   1.157    void *pArg;               /* First arg to xCompare() */
   1.158 @@ -414,10 +466,18 @@
   1.159  **   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
   1.160  **   this state, restoreOrClearCursorPosition() can be called to attempt to
   1.161  **   seek the cursor to the saved position.
   1.162 +**
   1.163 +** CURSOR_FAULT:
   1.164 +**   A unrecoverable error (an I/O error or a malloc failure) has occurred
   1.165 +**   on a different connection that shares the BtShared cache with this
   1.166 +**   cursor.  The error has left the cache in an inconsistent state.
   1.167 +**   Do nothing else with this cursor.  Any attempt to use the cursor
   1.168 +**   should return the error code stored in BtCursor.skip
   1.169  */
   1.170  #define CURSOR_INVALID           0
   1.171  #define CURSOR_VALID             1
   1.172  #define CURSOR_REQUIRESEEK       2
   1.173 +#define CURSOR_FAULT             3
   1.174  
   1.175  /*
   1.176  ** The TRACE macro will print high-level status information about the
   1.177 @@ -530,8 +590,6 @@
   1.178  ** of handle p (type Btree*) are internally consistent.
   1.179  */
   1.180  #define btreeIntegrity(p) \
   1.181 -  assert( p->inTrans!=TRANS_NONE || p->pBt->nTransaction<p->pBt->nRef ); \
   1.182 -  assert( p->pBt->nTransaction<=p->pBt->nRef ); \
   1.183    assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
   1.184    assert( p->pBt->inTransaction>=p->inTrans ); 
   1.185  
   1.186 @@ -580,7 +638,9 @@
   1.187  int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
   1.188  void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
   1.189  void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);
   1.190 +#ifdef SQLITE_TEST
   1.191  u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);
   1.192 +#endif
   1.193  int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);
   1.194  void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
   1.195  void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);