mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Additional speed enhancements in btree.c. (CVS 2935)
FossilOrigin-Name: 48b550ce2ea43c7c1c59cd43d0008ba18fc0215b
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Small\sperformance\simprovement\son\ssqlite3BtreeMoveto.\s(CVS\s2934)
|
C Additional\sspeed\senhancements\sin\sbtree.c.\s(CVS\s2935)
|
||||||
D 2006-01-13T02:35:10
|
D 2006-01-13T04:31:58
|
||||||
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
||||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -34,7 +34,7 @@ F src/alter.c 4139c8f1d0f12b1759e767b1d09dd594e2b5ac1d
|
|||||||
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
||||||
F src/attach.c d4b9d8bd71d72409720946355be41cafb6c09079
|
F src/attach.c d4b9d8bd71d72409720946355be41cafb6c09079
|
||||||
F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
|
F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
|
||||||
F src/btree.c 51b54ae0182d6b2cf129bc98064f5a2c4ed30ab9
|
F src/btree.c 91943e07457ced1842ff93f331ab6bc1e277747e
|
||||||
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
||||||
F src/build.c a055974683ddc465bdc8669d43d6ab35d3dbb55f
|
F src/build.c a055974683ddc465bdc8669d43d6ab35d3dbb55f
|
||||||
F src/callback.c ba3e6cc7a6beb562e7a66f92e26fabcb21aab1e2
|
F src/callback.c ba3e6cc7a6beb562e7a66f92e26fabcb21aab1e2
|
||||||
@@ -340,7 +340,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P a64e8251a606fb2c298d7d804f3964a9155c73c5
|
P c780152f3cff9c0a13d231935ae3c2e2d28b4460
|
||||||
R 88c254e780b2ea9454333fd58253e3cf
|
R faee7b6f93f8c539141e3d35033db1a4
|
||||||
U drh
|
U drh
|
||||||
Z cf8b778aba2aa976f9c38e986b5a01cc
|
Z 5297e80bacccd6731d8a506f98111dd3
|
||||||
|
@@ -1 +1 @@
|
|||||||
c780152f3cff9c0a13d231935ae3c2e2d28b4460
|
48b550ce2ea43c7c1c59cd43d0008ba18fc0215b
|
74
src/btree.c
74
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.294 2006/01/13 02:35:10 drh Exp $
|
** $Id: btree.c,v 1.295 2006/01/13 04:31:58 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -411,7 +411,7 @@ struct BtCursor {
|
|||||||
** The table that this cursor was opened on still exists, but has been
|
** The table that this cursor was opened on still exists, but has been
|
||||||
** modified since the cursor was last used. The cursor position is saved
|
** modified since the cursor was last used. The cursor position is saved
|
||||||
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
|
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
|
||||||
** this state, restoreCursorPosition() can be called to attempt to seek
|
** this state, restoreOrClearCursorPosition() can be called to attempt to seek
|
||||||
** the cursor to the saved position.
|
** the cursor to the saved position.
|
||||||
*/
|
*/
|
||||||
#define CURSOR_INVALID 0
|
#define CURSOR_INVALID 0
|
||||||
@@ -501,7 +501,7 @@ struct BtLock {
|
|||||||
#define queryTableLock(a,b,c) SQLITE_OK
|
#define queryTableLock(a,b,c) SQLITE_OK
|
||||||
#define lockTable(a,b,c) SQLITE_OK
|
#define lockTable(a,b,c) SQLITE_OK
|
||||||
#define unlockAllTables(a)
|
#define unlockAllTables(a)
|
||||||
#define restoreCursorPosition(a,b) SQLITE_OK
|
#define restoreOrClearCursorPosition(a,b) SQLITE_OK
|
||||||
#define saveAllCursors(a,b,c) SQLITE_OK
|
#define saveAllCursors(a,b,c) SQLITE_OK
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -574,14 +574,14 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
|
|||||||
** Restore the cursor to the position it was in (or as close to as possible)
|
** Restore the cursor to the position it was in (or as close to as possible)
|
||||||
** when saveCursorPosition() was called. Note that this call deletes the
|
** when saveCursorPosition() was called. Note that this call deletes the
|
||||||
** saved position info stored by saveCursorPosition(), so there can be
|
** saved position info stored by saveCursorPosition(), so there can be
|
||||||
** at most one effective restoreCursorPosition() call after each
|
** at most one effective restoreOrClearCursorPosition() call after each
|
||||||
** saveCursorPosition().
|
** saveCursorPosition().
|
||||||
**
|
**
|
||||||
** If the second argument argument - doSeek - is false, then instead of
|
** If the second argument argument - doSeek - is false, then instead of
|
||||||
** returning the cursor to it's saved position, any saved position is deleted
|
** returning the cursor to it's saved position, any saved position is deleted
|
||||||
** and the cursor state set to CURSOR_INVALID.
|
** and the cursor state set to CURSOR_INVALID.
|
||||||
*/
|
*/
|
||||||
static int restoreCursorPosition(BtCursor *pCur, int doSeek){
|
static int restoreOrClearCursorPosition(BtCursor *pCur, int doSeek){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
if( pCur->eState==CURSOR_REQUIRESEEK ){
|
if( pCur->eState==CURSOR_REQUIRESEEK ){
|
||||||
assert( sqlite3ThreadDataReadOnly()->useSharedData );
|
assert( sqlite3ThreadDataReadOnly()->useSharedData );
|
||||||
@@ -2768,7 +2768,7 @@ void sqlite3BtreeSetCompare(
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||||
BtShared *pBt = pCur->pBtree->pBt;
|
BtShared *pBt = pCur->pBtree->pBt;
|
||||||
restoreCursorPosition(pCur, 0);
|
restoreOrClearCursorPosition(pCur, 0);
|
||||||
if( pCur->pPrev ){
|
if( pCur->pPrev ){
|
||||||
pCur->pPrev->pNext = pCur->pNext;
|
pCur->pPrev->pNext = pCur->pNext;
|
||||||
}else{
|
}else{
|
||||||
@@ -2835,7 +2835,7 @@ static void getCellInfo(BtCursor *pCur){
|
|||||||
** itself, not the number of bytes in the key.
|
** itself, not the number of bytes in the key.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
||||||
int rc = restoreCursorPosition(pCur, 1);
|
int rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
|
||||||
if( pCur->eState==CURSOR_INVALID ){
|
if( pCur->eState==CURSOR_INVALID ){
|
||||||
@@ -2856,7 +2856,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
|||||||
** the database is empty) then *pSize is set to 0.
|
** the database is empty) then *pSize is set to 0.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
||||||
int rc = restoreCursorPosition(pCur, 1);
|
int rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
|
||||||
if( pCur->eState==CURSOR_INVALID ){
|
if( pCur->eState==CURSOR_INVALID ){
|
||||||
@@ -2970,7 +2970,7 @@ static int getPayload(
|
|||||||
** the available payload.
|
** the available payload.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||||
int rc = restoreCursorPosition(pCur, 1);
|
int rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( pCur->pPage!=0 );
|
assert( pCur->pPage!=0 );
|
||||||
@@ -2994,7 +2994,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
|||||||
** the available payload.
|
** the available payload.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||||
int rc = restoreCursorPosition(pCur, 1);
|
int rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( pCur->pPage!=0 );
|
assert( pCur->pPage!=0 );
|
||||||
@@ -3164,19 +3164,25 @@ static void moveToParent(BtCursor *pCur){
|
|||||||
*/
|
*/
|
||||||
static int moveToRoot(BtCursor *pCur){
|
static int moveToRoot(BtCursor *pCur){
|
||||||
MemPage *pRoot;
|
MemPage *pRoot;
|
||||||
int rc;
|
int rc = SQLITE_OK;
|
||||||
BtShared *pBt = pCur->pBtree->pBt;
|
BtShared *pBt = pCur->pBtree->pBt;
|
||||||
|
|
||||||
if(
|
restoreOrClearCursorPosition(pCur, 0);
|
||||||
SQLITE_OK!=(rc = restoreCursorPosition(pCur, 0)) ||
|
assert( pCur->pPage );
|
||||||
SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
|
pRoot = pCur->pPage;
|
||||||
){
|
if( pRoot->pgno==pCur->pgnoRoot ){
|
||||||
pCur->eState = CURSOR_INVALID;
|
assert( pRoot->isInit );
|
||||||
return rc;
|
}else{
|
||||||
|
if(
|
||||||
|
SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
|
||||||
|
){
|
||||||
|
pCur->eState = CURSOR_INVALID;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
releasePage(pCur->pPage);
|
||||||
|
pageIntegrity(pRoot);
|
||||||
|
pCur->pPage = pRoot;
|
||||||
}
|
}
|
||||||
releasePage(pCur->pPage);
|
|
||||||
pageIntegrity(pRoot);
|
|
||||||
pCur->pPage = pRoot;
|
|
||||||
pCur->idx = 0;
|
pCur->idx = 0;
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
if( pRoot->nCell==0 && !pRoot->leaf ){
|
if( pRoot->nCell==0 && !pRoot->leaf ){
|
||||||
@@ -3194,6 +3200,9 @@ static int moveToRoot(BtCursor *pCur){
|
|||||||
/*
|
/*
|
||||||
** Move the cursor down to the left-most leaf entry beneath the
|
** Move the cursor down to the left-most leaf entry beneath the
|
||||||
** entry to which it is currently pointing.
|
** entry to which it is currently pointing.
|
||||||
|
**
|
||||||
|
** The left-most leaf is the one with the smallest key - the first
|
||||||
|
** in ascending order.
|
||||||
*/
|
*/
|
||||||
static int moveToLeftmost(BtCursor *pCur){
|
static int moveToLeftmost(BtCursor *pCur){
|
||||||
Pgno pgno;
|
Pgno pgno;
|
||||||
@@ -3216,6 +3225,9 @@ static int moveToLeftmost(BtCursor *pCur){
|
|||||||
** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
|
** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
|
||||||
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
|
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
|
||||||
** finds the right-most entry beneath the *page*.
|
** finds the right-most entry beneath the *page*.
|
||||||
|
**
|
||||||
|
** The right-most entry is the one with the largest key - the last
|
||||||
|
** key in ascending order.
|
||||||
*/
|
*/
|
||||||
static int moveToRightmost(BtCursor *pCur){
|
static int moveToRightmost(BtCursor *pCur){
|
||||||
Pgno pgno;
|
Pgno pgno;
|
||||||
@@ -3301,10 +3313,12 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
|
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
|
||||||
int rc;
|
int rc;
|
||||||
|
int tryRightmost;
|
||||||
rc = moveToRoot(pCur);
|
rc = moveToRoot(pCur);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
assert( pCur->pPage );
|
assert( pCur->pPage );
|
||||||
assert( pCur->pPage->isInit );
|
assert( pCur->pPage->isInit );
|
||||||
|
tryRightmost = pCur->pPage->intKey;
|
||||||
if( pCur->eState==CURSOR_INVALID ){
|
if( pCur->eState==CURSOR_INVALID ){
|
||||||
*pRes = -1;
|
*pRes = -1;
|
||||||
assert( pCur->pPage->nCell==0 );
|
assert( pCur->pPage->nCell==0 );
|
||||||
@@ -3327,8 +3341,11 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
|
|||||||
pCur->idx = (lwr+upr)/2;
|
pCur->idx = (lwr+upr)/2;
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
if( pPage->intKey ){
|
if( pPage->intKey ){
|
||||||
u8 *pCell = findCell(pPage, pCur->idx);
|
u8 *pCell;
|
||||||
pCell += pPage->childPtrSize;
|
if( tryRightmost ){
|
||||||
|
pCur->idx = upr;
|
||||||
|
}
|
||||||
|
pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
|
||||||
if( pPage->hasData ){
|
if( pPage->hasData ){
|
||||||
int dummy;
|
int dummy;
|
||||||
pCell += getVarint32(pCell, &dummy);
|
pCell += getVarint32(pCell, &dummy);
|
||||||
@@ -3338,6 +3355,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
|
|||||||
c = -1;
|
c = -1;
|
||||||
}else if( nCellKey>nKey ){
|
}else if( nCellKey>nKey ){
|
||||||
c = +1;
|
c = +1;
|
||||||
|
tryRightmost = 0;
|
||||||
}else{
|
}else{
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
@@ -3422,7 +3440,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
|||||||
MemPage *pPage = pCur->pPage;
|
MemPage *pPage = pCur->pPage;
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
rc = restoreCursorPosition(pCur, 1);
|
rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -3489,7 +3507,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
rc = restoreCursorPosition(pCur, 1);
|
rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -5159,8 +5177,8 @@ int sqlite3BtreeInsert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save the positions of any other cursors open on this table */
|
/* Save the positions of any other cursors open on this table */
|
||||||
|
restoreOrClearCursorPosition(pCur, 0);
|
||||||
if(
|
if(
|
||||||
SQLITE_OK!=(rc = restoreCursorPosition(pCur, 0)) ||
|
|
||||||
SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
|
SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
|
||||||
SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
|
SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
|
||||||
){
|
){
|
||||||
@@ -5246,7 +5264,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
|||||||
** that the entry will be deleted from.
|
** that the entry will be deleted from.
|
||||||
*/
|
*/
|
||||||
if(
|
if(
|
||||||
(rc = restoreCursorPosition(pCur, 1)) ||
|
(rc = restoreOrClearCursorPosition(pCur, 1)) ||
|
||||||
(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
|
(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
|
||||||
(rc = sqlite3pager_write(pPage->aData))
|
(rc = sqlite3pager_write(pPage->aData))
|
||||||
){
|
){
|
||||||
@@ -5728,7 +5746,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeFlags(BtCursor *pCur){
|
int sqlite3BtreeFlags(BtCursor *pCur){
|
||||||
/* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
|
/* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
|
||||||
** restoreCursorPosition() here.
|
** restoreOrClearCursorPosition() here.
|
||||||
*/
|
*/
|
||||||
MemPage *pPage = pCur->pPage;
|
MemPage *pPage = pCur->pPage;
|
||||||
return pPage ? pPage->aData[pPage->hdrOffset] : 0;
|
return pPage ? pPage->aData[pPage->hdrOffset] : 0;
|
||||||
@@ -5863,7 +5881,7 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
|
|||||||
MemPage *pPage = pCur->pPage;
|
MemPage *pPage = pCur->pPage;
|
||||||
BtCursor tmpCur;
|
BtCursor tmpCur;
|
||||||
|
|
||||||
int rc = restoreCursorPosition(pCur, 1);
|
int rc = restoreOrClearCursorPosition(pCur, 1);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user