/ Check-in [b9b0c1e5]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Avoid freeing the array of instance matches each time the fts5 xNext() method is called.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b9b0c1e50d77f5d6e02f43fbb100c722cb692cc5
User & Date: dan 2015-07-03 17:14:18
Context
2015-07-03
17:54
Enable use of the __builtin_bswap32() only with GCC 4.3 and higher. check-in: 030f60a7 user: mistachkin tags: trunk
17:14
Avoid freeing the array of instance matches each time the fts5 xNext() method is called. check-in: b9b0c1e5 user: dan tags: trunk
14:34
New command-line options for speedtest1: --multithread, --nomemstat, --serialized, and --singlethread check-in: 2b756722 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_main.c.

   215    215   #define FTS5_BI_ORDER_DESC   0x0080
   216    216   
   217    217   /*
   218    218   ** Values for Fts5Cursor.csrflags
   219    219   */
   220    220   #define FTS5CSR_REQUIRE_CONTENT   0x01
   221    221   #define FTS5CSR_REQUIRE_DOCSIZE   0x02
   222         -#define FTS5CSR_EOF               0x04
   223         -#define FTS5CSR_FREE_ZRANK        0x08
   224         -#define FTS5CSR_REQUIRE_RESEEK    0x10
          222  +#define FTS5CSR_REQUIRE_INST      0x04
          223  +#define FTS5CSR_EOF               0x08
          224  +#define FTS5CSR_FREE_ZRANK        0x10
          225  +#define FTS5CSR_REQUIRE_RESEEK    0x20
   225    226   
   226    227   #define BitFlagAllTest(x,y) (((x) & (y))==(y))
   227    228   #define BitFlagTest(x,y)    (((x) & (y))!=0)
   228    229   
   229    230   /*
   230    231   ** Constants for the largest and smallest possible 64-bit signed integers.
   231    232   ** These are copied from sqliteInt.h.
................................................................................
   607    608   
   608    609   /*
   609    610   ** This function is called after the cursor passed as the only argument
   610    611   ** is moved to point at a different row. It clears all cached data 
   611    612   ** specific to the previous row stored by the cursor object.
   612    613   */
   613    614   static void fts5CsrNewrow(Fts5Cursor *pCsr){
   614         -  CsrFlagSet(pCsr, FTS5CSR_REQUIRE_CONTENT | FTS5CSR_REQUIRE_DOCSIZE );
   615         -  sqlite3_free(pCsr->aInst);
   616         -  pCsr->aInst = 0;
   617         -  pCsr->nInstCount = 0;
          615  +  CsrFlagSet(pCsr, 
          616  +      FTS5CSR_REQUIRE_CONTENT 
          617  +    | FTS5CSR_REQUIRE_DOCSIZE 
          618  +    | FTS5CSR_REQUIRE_INST 
          619  +  );
   618    620   }
   619    621   
   620    622   /*
   621    623   ** Close the cursor.  For additional information see the documentation
   622    624   ** on the xClose method of the virtual table interface.
   623    625   */
   624    626   static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
................................................................................
   625    627     if( pCursor ){
   626    628       Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
   627    629       Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
   628    630       Fts5Cursor **pp;
   629    631       Fts5Auxdata *pData;
   630    632       Fts5Auxdata *pNext;
   631    633   
   632         -    fts5CsrNewrow(pCsr);
          634  +    sqlite3_free(pCsr->aInst);
   633    635       if( pCsr->pStmt ){
   634    636         int eStmt = fts5StmtType(pCsr);
   635    637         sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
   636    638       }
   637    639       if( pCsr->pSorter ){
   638    640         Fts5Sorter *pSorter = pCsr->pSorter;
   639    641         sqlite3_finalize(pSorter->pStmt);
................................................................................
  1518   1520   /*
  1519   1521   ** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
  1520   1522   ** correctly for the current view. Return SQLITE_OK if successful, or an
  1521   1523   ** SQLite error code otherwise.
  1522   1524   */
  1523   1525   static int fts5CacheInstArray(Fts5Cursor *pCsr){
  1524   1526     int rc = SQLITE_OK;
  1525         -  if( pCsr->aInst==0 ){
         1527  +  if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST) ){
  1526   1528       Fts5PoslistReader *aIter;     /* One iterator for each phrase */
  1527   1529       int nIter;                    /* Number of iterators/phrases */
  1528   1530       int nByte;
  1529   1531       
  1530   1532       nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
  1531   1533       nByte = sizeof(Fts5PoslistReader) * nIter;
  1532   1534       aIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
................................................................................
  1560   1562           aInst = &((int*)buf.p)[3 * (nInst-1)];
  1561   1563           aInst[0] = iBest;
  1562   1564           aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
  1563   1565           aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
  1564   1566           sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
  1565   1567         }
  1566   1568   
         1569  +      sqlite3_free(pCsr->aInst);
  1567   1570         pCsr->aInst = (int*)buf.p;
  1568   1571         pCsr->nInstCount = nInst;
  1569   1572         sqlite3_free(aIter);
         1573  +      CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
  1570   1574       }
  1571   1575     }
  1572   1576     return rc;
  1573   1577   }
  1574   1578   
  1575   1579   static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
  1576   1580     Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;

Changes to ext/fts5/tool/loadfts5.tcl.

    98     98       }
    99     99     }
   100    100   }
   101    101   
   102    102   set dbfile [lindex $argv end-1]
   103    103   if {$O(delete)} { file delete -force $dbfile }
   104    104   sqlite3 db $dbfile
          105  +catch { load_static_extension db fts5 }
   105    106   db func loadfile loadfile
   106    107   
   107    108   db transaction {
   108    109     set pref ""
   109    110     if {$O(prefix)!=""} { set pref ", prefix='$O(prefix)'" }
   110    111     catch {
   111    112       db eval "CREATE VIRTUAL TABLE t1 USING $O(vtab) (path, content$O(tok)$pref)"

Changes to ext/fts5/tool/mkfts5c.tcl.

    74     74     puts -nonewline $G(fd) $G(hdr)
    75     75   }
    76     76   
    77     77   proc fts5c_printfile {zIn} {
    78     78     global G
    79     79     set data [readfile $zIn]
    80     80     set zTail [file tail $zIn]
    81         -  puts $G(fd) "#line 1 \"$zTail\""
           81  +  puts $G(fd) "#line 2 \"$zTail\""
    82     82   
    83     83     set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]]
    84     84     if {$zTail=="fts5parse.c"} {
    85     85       lappend sub_map yy fts5yy YY fts5YY TOKEN FTS5TOKEN
    86     86     }
    87     87   
    88     88     foreach line [split $data "\n"] {

Changes to ext/fts5/tool/showfts5.tcl.

    14     14   
    15     15   if {[llength $argv]!=2} usage
    16     16   
    17     17   set database [lindex $argv 0]
    18     18   set tbl [lindex $argv 1]
    19     19   
    20     20   sqlite3 db $database
           21  +catch { load_static_extension db fts5 }
    21     22   
    22     23   db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id=10" {
    23     24     foreach lvl [lrange $d 1 end] {
    24     25       puts $lvl
    25     26     }
    26     27   }
    27     28   
    28     29   
    29     30   
    30     31   
    31     32