/ Check-in [22ffdae4]
Login

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

Overview
Comment: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)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:22ffdae4b6f3d0ea584dafa5268af7aa6fdcdc6e
User & Date: shess 2007-04-27 21:02:00
Context
2007-04-27
21:24
Lift code to traverse interior nodes out of loadSegment(). Refactoring towards prefix searching. (CVS 3882) check-in: 25935db7 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: 22ffdae4 user: shess tags: trunk
17:16
Make sure sqlite3_value_bytes() does not reformat the content after a call to sqlite3_value_blob(). Add documentation to explain this hazard. Add many new tests. Ticket #2321. (CVS 3880) check-in: e92bd97a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts2/fts2.c.

5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101

5102
5103
5104
5105
5106
5107
5108
5109
5110
5111


5112
5113
5114

5115

5116















5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
  for(i=0; i<MERGE_COUNT; i++){
    leavesReaderDestroy(&lrs[i]);
  }
  leafWriterDestroy(&writer);
  return rc;
}

/* Read pData[nData] as a leaf node, and if the doclist for
** pTerm[nTerm] is present, merge it over *out (any duplicate doclists
** read from pData will overwrite those in *out).
*/
static int loadSegmentLeaf(fulltext_vtab *v, const char *pData, int nData,
                           const char *pTerm, int nTerm, DataBuffer *out){
  LeafReader reader;
  assert( nData>1 );
  assert( *pData=='\0' );

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

  leafReaderInit(pData, nData, &reader);
  while( !leafReaderAtEnd(&reader) ){
    int c = leafReaderTermCmp(&reader, pTerm, nTerm);
    if( c==0 ){
      if( out->nData==0 ){
        dataBufferReplace(out,
                          leafReaderData(&reader), leafReaderDataBytes(&reader));

      }else{
        DLReader readers[2];
        DataBuffer result;
        dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData);
        dlrInit(&readers[1], DL_DEFAULT,
                leafReaderData(&reader), leafReaderDataBytes(&reader));
        dataBufferInit(&result, out->nData+leafReaderDataBytes(&reader));
        docListMerge(&result, readers, 2);
        dataBufferDestroy(out);
        *out = result;


      }
    }
    if( c>=0 ) break;

    leafReaderStep(&reader);

  }















  leafReaderDestroy(&reader);
  return SQLITE_OK;
}

/* 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,







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>




|
<
|



>
>

|
|
>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|








5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107

5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
  for(i=0; i<MERGE_COUNT; i++){
    leavesReaderDestroy(&lrs[i]);
  }
  leafWriterDestroy(&writer);
  return rc;
}

/* Scan pReader for pTerm/nTerm, and merge the term's doclist over
** *out (any doclists with duplicate docids overwrite those in *out).
** Internal function for loadSegmentLeaf().
*/
static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
                                const char *pTerm, int nTerm, DataBuffer *out){
  assert( nTerm>0 );

  /* Process while the prefix matches. */
  while( !leavesReaderAtEnd(pReader) ){
    /* TODO(shess) Really want leavesReaderTermCmp(), but that name is
    ** already taken to compare the terms of two LeavesReaders.  Think
    ** on a better name.  [Meanwhile, break encapsulation rather than
    ** use a confusing name.]
    */
    int rc, c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm);
    if( c==0 ){
      const char *pData = leavesReaderData(pReader);
      int nData = leavesReaderDataBytes(pReader);
      if( out->nData==0 ){
        dataBufferReplace(out, pData, nData);
      }else{
        DLReader readers[2];
        DataBuffer result;
        dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData);
        dlrInit(&readers[1], DL_DEFAULT, pData, nData);

        dataBufferInit(&result, out->nData+nData);
        docListMerge(&result, readers, 2);
        dataBufferDestroy(out);
        *out = result;
        dlrDestroy(&readers[0]);
        dlrDestroy(&readers[1]);
      }
     }
    if( c>=0 ) break;      /* Past any possible matches. */

    rc = leavesReaderStep(v, pReader);
    if( rc!=SQLITE_OK ) return rc;
  }
  return SQLITE_OK;
}

/* Call loadSegmentLeavesInt() with pData/nData as input. */
static int loadSegmentLeaf(fulltext_vtab *v, const char *pData, int nData,
                           const char *pTerm, int nTerm, DataBuffer *out){
  LeavesReader reader;
  int rc;

  assert( nData>1 );
  assert( *pData=='\0' );
  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,