⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pager.c

📁 1.编译色情sqlite源代码为dll;2.运用sqlite3数据库存储二进制数据到数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
  u8 setMaster;               /* True if a m-j name has been written to jrnl */  u8 doNotSync;               /* Boolean. While true, do not spill the cache */  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */  u8 changeCountDone;         /* Set after incrementing the change-counter */  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */  int errCode;                /* One of several kinds of errors */  int dbSize;                 /* Number of pages in the file */  int origDbSize;             /* dbSize before the current change */  int stmtSize;               /* Size of database (in pages) at stmt_begin() */  int nRec;                   /* Number of pages written to the journal */  u32 cksumInit;              /* Quasi-random value added to every checksum */  int stmtNRec;               /* Number of records in stmt subjournal */  int nExtra;                 /* Add this many bytes to each in-memory page */  int pageSize;               /* Number of bytes in a page */  int nPage;                  /* Total number of in-memory pages */  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */  int mxPage;                 /* Maximum number of pages to hold in cache */  Pgno mxPgno;                /* Maximum allowed size of the database */  u8 *aInJournal;             /* One bit for each page in the database file */  u8 *aInStmt;                /* One bit for each page in the database */  char *zFilename;            /* Name of the database file */  char *zJournal;             /* Name of the journal file */  char *zDirectory;           /* Directory hold database and journal files */  char *zStmtJrnl;            /* Name of the statement journal file */  sqlite3_file *fd, *jfd;     /* File descriptors for database and journal */  sqlite3_file *stfd;         /* File descriptor for the statement subjournal*/  BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */  PagerLruList lru;           /* LRU list of free pages */  PgHdr *pAll;                /* List of all pages */  PgHdr *pStmt;               /* List of pages in the statement subjournal */  PgHdr *pDirty;              /* List of all dirty pages */  i64 journalOff;             /* Current byte offset in the journal file */  i64 journalHdr;             /* Byte offset to previous journal header */  i64 stmtHdrOff;             /* First journal header written this statement */  i64 stmtCksum;              /* cksumInit when statement was started */  i64 stmtJSize;              /* Size of journal at stmt_begin() */  int sectorSize;             /* Assumed sector size during rollback */#ifdef SQLITE_TEST  int nHit, nMiss;            /* Cache hits and missing */  int nRead, nWrite;          /* Database pages read/written */#endif  void (*xDestructor)(DbPage*,int); /* Call this routine when freeing pages */  void (*xReiniter)(DbPage*,int);   /* Call this routine when reloading pages */#ifdef SQLITE_HAS_CODEC  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */  void *pCodecArg;            /* First argument to xCodec() */#endif  int nHash;                  /* Size of the pager hash table */  PgHdr **aHash;              /* Hash table to map page number to PgHdr */#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  Pager *pNext;               /* Doubly linked list of pagers on which */  Pager *pPrev;               /* sqlite3_release_memory() will work */  int iInUseMM;               /* Non-zero if unavailable to MM */  int iInUseDB;               /* Non-zero if in sqlite3_release_memory() */#endif  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */  char dbFileVers[16];        /* Changes whenever database file changes */};/*** The following global variables hold counters used for** testing purposes only.  These variables do not exist in** a non-testing build.  These variables are not thread-safe.*/#ifdef SQLITE_TESTint sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */int sqlite3_pager_pgfree_count = 0;    /* Number of cache pages freed */# define PAGER_INCR(v)  v++#else# define PAGER_INCR(v)#endif/*** The following variable points to the head of a double-linked list** of all pagers that are eligible for page stealing by the** sqlite3_release_memory() interface.  Access to this list is** protected by the SQLITE_MUTEX_STATIC_MEM2 mutex.*/#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENTstatic Pager *sqlite3PagerList = 0;static PagerLruList sqlite3LruPageList = {0, 0, 0};#endif/*** Journal files begin with the following magic string.  The data** was obtained from /dev/random.  It is used only as a sanity check.**** Since version 2.8.0, the journal format contains additional sanity** checking information.  If the power fails while the journal is begin** written, semi-random garbage data might appear in the journal** file after power is restored.  If an attempt is then made** to roll the journal back, the database could be corrupted.  The additional** sanity checking data is an attempt to discover the garbage in the** journal and ignore it.**** The sanity checking information for the new journal format consists** of a 32-bit checksum on each page of data.  The checksum covers both** the page number and the pPager->pageSize bytes of data for the page.** This cksum is initialized to a 32-bit random value that appears in the** journal file right after the header.  The random initializer is important,** because garbage data that appears at the end of a journal is likely** data that was once in other files that have now been deleted.  If the** garbage data came from an obsolete journal file, the checksums might** be correct.  But by initializing the checksum to random value which** is different for every journal, we minimize that risk.*/static const unsigned char aJournalMagic[] = {  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,};/*** The size of the header and of each page in the journal is determined** by the following macros.*/#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)/*** The journal header size for this pager. In the future, this could be** set to some value read from the disk controller. The important** characteristic is that it is the same size as a disk sector.*/#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)/*** The macro MEMDB is true if we are dealing with an in-memory database.** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,** the value of MEMDB will be a constant and the compiler will optimize** out code that would never execute.*/#ifdef SQLITE_OMIT_MEMORYDB# define MEMDB 0#else# define MEMDB pPager->memDb#endif/*** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is** reserved for working around a windows/posix incompatibility). It is** used in the journal to signify that the remainder of the journal file ** is devoted to storing a master journal name - there are no more pages to** roll back. See comments for function writeMasterJournal() for details.*//* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)/*** The maximum legal page number is (2^31 - 1).*/#define PAGER_MAX_PGNO 2147483647/*** The pagerEnter() and pagerLeave() routines acquire and release** a mutex on each pager.  The mutex is recursive.**** This is a special-purpose mutex.  It only provides mutual exclusion** between the Btree and the Memory Management sqlite3_release_memory()** function.  It does not prevent, for example, two Btrees from accessing** the same pager at the same time.  Other general-purpose mutexes in** the btree layer handle that chore.*/#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  static void pagerEnter(Pager *p){    p->iInUseDB++;    if( p->iInUseMM && p->iInUseDB==1 ){      sqlite3_mutex *mutex;      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);      p->iInUseDB = 0;      sqlite3_mutex_enter(mutex);      p->iInUseDB = 1;      sqlite3_mutex_leave(mutex);    }    assert( p->iInUseMM==0 );  }  static void pagerLeave(Pager *p){    p->iInUseDB--;    assert( p->iInUseDB>=0 );  }#else# define pagerEnter(X)# define pagerLeave(X)#endif/*** Add page pPg to the end of the linked list managed by structure** pList (pPg becomes the last entry in the list - the most recently ** used). Argument pLink should point to either pPg->free or pPg->gfree,** depending on whether pPg is being added to the pager-specific or** global LRU list.*/static void listAdd(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){  pLink->pNext = 0;  pLink->pPrev = pList->pLast;#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  assert(pLink==&pPg->free || pLink==&pPg->gfree);  assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList);#endif  if( pList->pLast ){    int iOff = (char *)pLink - (char *)pPg;    PagerLruLink *pLastLink = (PagerLruLink *)(&((u8 *)pList->pLast)[iOff]);    pLastLink->pNext = pPg;  }else{    assert(!pList->pFirst);    pList->pFirst = pPg;  }  pList->pLast = pPg;  if( !pList->pFirstSynced && pPg->needSync==0 ){    pList->pFirstSynced = pPg;  }}/*** Remove pPg from the list managed by the structure pointed to by pList.**** Argument pLink should point to either pPg->free or pPg->gfree, depending ** on whether pPg is being added to the pager-specific or global LRU list.*/static void listRemove(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){  int iOff = (char *)pLink - (char *)pPg;#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  assert(pLink==&pPg->free || pLink==&pPg->gfree);  assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList);#endif  if( pPg==pList->pFirst ){    pList->pFirst = pLink->pNext;  }  if( pPg==pList->pLast ){    pList->pLast = pLink->pPrev;  }  if( pLink->pPrev ){    PagerLruLink *pPrevLink = (PagerLruLink *)(&((u8 *)pLink->pPrev)[iOff]);    pPrevLink->pNext = pLink->pNext;  }  if( pLink->pNext ){    PagerLruLink *pNextLink = (PagerLruLink *)(&((u8 *)pLink->pNext)[iOff]);    pNextLink->pPrev = pLink->pPrev;  }  if( pPg==pList->pFirstSynced ){    PgHdr *p = pLink->pNext;    while( p && p->needSync ){      PagerLruLink *pL = (PagerLruLink *)(&((u8 *)p)[iOff]);      p = pL->pNext;    }    pList->pFirstSynced = p;  }  pLink->pNext = pLink->pPrev = 0;}/* ** Add page pPg to the list of free pages for the pager. If ** memory-management is enabled, also add the page to the global ** list of free pages.*/static void lruListAdd(PgHdr *pPg){  listAdd(&pPg->pPager->lru, &pPg->free, pPg);#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  if( !pPg->pPager->memDb ){    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));    listAdd(&sqlite3LruPageList, &pPg->gfree, pPg);    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));  }#endif}/* ** Remove page pPg from the list of free pages for the associated pager.** If memory-management is enabled, also remove pPg from the global list** of free pages.*/static void lruListRemove(PgHdr *pPg){  listRemove(&pPg->pPager->lru, &pPg->free, pPg);#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  if( !pPg->pPager->memDb ){    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));    listRemove(&sqlite3LruPageList, &pPg->gfree, pPg);    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));  }#endif}/* ** This function is called just after the needSync flag has been cleared** from all pages managed by pPager (usually because the journal file** has just been synced). It updates the pPager->lru.pFirstSynced variable** and, if memory-management is enabled, the sqlite3LruPageList.pFirstSynced** variable also.*/static void lruListSetFirstSynced(Pager *pPager){  pPager->lru.pFirstSynced = pPager->lru.pFirst;#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  if( !pPager->memDb ){    PgHdr *p;    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));    for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext);    assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced);    sqlite3LruPageList.pFirstSynced = p;    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));  }#endif}/*** Return true if page *pPg has already been written to the statement** journal (or statement snapshot has been created, if *pPg is part** of an in-memory database).*/static int pageInStatement(PgHdr *pPg){  Pager *pPager = pPg->pPager;  if( MEMDB ){    return PGHDR_TO_HIST(pPg, pPager)->inStmt;  }else{    Pgno pgno = pPg->pgno;    u8 *a = pPager->aInStmt;    return (a && (int)pgno<=pPager->stmtSize && (a[pgno/8] & (1<<(pgno&7))));  }}/*** Change the size of the pager hash table to N.  N must be a power** of two.*/static void pager_resize_hash_table(Pager *pPager, int N){  PgHdr **aHash, *pPg;  assert( N>0 && (N&(N-1))==0 );  pagerLeave(pPager);  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, pPager->aHash!=0);  aHash = sqlite3MallocZero( sizeof(aHash[0])*N );  sqlite3FaultBenign(SQLITE_FAULTINJECTOR_MALLOC, 0);  pagerEnter(pPager);  if( aHash==0 ){    /* Failure to rehash is not an error.  It is only a performance hit. */    return;  }  sqlite3_free(pPager->aHash);  pPager->nHash = N;  pPager->aHash = aHash;  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){    int h;    if( pPg->pgno==0 ){      assert( pPg->pNextHash==0 && pPg->pPrevHash==0 );      continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -