/ Check-in [67ff5ae8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use macros to make the code in fts5_index.c easier to read.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts5-incompatible
Files: files | file ages | folders
SHA1: 67ff5ae81357eb7fa28049bb724a22cb6f52e076
User & Date: dan 2015-09-07 08:14:30
Context
2015-09-08
19:55
Remove the 0x00 terminators from the end of fts5 doclists stored on disk. check-in: 00d99006 user: dan tags: fts5-incompatible
2015-09-07
08:14
Use macros to make the code in fts5_index.c easier to read. check-in: 67ff5ae8 user: dan tags: fts5-incompatible
2015-09-05
19:52
Experiment with a different fts5 leaf page format that allows faster seeks. check-in: a1f4c3b5 user: dan tags: fts5-incompatible
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

   518    518   /* 
   519    519   ** Argument is a pointer to an Fts5Data structure that contains a leaf
   520    520   ** page. This macro evaluates to true if the leaf contains no terms, or
   521    521   ** false if it contains at least one term.
   522    522   */
   523    523   #define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn)
   524    524   
   525         -#define fts5LeafFirstTermOff(x) (fts5GetU16(&x->p[(x)->szLeaf]))
          525  +#define fts5LeafFirstTermOff(x) (fts5GetU16(&(x)->p[(x)->szLeaf]))
          526  +#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
   526    527   
   527    528   /*
   528    529   ** poslist:
   529    530   **   Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
   530    531   **   There is no way to tell if this is populated or not.
   531    532   */
   532    533   struct Fts5IndexIter {
................................................................................
  1581   1582       pIter->pSeg = pSeg;
  1582   1583       pIter->iLeafPgno = pSeg->pgnoFirst-1;
  1583   1584       fts5SegIterNextPage(p, pIter);
  1584   1585     }
  1585   1586   
  1586   1587     if( p->rc==SQLITE_OK ){
  1587   1588       u8 *a = pIter->pLeaf->p;
  1588         -    pIter->iLeafOffset = fts5GetU16(&a[pIter->pLeaf->szLeaf]);
  1589         -    assert( pIter->iLeafOffset==4 );
         1589  +    pIter->iLeafOffset = 4;
         1590  +    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
  1590   1591       fts5SegIterLoadTerm(p, pIter, 0);
  1591   1592       fts5SegIterLoadNPos(p, pIter);
  1592   1593     }
  1593   1594   }
  1594   1595   
  1595   1596   /*
  1596   1597   ** This function is only ever called on iterators created by calls to
................................................................................
  1783   1784           iOff = 0;
  1784   1785           /* Next entry is not on the current page */
  1785   1786           while( iOff==0 ){
  1786   1787             fts5SegIterNextPage(p, pIter);
  1787   1788             pLeaf = pIter->pLeaf;
  1788   1789             if( pLeaf==0 ) break;
  1789   1790             ASSERT_SZLEAF_OK(pLeaf);
  1790         -          if( (iOff = fts5GetU16(&pLeaf->p[0])) && iOff<pLeaf->szLeaf ){
         1791  +          if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
  1791   1792               iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
  1792   1793               pIter->iLeafOffset = iOff;
  1793   1794             }
  1794   1795             else if( pLeaf->nn>pLeaf->szLeaf ){
  1795         -            iOff = fts5GetU16(&pLeaf->p[pLeaf->szLeaf]);
         1796  +            iOff = fts5LeafFirstTermOff(pLeaf);
  1796   1797               pIter->iLeafOffset = iOff;
  1797   1798               bNewTerm = 1;
  1798   1799             }
  1799   1800             if( iOff>=pLeaf->szLeaf ){
  1800   1801               p->rc = FTS5_CORRUPT;
  1801   1802               return;
  1802   1803             }
................................................................................
  1877   1878         /* The last rowid in the doclist may not be on the current page. Search
  1878   1879         ** forward to find the page containing the last rowid.  */
  1879   1880         for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
  1880   1881           i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, 0, pgno);
  1881   1882           Fts5Data *pNew = fts5DataRead(p, iAbs);
  1882   1883           if( pNew ){
  1883   1884             int iRowid, bTermless;
  1884         -          iRowid = fts5GetU16(pNew->p);
         1885  +          iRowid = fts5LeafFirstRowidOff(pNew);
  1885   1886             bTermless = fts5LeafIsTermless(pNew);
  1886   1887             if( iRowid ){
  1887   1888               SWAPVAL(Fts5Data*, pNew, pLast);
  1888   1889               pgnoLast = pgno;
  1889   1890             }
  1890   1891             fts5DataRelease(pNew);
  1891   1892             if( bTermless==0 ) break;
................................................................................
  1995   1996     int nNew = 0;
  1996   1997     int iTerm = 0;
  1997   1998     int nPgTerm = (pIter->pLeaf->nn - pIter->pLeaf->szLeaf) >> 1;
  1998   1999   
  1999   2000     assert( p->rc==SQLITE_OK );
  2000   2001     assert( pIter->pLeaf );
  2001   2002   
  2002         -  iOff = fts5GetU16(&a[n]);
         2003  +  iOff = fts5LeafFirstTermOff(pIter->pLeaf);
  2003   2004     if( iOff<4 || iOff>=n ){
  2004   2005       p->rc = FTS5_CORRUPT;
  2005   2006       return;
  2006   2007     }
  2007   2008   
  2008   2009     while( 1 ){
  2009   2010       int i;
................................................................................
  2430   2431       assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
  2431   2432   
  2432   2433       if( p->rc==SQLITE_OK ){
  2433   2434         int iOff;
  2434   2435         u8 *a = pIter->pLeaf->p;
  2435   2436         int n = pIter->pLeaf->szLeaf;
  2436   2437   
  2437         -      iOff = fts5GetU16(&a[0]);
         2438  +      iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
  2438   2439         if( iOff<4 || iOff>=n ){
  2439   2440           p->rc = FTS5_CORRUPT;
  2440   2441         }else{
  2441   2442           iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
  2442   2443           pIter->iLeafOffset = iOff;
  2443   2444           fts5SegIterLoadNPos(p, pIter);
  2444   2445         }
................................................................................
  4959   4960   
  4960   4961     /* Now check that the iter.nEmpty leaves following the current leaf
  4961   4962     ** (a) exist and (b) contain no terms. */
  4962   4963     for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
  4963   4964       Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, 0, i));
  4964   4965       if( pLeaf ){
  4965   4966         if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
  4966         -      if( i>=iNoRowid && 0!=fts5GetU16(&pLeaf->p[0]) ) p->rc = FTS5_CORRUPT;
         4967  +      if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
  4967   4968       }
  4968   4969       fts5DataRelease(pLeaf);
  4969   4970       if( p->rc ) break;
  4970   4971     }
  4971   4972   }
  4972   4973   
  4973   4974   static void fts5IndexIntegrityCheckSegment(
................................................................................
  5013   5014       }else{
  5014   5015         int iOff;                   /* Offset of first term on leaf */
  5015   5016         int iRowidOff;              /* Offset of first rowid on leaf */
  5016   5017         int nTerm;                  /* Size of term on leaf in bytes */
  5017   5018         int res;                    /* Comparison of term and split-key */
  5018   5019   
  5019   5020         iOff = fts5LeafFirstTermOff(pLeaf);
  5020         -      iRowidOff = fts5GetU16(&pLeaf->p[0]);
         5021  +      iRowidOff = fts5LeafFirstRowidOff(pLeaf);
  5021   5022         if( iRowidOff>=iOff ){
  5022   5023           p->rc = FTS5_CORRUPT;
  5023   5024         }else{
  5024   5025           iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
  5025   5026           res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
  5026   5027           if( res==0 ) res = nTerm - nIdxTerm;
  5027   5028           if( res<0 ) p->rc = FTS5_CORRUPT;
................................................................................
  5052   5053         ){
  5053   5054   
  5054   5055           /* Check any rowid-less pages that occur before the current leaf. */
  5055   5056           for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
  5056   5057             iKey = FTS5_SEGMENT_ROWID(iSegid, 0, iPg);
  5057   5058             pLeaf = fts5DataRead(p, iKey);
  5058   5059             if( pLeaf ){
  5059         -            if( fts5GetU16(&pLeaf->p[0])!=0 ) p->rc = FTS5_CORRUPT;
         5060  +            if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
  5060   5061               fts5DataRelease(pLeaf);
  5061   5062             }
  5062   5063           }
  5063   5064           iPrevLeaf = fts5DlidxIterPgno(pDlidx);
  5064   5065   
  5065   5066           /* Check that the leaf page indicated by the iterator really does
  5066   5067           ** contain the rowid suggested by the same. */
  5067   5068           iKey = FTS5_SEGMENT_ROWID(iSegid, 0, iPrevLeaf);
  5068   5069           pLeaf = fts5DataRead(p, iKey);
  5069   5070           if( pLeaf ){
  5070   5071             i64 iRowid;
  5071         -          int iRowidOff = fts5GetU16(&pLeaf->p[0]);
         5072  +          int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
  5072   5073             ASSERT_SZLEAF_OK(pLeaf);
  5073   5074             if( iRowidOff>=pLeaf->szLeaf ){
  5074   5075               p->rc = FTS5_CORRUPT;
  5075   5076             }else{
  5076   5077               fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
  5077   5078               if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
  5078   5079             }