Speed up eof checks on fts5 cursors.

FossilOrigin-Name: 3df4af5d8c28863783b0bc867abfbe31cc96f1b9
This commit is contained in:
dan 2015-07-03 19:13:56 +00:00
parent f156c9b684
commit 00a1351e55
4 changed files with 75 additions and 46 deletions

View File

@ -440,6 +440,7 @@ struct Fts5MultiSegIter {
int nSeg; /* Size of aSeg[] array */
int bRev; /* True to iterate in reverse order */
int bSkipEmpty; /* True to skip deleted entries */
int bEof; /* True at EOF */
Fts5SegIter *aSeg; /* Array of segment iterators */
Fts5CResult *aFirst; /* Current merge state (see above) */
};
@ -2222,6 +2223,9 @@ static void fts5AssertComparisonResult(
static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5MultiSegIter *pIter){
if( p->rc==SQLITE_OK ){
int i;
assert( (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof );
for(i=0; i<pIter->nSeg; i+=2){
Fts5SegIter *p1 = &pIter->aSeg[i];
Fts5SegIter *p2 = &pIter->aSeg[i+1];
@ -2230,10 +2234,9 @@ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5MultiSegIter *pIter){
}
for(i=1; i<(pIter->nSeg / 2); i+=2){
Fts5CResult *pRes = &pIter->aFirst[i];
Fts5SegIter *p1 = &pIter->aSeg[ pIter->aFirst[i*2].iFirst ];
Fts5SegIter *p2 = &pIter->aSeg[ pIter->aFirst[i*2+1].iFirst ];
Fts5CResult *pRes = &pIter->aFirst[i];
fts5AssertComparisonResult(pIter, p1, p2, pRes);
}
}
@ -2422,6 +2425,16 @@ static void fts5MultiIterAdvanced(
}
}
/*
** Sub-iterator iChanged of iterator pIter has just been advanced. It still
** points to the same term though - just a different rowid. This function
** attempts to update the contents of the pIter->aFirst[] accordingly.
** If it does so successfully, 0 is returned. Otherwise 1.
**
** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
** on the iterator instead. That function does the same as this one, except
** that it deals with more complicated cases as well.
*/
static int fts5MultiIterAdvanceRowid(
Fts5Index *p, /* FTS5 backend to iterate within */
Fts5MultiSegIter *pIter, /* Iterator to update aFirst[] array for */
@ -2453,6 +2466,13 @@ static int fts5MultiIterAdvanceRowid(
return 0;
}
/*
** Set the pIter->bEof variable based on the state of the sub-iterators.
*/
static void fts5MultiIterSetEof(Fts5MultiSegIter *pIter){
pIter->bEof = pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0;
}
/*
** Move the iterator to the next entry.
**
@ -2483,6 +2503,7 @@ static void fts5MultiIterNext(
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
){
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
fts5MultiIterSetEof(pIter);
}
fts5AssertMultiIterSetup(p, pIter);
@ -2595,6 +2616,7 @@ static void fts5MultiIterNew(
fts5MultiIterAdvanced(p, pNew, iEq, iIter);
}
}
fts5MultiIterSetEof(pNew);
fts5AssertMultiIterSetup(p, pNew);
if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
@ -2634,6 +2656,8 @@ static void fts5MultiIterNew2(
fts5SegIterLoadNPos(p, pIter);
}
pData = 0;
}else{
pNew->bEof = 1;
}
*ppOut = pNew;
@ -2647,7 +2671,10 @@ static void fts5MultiIterNew2(
** False otherwise.
*/
static int fts5MultiIterEof(Fts5Index *p, Fts5MultiSegIter *pIter){
return (p->rc || pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0);
assert( p->rc
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof
);
return (p->rc || pIter->bEof);
}
/*
@ -4401,7 +4428,7 @@ int sqlite3Fts5IndexQuery(
*/
int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
assert( pIter->pIndex->rc==SQLITE_OK );
return fts5MultiIterEof(pIter->pIndex, pIter->pMulti);
return pIter->pMulti->bEof;
}
/*
@ -4429,6 +4456,7 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){
if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
fts5DataRelease(pSeg->pLeaf);
pSeg->pLeaf = 0;
pMulti->bEof = 1;
}
}

View File

@ -438,12 +438,12 @@ static int fts5CreateMethod(
/*
** The different query plans.
*/
#define FTS5_PLAN_SCAN 1 /* No usable constraint */
#define FTS5_PLAN_MATCH 2 /* (<tbl> MATCH ?) */
#define FTS5_PLAN_MATCH 0 /* (<tbl> MATCH ?) */
#define FTS5_PLAN_SOURCE 1 /* A source cursor for SORTED_MATCH */
#define FTS5_PLAN_SPECIAL 2 /* An internal query */
#define FTS5_PLAN_SORTED_MATCH 3 /* (<tbl> MATCH ? ORDER BY rank) */
#define FTS5_PLAN_ROWID 4 /* (rowid = ?) */
#define FTS5_PLAN_SOURCE 5 /* A source cursor for SORTED_MATCH */
#define FTS5_PLAN_SPECIAL 6 /* An internal query */
#define FTS5_PLAN_SCAN 4 /* No usable constraint */
#define FTS5_PLAN_ROWID 5 /* (rowid = ?) */
/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
@ -764,41 +764,42 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
*/
static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int ePlan = pCsr->ePlan;
int bSkip = 0;
int rc;
if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
assert( (pCsr->ePlan<2)==
(pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
);
switch( ePlan ){
case FTS5_PLAN_MATCH:
case FTS5_PLAN_SOURCE:
rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
}
fts5CsrNewrow(pCsr);
break;
case FTS5_PLAN_SPECIAL: {
if( pCsr->ePlan<2 ){
int bSkip = 0;
if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
break;
}
case FTS5_PLAN_SORTED_MATCH: {
rc = fts5SorterNext(pCsr);
break;
}
default:
rc = sqlite3_step(pCsr->pStmt);
if( rc!=SQLITE_ROW ){
fts5CsrNewrow(pCsr);
}else{
switch( pCsr->ePlan ){
case FTS5_PLAN_SPECIAL: {
CsrFlagSet(pCsr, FTS5CSR_EOF);
rc = sqlite3_reset(pCsr->pStmt);
}else{
rc = SQLITE_OK;
break;
}
break;
case FTS5_PLAN_SORTED_MATCH: {
rc = fts5SorterNext(pCsr);
break;
}
default:
rc = sqlite3_step(pCsr->pStmt);
if( rc!=SQLITE_ROW ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
rc = sqlite3_reset(pCsr->pStmt);
}else{
rc = SQLITE_OK;
}
break;
}
}
return rc;

View File

@ -1,5 +1,5 @@
C Enable\suse\sof\sthe\s__builtin_bswap32()\sonly\swith\sGCC\s4.3\sand\shigher.
D 2015-07-03T17:54:49.505
C Speed\sup\seof\schecks\son\sfts5\scursors.
D 2015-07-03T19:13:56.700
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 78db7e3b643002849258892ab2a9df10c24ee63d
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -112,8 +112,8 @@ F ext/fts5/fts5_buffer.c 80f9ba4431848cb857e3d2158f5280093dcd8015
F ext/fts5/fts5_config.c b2456e9625bca41c51d54c363e369c6356895c90
F ext/fts5/fts5_expr.c d2e148345639c5a5583e0daa39a639bf298ae6a7
F ext/fts5/fts5_hash.c 219f4edd72e5cf95b19c33f1058809a18fad5229
F ext/fts5/fts5_index.c fb1f0de6b4cd02a212c0c9c5580daa64a5634035
F ext/fts5/fts5_main.c f35f445dfe7578b79243a696f30ad8154a1cd313
F ext/fts5/fts5_index.c 84c8aa1c226898b781f2cbe90040a57ddc4a4259
F ext/fts5/fts5_main.c 37b0055cb4036c4b4bb4eb36e30ebd1c21c63939
F ext/fts5/fts5_storage.c 4cae85b5287b159d9d98174a4e70adf872b0930a
F ext/fts5/fts5_tcl.c 85eb4e0d0fefa9420b78151496ad4599a1783e20
F ext/fts5/fts5_tokenize.c 30f97a8c74683797b4cd233790444fbefb3b0708
@ -1364,7 +1364,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P b9b0c1e50d77f5d6e02f43fbb100c722cb692cc5
R d6a0b54da592b5928ec9d859952e5495
U mistachkin
Z 35231e9548761f3a117648fdf36fee13
P 030f60a7ba171650ce8c0ac32dc166eab80aca32
R 2a024a904d5b19f97eab1afbe90fa7a1
U dan
Z 8ac5a178ca95670b120c3cf4b40c3d86

View File

@ -1 +1 @@
030f60a7ba171650ce8c0ac32dc166eab80aca32
3df4af5d8c28863783b0bc867abfbe31cc96f1b9