From: dan Date: Fri, 3 Jul 2015 19:13:56 +0000 (+0000) Subject: Speed up eof checks on fts5 cursors. X-Git-Tag: version-3.8.11~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00a1351e554b65b2bd51ba322ba260e33910af9b;p=thirdparty%2Fsqlite.git Speed up eof checks on fts5 cursors. FossilOrigin-Name: 3df4af5d8c28863783b0bc867abfbe31cc96f1b9 --- diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1cde21f437..2db148c215 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -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; inSeg; 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; } } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index aead532733..05ae344479 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -438,12 +438,12 @@ static int fts5CreateMethod( /* ** The different query plans. */ -#define FTS5_PLAN_SCAN 1 /* No usable constraint */ -#define FTS5_PLAN_MATCH 2 /* ( MATCH ?) */ +#define FTS5_PLAN_MATCH 0 /* ( 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 /* ( 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; - - 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; + assert( (pCsr->ePlan<2)== + (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) + ); - 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; diff --git a/manifest b/manifest index 7b2614fac4..e3ab480915 100644 --- a/manifest +++ b/manifest @@ -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 diff --git a/manifest.uuid b/manifest.uuid index e92b5d1a94..ee55a3b26f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -030f60a7ba171650ce8c0ac32dc166eab80aca32 \ No newline at end of file +3df4af5d8c28863783b0bc867abfbe31cc96f1b9 \ No newline at end of file