Optimize seek operations on fts5 b-trees.
FossilOrigin-Name: 8cf02090ce53ec150492d77d9e5e5f27665bd34f
This commit is contained in:
parent
01c5c00c12
commit
30ae503167
@ -2012,6 +2012,118 @@ static void fts5SegIterLoadDlidx(Fts5Index *p, Fts5SegIter *pIter){
|
||||
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.
|
||||
@ -2040,24 +2152,11 @@ static void fts5SegIterSeekInit(
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
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
|
||||
@ -112,7 +112,7 @@ 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 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
|
||||
@ -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 4e473559c9bdcf4d0b823e995a3642cd50ebd337
|
||||
R 3bd4765a55a11bf2fbafbabfd8169c43
|
||||
U drh
|
||||
Z 0199ebd97104f84a289dac04b3e8dc79
|
||||
P dacb2a615ce1c0573baf4518000454038745cf2a
|
||||
R a74787a76aedf64f2fa9d52272be4a28
|
||||
U dan
|
||||
Z 70c5b32ed488e093070d3138a449d5f1
|
||||
|
@ -1 +1 @@
|
||||
dacb2a615ce1c0573baf4518000454038745cf2a
|
||||
8cf02090ce53ec150492d77d9e5e5f27665bd34f
|
Loading…
x
Reference in New Issue
Block a user