Further minor performance improvements and code-size reductions related to fts5 column filters on detail=col tables.
FossilOrigin-Name: b4ac61aeee976296e7719949cd4fb496147a29e8
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
index 6d442de..ca3feb8 100644
--- a/ext/fts5/fts5_index.c
+++ b/ext/fts5/fts5_index.c
@@ -5004,96 +5004,63 @@
}
/*
-** xSetOutputs callback used when: detail=col when there is a column filter.
-**
-** * detail=col,
-** * there is a column filter, and
-** * the table contains 32 or fewer columns.
+** xSetOutputs callback used by detail=col when there is a column filter
+** and there are 100 or more columns. Also called as a fallback from
+** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
*/
-static void fts5IterSetOutputs_Col32(Fts5Iter *pIter, Fts5SegIter *pSeg){
- Fts5Colset *pColset = pIter->pColset;
- pIter->base.iRowid = pSeg->iRowid;
-
- assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
- assert( pColset );
-
+static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
fts5BufferZero(&pIter->poslist);
- if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
- int i;
- int iPrev = 0;
- u32 m = 0;
- u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
- u8 *pEnd = (u8*)&a[pSeg->nPos];
-
- while( a<pEnd ){
- iPrev += (int)a[0] - 2;
- m |= (1 << iPrev);
- a++;
- }
-
- iPrev = 0;
- a = pIter->poslist.p;
- for(i=0; i<pColset->nCol; i++){
- int iCol = pColset->aiCol[i];
- if( m & (1 << iCol) ){
- *a++ = (iCol - iPrev) + 2;
- iPrev = iCol;
- }
- }
- pIter->poslist.n = a - pIter->poslist.p;
-
- }else{
- fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
- }
-
+ fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
+ pIter->base.iRowid = pSeg->iRowid;
pIter->base.pData = pIter->poslist.p;
pIter->base.nData = pIter->poslist.n;
}
/*
-** xSetOutputs callback used by detail=col when there is a column filter.
+** xSetOutputs callback used when:
+**
+** * detail=col,
+** * there is a column filter, and
+** * the table contains 100 or fewer columns.
+**
+** The last point is to ensure all column numbers are stored as
+** single-byte varints.
*/
-static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
- Fts5Colset *pColset = pIter->pColset;
- pIter->base.iRowid = pSeg->iRowid;
+static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
- assert( pColset );
+ assert( pIter->pColset );
- if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
- /* All data is stored on the current page. Populate the output
- ** variables to point into the body of the page object. */
- Fts5PoslistWriter writer = {0};
- const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
- int n = pSeg->nPos;
- int iCol = 0;
- int iCVal = pColset->aiCol[0];
- i64 iPos = 0;
- int iOff = 0;
+ if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
+ fts5IterSetOutputs_Col(pIter, pSeg);
+ }else{
+ u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
+ u8 *pEnd = (u8*)&a[pSeg->nPos];
+ int iPrev = 0;
+ int *aiCol = pIter->pColset->aiCol;
+ int *aiColEnd = &aiCol[pIter->pColset->nCol];
- fts5BufferZero(&pIter->poslist);
- while( 0==sqlite3Fts5PoslistNext64(a, n, &iOff, &iPos) ){
- while( iPos>=iCVal ){
- if( iPos==iCVal ){
- sqlite3Fts5PoslistWriterAppend(&pIter->poslist, &writer, iPos);
- }
- if( ++iCol>=pColset->nCol ) goto setoutputs_col_out;
- assert( pColset->aiCol[iCol]>iCVal );
- iCVal = pColset->aiCol[iCol];
+ u8 *aOut = pIter->poslist.p;
+ int iPrevOut = 0;
+
+ pIter->base.iRowid = pSeg->iRowid;
+
+ while( a<pEnd ){
+ iPrev += (int)a++[0] - 2;
+ while( *aiCol<iPrev ){
+ aiCol++;
+ if( aiCol==aiColEnd ) goto setoutputs_col_out;
+ }
+ if( *aiCol==iPrev ){
+ *aOut++ = (iPrev - iPrevOut) + 2;
+ iPrevOut = iPrev;
}
}
- }else{
- /* The data is distributed over two or more pages. Copy it into the
- ** Fts5Iter.poslist buffer and then set the output pointer to point
- ** to this buffer. */
- fts5BufferZero(&pIter->poslist);
- fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
- }
-
setoutputs_col_out:
- pIter->base.pData = pIter->poslist.p;
- pIter->base.nData = pIter->poslist.n;
+ pIter->base.pData = pIter->poslist.p;
+ pIter->base.nData = aOut - pIter->poslist.p;
+ }
}
/*
@@ -5146,8 +5113,8 @@
else{
assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
- if( pConfig->nCol<=32 ){
- pIter->xSetOutputs = fts5IterSetOutputs_Col32;
+ if( pConfig->nCol<=100 ){
+ pIter->xSetOutputs = fts5IterSetOutputs_Col100;
sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
}else{
pIter->xSetOutputs = fts5IterSetOutputs_Col;
diff --git a/manifest b/manifest
index 2e90cb8..173bd3a 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improve\sthe\sperformance\sof\sfts5\scolumn\sfilters\son\sdetail=col\stables.
-D 2016-01-26T19:30:49.768
+C Further\sminor\sperformance\simprovements\sand\scode-size\sreductions\srelated\sto\sfts5\scolumn\sfilters\son\sdetail=col\stables.
+D 2016-01-26T20:08:50.348
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9
@@ -103,7 +103,7 @@
F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238
F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412
F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955
-F ext/fts5/fts5_index.c b34b7257f73929dc1b25c420aad2453dcbe36128
+F ext/fts5/fts5_index.c 5558bfbeaf364cc67f937e25753ceed8757cb6d1
F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e
F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
@@ -1420,7 +1420,7 @@
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P c646e40350e5aa91abcf52de61fb31275bad38f9
-R a44979856d96ea38951595ad6e15598a
+P 249a2d070c34bf884a04cb248b9691e239f2871c
+R a28f5f4bedd812396ab85ff0aefd35c4
U dan
-Z a6d46df0ea079f8f36131bee8e2cf5b7
+Z 56fb7a3fddaab518f0c4eb551a124662
diff --git a/manifest.uuid b/manifest.uuid
index 54ccb7a..708359e 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-249a2d070c34bf884a04cb248b9691e239f2871c
\ No newline at end of file
+b4ac61aeee976296e7719949cd4fb496147a29e8
\ No newline at end of file