return;
}
}
+ assert( pExpr->pPhrase->iDoclistToken==0 );
+ pExpr->pPhrase->iDoclistToken = -1;
}else{
*pnOr += (pExpr->eType==FTSQUERY_OR);
fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc);
}
}
+static void fts3EvalPhraseMergeToken(
+ Fts3Table *pTab,
+ Fts3Phrase *p,
+ int iToken,
+ char *pList,
+ int nList
+){
+ assert( iToken!=p->iDoclistToken );
+
+ if( pList==0 ){
+ sqlite3_free(p->doclist.aAll);
+ p->doclist.aAll = 0;
+ p->doclist.nAll = 0;
+ }
+
+ else if( p->iDoclistToken<0 ){
+ p->doclist.aAll = pList;
+ p->doclist.nAll = nList;
+ }
+
+ else if( p->doclist.aAll==0 ){
+ sqlite3_free(pList);
+ }
+
+ else {
+ char *pLeft;
+ char *pRight;
+ int nLeft;
+ int nRight;
+ int nDiff;
+
+ if( p->iDoclistToken<iToken ){
+ pLeft = p->doclist.aAll;
+ nLeft = p->doclist.nAll;
+ pRight = pList;
+ nRight = nList;
+ nDiff = iToken - p->iDoclistToken;
+ }else{
+ pRight = p->doclist.aAll;
+ nRight = p->doclist.nAll;
+ pLeft = pList;
+ nLeft = nList;
+ nDiff = p->iDoclistToken - iToken;
+ }
+
+ fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight);
+ sqlite3_free(pLeft);
+ p->doclist.aAll = pRight;
+ p->doclist.nAll = nRight;
+ }
+
+ if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken;
+}
+
static int fts3EvalPhraseLoad(
Fts3Cursor *pCsr,
Fts3Phrase *p
int iToken;
int rc = SQLITE_OK;
- char *aDoclist = 0;
- int nDoclist = 0;
- int iPrev = -1;
-
for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){
Fts3PhraseToken *pToken = &p->aToken[iToken];
- assert( pToken->pSegcsr || pToken->pDeferred );
+ assert( pToken->pDeferred==0 || pToken->pSegcsr==0 );
- if( pToken->pDeferred==0 ){
+ if( pToken->pSegcsr ){
int nThis = 0;
char *pThis = 0;
rc = fts3TermSelect(pTab, pToken, p->iColumn, 1, &nThis, &pThis);
if( rc==SQLITE_OK ){
- if( pThis==0 ){
- sqlite3_free(aDoclist);
- aDoclist = 0;
- nDoclist = 0;
- break;
- }else if( aDoclist==0 ){
- aDoclist = pThis;
- nDoclist = nThis;
- }else{
- assert( iPrev>=0 );
- fts3DoclistPhraseMerge(pTab->bDescIdx,
- iToken-iPrev, aDoclist, nDoclist, pThis, &nThis
- );
- sqlite3_free(aDoclist);
- aDoclist = pThis;
- nDoclist = nThis;
- }
- iPrev = iToken;
+ fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
}
}
+ assert( pToken->pSegcsr==0 );
}
- if( rc==SQLITE_OK ){
- p->doclist.aAll = aDoclist;
- p->doclist.nAll = nDoclist;
- }else{
- sqlite3_free(aDoclist);
- }
return rc;
}
int iToken;
int rc = SQLITE_OK;
- int nMaxUndeferred = -1;
+ int nMaxUndeferred = pPhrase->iDoclistToken;
char *aPoslist = 0;
int nPoslist = 0;
int iPrev = -1;
}
}
iPrev = iToken;
- }else{
- nMaxUndeferred = iToken;
}
}
Fts3PhraseToken *pFirst = &p->aToken[0];
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- assert( p->doclist.aAll==0 );
- if( pCsr->bDesc==pTab->bDescIdx && bOptOk==1 && p->nToken==1
- && pFirst->pSegcsr && pFirst->pSegcsr->bLookup
+ if( pCsr->bDesc==pTab->bDescIdx
+ && bOptOk==1
+ && p->nToken==1
+ && pFirst->pSegcsr
+ && pFirst->pSegcsr->bLookup
){
/* Use the incremental approach. */
int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
}
}
-
typedef struct Fts3TokenAndCost Fts3TokenAndCost;
struct Fts3TokenAndCost {
- Fts3PhraseToken *pToken;
- Fts3Expr *pRoot;
+ Fts3Phrase *pPhrase; /* The phrase the token belongs to */
+ int iToken; /* Position of token in phrase */
+ Fts3PhraseToken *pToken; /* The token itself */
+ Fts3Expr *pRoot;
int nOvfl;
- int iCol;
+ int iCol; /* The column the token must match */
};
static void fts3EvalTokenCosts(
int i;
for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
Fts3TokenAndCost *pTC = (*ppTC)++;
+ pTC->pPhrase = pPhrase;
+ pTC->iToken = i;
pTC->pRoot = pRoot;
pTC->pToken = &pPhrase->aToken[i];
pTC->iCol = pPhrase->iColumn;
if( pTC->nOvfl ){
nDocEst = (pTC->nOvfl * pTab->nPgsz + pTab->nPgsz) / 10;
}else{
- /* TODO: Fix this so that the doclist need not be read twice. */
Fts3PhraseToken *pToken = pTC->pToken;
int nList = 0;
char *pList = 0;
rc = fts3TermSelect(pTab, pToken, pTC->iCol, 1, &nList, &pList);
+ assert( rc==SQLITE_OK || pList==0 );
+
if( rc==SQLITE_OK ){
nDocEst = fts3DoclistCountDocids(1, pList, nList);
- }
- sqlite3_free(pList);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3TermSegReaderCursor(pCsr,
- pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr
- );
+ fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList);
}
}
}else{
-C Add\sa\smissing\sdeclaration\sto\sfts3Int.h.
-D 2011-06-17T16:04:39.347
+C Avoid\sloading\sdoclists\sfor\sinfrequent\sterms\sthat\sare\spart\sof\sphrases\stwice.
+D 2011-06-17T17:37:31.284
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 78b02b5f0195e397c4239ef9213e5506b7d3fa97
+F ext/fts3/fts3.c f919a7966426e539b3f39f696bc94269e3726033
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h 974cf471fae5fed8ad87069cd86c1fe5a9bf6f9c
+F ext/fts3/fts3Int.h 8ece4390eb44e7179bb05c59d40f447663f5c077
F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691
F ext/fts3/fts3_expr.c 23791de01b3a5d313d76e02befd2601d4096bc2b
F ext/fts3/fts3_hash.c aad95afa01cf2a5ffaa448e4b0ab043880cd1efb
F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d
-P a117005f502482c4529661616cbb26eee1fe75d1
-R faf357353d86a944921df5db701e63d3
+P 3bfd4466f50711eb71d1a13231025ff4e1e76246
+R cd3d6544b7cd834ce139927827bd3fe8
U dan
-Z d361a7bc828cbb05e3ac27317d622fe4
+Z fa9494c386a1e1a2787b09d7f28a7b96