mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Performance optimization in the B-Tree cursor allocator btreeCursor(), making
it about 800K CPU cycles faster in speedtest1, and reducing the executable size by about 100 bytes. FossilOrigin-Name: 9df939716ace8cfe60340bbe83fc52d452ea40c29c856c588f9a1b8973282391
This commit is contained in:
74
src/btree.c
74
src/btree.c
@@ -2693,30 +2693,40 @@ static int removeFromSharingList(BtShared *pBt){
|
||||
** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
|
||||
** pointer.
|
||||
*/
|
||||
static void allocateTempSpace(BtShared *pBt){
|
||||
if( !pBt->pTmpSpace ){
|
||||
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
|
||||
|
||||
/* One of the uses of pBt->pTmpSpace is to format cells before
|
||||
** inserting them into a leaf page (function fillInCell()). If
|
||||
** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
|
||||
** by the various routines that manipulate binary cells. Which
|
||||
** can mean that fillInCell() only initializes the first 2 or 3
|
||||
** bytes of pTmpSpace, but that the first 4 bytes are copied from
|
||||
** it into a database page. This is not actually a problem, but it
|
||||
** does cause a valgrind error when the 1 or 2 bytes of unitialized
|
||||
** data is passed to system call write(). So to avoid this error,
|
||||
** zero the first 4 bytes of temp space here.
|
||||
**
|
||||
** Also: Provide four bytes of initialized space before the
|
||||
** beginning of pTmpSpace as an area available to prepend the
|
||||
** left-child pointer to the beginning of a cell.
|
||||
*/
|
||||
if( pBt->pTmpSpace ){
|
||||
memset(pBt->pTmpSpace, 0, 8);
|
||||
pBt->pTmpSpace += 4;
|
||||
}
|
||||
static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){
|
||||
assert( pBt!=0 );
|
||||
assert( pBt->pTmpSpace==0 );
|
||||
/* This routine is called only by btreeCursor() when allocating the
|
||||
** first write cursor for the BtShared object */
|
||||
assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 );
|
||||
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
|
||||
if( pBt->pTmpSpace==0 ){
|
||||
BtCursor *pCur = pBt->pCursor;
|
||||
pBt->pCursor = pCur->pNext; /* Unlink the cursor */
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
|
||||
/* One of the uses of pBt->pTmpSpace is to format cells before
|
||||
** inserting them into a leaf page (function fillInCell()). If
|
||||
** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
|
||||
** by the various routines that manipulate binary cells. Which
|
||||
** can mean that fillInCell() only initializes the first 2 or 3
|
||||
** bytes of pTmpSpace, but that the first 4 bytes are copied from
|
||||
** it into a database page. This is not actually a problem, but it
|
||||
** does cause a valgrind error when the 1 or 2 bytes of unitialized
|
||||
** data is passed to system call write(). So to avoid this error,
|
||||
** zero the first 4 bytes of temp space here.
|
||||
**
|
||||
** Also: Provide four bytes of initialized space before the
|
||||
** beginning of pTmpSpace as an area available to prepend the
|
||||
** left-child pointer to the beginning of a cell.
|
||||
*/
|
||||
if( pBt->pTmpSpace ){
|
||||
memset(pBt->pTmpSpace, 0, 8);
|
||||
pBt->pTmpSpace += 4;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4457,10 +4467,6 @@ static int btreeCursor(
|
||||
assert( pBt->pPage1 && pBt->pPage1->aData );
|
||||
assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||
|
||||
if( wrFlag ){
|
||||
allocateTempSpace(pBt);
|
||||
if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
if( iTable<=1 ){
|
||||
if( iTable<1 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
@@ -4477,19 +4483,25 @@ static int btreeCursor(
|
||||
pCur->pKeyInfo = pKeyInfo;
|
||||
pCur->pBtree = p;
|
||||
pCur->pBt = pBt;
|
||||
pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
|
||||
pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
|
||||
pCur->curFlags = 0;
|
||||
/* If there are two or more cursors on the same btree, then all such
|
||||
** cursors *must* have the BTCF_Multiple flag set. */
|
||||
for(pX=pBt->pCursor; pX; pX=pX->pNext){
|
||||
if( pX->pgnoRoot==iTable ){
|
||||
pX->curFlags |= BTCF_Multiple;
|
||||
pCur->curFlags |= BTCF_Multiple;
|
||||
pCur->curFlags = BTCF_Multiple;
|
||||
}
|
||||
}
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
pCur->pNext = pBt->pCursor;
|
||||
pBt->pCursor = pCur;
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
if( wrFlag ){
|
||||
pCur->curFlags |= BTCF_WriteFlag;
|
||||
pCur->curPagerFlags = 0;
|
||||
if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt);
|
||||
}else{
|
||||
pCur->curPagerFlags = PAGER_GET_READONLY;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static int btreeCursorWithLock(
|
||||
|
Reference in New Issue
Block a user