aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-04-06 20:14:10 +0000
committerdrh <>2023-04-06 20:14:10 +0000
commit50dc8d972086dfbbc3ef3c7f664d58b5c44c4ac8 (patch)
tree1c78ebf4a5f04c5462473334c0f6ad4b8a31eb53 /src
parent82412051dbf9edebf7bee53770660f80e7abb3a1 (diff)
downloadsqlite-50dc8d972086dfbbc3ef3c7f664d58b5c44c4ac8.tar.gz
sqlite-50dc8d972086dfbbc3ef3c7f664d58b5c44c4ac8.zip
Increase the size of the cache of free blocks inside of pageFreeArray() to
reduce the number of calls to freeSpace(). FossilOrigin-Name: 27c59f1ea789f3ff245f23e79ded5cd71c48e3a51ffbb8c220b51101a4e69fd7
Diffstat (limited to 'src')
-rw-r--r--src/btree.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/src/btree.c b/src/btree.c
index 2f3063c3a..86ff2b466 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -7496,42 +7496,49 @@ static int pageFreeArray(
u8 * const pEnd = &aData[pPg->pBt->usableSize];
u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
int nRet = 0;
- int i;
+ int i, j;
int iEnd = iFirst + nCell;
- u8 *pFree = 0; /* \__ Parameters for pending call to */
- int szFree = 0; /* / freeSpace() */
+ 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 );
- if( pFree!=(pCell + sz) ){
- if( pFree ){
- assert( pFree>aData && (pFree - aData)<65536 );
- freeSpace(pPg, (u16)(pFree - aData), szFree);
+ 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;
}
- pFree = pCell;
- szFree = sz;
- if( pFree+sz>pEnd ){
- return 0;
+ }
+ 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;
}
- }else{
- /* The current cell is adjacent to and before the pFree cell.
- ** Combine the two regions into one to reduce the number of calls
- ** to freeSpace(). */
- pFree = pCell;
- szFree += sz;
+ aOfst[nFree] = iOfst;
+ aAfter[nFree] = iAfter;
+ nFree++;
}
nRet++;
}
}
- if( pFree ){
- assert( pFree>aData && (pFree - aData)<65536 );
- freeSpace(pPg, (u16)(pFree - aData), szFree);
+ for(j=0; j<nFree; j++){
+ freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]);
}
return nRet;
}