mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Combine the various boolean fields of the BtCursor object into a single
bit-vector. This allows setting or clearing more than one boolean at a time and makes the overflow-pgno-cache branch faster than trunk on speedtest1. FossilOrigin-Name: 968fec44d7fde3adbd3e9603e4282351f0d4bda1
This commit is contained in:
21
manifest
21
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Enable\sthe\sb-tree\scursor\sobjects\soverflow\spage-number\scache,\swhich\sis\snormally\senabled\sonly\sfor\sincr-blob\scursors,\sfor\sall\scursors.
|
C Combine\sthe\svarious\sboolean\sfields\sof\sthe\sBtCursor\sobject\sinto\sa\ssingle\nbit-vector.\s\sThis\sallows\ssetting\sor\sclearing\smore\sthan\sone\sboolean\sat\sa\ntime\sand\smakes\sthe\soverflow-pgno-cache\sbranch\sfaster\sthan\strunk\son\s\nspeedtest1.
|
||||||
D 2014-03-11T20:33:04.219
|
D 2014-03-11T23:40:44.961
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -164,9 +164,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
|||||||
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
||||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||||
F src/btree.c c748d8387789d01769e442b9da65e52ed61f408e
|
F src/btree.c 225a3f4d5511d4f5eab38a686f6c7e22290739f3
|
||||||
F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27
|
F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27
|
||||||
F src/btreeInt.h 22a8f07968ec821910ab93cc822d7f0c404c74d1
|
F src/btreeInt.h d1784d1e17d08d29e890190dbb9836fa64573381
|
||||||
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
|
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
|
||||||
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
|
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
@@ -239,7 +239,7 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
|||||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||||
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
|
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
|
||||||
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
|
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||||
F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585
|
F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585
|
||||||
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
|
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
|
||||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||||
@@ -1156,10 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 018d317b1257ce68a92908b05c9c7cf1494050d0
|
P da59198505990a4fe832be7932117c7e014955b7
|
||||||
R 9660042129e37a760044c3b5edf13974
|
R a9a97bb8415d8a76adacb051af2ccc88
|
||||||
T *branch * overflow-pgno-cache
|
U drh
|
||||||
T *sym-overflow-pgno-cache *
|
Z 90b8a93448c14945f126312bc79eea6f
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
|
||||||
Z 262878375cf61ff20b91f83b47f52bc2
|
|
||||||
|
@@ -1 +1 @@
|
|||||||
da59198505990a4fe832be7932117c7e014955b7
|
968fec44d7fde3adbd3e9603e4282351f0d4bda1
|
84
src/btree.c
84
src/btree.c
@@ -450,7 +450,7 @@ static int cursorHoldsMutex(BtCursor *p){
|
|||||||
** Invalidate the overflow cache of the cursor passed as the first argument.
|
** Invalidate the overflow cache of the cursor passed as the first argument.
|
||||||
** on the shared btree structure pBt.
|
** on the shared btree structure pBt.
|
||||||
*/
|
*/
|
||||||
#define invalidateOverflowCache(pCur) (pCur->bOvflValid = 0)
|
#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Invalidate the overflow page-list cache for all cursors opened
|
** Invalidate the overflow page-list cache for all cursors opened
|
||||||
@@ -487,7 +487,7 @@ static void invalidateIncrblobCursors(
|
|||||||
BtShared *pBt = pBtree->pBt;
|
BtShared *pBt = pBtree->pBt;
|
||||||
assert( sqlite3BtreeHoldsMutex(pBtree) );
|
assert( sqlite3BtreeHoldsMutex(pBtree) );
|
||||||
for(p=pBt->pCursor; p; p=p->pNext){
|
for(p=pBt->pCursor; p; p=p->pNext){
|
||||||
if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
|
if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){
|
||||||
p->eState = CURSOR_INVALID;
|
p->eState = CURSOR_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2543,7 +2543,8 @@ static int countValidCursors(BtShared *pBt, int wrOnly){
|
|||||||
BtCursor *pCur;
|
BtCursor *pCur;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
||||||
if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++;
|
if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0)
|
||||||
|
&& pCur->eState!=CURSOR_FAULT ) r++;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -3618,7 +3619,7 @@ static int btreeCursor(
|
|||||||
pCur->pKeyInfo = pKeyInfo;
|
pCur->pKeyInfo = pKeyInfo;
|
||||||
pCur->pBtree = p;
|
pCur->pBtree = p;
|
||||||
pCur->pBt = pBt;
|
pCur->pBt = pBt;
|
||||||
pCur->wrFlag = (u8)wrFlag;
|
pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
|
||||||
pCur->pNext = pBt->pCursor;
|
pCur->pNext = pBt->pCursor;
|
||||||
if( pCur->pNext ){
|
if( pCur->pNext ){
|
||||||
pCur->pNext->pPrev = pCur;
|
pCur->pNext->pPrev = pCur;
|
||||||
@@ -3727,7 +3728,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
|||||||
if( pCur->info.nSize==0 ){
|
if( pCur->info.nSize==0 ){
|
||||||
int iPage = pCur->iPage;
|
int iPage = pCur->iPage;
|
||||||
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
|
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
|
||||||
pCur->validNKey = 1;
|
pCur->curFlags |= BTCF_ValidNKey;
|
||||||
}else{
|
}else{
|
||||||
assertCellInfo(pCur);
|
assertCellInfo(pCur);
|
||||||
}
|
}
|
||||||
@@ -3737,8 +3738,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
|||||||
#define getCellInfo(pCur) \
|
#define getCellInfo(pCur) \
|
||||||
if( pCur->info.nSize==0 ){ \
|
if( pCur->info.nSize==0 ){ \
|
||||||
int iPage = pCur->iPage; \
|
int iPage = pCur->iPage; \
|
||||||
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
|
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
|
||||||
pCur->validNKey = 1; \
|
pCur->curFlags |= BTCF_ValidNKey; \
|
||||||
}else{ \
|
}else{ \
|
||||||
assertCellInfo(pCur); \
|
assertCellInfo(pCur); \
|
||||||
}
|
}
|
||||||
@@ -3987,14 +3988,14 @@ static int accessPayload(
|
|||||||
|
|
||||||
nextPage = get4byte(&aPayload[pCur->info.nLocal]);
|
nextPage = get4byte(&aPayload[pCur->info.nLocal]);
|
||||||
|
|
||||||
/* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
|
/* If the BTCF_Incrblob flag is set and the BtCursor.aOverflow[]
|
||||||
** has not been allocated, allocate it now. The array is sized at
|
** has not been allocated, allocate it now. The array is sized at
|
||||||
** one entry for each overflow page in the overflow chain. The
|
** one entry for each overflow page in the overflow chain. The
|
||||||
** page number of the first overflow page is stored in aOverflow[0],
|
** page number of the first overflow page is stored in aOverflow[0],
|
||||||
** etc. A value of 0 in the aOverflow[] array means "not yet known"
|
** etc. A value of 0 in the aOverflow[] array means "not yet known"
|
||||||
** (the cache is lazily populated).
|
** (the cache is lazily populated).
|
||||||
*/
|
*/
|
||||||
if( eOp!=2 && !pCur->bOvflValid ){
|
if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
|
||||||
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
|
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
|
||||||
if( nOvfl>pCur->nOvflAlloc ){
|
if( nOvfl>pCur->nOvflAlloc ){
|
||||||
Pgno *aNew = (Pgno*)sqlite3DbRealloc(
|
Pgno *aNew = (Pgno*)sqlite3DbRealloc(
|
||||||
@@ -4009,7 +4010,7 @@ static int accessPayload(
|
|||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
|
memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
|
||||||
pCur->bOvflValid = 1;
|
pCur->curFlags |= BTCF_ValidOvfl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4017,7 +4018,7 @@ static int accessPayload(
|
|||||||
** entry for the first required overflow page is valid, skip
|
** entry for the first required overflow page is valid, skip
|
||||||
** directly to it.
|
** directly to it.
|
||||||
*/
|
*/
|
||||||
if( pCur->bOvflValid && pCur->aOverflow[offset/ovflSize] ){
|
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){
|
||||||
iIdx = (offset/ovflSize);
|
iIdx = (offset/ovflSize);
|
||||||
nextPage = pCur->aOverflow[iIdx];
|
nextPage = pCur->aOverflow[iIdx];
|
||||||
offset = (offset%ovflSize);
|
offset = (offset%ovflSize);
|
||||||
@@ -4026,7 +4027,7 @@ static int accessPayload(
|
|||||||
for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
|
for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
|
||||||
|
|
||||||
/* If required, populate the overflow page-list cache. */
|
/* If required, populate the overflow page-list cache. */
|
||||||
if( pCur->bOvflValid ){
|
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
|
||||||
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
|
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
|
||||||
pCur->aOverflow[iIdx] = nextPage;
|
pCur->aOverflow[iIdx] = nextPage;
|
||||||
}
|
}
|
||||||
@@ -4038,7 +4039,7 @@ static int accessPayload(
|
|||||||
** page-list cache, if any, then fall back to the getOverflowPage()
|
** page-list cache, if any, then fall back to the getOverflowPage()
|
||||||
** function.
|
** function.
|
||||||
*/
|
*/
|
||||||
if( pCur->bOvflValid && pCur->aOverflow[iIdx+1] ){
|
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[iIdx+1] ){
|
||||||
nextPage = pCur->aOverflow[iIdx+1];
|
nextPage = pCur->aOverflow[iIdx+1];
|
||||||
} else
|
} else
|
||||||
rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
|
rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
|
||||||
@@ -4239,14 +4240,14 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
|||||||
return SQLITE_CORRUPT_BKPT;
|
return SQLITE_CORRUPT_BKPT;
|
||||||
}
|
}
|
||||||
rc = getAndInitPage(pBt, newPgno, &pNewPage,
|
rc = getAndInitPage(pBt, newPgno, &pNewPage,
|
||||||
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
|
(pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
pCur->apPage[i+1] = pNewPage;
|
pCur->apPage[i+1] = pNewPage;
|
||||||
pCur->aiIdx[i+1] = 0;
|
pCur->aiIdx[i+1] = 0;
|
||||||
pCur->iPage++;
|
pCur->iPage++;
|
||||||
|
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
|
if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
|
||||||
return SQLITE_CORRUPT_BKPT;
|
return SQLITE_CORRUPT_BKPT;
|
||||||
}
|
}
|
||||||
@@ -4304,7 +4305,7 @@ static void moveToParent(BtCursor *pCur){
|
|||||||
releasePage(pCur->apPage[pCur->iPage]);
|
releasePage(pCur->apPage[pCur->iPage]);
|
||||||
pCur->iPage--;
|
pCur->iPage--;
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4336,7 +4337,7 @@ static int moveToRoot(BtCursor *pCur){
|
|||||||
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
|
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
|
||||||
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
|
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
|
||||||
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
|
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
|
||||||
invalidateOverflowCache(pCur);
|
// invalidateOverflowCache(pCur);
|
||||||
if( pCur->eState>=CURSOR_REQUIRESEEK ){
|
if( pCur->eState>=CURSOR_REQUIRESEEK ){
|
||||||
if( pCur->eState==CURSOR_FAULT ){
|
if( pCur->eState==CURSOR_FAULT ){
|
||||||
assert( pCur->skipNext!=SQLITE_OK );
|
assert( pCur->skipNext!=SQLITE_OK );
|
||||||
@@ -4352,7 +4353,7 @@ static int moveToRoot(BtCursor *pCur){
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}else{
|
}else{
|
||||||
rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
|
rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
|
||||||
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
|
(pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
pCur->eState = CURSOR_INVALID;
|
pCur->eState = CURSOR_INVALID;
|
||||||
return rc;
|
return rc;
|
||||||
@@ -4379,8 +4380,7 @@ static int moveToRoot(BtCursor *pCur){
|
|||||||
|
|
||||||
pCur->aiIdx[0] = 0;
|
pCur->aiIdx[0] = 0;
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->atLast = 0;
|
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
pCur->validNKey = 0;
|
|
||||||
|
|
||||||
if( pRoot->nCell>0 ){
|
if( pRoot->nCell>0 ){
|
||||||
pCur->eState = CURSOR_VALID;
|
pCur->eState = CURSOR_VALID;
|
||||||
@@ -4443,7 +4443,7 @@ static int moveToRightmost(BtCursor *pCur){
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
|
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~BTCF_ValidNKey;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -4482,7 +4482,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
|||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
|
|
||||||
/* If the cursor already points to the last entry, this is a no-op. */
|
/* If the cursor already points to the last entry, this is a no-op. */
|
||||||
if( CURSOR_VALID==pCur->eState && pCur->atLast ){
|
if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
/* This block serves to assert() that the cursor really does point
|
/* This block serves to assert() that the cursor really does point
|
||||||
** to the last entry in the b-tree. */
|
** to the last entry in the b-tree. */
|
||||||
@@ -4505,7 +4505,12 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
|||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
rc = moveToRightmost(pCur);
|
rc = moveToRightmost(pCur);
|
||||||
pCur->atLast = rc==SQLITE_OK ?1:0;
|
if( rc==SQLITE_OK ){
|
||||||
|
pCur->curFlags |= BTCF_AtLast;
|
||||||
|
}else{
|
||||||
|
pCur->curFlags &= ~BTCF_AtLast;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@@ -4556,14 +4561,14 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
|
|
||||||
/* If the cursor is already positioned at the point we are trying
|
/* If the cursor is already positioned at the point we are trying
|
||||||
** to move to, then just return without doing any work */
|
** to move to, then just return without doing any work */
|
||||||
if( pCur->eState==CURSOR_VALID && pCur->validNKey
|
if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
|
||||||
&& pCur->apPage[0]->intKey
|
&& pCur->apPage[0]->intKey
|
||||||
){
|
){
|
||||||
if( pCur->info.nKey==intKey ){
|
if( pCur->info.nKey==intKey ){
|
||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
if( pCur->atLast && pCur->info.nKey<intKey ){
|
if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
|
||||||
*pRes = -1;
|
*pRes = -1;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@@ -4629,7 +4634,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
if( lwr>upr ){ c = +1; break; }
|
if( lwr>upr ){ c = +1; break; }
|
||||||
}else{
|
}else{
|
||||||
assert( nCellKey==intKey );
|
assert( nCellKey==intKey );
|
||||||
pCur->validNKey = 1;
|
pCur->curFlags |= BTCF_ValidNKey;
|
||||||
pCur->info.nKey = nCellKey;
|
pCur->info.nKey = nCellKey;
|
||||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||||
if( !pPage->leaf ){
|
if( !pPage->leaf ){
|
||||||
@@ -4731,7 +4736,7 @@ moveto_next_layer:
|
|||||||
}
|
}
|
||||||
moveto_finish:
|
moveto_finish:
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4775,8 +4780,8 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
|||||||
assert( pRes!=0 );
|
assert( pRes!=0 );
|
||||||
assert( *pRes==0 || *pRes==1 );
|
assert( *pRes==0 || *pRes==1 );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
invalidateOverflowCache(pCur);
|
|
||||||
if( pCur->eState!=CURSOR_VALID ){
|
if( pCur->eState!=CURSOR_VALID ){
|
||||||
|
invalidateOverflowCache(pCur);
|
||||||
rc = restoreCursorPosition(pCur);
|
rc = restoreCursorPosition(pCur);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
@@ -4810,7 +4815,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
|||||||
testcase( idx>pPage->nCell );
|
testcase( idx>pPage->nCell );
|
||||||
|
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
if( idx>=pPage->nCell ){
|
if( idx>=pPage->nCell ){
|
||||||
if( !pPage->leaf ){
|
if( !pPage->leaf ){
|
||||||
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
|
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
|
||||||
@@ -4871,8 +4876,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
assert( pRes!=0 );
|
assert( pRes!=0 );
|
||||||
assert( *pRes==0 || *pRes==1 );
|
assert( *pRes==0 || *pRes==1 );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
invalidateOverflowCache(pCur);
|
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl);
|
||||||
pCur->atLast = 0;
|
|
||||||
if( pCur->eState!=CURSOR_VALID ){
|
if( pCur->eState!=CURSOR_VALID ){
|
||||||
if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
|
if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
|
||||||
rc = btreeRestoreCursorPosition(pCur);
|
rc = btreeRestoreCursorPosition(pCur);
|
||||||
@@ -4917,7 +4921,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
moveToParent(pCur);
|
moveToParent(pCur);
|
||||||
}
|
}
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||||
|
|
||||||
pCur->aiIdx[pCur->iPage]--;
|
pCur->aiIdx[pCur->iPage]--;
|
||||||
pPage = pCur->apPage[pCur->iPage];
|
pPage = pCur->apPage[pCur->iPage];
|
||||||
@@ -6942,7 +6946,7 @@ int sqlite3BtreeInsert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE
|
assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE
|
||||||
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||||
|
|
||||||
@@ -6975,7 +6979,7 @@ int sqlite3BtreeInsert(
|
|||||||
/* If the cursor is currently on the last row and we are appending a
|
/* 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()
|
** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
|
||||||
** call */
|
** call */
|
||||||
if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){
|
if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){
|
||||||
loc = -1;
|
loc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7028,7 +7032,7 @@ int sqlite3BtreeInsert(
|
|||||||
|
|
||||||
/* If no error has occurred and pPage has an overflow cell, call balance()
|
/* If no error has occurred and pPage has an overflow cell, call balance()
|
||||||
** to redistribute the cells within the tree. Since balance() may move
|
** to redistribute the cells within the tree. Since balance() may move
|
||||||
** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
|
** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey
|
||||||
** variables.
|
** variables.
|
||||||
**
|
**
|
||||||
** Previous versions of SQLite called moveToRoot() to move the cursor
|
** Previous versions of SQLite called moveToRoot() to move the cursor
|
||||||
@@ -7048,7 +7052,7 @@ int sqlite3BtreeInsert(
|
|||||||
*/
|
*/
|
||||||
pCur->info.nSize = 0;
|
pCur->info.nSize = 0;
|
||||||
if( rc==SQLITE_OK && pPage->nOverflow ){
|
if( rc==SQLITE_OK && pPage->nOverflow ){
|
||||||
pCur->validNKey = 0;
|
pCur->curFlags &= ~(BTCF_ValidNKey);
|
||||||
rc = balance(pCur);
|
rc = balance(pCur);
|
||||||
|
|
||||||
/* Must make sure nOverflow is reset to zero even if the balance()
|
/* Must make sure nOverflow is reset to zero even if the balance()
|
||||||
@@ -7080,7 +7084,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
|||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( pBt->inTransaction==TRANS_WRITE );
|
assert( pBt->inTransaction==TRANS_WRITE );
|
||||||
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||||
assert( pCur->wrFlag );
|
assert( pCur->curFlags & BTCF_WriteFlag );
|
||||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||||
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
|
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
|
||||||
|
|
||||||
@@ -8384,7 +8388,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
|||||||
int rc;
|
int rc;
|
||||||
assert( cursorHoldsMutex(pCsr) );
|
assert( cursorHoldsMutex(pCsr) );
|
||||||
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
||||||
assert( pCsr->isIncrblobHandle );
|
assert( pCsr->curFlags & BTCF_Incrblob );
|
||||||
|
|
||||||
rc = restoreCursorPosition(pCsr);
|
rc = restoreCursorPosition(pCsr);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -8413,7 +8417,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
|||||||
** (d) there are no conflicting read-locks, and
|
** (d) there are no conflicting read-locks, and
|
||||||
** (e) the cursor points at a valid row of an intKey table.
|
** (e) the cursor points at a valid row of an intKey table.
|
||||||
*/
|
*/
|
||||||
if( !pCsr->wrFlag ){
|
if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){
|
||||||
return SQLITE_READONLY;
|
return SQLITE_READONLY;
|
||||||
}
|
}
|
||||||
assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0
|
assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0
|
||||||
@@ -8429,7 +8433,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
|||||||
** Mark this cursor as an incremental blob cursor.
|
** Mark this cursor as an incremental blob cursor.
|
||||||
*/
|
*/
|
||||||
void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
|
void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
|
||||||
pCur->isIncrblobHandle = 1;
|
pCur->curFlags |= BTCF_Incrblob;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -496,29 +496,30 @@ struct BtCursor {
|
|||||||
BtShared *pBt; /* The BtShared this cursor points to */
|
BtShared *pBt; /* The BtShared this cursor points to */
|
||||||
BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
|
BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
|
||||||
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
||||||
#ifndef SQLITE_OMIT_INCRBLOB
|
|
||||||
int nOvflAlloc; /* Allocated size of aOverflow[] array */
|
|
||||||
u8 bOvflValid; /* True if size and contents of aOverflow[] valid */
|
|
||||||
Pgno *aOverflow; /* Cache of overflow page locations */
|
Pgno *aOverflow; /* Cache of overflow page locations */
|
||||||
#endif
|
|
||||||
Pgno pgnoRoot; /* The root page of this tree */
|
|
||||||
CellInfo info; /* A parse of the cell we are pointing at */
|
CellInfo info; /* A parse of the cell we are pointing at */
|
||||||
i64 nKey; /* Size of pKey, or last integer key */
|
i64 nKey; /* Size of pKey, or last integer key */
|
||||||
void *pKey; /* Saved key that was cursor's last known position */
|
void *pKey; /* Saved key that was cursor last known position */
|
||||||
|
Pgno pgnoRoot; /* The root page of this tree */
|
||||||
|
int nOvflAlloc; /* Allocated size of aOverflow[] array */
|
||||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
||||||
u8 wrFlag; /* True if writable */
|
u8 curFlags; /* zero or more BTCF_* flags defined below */
|
||||||
u8 atLast; /* Cursor pointing to the last entry */
|
|
||||||
u8 validNKey; /* True if info.nKey is valid */
|
|
||||||
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
||||||
#ifndef SQLITE_OMIT_INCRBLOB
|
|
||||||
u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
|
|
||||||
#endif
|
|
||||||
u8 hints; /* As configured by CursorSetHints() */
|
u8 hints; /* As configured by CursorSetHints() */
|
||||||
i16 iPage; /* Index of current page in apPage */
|
i16 iPage; /* Index of current page in apPage */
|
||||||
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
||||||
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Legal values for BtCursor.curFlags
|
||||||
|
*/
|
||||||
|
#define BTCF_ValidNKey 0x01 /* True if info.nKey is valid */
|
||||||
|
#define BTCF_ValidOvfl 0x02 /* True if aOverflow is valid */
|
||||||
|
#define BTCF_AtLast 0x04 /* Cursor is pointing ot the last entry */
|
||||||
|
#define BTCF_WriteFlag 0x08 /* True if a write cursor */
|
||||||
|
#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Potential values for BtCursor.eState.
|
** Potential values for BtCursor.eState.
|
||||||
**
|
**
|
||||||
|
@@ -51,7 +51,7 @@ void sqlite3BtreeCursorList(Btree *p){
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
||||||
MemPage *pPage = pCur->apPage[pCur->iPage];
|
MemPage *pPage = pCur->apPage[pCur->iPage];
|
||||||
char *zMode = pCur->wrFlag ? "rw" : "ro";
|
char *zMode = (pCur->curFlags & BTCF_WriteFlag) ? "rw" : "ro";
|
||||||
sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
|
sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
|
||||||
pCur, pCur->pgnoRoot, zMode,
|
pCur, pCur->pgnoRoot, zMode,
|
||||||
pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage],
|
pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage],
|
||||||
|
Reference in New Issue
Block a user