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) */
};
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];
}
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);
}
}
}
}
+/*
+** 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 */
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.
**
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
){
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
+ fts5MultiIterSetEof(pIter);
}
fts5AssertMultiIterSetup(p, pIter);
fts5MultiIterAdvanced(p, pNew, iEq, iIter);
}
}
+ fts5MultiIterSetEof(pNew);
fts5AssertMultiIterSetup(p, pNew);
if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
fts5SegIterLoadNPos(p, pIter);
}
pData = 0;
+ }else{
+ pNew->bEof = 1;
}
*ppOut = pNew;
** 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);
}
/*
*/
int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
assert( pIter->pIndex->rc==SQLITE_OK );
- return fts5MultiIterEof(pIter->pIndex, pIter->pMulti);
+ return pIter->pMulti->bEof;
}
/*
if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
fts5DataRelease(pSeg->pLeaf);
pSeg->pLeaf = 0;
+ pMulti->bEof = 1;
}
}
/*
** 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
*/
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;
-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
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
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
-030f60a7ba171650ce8c0ac32dc166eab80aca32
\ No newline at end of file
+3df4af5d8c28863783b0bc867abfbe31cc96f1b9
\ No newline at end of file