/ Check-in [badd0873]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Performance improvements in getAndInitPage(): omit the upper bound check on page number if the page is already in cache. (CVS 5716)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: badd0873e6dffac9463b06a381b9f797a54d33e9
User & Date: drh 2008-09-18 01:08:16
Context
2008-09-18
11:18
Changes to test script io.test to work on symbian. (CVS 5717) check-in: 2b41c495 user: danielk1977 tags: trunk
01:08
Performance improvements in getAndInitPage(): omit the upper bound check on page number if the page is already in cache. (CVS 5716) check-in: badd0873 user: drh tags: trunk
2008-09-17
20:06
Speed improvements for in-memory databases by omitting flag clearing on pages where it is impossible for the flag to be set and by avoiding assert()s on non-debugging builds. Ticket #3384. (CVS 5715) check-in: a7fd9e62 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.511 2008/09/10 17:53:36 danielk1977 Exp $
           12  +** $Id: btree.c,v 1.512 2008/09/18 01:08:16 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
  1047   1047     assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
  1048   1048     pPage->maskPage = pBt->pageSize - 1;
  1049   1049     pPage->idxShift = 0;
  1050   1050     pPage->nCell = 0;
  1051   1051     pPage->isInit = 1;
  1052   1052   }
  1053   1053   
         1054  +
         1055  +/*
         1056  +** Convert a DbPage obtained from the pager into a MemPage used by
         1057  +** the btree layer.
         1058  +*/
         1059  +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
         1060  +  MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
         1061  +  pPage->aData = sqlite3PagerGetData(pDbPage);
         1062  +  pPage->pDbPage = pDbPage;
         1063  +  pPage->pBt = pBt;
         1064  +  pPage->pgno = pgno;
         1065  +  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
         1066  +  return pPage; 
         1067  +}
         1068  +
  1054   1069   /*
  1055   1070   ** Get a page from the pager.  Initialize the MemPage.pBt and
  1056   1071   ** MemPage.aData elements if needed.
  1057   1072   **
  1058   1073   ** If the noContent flag is set, it means that we do not care about
  1059   1074   ** the content of the page at this time.  So do not go to the disk
  1060   1075   ** to fetch the content.  Just fill in the content with zeros for now.
................................................................................
  1065   1080   int sqlite3BtreeGetPage(
  1066   1081     BtShared *pBt,       /* The btree */
  1067   1082     Pgno pgno,           /* Number of the page to fetch */
  1068   1083     MemPage **ppPage,    /* Return the page in this parameter */
  1069   1084     int noContent        /* Do not load page content if true */
  1070   1085   ){
  1071   1086     int rc;
  1072         -  MemPage *pPage;
  1073   1087     DbPage *pDbPage;
  1074   1088   
  1075   1089     assert( sqlite3_mutex_held(pBt->mutex) );
  1076   1090     rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
  1077   1091     if( rc ) return rc;
  1078         -  pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage);
  1079         -  pPage->aData = sqlite3PagerGetData(pDbPage);
  1080         -  pPage->pDbPage = pDbPage;
  1081         -  pPage->pBt = pBt;
  1082         -  pPage->pgno = pgno;
  1083         -  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  1084         -  *ppPage = pPage;
         1092  +  *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
  1085   1093     return SQLITE_OK;
  1086   1094   }
  1087   1095   
  1088   1096   /*
  1089   1097   ** Return the size of the database file in pages.  Or return -1 if
  1090   1098   ** there is any kind of error.
  1091   1099   */
................................................................................
  1104   1112   static int getAndInitPage(
  1105   1113     BtShared *pBt,          /* The database file */
  1106   1114     Pgno pgno,           /* Number of the page to get */
  1107   1115     MemPage **ppPage,    /* Write the page pointer here */
  1108   1116     MemPage *pParent     /* Parent of the page */
  1109   1117   ){
  1110   1118     int rc;
         1119  +  DbPage *pDbPage;
         1120  +  MemPage *pPage;
         1121  +
  1111   1122     assert( sqlite3_mutex_held(pBt->mutex) );
  1112   1123     assert( !pParent || pParent->isInit );
  1113         -  if( pgno==0 || pgno>pagerPagecount(pBt->pPager) ){
         1124  +  if( pgno==0 ){
  1114   1125       return SQLITE_CORRUPT_BKPT; 
  1115   1126     }
  1116         -  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
  1117         -  if( rc==SQLITE_OK ){
  1118         -    if( (*ppPage)->isInit==0 ){
  1119         -      rc = sqlite3BtreeInitPage(*ppPage, pParent);
  1120         -    }else if( pParent && ((*ppPage)==pParent || (*ppPage)->pParent!=pParent) ){
  1121         -      /* This condition indicates a loop in the b-tree structure (the scenario
  1122         -      ** where database corruption has caused a page to be a direct or
  1123         -      ** indirect descendant of itself).
  1124         -      */ 
  1125         -      rc = SQLITE_CORRUPT_BKPT;
  1126         -    }
  1127         -    if( rc!=SQLITE_OK ){
  1128         -      releasePage(*ppPage);
  1129         -      *ppPage = 0;
  1130         -    }
  1131         -  }
  1132         -
         1127  +
         1128  +  /* It is often the case that the page we want is already in cache.
         1129  +  ** If so, get it directly.  This saves us from having to call
         1130  +  ** pagerPagecount() to make sure pgno is within limits, which results
         1131  +  ** in a measureable performance improvements.
         1132  +  */
         1133  +  pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
         1134  +  if( pDbPage ){
         1135  +    /* Page is already in cache */
         1136  +    *ppPage = pPage = btreePageFromDbPage(pDbPage, pgno, pBt);
         1137  +    rc = SQLITE_OK;
         1138  +  }else{
         1139  +    /* Page not in cache.  Acquire it. */
         1140  +    if( pgno>pagerPagecount(pBt->pPager) ){
         1141  +      return SQLITE_CORRUPT_BKPT; 
         1142  +    }
         1143  +    rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
         1144  +    if( rc ) return rc;
         1145  +    pPage = *ppPage;
         1146  +  }
         1147  +  if( pPage->isInit==0 ){
         1148  +     rc = sqlite3BtreeInitPage(pPage, pParent);
         1149  +  }else if( pParent && (pPage==pParent || pPage->pParent!=pParent) ){
         1150  +    /* This condition indicates a loop in the b-tree structure (the scenario
         1151  +    ** where database corruption has caused a page to be a direct or
         1152  +    ** indirect descendant of itself).
         1153  +    */ 
         1154  +    rc = SQLITE_CORRUPT_BKPT;
         1155  +  }
         1156  +  if( rc!=SQLITE_OK ){
         1157  +    releasePage(pPage);
         1158  +    *ppPage = 0;
         1159  +  }
  1133   1160     return rc;
  1134   1161   }
  1135   1162   
  1136   1163   /*
  1137   1164   ** Release a MemPage.  This should be called once for each prior
  1138   1165   ** call to sqlite3BtreeGetPage.
  1139   1166   */