SQLite

Check-in [25935db738]
Login

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

Overview
Comment:Lift code to traverse interior nodes out of loadSegment(). Refactoring towards prefix searching. (CVS 3882)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 25935db73877c0cb132acb30c2fed2544d0e5e32
User & Date: shess 2007-04-27 21:24:18.000
Context
2007-04-27
21:59
Internationalize the TRIM functions. Ticket #2323. (CVS 3883) (check-in: ff1f4e7447 user: drh tags: trunk)
21:24
Lift code to traverse interior nodes out of loadSegment(). Refactoring towards prefix searching. (CVS 3882) (check-in: 25935db738 user: shess tags: trunk)
21:02
Refactor fts2 loadSegmentLeaf() in preparation for prefix-searching. Prefix-searching will want to accumulate data across multiple leaves in the segment, using LeavesReader instead of LeafReader is the first step in that direction. (CVS 3881) (check-in: 22ffdae4b6 user: shess tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts2/fts2.c.
5132
5133
5134
5135
5136
5137
5138
























5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
  rc = leavesReaderInit(v, 0, 0, 0, pData, nData, &reader);
  if( rc!=SQLITE_OK ) return rc;

  rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, out);
  leavesReaderDestroy(&reader);
  return rc;
}

























/* Traverse the tree represented by pData[nData] looking for
** pTerm[nTerm], merging its doclist over *out if found (any duplicate
** doclists read from the segment rooted at pData will overwrite those
** in *out).
*/
static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
                       const char *pTerm, int nTerm, DataBuffer *out){
  int rc;
  sqlite3_stmt *s = NULL;

  assert( nData>1 );

  /* This code should never be called with buffered updates. */
  assert( v->nPendingData<0 );

  /* Process data as an interior node until we reach a leaf. */
  while( *pData!='\0' ){
    sqlite_int64 iBlockid;
    InteriorReader reader;

    /* Scan the node data until we find a term greater than our term.
    ** Our target child will be in the blockid under that term, or in
    ** the last blockid in the node if we never find such a term.
    */
    interiorReaderInit(pData, nData, &reader);
    while( !interiorReaderAtEnd(&reader) ){
      if( interiorReaderTermCmp(&reader, pTerm, nTerm)>0 ) break;
      interiorReaderStep(&reader);
    }

    /* Grab the child blockid before calling sql_get_statement(),
    ** because sql_get_statement() may reset our data out from under
    ** us.
    */
    iBlockid = interiorReaderCurrentBlockid(&reader);
    interiorReaderDestroy(&reader);

    rc = sql_get_statement(v, BLOCK_SELECT_STMT, &s);
    if( rc!=SQLITE_OK ) return rc;

    rc = sqlite3_bind_int64(s, 1, iBlockid);
    if( rc!=SQLITE_OK ) return rc;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



















<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181

5182
















5183
5184
5185
5186
5187
5188
5189
  rc = leavesReaderInit(v, 0, 0, 0, pData, nData, &reader);
  if( rc!=SQLITE_OK ) return rc;

  rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, out);
  leavesReaderDestroy(&reader);
  return rc;
}

/* Taking pData/nData as an interior node, find the child node which
** could include pTerm/nTerm.  Note that the interior node terms
** logically come between the blocks, so there is one more blockid
** than there are terms (that block contains terms >= the last
** interior-node term).
*/
static void getNextChild(const char *pData, int nData,
                         const char *pTerm, int nTerm,
                         sqlite_int64 *piBlockid){
  InteriorReader reader;

  assert( nData>1 );
  assert( *pData!='\0' );
  interiorReaderInit(pData, nData, &reader);

  while( !interiorReaderAtEnd(&reader) ){
    if( interiorReaderTermCmp(&reader, pTerm, nTerm)>0 ) break;
    interiorReaderStep(&reader);
  }
  *piBlockid = interiorReaderCurrentBlockid(&reader);

  interiorReaderDestroy(&reader);
}

/* Traverse the tree represented by pData[nData] looking for
** pTerm[nTerm], merging its doclist over *out if found (any duplicate
** doclists read from the segment rooted at pData will overwrite those
** in *out).
*/
static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
                       const char *pTerm, int nTerm, DataBuffer *out){
  int rc;
  sqlite3_stmt *s = NULL;

  assert( nData>1 );

  /* This code should never be called with buffered updates. */
  assert( v->nPendingData<0 );

  /* Process data as an interior node until we reach a leaf. */
  while( *pData!='\0' ){
    sqlite_int64 iBlockid;

    getNextChild(pData, nData, pTerm, nTerm, &iBlockid);

















    rc = sql_get_statement(v, BLOCK_SELECT_STMT, &s);
    if( rc!=SQLITE_OK ) return rc;

    rc = sqlite3_bind_int64(s, 1, iBlockid);
    if( rc!=SQLITE_OK ) return rc;