/ Check-in [f7f41818]
Login

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

Overview
Comment:Change pageInsertArray() and pageFreeArray() so that they use the CellArray object and compute cell sizes as needed, resulting in smaller and faster code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | btree-opt2
Files: files | file ages | folders
SHA1: f7f41818119bb7bfbd1f1297d294b32f32769cd3
User & Date: drh 2015-06-23 15:36:34
Context
2015-06-23
16:00
Avoid unnecessary cachedCellSize() calls in the cell partition adjustment phase of balance_nonroot(). check-in: 6319ee12 user: drh tags: btree-opt2
15:36
Change pageInsertArray() and pageFreeArray() so that they use the CellArray object and compute cell sizes as needed, resulting in smaller and faster code. check-in: f7f41818 user: drh tags: btree-opt2
14:49
Improvements to the way balance_nonroot() constructs the b.apCell array of pointers to cells. check-in: ee44bb25 user: drh tags: btree-opt2
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  6410   6410   ** cells in apCell[], then the cells do not fit and non-zero is returned.
  6411   6411   */
  6412   6412   static int pageInsertArray(
  6413   6413     MemPage *pPg,                   /* Page to add cells to */
  6414   6414     u8 *pBegin,                     /* End of cell-pointer array */
  6415   6415     u8 **ppData,                    /* IN/OUT: Page content -area pointer */
  6416   6416     u8 *pCellptr,                   /* Pointer to cell-pointer area */
         6417  +  int iFirst,                     /* Index of first cell to add */
  6417   6418     int nCell,                      /* Number of cells to add to pPg */
  6418         -  u8 **apCell,                    /* Array of cells */
  6419         -  u16 *szCell                     /* Array of cell sizes */
         6419  +  CellArray *pCArray              /* Array of cells */
  6420   6420   ){
  6421   6421     int i;
  6422   6422     u8 *aData = pPg->aData;
  6423   6423     u8 *pData = *ppData;
  6424   6424     const int bFreelist = aData[1] || aData[2];
         6425  +  int iEnd = iFirst + nCell;
  6425   6426     assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
  6426         -  for(i=0; i<nCell; i++){
  6427         -    int sz = szCell[i];
  6428         -    int rc;
         6427  +  for(i=iFirst; i<iEnd; i++){
         6428  +    int sz, rc;
  6429   6429       u8 *pSlot;
         6430  +    sz = cachedCellSize(pCArray, i);
  6430   6431       if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
  6431   6432         pData -= sz;
  6432   6433         if( pData<pBegin ) return 1;
  6433   6434         pSlot = pData;
  6434   6435       }
  6435         -    memcpy(pSlot, apCell[i], sz);
         6436  +    memcpy(pSlot, pCArray->apCell[i], sz);
  6436   6437       put2byte(pCellptr, (pSlot - aData));
  6437   6438       pCellptr += 2;
  6438   6439     }
  6439   6440     *ppData = pData;
  6440   6441     return 0;
  6441   6442   }
  6442   6443   
................................................................................
  6447   6448   ** within the body of pPg to the pPg free-list. The cell-pointers and other
  6448   6449   ** fields of the page are not updated.
  6449   6450   **
  6450   6451   ** This function returns the total number of cells added to the free-list.
  6451   6452   */
  6452   6453   static int pageFreeArray(
  6453   6454     MemPage *pPg,                   /* Page to edit */
         6455  +  int iFirst,                     /* First cell to delete */
  6454   6456     int nCell,                      /* Cells to delete */
  6455         -  u8 **apCell,                    /* Array of cells */
  6456         -  u16 *szCell                     /* Array of cell sizes */
         6457  +  CellArray *pCArray              /* Array of cells */
  6457   6458   ){
  6458   6459     u8 * const aData = pPg->aData;
  6459   6460     u8 * const pEnd = &aData[pPg->pBt->usableSize];
  6460   6461     u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  6461   6462     int nRet = 0;
  6462   6463     int i;
         6464  +  int iEnd = iFirst + nCell;
  6463   6465     u8 *pFree = 0;
  6464   6466     int szFree = 0;
  6465   6467   
  6466         -  for(i=0; i<nCell; i++){
  6467         -    u8 *pCell = apCell[i];
         6468  +  for(i=iFirst; i<iEnd; i++){
         6469  +    u8 *pCell = pCArray->apCell[i];
  6468   6470       if( pCell>=pStart && pCell<pEnd ){
  6469         -      int sz = szCell[i];
         6471  +      int sz;
         6472  +      /* No need to use cachedCellSize() here.  The sizes of all cells that
         6473  +      ** are to be freed have already been computing while deciding which
         6474  +      ** cells need freeing */
         6475  +      sz = pCArray->szCell[i];  assert( sz>0 );
  6470   6476         if( pFree!=(pCell + sz) ){
  6471   6477           if( pFree ){
  6472   6478             assert( pFree>aData && (pFree - aData)<65536 );
  6473   6479             freeSpace(pPg, (u16)(pFree - aData), szFree);
  6474   6480           }
  6475   6481           pFree = pCell;
  6476   6482           szFree = sz;
................................................................................
  6521   6527   #ifdef SQLITE_DEBUG
  6522   6528     u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  6523   6529     memcpy(pTmp, aData, pPg->pBt->usableSize);
  6524   6530   #endif
  6525   6531   
  6526   6532     /* Remove cells from the start and end of the page */
  6527   6533     if( iOld<iNew ){
  6528         -    int nShift;
  6529         -    populateCellCache(pCArray, iOld, iNew-iOld);
  6530         -    nShift = pageFreeArray(
  6531         -        pPg, iNew-iOld, &pCArray->apCell[iOld], &pCArray->szCell[iOld]
  6532         -    );
         6534  +    int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
  6533   6535       memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
  6534   6536       nCell -= nShift;
  6535   6537     }
  6536   6538     if( iNewEnd < iOldEnd ){
  6537         -    populateCellCache(pCArray, iNewEnd, iOldEnd-iNewEnd);
  6538         -    nCell -= pageFreeArray(
  6539         -        pPg, iOldEnd-iNewEnd,
  6540         -        &pCArray->apCell[iNewEnd], &pCArray->szCell[iNewEnd]
  6541         -    );
         6539  +    nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
  6542   6540     }
  6543   6541   
  6544   6542     pData = &aData[get2byteNotZero(&aData[hdr+5])];
  6545   6543     if( pData<pBegin ) goto editpage_fail;
  6546   6544   
  6547   6545     /* Add cells to the start of the page */
  6548   6546     if( iNew<iOld ){
  6549   6547       int nAdd = MIN(nNew,iOld-iNew);
  6550   6548       assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
  6551   6549       pCellptr = pPg->aCellIdx;
  6552   6550       memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
  6553         -    populateCellCache(pCArray, iNew, nAdd);
  6554   6551       if( pageInsertArray(
  6555   6552             pPg, pBegin, &pData, pCellptr,
  6556         -          nAdd, &pCArray->apCell[iNew], &pCArray->szCell[iNew]
         6553  +          iNew, nAdd, pCArray
  6557   6554       ) ) goto editpage_fail;
  6558   6555       nCell += nAdd;
  6559   6556     }
  6560   6557   
  6561   6558     /* Add any overflow cells */
  6562   6559     for(i=0; i<pPg->nOverflow; i++){
  6563   6560       int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
  6564   6561       if( iCell>=0 && iCell<nNew ){
  6565   6562         pCellptr = &pPg->aCellIdx[iCell * 2];
  6566   6563         memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
  6567   6564         nCell++;
  6568         -      (void)cachedCellSize(pCArray, iCell + iNew);
  6569   6565         if( pageInsertArray(
  6570   6566               pPg, pBegin, &pData, pCellptr,
  6571         -            1, &pCArray->apCell[iCell + iNew], &pCArray->szCell[iCell + iNew]
         6567  +            iCell+iNew, 1, pCArray
  6572   6568         ) ) goto editpage_fail;
  6573   6569       }
  6574   6570     }
  6575   6571   
  6576   6572     /* Append cells to the end of the page */
  6577   6573     pCellptr = &pPg->aCellIdx[nCell*2];
  6578         -  populateCellCache(pCArray, iNew+nCell, nNew-nCell);
  6579   6574     if( pageInsertArray(
  6580   6575           pPg, pBegin, &pData, pCellptr,
  6581         -        nNew-nCell, &pCArray->apCell[iNew+nCell], &pCArray->szCell[iNew+nCell]
         6576  +        iNew+nCell, nNew-nCell, pCArray
  6582   6577     ) ) goto editpage_fail;
  6583   6578   
  6584   6579     pPg->nCell = nNew;
  6585   6580     pPg->nOverflow = 0;
  6586   6581   
  6587   6582     put2byte(&aData[hdr+3], pPg->nCell);
  6588   6583     put2byte(&aData[hdr+5], pData - aData);