Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -7030,10 +7030,11 @@ } } 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 @@ -7474,10 +7475,42 @@ } } *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 @@ -7494,54 +7527,32 @@ ){ 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 i; int iEnd = iFirst + nCell; - int nFree = 0; - int aOfst[10]; - int aAfter[10]; + u32 aHeap[100]; + aHeap[0] = 0; for(i=iFirst; iapCell[i]; if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ - int sz; - int iAfter; - int iOfst; + 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); - iAfter = iOfst+sz; - for(j=0; j=nFree ){ - if( nFree>=sizeof(aOfst)/sizeof(aOfst[0]) ){ - for(j=0; j=90 ) btreeFreeCellsOnHeap(pPg, aHeap); nRet++; } } - for(j=0; j