Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | If a free-slot is found within a page, but using that free-slot would fragment the page further and there are already at least 60 fragmented bytes, degragment the page. This matches the behaviour of the trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | defrag-opt |
Files: | files | file ages | folders |
SHA1: |
1f80f8c136ac970dcc7fb2337263dc59 |
User & Date: | dan 2014-10-27 08:02:16.531 |
Context
2014-10-27
| ||
14:26 | Optimizations aimed at reducing the number of memcpy() operations required by balance_nonroot(). (check-in: face33bea1 user: dan tags: trunk) | |
08:02 | If a free-slot is found within a page, but using that free-slot would fragment the page further and there are already at least 60 fragmented bytes, degragment the page. This matches the behaviour of the trunk. (Closed-Leaf check-in: 1f80f8c136 user: dan tags: defrag-opt) | |
07:01 | Merge trunk with this branch. (check-in: a13df3013b user: dan tags: defrag-opt) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 1238 | ** ** If no suitable space can be found on the free-list, return NULL. ** ** This function may detect corruption within pPg. If it does and argument ** pRc is non-NULL, then *pRc is set to SQLITE_CORRUPT and NULL is returned. ** Or, if corruption is detected and pRc is NULL, NULL is returned and the ** corruption goes unreported. */ | > > > > | | > > > | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 | ** ** If no suitable space can be found on the free-list, return NULL. ** ** This function may detect corruption within pPg. If it does and argument ** pRc is non-NULL, then *pRc is set to SQLITE_CORRUPT and NULL is returned. ** Or, if corruption is detected and pRc is NULL, NULL is returned and the ** corruption goes unreported. ** ** If a slot of at least nByte bytes is found but cannot be used because ** there are already at least 60 fragmented bytes on the page, return NULL. ** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true. */ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ const int hdr = pPg->hdrOffset; u8 * const aData = pPg->aData; int iAddr; int pc; int usableSize = pPg->pBt->usableSize; for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){ int size; /* Size of the free slot */ if( pc>usableSize-4 || pc<iAddr+4 ){ if( pRc ) *pRc = SQLITE_CORRUPT_BKPT; return 0; } size = get2byte(&aData[pc+2]); if( size>=nByte ){ int x = size - nByte; testcase( x==4 ); testcase( x==3 ); if( x<4 ){ if( aData[hdr+7]>=60 ){ if( pbDefrag ) *pbDefrag = 1; return 0; } /* Remove the slot from the free-list. Update the number of ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; }else if( size+pc > usableSize ){ if( pRc ) *pRc = SQLITE_CORRUPT_BKPT; return 0; |
︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 | ** freelist looking for a free slot big enough to satisfy the request. */ testcase( gap+2==top ); testcase( gap+1==top ); testcase( gap==top ); if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){ int rc = SQLITE_OK; | > | > > | 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 | ** freelist looking for a free slot big enough to satisfy the request. */ testcase( gap+2==top ); testcase( gap+1==top ); testcase( gap==top ); if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){ int rc = SQLITE_OK; int bDefrag = 0; u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag); if( rc ) return rc; if( bDefrag ) goto defragment_page; if( pSpace ){ *pIdx = pSpace - data; return SQLITE_OK; } } /* The request could not be fulfilled using a freelist slot. Check ** to see if defragmentation is necessary. */ testcase( gap+2+nByte==top ); if( gap+2+nByte>top ){ defragment_page: testcase( pPage->nCell==0 ); rc = defragmentPage(pPage); if( rc ) return rc; top = get2byteNotZero(&data[hdr+5]); assert( gap+nByte<=top ); } |
︙ | ︙ | |||
6065 6066 6067 6068 6069 6070 6071 | u8 *aData = pPg->aData; u8 *pData = *ppData; const int bFreelist = aData[1] || aData[2]; assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ for(i=0; i<nCell; i++){ int sz = szCell[i]; u8 *pSlot; | | | 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 | u8 *aData = pPg->aData; u8 *pData = *ppData; const int bFreelist = aData[1] || aData[2]; assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ for(i=0; i<nCell; i++){ int sz = szCell[i]; u8 *pSlot; if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, 0, 0))==0 ){ pData -= sz; if( pData<pBegin ) return 1; pSlot = pData; } memcpy(pSlot, apCell[i], sz); put2byte(pCellptr, (pSlot - aData)); pCellptr += 2; |
︙ | ︙ |