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

📄 pager.c

📁 这是一个开源的数据库系统,值得学习啊, 里面用了SQL语句,与微软的SQL SERVIER,差不了多少
💻 C
📖 第 1 页 / 共 5 页
字号:
  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;    }    h = pPg->pgno & (N-1);    pPg->pNextHash = aHash[h];    if( aHash[h] ){      aHash[h]->pPrevHash = pPg;    }    aHash[h] = pPg;    pPg->pPrevHash = 0;  }}/*** Read a 32-bit integer from the given file descriptor.  Store the integer** that is read in *pRes.  Return SQLITE_OK if everything worked, or an** error code is something goes wrong.**** All values are stored on disk as big-endian.*/static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){  unsigned char ac[4];  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);  if( rc==SQLITE_OK ){    *pRes = sqlite3Get4byte(ac);  }  return rc;}/*** Write a 32-bit integer into a string buffer in big-endian byte order.*/#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)/*** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK** on success or an error code is something goes wrong.*/static int write32bits(sqlite3_file *fd, i64 offset, u32 val){  char ac[4];  put32bits(ac, val);  return sqlite3OsWrite(fd, ac, 4, offset);}/*** If file pFd is open, call sqlite3OsUnlock() on it.*/static int osUnlock(sqlite3_file *pFd, int eLock){  if( !pFd->pMethods ){    return SQLITE_OK;  }  return sqlite3OsUnlock(pFd, eLock);}/*** This function determines whether or not the atomic-write optimization** can be used with this pager. The optimization can be used if:****  (a) the value returned by OsDeviceCharacteristics() indicates that**      a database page may be written atomically, and**  (b) the value returned by OsSectorSize() is less than or equal**      to the page size.**** If the optimization cannot be used, 0 is returned. If it can be used,** then the value returned is the size of the journal file when it** contains rollback data for exactly one page.*/#ifdef SQLITE_ENABLE_ATOMIC_WRITEstatic int jrnlBufferSize(Pager *pPager){  int dc;           /* Device characteristics */  int nSector;      /* Sector size */  int nPage;        /* Page size */  sqlite3_file *fd = pPager->fd;  if( fd->pMethods ){    dc = sqlite3OsDeviceCharacteristics(fd);    nSector = sqlite3OsSectorSize(fd);    nPage = pPager->pageSize;  }  assert(SQLITE_IOCAP_ATOMIC512==(512>>8));  assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));  if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage>>8))&&nSector<=nPage) ){    return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);  }  return 0;}#endif/*** This function should be called when an error occurs within the pager** code. The first argument is a pointer to the pager structure, the** second the error-code about to be returned by a pager API function. ** The value returned is a copy of the second argument to this function. **** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL** the error becomes persistent. All subsequent API calls on this Pager** will immediately return the same error code.*/static int pager_error(Pager *pPager, int rc){  int rc2 = rc & 0xff;  assert(       pPager->errCode==SQLITE_FULL ||       pPager->errCode==SQLITE_OK ||       (pPager->errCode & 0xff)==SQLITE_IOERR  );  if(    rc2==SQLITE_FULL ||    rc2==SQLITE_IOERR ||    rc2==SQLITE_CORRUPT  ){    pPager->errCode = rc;  }  return rc;}/*** If SQLITE_CHECK_PAGES is defined then we do some sanity checking** on the cache using a hash function.  This is used for testing** and debugging only.*/#ifdef SQLITE_CHECK_PAGES/*** Return a 32-bit hash of the page data for pPage.*/static u32 pager_datahash(int nByte, unsigned char *pData){  u32 hash = 0;  int i;  for(i=0; i<nByte; i++){    hash = (hash*1039) + pData[i];  }  return hash;}static u32 pager_pagehash(PgHdr *pPage){  return pager_datahash(pPage->pPager->pageSize,                         (unsigned char *)PGHDR_TO_DATA(pPage));}/*** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES** is defined, and NDEBUG is not defined, an assert() statement checks** that the page is either dirty or still matches the calculated page-hash.*/#define CHECK_PAGE(x) checkPage(x)static void checkPage(PgHdr *pPg){  Pager *pPager = pPg->pPager;  assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty ||       pPg->pageHash==pager_pagehash(pPg) );}#else#define pager_datahash(X,Y)  0#define pager_pagehash(X)  0#define CHECK_PAGE(x)#endif/*** When this is called the journal file for pager pPager must be open.** The master journal file name is read from the end of the file and ** written into memory supplied by the caller. **** zMaster must point to a buffer of at least nMaster bytes allocated by** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is** enough space to write the master journal name). If the master journal** name in the journal is longer than nMaster bytes (including a** nul-terminator), then this is handled as if no master journal name** were present in the journal.**** If no master journal file name is present zMaster[0] is set to 0 and** SQLITE_OK returned.*/static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, int nMaster){  int rc;  u32 len;  i64 szJ;  u32 cksum;  int i;  unsigned char aMagic[8]; /* A buffer to hold the magic header */  zMaster[0] = '\0';  rc = sqlite3OsFileSize(pJrnl, &szJ);  if( rc!=SQLITE_OK || szJ<16 ) return rc;  rc = read32bits(pJrnl, szJ-16, &len);  if( rc!=SQLITE_OK ) return rc;  if( len>=nMaster ){    return SQLITE_OK;  }  rc = read32bits(pJrnl, szJ-12, &cksum);  if( rc!=SQLITE_OK ) return rc;  rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8);  if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;  rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len);  if( rc!=SQLITE_OK ){    return rc;  }  zMaster[len] = '\0';  /* See if the checksum matches the master journal name */  for(i=0; i<len; i++){    cksum -= zMaster[i];   }  if( cksum ){    /* If the checksum doesn't add up, then one or more of the disk sectors    ** containing the master journal filename is corrupted. This means    ** definitely roll back, so just return SQLITE_OK and report a (nul)    ** master-journal filename.    */    zMaster[0] = '\0';  }     return SQLITE_OK;}/*** Seek the journal file descriptor to the next sector boundary where a** journal header may be read or written. Pager.journalOff is updated with** the new seek offset.**** i.e for a sector size of 512:**** Input Offset              Output Offset** ---------------------------------------** 0                         0** 512                       512** 100                       512** 2000                      2048** */static void seekJournalHdr(Pager *pPager){  i64 offset = 0;  i64 c = pPager->journalOff;  if( c ){    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);  }  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );  assert( offset>=c );  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );  pPager->journalOff = offset;}/*** The journal file must be open when this routine is called. A journal** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the** current location.**** The format for the journal header is as follows:** - 8 bytes: Magic identifying journal format.** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.** - 4 bytes: Random number used for page hash.** - 4 bytes: Initial database page count.** - 4 bytes: Sector size used by the process that wrote this journal.** ** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.*/static int writeJournalHdr(Pager *pPager){  char zHeader[sizeof(aJournalMagic)+16];  int rc;  if( pPager->stmtHdrOff==0 ){    pPager->stmtHdrOff = pPager->journalOff;  }  seekJournalHdr(pPager);  pPager->journalHdr = pPager->journalOff;  memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));  /*   ** Write the nRec Field - the number of page records that follow this  ** journal header. Normally, zero is written to this value at this time.  ** After the records are added to the journal (and the journal synced,   ** if in full-sync mode), the zero is overwritten with the true number  ** of records (see syncJournal()).  **  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When  ** reading the journal this value tells SQLite to assume that the  ** rest of the journal file contains valid page records. This assumption  ** is dangerous, as if a failure occured whilst writing to the journal  ** file it may contain some garbage data. There are two scenarios  ** where this risk can be ignored:  **  **   * When the pager is in no-sync mode. Corruption can follow a  **     power failure in this case anyway.  **  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees  **     that garbage data is never appended to the journal file.  */  assert(pPager->fd->pMethods||pPager->noSync);  if( (pPager->noSync)    || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)   ){    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);  }else{    put32bits(&zHeader[sizeof(aJournalMagic)], 0);  }  /* The random check-hash initialiser */   sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);  /* The initial database size */  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);  /* The assumed sector size for this process */  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);  IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader)))  rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader),pPager->journalOff);  pPager->journalOff += JOURNAL_HDR_SZ(pPager);  /* The journal header has been written successfully. Seek the journal  ** file descriptor to the end of the journal header sector.  */  if( rc==SQLITE_OK ){    IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1))    rc = sqlite3OsWrite(pPager->jfd, "\000", 1, pPager->journalOff-1);  }  return rc;}/*** The journal file must be open when this is called. A journal header file** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal** file. See comments above function writeJournalHdr() for a description of** the journal header format.**** If the header is read successfully, *nRec is set to the number of** page records following this header and *dbSize is set to the size of the** database before the transaction began, in pages. Also, pPager->cksumInit** is set to the value read from the journal header. SQLITE_OK is returned** in this case.**** If the journal header file appears to be corrupted, SQLITE_DONE is** returned and *nRec and *dbSize are not set.  If JOURNAL_HDR_SZ bytes** cannot be read from the journal file an error code is returned.*/static int readJournalHdr(

⌨️ 快捷键说明

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