Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The sqlite3BtreeInsert() routine tries to overwrite an existing cell with modified content if the new content is the same size. Pages are only dirtied if they change. This prototype works some, but still has issues. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | cell-overwrite-prototype |
Files: | files | file ages | folders |
SHA3-256: |
489451b378819621537231c1c8a07704 |
User & Date: | drh 2018-05-03 03:59:02.523 |
Context
2018-05-03
| ||
12:57 | Bug fixes in the overwrite optimization. (check-in: 0cb6cd2a6a user: drh tags: cell-overwrite-prototype) | |
03:59 | The sqlite3BtreeInsert() routine tries to overwrite an existing cell with modified content if the new content is the same size. Pages are only dirtied if they change. This prototype works some, but still has issues. (check-in: 489451b378 user: drh tags: cell-overwrite-prototype) | |
2018-05-02
| ||
15:00 | Prevent VACUUM from running any commands in sqlite_master.sql other than CREATE statements. That is all that should be there anyhow. This fixes a problem discovered by OSSFuzz. Test cases in TH3. (check-in: ab0d99d0b5 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 | if( pFree ){ sqlite3PageFree(pFree); } return rc; } /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left ** pointing at a random location. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 | if( pFree ){ sqlite3PageFree(pFree); } return rc; } /* Overwrite content from pX into pDest. Only do the write if the ** content is different from what is already there. */ static int btreeOverwriteContent( MemPage *pPage, /* MemPage on which writing will occur */ u8 *pDest, /* Pointer to the place to start writing */ const BtreePayload *pX, /* Source of data to write */ int iOffset, /* Offset of first byte to write */ int iAmt /* Number of bytes to be written */ ){ int nData = pX->nData - iOffset; if( nData<=0 ){ /* Overwritting with zeros */ int i; for(i=0; i<iAmt && pDest[i]==0; i++){} if( i<iAmt ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memset(pDest + i, 0, iAmt - i); } }else{ if( nData<iAmt ){ /* Mixed read data and zeros at the end. Make a recursive call ** to write the zeros then fall through to write the real data */ btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData, iAmt-nData); iAmt = nData; } if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt); } } return SQLITE_OK; } /* ** Overwrite the cell that cursor pCur is pointing to with fresh content ** contained in pX. */ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ int iOffset; /* Next byte of pX->pData to write */ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ int rc; /* Return code */ MemPage *pPage = pCur->pPage; /* Page being written */ BtShared *pBt; /* Btree */ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ /* Overwrite the local portion first */ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, 0, pCur->info.nLocal); if( rc ) return rc; if( pCur->info.nLocal==nTotal ) return SQLITE_OK; /* Now overwrite the overflow pages */ iOffset = pCur->info.nLocal; ovflPgno = get4byte(pCur->info.pPayload + iOffset); pBt = pPage->pBt; ovflPageSize = pBt->usableSize - 4; do{ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; if( iOffset+ovflPageSize>nTotal ){ ovflPgno = get4byte(pPage->aData + ovflPageSize); }else{ ovflPageSize = nTotal - iOffset; } rc = btreeOverwriteContent(pPage, pPage->aData, pX, iOffset, ovflPageSize); if( rc ) return rc; iOffset += ovflPageSize; sqlite3PagerUnref(pPage->pDbPage); }while( iOffset<nTotal ); return SQLITE_OK; } /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left ** pointing at a random location. ** |
︙ | ︙ | |||
8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 | assert( (flags & BTREE_SAVEPOSITION)==0 || ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ loc = 0; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ if( pX->nMem ){ | > > > > > | 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 | assert( (flags & BTREE_SAVEPOSITION)==0 || ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ /* The current is currently pointing to the entry that is to be ** overwritten */ if( pCur->info.nPayload==pX->nData+pX->nZero ){ return btreeOverwriteCell(pCur, pX); } loc = 0; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ if( pX->nMem ){ |
︙ | ︙ |