1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Experimental changes to vacuum to avoid loading large records entirely into memory. Currently only works in limited cases only - for rowid tables when the page-size does not change.

FossilOrigin-Name: c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d
This commit is contained in:
dan
2020-12-08 20:19:07 +00:00
parent 0dffe465f7
commit 036e0675e6
6 changed files with 142 additions and 27 deletions

View File

@@ -6500,6 +6500,10 @@ static int fillInCell(
/* Fill in the header. */
nHeader = pPage->childPtrSize;
if( pPage->intKey ){
if( pX->pData==(const void*)pPage->pBt->pTmpSpace ){
*pnSize = pX->nData;
return SQLITE_OK;
}
nPayload = pX->nData + pX->nZero;
pSrc = pX->pData;
nSrc = pX->nData;
@@ -8912,6 +8916,85 @@ end_insert:
return rc;
}
int sqlite3BtreeTransfer(
BtCursor *pDest,
BtCursor *pSrc,
i64 iKey,
int seekResult
){
int rc = SQLITE_OK;
BtreePayload x;
memset(&x, 0, sizeof(x));
x.nKey = iKey;
getCellInfo(pSrc);
if( pDest->pBt->usableSize!=pSrc->pBt->usableSize ){
void *pFree = 0;
x.nData = pSrc->info.nPayload;
if( pSrc->info.nLocal==pSrc->info.nPayload ){
x.pData = pSrc->info.pPayload;
}else{
x.pData = pFree = sqlite3_malloc(pSrc->info.nPayload);
if( pFree==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3BtreePayload(pSrc, 0, x.nData, pFree);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult);
}
sqlite3_free(pFree);
}else{
/* Page sizes match. This means each overflow page (if any) and the
** cell itself can be copied verbatim. */
u8 *pCell = pDest->pBt->pTmpSpace;
x.pData = pCell;
x.nData = putVarint32(pCell, pSrc->info.nPayload);
x.nData += putVarint(&pCell[x.nData], iKey);
memcpy(&pCell[x.nData], pSrc->info.pPayload, pSrc->info.nLocal);
x.nData += pSrc->info.nLocal;
assert( pSrc->info.nLocal<=pSrc->info.nPayload );
if( pSrc->info.nLocal<pSrc->info.nPayload ){
Pager *pSrcPager = pSrc->pBt->pPager;
u8 *pPgno = &pCell[x.nData];
Pgno ovfl;
x.nData += 4;
ovfl = get4byte(pSrc->info.pPayload + pSrc->info.nLocal);
do{
MemPage *pNew = 0;
Pgno pgnoNew = 0;
if( rc==SQLITE_OK ){
rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0);
put4byte(pPgno, pgnoNew);
}
if( rc==SQLITE_OK ){
pPgno = pNew->aData;
rc = sqlite3PagerWrite(pNew->pDbPage);
}
if( rc==SQLITE_OK ){
DbPage *pOrig = 0;
void *pOrigData;
rc = sqlite3PagerGet(pSrcPager, ovfl, &pOrig, PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
pOrigData = sqlite3PagerGetData(pOrig);
memcpy(pNew->aData, pOrigData, pDest->pBt->usableSize);
put4byte(pNew->aData, 0);
ovfl = get4byte(pOrigData);
}
sqlite3PagerUnref(pOrig);
}
releasePage(pNew);
}while( rc==SQLITE_OK && ovfl>0 );
}
if( rc==SQLITE_OK ){
rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult);
}
}
return rc;
}
/*
** Delete the entry that the cursor is pointing to.
**