/ Changes On Branch deadend
Login

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

Changes In Branch deadend Excluding Merge-Ins

This is equivalent to a diff from 27c59f1ea7 to 5d7e833f25

2023-04-07
13:21
Small performance improvement in freeSpace(). (check-in: 8dc5292ee5 user: drh tags: btree-freespace-opt)
11:55
Try to use a heap to make coalescence of adjacent free slots faster when freeing space on a btree page. Turns out that the overhead of managing the heap overwhelms any performance gain and the result is slower. (Closed-Leaf check-in: 5d7e833f25 user: drh tags: deadend)
2023-04-06
20:14
Increase the size of the cache of free blocks inside of pageFreeArray() to reduce the number of calls to freeSpace(). (check-in: 27c59f1ea7 user: drh tags: btree-freespace-opt)
17:29
Work around a harmless assertion fault associated with sqlite3VdbeMemAboutToChange() such that the detection of stale values in registers is preserved in debugging builds, but we avoid a false-positive assertion fault in cases involving a virtual table with a LIMIT clause in an IN-operator loop. dbsqlfuzz 3fd70d4ab4950acf1deb8f610a7a7c67cd38713b (check-in: 56ea2c2fe6 user: drh tags: trunk)

Changes to src/btree.c.

7028
7029
7030
7031
7032
7033
7034

7035
7036
7037
7038
7039
7040
7041
      pPayload = &pOvfl->aData[4];
      spaceLeft = pBt->usableSize - 4;
    }
  }
  releasePage(pToRelease);
  return SQLITE_OK;
}


/*
** Remove the i-th cell from pPage.  This routine effects pPage only.
** The cell content is not freed or deallocated.  It is assumed that
** the cell content has been copied someplace else.  This routine just
** removes the reference to the cell from pPage.
**







>







7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
      pPayload = &pOvfl->aData[4];
      spaceLeft = pBt->usableSize - 4;
    }
  }
  releasePage(pToRelease);
  return SQLITE_OK;
}


/*
** Remove the i-th cell from pPage.  This routine effects pPage only.
** The cell content is not freed or deallocated.  It is assumed that
** the cell content has been copied someplace else.  This routine just
** removes the reference to the cell from pPage.
**
7472
7473
7474
7475
7476
7477
7478
































7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504

7505
7506
7507
7508
7509
7510

7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
      k++;
      pEnd = pCArray->apEnd[k];
    }
  }
  *ppData = pData;
  return 0;
}

































/*
** The pCArray object contains pointers to b-tree cells and their sizes.
**
** This function adds the space associated with each cell in the array
** that is currently stored within the body of pPg to the pPg free-list.
** The cell-pointers and other fields of the page are not updated.
**
** This function returns the total number of cells added to the free-list.
*/
static int pageFreeArray(
  MemPage *pPg,                   /* Page to edit */
  int iFirst,                     /* First cell to delete */
  int nCell,                      /* Cells to delete */
  CellArray *pCArray              /* Array of cells */
){
  u8 * const aData = pPg->aData;
  u8 * const pEnd = &aData[pPg->pBt->usableSize];
  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  int nRet = 0;
  int i, j;
  int iEnd = iFirst + nCell;
  int nFree = 0;
  int aOfst[10];
  int aAfter[10];


  for(i=iFirst; i<iEnd; i++){
    u8 *pCell = pCArray->apCell[i];
    if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
      int sz;
      int iAfter;
      int iOfst;

      /* No need to use cachedCellSize() here.  The sizes of all cells that
      ** are to be freed have already been computing while deciding which
      ** cells need freeing */
      sz = pCArray->szCell[i];  assert( sz>0 );
      iOfst = (u16)(pCell - aData);
      iAfter = iOfst+sz;
      for(j=0; j<nFree; j++){
        if( aOfst[j]==iAfter ){
          aOfst[j] = iOfst;
          break;
        }else if( aAfter[j]==iOfst ){
          aAfter[j] = iAfter;
          break;
        }
      }
      if( j>=nFree ){
        if( nFree>=sizeof(aOfst)/sizeof(aOfst[0]) ){
          for(j=0; j<nFree; j++){
            freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]);
          }
          nFree = 0;
        }
        aOfst[nFree] = iOfst;
        aAfter[nFree] = iAfter;
        nFree++;
      }
      nRet++;
    }
  }
  for(j=0; j<nFree; j++){
    freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]);
  }
  return nRet;
}

/*
** pCArray contains pointers to and sizes of all cells in the page being
** balanced.  The current page, pPg, has pPg->nCell cells starting with
** pCArray->apCell[iOld].  After balancing, this page should hold nNew cells







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|

<
|
<

>



|
<
|
>





|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
<
<







7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533

7534

7535
7536
7537
7538
7539
7540

7541
7542
7543
7544
7545
7546
7547
7548

7549


















7550
7551
7552
7553


7554
7555
7556
7557
7558
7559
7560
      k++;
      pEnd = pCArray->apEnd[k];
    }
  }
  *ppData = pData;
  return 0;
}

static void btreeHeapInsert(u32 *aHeap, u32 x);
static int btreeHeapPull(u32 *aHeap, u32 *pOut);

/*
** Add all of the cells on aHep to the freelist for a page.
*/
static void btreeFreeCellsOnHeap(MemPage *pPg, u32 *aHeap){
  u32 x;
  int iOfst;
  int iSize;

  assert( aHeap[0] );
  btreeHeapPull(aHeap, &x);
  iSize = x & 0xffff;
  iOfst = x>>16;
  while( aHeap[0] ){
    int iNxOfst;
    int iNxSize;
    btreeHeapPull(aHeap, &x);
    iNxSize = x & 0xffff;
    iNxOfst = x>>16;
    if( iSize+iOfst==iNxOfst ){
      iSize += iNxSize;
    }else{
      freeSpace(pPg, iOfst, iSize);
      iOfst = iNxOfst;
      iSize = iNxSize;
    }
  }
  freeSpace(pPg, iOfst, iSize);
}

/*
** The pCArray object contains pointers to b-tree cells and their sizes.
**
** This function adds the space associated with each cell in the array
** that is currently stored within the body of pPg to the pPg free-list.
** The cell-pointers and other fields of the page are not updated.
**
** This function returns the total number of cells added to the free-list.
*/
static int pageFreeArray(
  MemPage *pPg,                   /* Page to edit */
  int iFirst,                     /* First cell to delete */
  int nCell,                      /* Cells to delete */
  CellArray *pCArray              /* Array of cells */
){
  u8 * const aData = pPg->aData;
  u8 * const pEnd = &aData[pPg->pBt->usableSize];
  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  int nRet = 0;
  int i;
  int iEnd = iFirst + nCell;

  u32 aHeap[100];


  aHeap[0] = 0;
  for(i=iFirst; i<iEnd; i++){
    u8 *pCell = pCArray->apCell[i];
    if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
      u16 sz;

      u16 iOfst;

      /* No need to use cachedCellSize() here.  The sizes of all cells that
      ** are to be freed have already been computing while deciding which
      ** cells need freeing */
      sz = pCArray->szCell[i];  assert( sz>0 );
      iOfst = (u16)(pCell - aData);
      btreeHeapInsert(aHeap, (iOfst<<16)|sz);

      if( aHeap[0]>=90 ) btreeFreeCellsOnHeap(pPg, aHeap);


















      nRet++;
    }
  }
  if( aHeap[0] ) btreeFreeCellsOnHeap(pPg, aHeap);


  return nRet;
}

/*
** pCArray contains pointers to and sizes of all cells in the page being
** balanced.  The current page, pPg, has pPg->nCell cells starting with
** pCArray->apCell[iOld].  After balancing, this page should hold nNew cells