pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
}
+#ifdef SQLITE_DEBUG
+static void fts5AssertNodeSeekOk(
+ Fts5Data *pNode,
+ const u8 *pTerm, int nTerm, /* Term to search for */
+ int iExpectPg,
+ int bExpectDlidx
+){
+ int bDlidx;
+ int iPg;
+ int rc = SQLITE_OK;
+ Fts5NodeIter node;
+
+ fts5NodeIterInit(pNode->p, pNode->n, &node);
+ assert( node.term.n==0 );
+ iPg = node.iChild;
+ bDlidx = node.bDlidx;
+ for(fts5NodeIterNext(&rc, &node);
+ node.aData && fts5BufferCompareBlob(&node.term, pTerm, nTerm)<=0;
+ fts5NodeIterNext(&rc, &node)
+ ){
+ iPg = node.iChild;
+ bDlidx = node.bDlidx;
+ }
+ fts5NodeIterFree(&node);
+
+ assert( rc!=SQLITE_OK || iPg==iExpectPg );
+ assert( rc!=SQLITE_OK || bDlidx==bExpectDlidx );
+}
+#else
+#define fts5AssertNodeSeekOk(v,w,x,y,z)
+#endif
+
+/*
+** Argument pNode is an internal b-tree node. This function searches
+** within the node for the largest term that is smaller than or equal
+** to (pTerm/nTerm).
+**
+** It returns the associated page number. Or, if (pTerm/nTerm) is smaller
+** than all terms within the node, the leftmost child page number.
+**
+** Before returning, (*pbDlidx) is set to true if the last term on the
+** returned child page number has a doclist-index. Or left as is otherwise.
+*/
+static int fts5NodeSeek(
+ Fts5Data *pNode, /* Node to search */
+ const u8 *pTerm, int nTerm, /* Term to search for */
+ int *pbDlidx /* OUT: True if dlidx flag is set */
+){
+ int iPg;
+ u8 *pPtr = pNode->p;
+ u8 *pEnd = &pPtr[pNode->n];
+ int nMatch = 0; /* Number of bytes of pTerm already matched */
+
+ assert( *pbDlidx==0 );
+
+ pPtr += fts5GetVarint32(pPtr, iPg);
+ while( pPtr<pEnd ){
+ int nEmpty = 0;
+ int nKeep;
+ int nNew;
+
+ /* If there is a "no terms" record at pPtr, read it now. Store the
+ ** number of termless pages in nEmpty. If it indicates a doclist-index,
+ ** set (*pbDlidx) to true.*/
+ if( *pPtr<2 ){
+ *pbDlidx = (*pPtr==0x01);
+ pPtr++;
+ pPtr += fts5GetVarint32(pPtr, nEmpty);
+ }
+
+ /* Read the next "term" pointer. Set nKeep to the number of bytes to
+ ** keep from the previous term, and nNew to the number of bytes of
+ ** new data that will be appended to it. */
+ nKeep = (int)*pPtr++;
+ nNew = (int)*pPtr++;
+ if( (nKeep | nNew) & 0x0080 ){
+ pPtr -= 2;
+ pPtr += fts5GetVarint32(pPtr, nKeep);
+ pPtr += fts5GetVarint32(pPtr, nNew);
+ }
+ nKeep -= 2;
+
+ /* Compare (pTerm/nTerm) to the current term on the node (the one described
+ ** by nKeep/nNew). If the node term is larger, break out of the while()
+ ** loop.
+ **
+ ** Otherwise, if (pTerm/nTerm) is larger or the two terms are equal,
+ ** leave variable nMatch set to the size of the largest prefix common to
+ ** both terms in bytes. */
+ if( nKeep==nMatch ){
+ int nTst = MIN(nNew, nTerm-nMatch);
+ int i;
+ for(i=0; i<nTst; i++){
+ if( pTerm[nKeep+i]!=pPtr[i] ) break;
+ }
+ nMatch += i;
+ assert( nMatch<=nTerm );
+
+ if( i<nNew && (nMatch==nTerm || pPtr[i] > pTerm[nMatch]) ) break;
+ }else if( nKeep<nMatch ){
+ break;
+ }
+
+ iPg += 1 + nEmpty;
+ *pbDlidx = 0;
+ pPtr += nNew;
+ }
+
+ fts5AssertNodeSeekOk(pNode, pTerm, nTerm, iPg, *pbDlidx);
+ return iPg;
+}
+
/*
** Initialize the object pIter to point to term pTerm/nTerm within segment
** pSeg. If there is no such term in the index, the iterator is set to EOF.
/* This block sets stack variable iPg to the leaf page number that may
** contain term (pTerm/nTerm), if it is present in the segment. */
for(h=pSeg->nHeight-1; h>0; h--){
- Fts5NodeIter node; /* For iterating through internal nodes */
i64 iRowid = FTS5_SEGMENT_ROWID(pSeg->iSegid, h, iPg);
Fts5Data *pNode = fts5DataRead(p, iRowid);
if( pNode==0 ) break;
- fts5NodeIterInit(pNode->p, pNode->n, &node);
- assert( node.term.n==0 );
-
- iPg = node.iChild;
- bDlidx = node.bDlidx;
- for(fts5NodeIterNext(&p->rc, &node);
- node.aData && fts5BufferCompareBlob(&node.term, pTerm, nTerm)<=0;
- fts5NodeIterNext(&p->rc, &node)
- ){
- iPg = node.iChild;
- bDlidx = node.bDlidx;
- }
- fts5NodeIterFree(&node);
+ iPg = fts5NodeSeek(pNode, pTerm, nTerm, &bDlidx);
fts5DataRelease(pNode);
}
-C Preserve\sthe\snumber\sof\srequested\sPAGECACHE\spages\seven\sif\sthe\smemory\spointer\nor\ssize\sis\szero.\s\sEnhance\sthe\spcache1.c\sheader\scomment\sto\sexplain\sthe\smemory\nlayout\sof\sa\spage\scache\sline.
-D 2015-07-04T18:15:04.326
+C Optimize\sseek\soperations\son\sfts5\sb-trees.
+D 2015-07-04T18:44:07.139
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 017bf0511d1b2dd1db5e16488fbf75a17b526cbc
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 6564c103148e8b59d6b816f34d0b31f5f4025054
+F ext/fts5/fts5_index.c 6224454702f852392cae8755c920f93b06b09283
F ext/fts5/fts5_main.c 37b0055cb4036c4b4bb4eb36e30ebd1c21c63939
F ext/fts5/fts5_storage.c 4cae85b5287b159d9d98174a4e70adf872b0930a
F ext/fts5/fts5_tcl.c 85eb4e0d0fefa9420b78151496ad4599a1783e20
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 4e473559c9bdcf4d0b823e995a3642cd50ebd337
-R 3bd4765a55a11bf2fbafbabfd8169c43
-U drh
-Z 0199ebd97104f84a289dac04b3e8dc79
+P dacb2a615ce1c0573baf4518000454038745cf2a
+R a74787a76aedf64f2fa9d52272be4a28
+U dan
+Z 70c5b32ed488e093070d3138a449d5f1