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]);
- }
- }
+ assert( out->nData==0 );
+ dataBufferReplace(out, pData, nData);
+ }
if( c>=0 ) break; /* Past any possible matches. */
rc = leavesReaderStep(v, pReader);
}
/* 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).
+** pTerm[nTerm], placing its doclist into *out. This is internal to
+** loadSegment() to make error-handling cleaner.
*/
-static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
- sqlite_int64 iLeavesEnd,
- const char *pTerm, int nTerm, DataBuffer *out){
- assert( nData>1 );
-
- /* This code should never be called with buffered updates. */
- assert( v->nPendingData<0 );
-
+static int loadSegmentInt(fulltext_vtab *v, const char *pData, int nData,
+ sqlite_int64 iLeavesEnd,
+ const char *pTerm, int nTerm, DataBuffer *out){
/* Special case where root is a leaf. */
if( *pData=='\0' ){
return loadSegmentLeaf(v, pData, nData, pTerm, nTerm, out);
}
}
+/* Call loadSegmentInt() to collect the doclist for pTerm/nTerm, then
+** merge its doclist over *out (any duplicate doclists read from the
+** segment rooted at pData will overwrite those in *out).
+*/
+/* NOTE(shess) Previous code passed out down to sub-routines for use
+** in docListMerge(). This version deoptimizes things slightly, but
+** prefix searches require a different merge function entirely.
+*/
+static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
+ sqlite_int64 iLeavesEnd,
+ const char *pTerm, int nTerm, DataBuffer *out){
+ DataBuffer result;
+ int rc;
+
+ assert( nData>1 );
+
+ /* This code should never be called with buffered updates. */
+ assert( v->nPendingData<0 );
+
+ dataBufferInit(&result, 0);
+ rc = loadSegmentInt(v, pData, nData, iLeavesEnd, pTerm, nTerm, &result);
+ if( rc==SQLITE_OK && result.nData>0 ){
+ if( out->nData==0 ){
+ DataBuffer tmp = *out;
+ *out = result;
+ result = tmp;
+ }else{
+ DataBuffer merged;
+ DLReader readers[2];
+
+ dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData);
+ dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData);
+ dataBufferInit(&merged, out->nData+result.nData);
+ docListMerge(&merged, readers, 2);
+ dataBufferDestroy(out);
+ *out = merged;
+ dlrDestroy(&readers[0]);
+ dlrDestroy(&readers[1]);
+ }
+ }
+ dataBufferDestroy(&result);
+ return rc;
+}
+
/* Scan the database and merge together the posting lists for the term
** into *out.
*/
-C Try\sto\savoid\sreading\spages\swhen\smoving\soverflow\schains\sto\sthe\sfree-list.\s(CVS\s3886)
-D 2007-04-30T16:55:01
+C Lift\sdocListMerge()\scall\sout\sof\sloadSegmentLeavesInt()\sfor\sprefix\nsearch.\s\sDoclists\sfrom\smultiple\sprefix\smatches\swill\sneed\sa\sunion\smerge\nfunction,\swhich\swill\shave\sto\slogically\shappen\sacross\sa\ssegment\sbefore\ndoclists\sare\smerged\sbetween\ssegments.\s(CVS\s3887)
+D 2007-04-30T17:52:52
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts2/fts2.c b45e07a23646e82525657af9bab063e10f9acffc
+F ext/fts2/fts2.c cb7ca4e320f9aa99dad1d160288944c13778a678
F ext/fts2/fts2.h 591916a822cfb6426518fdbf6069359119bc46eb
F ext/fts2/fts2_hash.c b3f22116d4ef0bc8f2da6e3fdc435c86d0951a9b
F ext/fts2/fts2_hash.h e283308156018329f042816eb09334df714e105e
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 89b1b3f897bda1fffceb9cf72fa4d42b809ccb8e
-R 25da30ea21a3fd3e2f878c36734a5bb9
-U danielk1977
-Z f3a814360f6db57fb203458a6b31fb7b
+P 8cccec68bd9073b2b19d3d31cf0b77b0ce76172e
+R 7069672da6b54cde9af80d1ef9e46049
+U shess
+Z 8a2908873a8cd6c0a742806cb3215c42