/ Check-in [dee20ba9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In the pager, avoid checking for the illegal page number 0 except when creating a new page.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | pager-get-method
Files: files | file ages | folders
SHA1: dee20ba982125ea98c280ad1571789af0f393903
User & Date: drh 2016-12-13 18:34:01
Context
2016-12-13
18:47
Convert sqlite3PagerGet() into a pointer-dispatched virtual method. This makes it about 25% faster. check-in: 7f88bb44 user: drh tags: trunk
18:34
In the pager, avoid checking for the illegal page number 0 except when creating a new page. Closed-Leaf check-in: dee20ba9 user: drh tags: pager-get-method
15:53
Further refinements to the virtual method implementation of sqlite3PagerGet(). check-in: 67df4446 user: drh tags: pager-get-method
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  5362   5362     int flags           /* PAGER_GET_XXX flags */
  5363   5363   ){
  5364   5364     int rc = SQLITE_OK;
  5365   5365     PgHdr *pPg;
  5366   5366     u8 noContent;                   /* True if PAGER_GET_NOCONTENT is set */
  5367   5367     sqlite3_pcache_page *pBase;
  5368   5368   
  5369         -  if( pgno==0 ){
  5370         -    return SQLITE_CORRUPT_BKPT;
  5371         -  }
  5372   5369     assert( pPager->errCode==SQLITE_OK );
  5373   5370     assert( pPager->eState>=PAGER_READER );
  5374   5371     assert( assert_pager_state(pPager) );
  5375   5372     assert( pPager->hasHeldSharedLock==1 );
  5376         -
  5377   5373   
  5378   5374     pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
  5379   5375     if( pBase==0 ){
  5380   5376       pPg = 0;
  5381   5377       rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
  5382   5378       if( rc!=SQLITE_OK ) goto pager_acquire_err;
  5383   5379       if( pBase==0 ){
................................................................................
  5395   5391       ** the page. Return without further ado.  */
  5396   5392       assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
  5397   5393       pPager->aStat[PAGER_STAT_HIT]++;
  5398   5394       return SQLITE_OK;
  5399   5395   
  5400   5396     }else{
  5401   5397       /* The pager cache has created a new page. Its content needs to 
  5402         -    ** be initialized.  */
  5403         -
  5404         -    pPg->pPager = pPager;
  5405         -
  5406         -    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
  5407         -    ** number greater than this, or the unused locking-page, is requested. */
  5408         -    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
         5398  +    ** be initialized. But first some error checks:
         5399  +    **
         5400  +    ** (1) Minimum page number is 1
         5401  +    ** (2) The maximum page number is 2^31
         5402  +    ** (3) Never try to fetch the locking page
         5403  +    */
         5404  +    if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
  5409   5405         rc = SQLITE_CORRUPT_BKPT;
  5410   5406         goto pager_acquire_err;
  5411   5407       }
         5408  +
         5409  +    pPg->pPager = pPager;
  5412   5410   
  5413   5411       assert( !isOpen(pPager->fd) || !MEMDB );
  5414   5412       noContent = (flags & PAGER_GET_NOCONTENT)!=0;
  5415   5413       if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
  5416   5414         if( pgno>pPager->mxPgno ){
  5417   5415           rc = SQLITE_FULL;
  5418   5416           goto pager_acquire_err;

Changes to src/pcache.c.

   104    104   **
   105    105   **          assert( sqlite3PcachePageSanity(pPg) );
   106    106   */
   107    107   #if SQLITE_DEBUG
   108    108   int sqlite3PcachePageSanity(PgHdr *pPg){
   109    109     PCache *pCache;
   110    110     assert( pPg!=0 );
   111         -  assert( pPg->pgno>0 );    /* Page number is 1 or more */
          111  +  assert( pPg->pgno>0 || pPg->pPager==0 );    /* Page number is 1 or more */
   112    112     pCache = pPg->pCache;
   113    113     assert( pCache!=0 );      /* Every page has an associated PCache */
   114    114     if( pPg->flags & PGHDR_CLEAN ){
   115    115       assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
   116    116       assert( pCache->pDirty!=pPg );          /* CLEAN pages not on dirty list */
   117    117       assert( pCache->pDirtyTail!=pPg );
   118    118     }
................................................................................
   368    368   ){
   369    369     int eCreate;
   370    370     sqlite3_pcache_page *pRes;
   371    371   
   372    372     assert( pCache!=0 );
   373    373     assert( pCache->pCache!=0 );
   374    374     assert( createFlag==3 || createFlag==0 );
   375         -  assert( pgno>0 );
   376    375     assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
   377    376   
   378    377     /* eCreate defines what to do if the page does not exist.
   379    378     **    0     Do not allocate a new page.  (createFlag==0)
   380    379     **    1     Allocate a new page if doing so is inexpensive.
   381    380     **          (createFlag==1 AND bPurgeable AND pDirty)
   382    381     **    2     Allocate a new page even it doing so is difficult.