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