/ Check-in [1969372a]
Login

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

Overview
Comment:Small performance improvement and size reduction for pageFindSlot() - the routine in btree.c that locates a free slot for a cell on a btree page.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:1969372ac72d25cc642a0268f4bb0ae4b59f2dca568c119ef61b67183b3a8bd9
User & Date: drh 2019-02-08 22:34:59
Context
2019-02-09
19:23
Change a few assert() statements in fts3 that might fail if the database is corrupt. check-in: db74a56a user: dan tags: trunk
2019-02-08
22:34
Small performance improvement and size reduction for pageFindSlot() - the routine in btree.c that locates a free slot for a cell on a btree page. check-in: 1969372a user: drh tags: trunk
17:28
Further simplifications to sqlite3VdbeMemSetStr(). check-in: 1d212957 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  1529   1529   ** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
  1530   1530   **
  1531   1531   ** Slots on the free list that are between 1 and 3 bytes larger than nByte
  1532   1532   ** will be ignored if adding the extra space to the fragmentation count
  1533   1533   ** causes the fragmentation count to exceed 60.
  1534   1534   */
  1535   1535   static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
  1536         -  const int hdr = pPg->hdrOffset;
  1537         -  u8 * const aData = pPg->aData;
  1538         -  int iAddr = hdr + 1;
  1539         -  int pc = get2byte(&aData[iAddr]);
  1540         -  int x;
  1541         -  int usableSize = pPg->pBt->usableSize;
  1542         -  int size;            /* Size of the free slot */
         1536  +  const int hdr = pPg->hdrOffset;            /* Offset to page header */
         1537  +  u8 * const aData = pPg->aData;             /* Page data */
         1538  +  int iAddr = hdr + 1;                       /* Address of ptr to pc */
         1539  +  int pc = get2byte(&aData[iAddr]);          /* Address of a free slot */
         1540  +  int x;                                     /* Excess size of the slot */
         1541  +  int maxPC = pPg->pBt->usableSize - nByte;  /* Max address for a usable slot */
         1542  +  int size;                                  /* Size of the free slot */
  1543   1543   
  1544   1544     assert( pc>0 );
  1545         -  while( pc<=usableSize-4 ){
         1545  +  while( pc<=maxPC ){
  1546   1546       /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
  1547   1547       ** freeblock form a big-endian integer which is the size of the freeblock
  1548   1548       ** in bytes, including the 4-byte header. */
  1549   1549       size = get2byte(&aData[pc+2]);
  1550   1550       if( (x = size - nByte)>=0 ){
  1551   1551         testcase( x==4 );
  1552   1552         testcase( x==3 );
  1553         -      if( size+pc > usableSize ){
  1554         -        *pRc = SQLITE_CORRUPT_PAGE(pPg);
  1555         -        return 0;
  1556         -      }else if( x<4 ){
         1553  +      if( x<4 ){
  1557   1554           /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
  1558   1555           ** number of bytes in fragments may not exceed 60. */
  1559   1556           if( aData[hdr+7]>57 ) return 0;
  1560   1557   
  1561   1558           /* Remove the slot from the free-list. Update the number of
  1562   1559           ** fragmented bytes within the page. */
  1563   1560           memcpy(&aData[iAddr], &aData[pc], 2);
  1564   1561           aData[hdr+7] += (u8)x;
         1562  +      }else if( x+pc > maxPC ){
         1563  +        /* This slot extends off the end of the usable part of the page */
         1564  +        *pRc = SQLITE_CORRUPT_PAGE(pPg);
         1565  +        return 0;
  1565   1566         }else{
  1566   1567           /* The slot remains on the free-list. Reduce its size to account
  1567         -         ** for the portion used by the new allocation. */
         1568  +        ** for the portion used by the new allocation. */
  1568   1569           put2byte(&aData[pc+2], x);
  1569   1570         }
  1570   1571         return &aData[pc + x];
  1571   1572       }
  1572   1573       iAddr = pc;
  1573   1574       pc = get2byte(&aData[pc]);
  1574         -    if( pc<iAddr+size ) break;
         1575  +    if( pc<iAddr+size ){
         1576  +      if( pc ){
         1577  +        /* The next slot in the chain is not past the end of the current slot */
         1578  +        *pRc = SQLITE_CORRUPT_PAGE(pPg);
         1579  +      }
         1580  +      return 0;
         1581  +    }
  1575   1582     }
  1576         -  if( pc ){
         1583  +  if( pc>maxPC+nByte-4 ){
         1584  +    /* The free slot chain extends off the end of the page */
  1577   1585       *pRc = SQLITE_CORRUPT_PAGE(pPg);
  1578   1586     }
  1579         -
  1580   1587     return 0;
  1581   1588   }
  1582   1589   
  1583   1590   /*
  1584   1591   ** Allocate nByte bytes of space from within the B-Tree page passed
  1585   1592   ** as the first argument. Write into *pIdx the index into pPage->aData[]
  1586   1593   ** of the first byte of allocated space. Return either SQLITE_OK or