From: dan Date: Fri, 20 Nov 2009 10:23:12 +0000 (+0000) Subject: Merge leaf accidentally created by [1c4984c62f]. X-Git-Tag: version-3.7.2~805 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6828f5503df0fdb0d625f5112bba1f56d8d4d44;p=thirdparty%2Fsqlite.git Merge leaf accidentally created by [1c4984c62f]. FossilOrigin-Name: cae949ce971ca216e0f8880b2f93866619fa05be --- e6828f5503df0fdb0d625f5112bba1f56d8d4d44 diff --cc ext/fts3/fts3_write.c index 7a9ca71ea3,7a9ca71ea3..98e0a932b8 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@@ -834,6 -834,6 +834,9 @@@ void sqlite3Fts3SegReaderFree(Fts3Tabl } } ++/* ++** Allocate a new SegReader object. ++*/ int sqlite3Fts3SegReaderNew( Fts3Table *p, /* Virtual table handle */ int iAge, /* Segment "age". */ @@@ -963,7 -963,7 +966,8 @@@ static int fts3SegReaderNew } /* --** Compare the two Fts3SegReader structures. Comparison is as follows: ++** Compare the entries pointed to by two Fts3SegReader structures. ++** Comparison is as follows: ** ** 1) EOF is greater than not EOF. ** @@@ -995,11 -995,11 +999,22 @@@ static int fts3SegReaderCmp(Fts3SegRead return rc; } --static int fts3SegReaderCmp2(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ ++/* ++** A different comparison function for SegReader structures. In this ++** version, it is assumed that each SegReader points to an entry in ++** a doclist for identical terms. Comparison is made as follows: ++** ++** 1) EOF (end of doclist in this case) is greater than not EOF. ++** ++** 2) By current docid. ++** ++** 3) By segment age. An older segment is considered larger. ++*/ ++static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); if( rc==0 ){ if( pLhs->iDocid==pRhs->iDocid ){ -- rc = pRhs->iIdx-pLhs->iIdx; ++ rc = pRhs->iIdx - pLhs->iIdx; }else{ rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1; } @@@ -1075,9 -1075,9 +1090,10 @@@ static void fts3SegReaderSort ** Insert a record into the %_segments table. */ static int fts3WriteSegment( -- Fts3Table *p, -- sqlite3_int64 iBlock, -- char *z, int n ++ Fts3Table *p, /* Virtual table handle */ ++ sqlite3_int64 iBlock, /* Block id for new block */ ++ char *z, /* Pointer to buffer containing block data */ ++ int n /* Size of buffer z in bytes */ ){ sqlite3_stmt *pStmt; int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); @@@ -1096,7 -1096,7 +1112,7 @@@ ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( -- Fts3Table *p, /* Virtual table handle */ ++ Fts3Table *p, /* Virtual table handle */ int iLevel, /* Value for "level" field */ int iIdx, /* Value for "idx" field */ sqlite3_int64 iStartBlock, /* Value for "start_block" field */ @@@ -1122,16 -1122,16 +1138,23 @@@ return rc; } --static void fts3PrefixCompress( -- const char *zPrev, -- int nPrev, -- const char *zNext, -- int nNext, -- int *pnPrefix ++/* ++** Return the size of the common prefix (if any) shared by zPrev and ++** zNext, in bytes. For example, ++** ++** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 ++** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 ++** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0 ++*/ ++static int fts3PrefixCompress( ++ const char *zPrev, /* Buffer containing previous term */ ++ int nPrev, /* Size of buffer zPrev in bytes */ ++ const char *zNext, /* Buffer containing next term */ ++ int nNext /* Size of buffer zNext in bytes */ ){ int n; for(n=0; nzTerm, pTree->nTerm, zTerm, nTerm, &nPrefix); ++ nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); nSuffix = nTerm-nPrefix; nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; @@@ -1263,10 -1263,10 +1286,20 @@@ static int fts3TreeFinishNode } /* --** Helper function for fts3NodeWrite(). ++** Write the buffer for the segment node pTree and all of its peers to the ++** database. Then call this function recursively to write the parent of ++** pTree and its peers to the database. ++** ++** Except, if pTree is a root node, do not write it to the database. Instead, ++** set output variables *paRoot and *pnRoot to contain the root node. ++** ++** If successful, SQLITE_OK is returned and output variable *piLast is ++** set to the largest blockid written to the database (or zero if no ++** blocks were written to the db). Otherwise, an SQLite error code is ++** returned. */ static int fts3NodeWrite( -- Fts3Table *p, /* Virtual table handle */ ++ Fts3Table *p, /* Virtual table handle */ SegmentNode *pTree, /* SegmentNode handle */ int iHeight, /* Height of this node in tree */ sqlite3_int64 iLeaf, /* Block id of first leaf node */ @@@ -1326,6 -1326,6 +1359,14 @@@ static void fts3NodeFree(SegmentNode *p } } ++/* ++** Add a term to the segment being constructed by the SegmentWriter object ++** *ppWriter. When adding the first term to a segment, *ppWriter should ++** be passed NULL. This function will allocate a new SegmentWriter object ++** and return it via the input/output variable *ppWriter in this case. ++** ++** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. ++*/ static int fts3SegWriterAdd( Fts3Table *p, /* Virtual table handle */ SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ @@@ -1368,7 -1368,7 +1409,7 @@@ } nData = pWriter->nData; -- fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm, &nPrefix); ++ nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); nSuffix = nTerm-nPrefix; /* Figure out how many bytes are required by this new entry */ @@@ -1458,18 -1458,18 +1499,26 @@@ return SQLITE_OK; } ++/* ++** Flush all data associated with the SegmentWriter object pWriter to the ++** database. This function must be called after all terms have been added ++** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is ++** returned. Otherwise, an SQLite error code. ++*/ static int fts3SegWriterFlush( -- Fts3Table *p, -- SegmentWriter *pWriter, -- int iLevel, -- int iIdx ++ Fts3Table *p, /* Virtual table handle */ ++ SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ ++ int iLevel, /* Value for 'level' column of %_segdir */ ++ int iIdx /* Value for 'idx' column of %_segdir */ ){ -- int rc; ++ int rc; /* Return code */ if( pWriter->pTree ){ -- sqlite3_int64 iLast; -- char *zRoot; -- int nRoot; -- sqlite3_int64 iLastLeaf = pWriter->iFree; ++ sqlite3_int64 iLast; /* Largest block id written to database */ ++ sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ ++ char *zRoot; /* Pointer to buffer containing root node */ ++ int nRoot; /* Size of buffer zRoot */ ++ ++ iLastLeaf = pWriter->iFree; rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData); if( rc==SQLITE_OK ){ rc = fts3NodeWrite(p, pWriter->pTree, 1, @@@ -1487,6 -1487,6 +1536,10 @@@ return rc; } ++/* ++** Release all memory held by the SegmentWriter object passed as the ++** first argument. ++*/ static void fts3SegWriterFree(SegmentWriter *pWriter){ if( pWriter ){ sqlite3_free(pWriter->aData); @@@ -1519,6 -1519,6 +1572,11 @@@ static int fts3IsEmpty(Fts3Table *p, sq return rc; } ++/* ++** Set *pnSegment to the number of segments of level iLevel in the database. ++** ++** Return SQLITE_OK if successful, or an SQLite error code if not. ++*/ static int fts3SegmentCount(Fts3Table *p, int iLevel, int *pnSegment){ sqlite3_stmt *pStmt; int rc; @@@ -1533,6 -1533,6 +1591,13 @@@ return sqlite3_reset(pStmt); } ++/* ++** Set *pnSegment to the total number of segments in the database. Set ++** *pnMax to the largest segment level in the database (segment levels ++** are stored in the 'level' column of the %_segdir table). ++** ++** Return SQLITE_OK if successful, or an SQLite error code if not. ++*/ static int fts3SegmentCountMax(Fts3Table *p, int *pnSegment, int *pnMax){ sqlite3_stmt *pStmt; int rc; @@@ -1546,11 -1546,11 +1611,25 @@@ return sqlite3_reset(pStmt); } ++/* ++** This function is used after merging multiple segments into a single large ++** segment to delete the old, now redundant, segment b-trees. Specifically, ++** it: ++** ++** 1) Deletes all %_segments entries for the segments associated with ++** each of the SegReader objects in the array passed as the third ++** argument, and ++** ++** 2) deletes all %_segdir entries with level iLevel, or all %_segdir ++** entries regardless of level if (iLevel<0). ++** ++** SQLITE_OK is returned if successful, otherwise an SQLite error code. ++*/ static int fts3DeleteSegdir( -- Fts3Table *p, -- int iLevel, -- Fts3SegReader **apSegment, -- int nReader ++ Fts3Table *p, /* Virtual table handle */ ++ int iLevel, /* Level of %_segdir entries to delete */ ++ Fts3SegReader **apSegment, /* Array of SegReader objects */ ++ int nReader /* Size of array apSegment */ ){ int rc; /* Return Code */ int i; /* Iterator variable */ @@@ -1584,7 -1584,7 +1663,20 @@@ return rc; } --static void fts3ColumnFilter(int iCol, char **ppList, int *pnList){ ++/* ++** When this function is called, buffer *ppList (size *pnList bytes) contains ++** a position list that may (or may not) feature multiple columns. This ++** function adjusts the pointer *ppList and the length *pnList so that they ++** identify the subset of the position list that corresponds to column iCol. ++** ++** If there are no entries in the input position list for column iCol, then ++** *pnList is set to zero before returning. ++*/ ++static void fts3ColumnFilter( ++ int iCol, /* Column to filter on */ ++ char **ppList, /* IN/OUT: Pointer to position list */ ++ int *pnList /* IN/OUT: Size of buffer *ppList in bytes */ ++){ char *pList = *ppList; int nList = *pnList; char *pEnd = &pList[nList]; @@@ -1614,6 -1614,6 +1706,10 @@@ *pnList = nList; } ++/* ++** sqlite3Fts3SegReaderIterate() callback used when merging multiple ++** segments to create a single, larger segment. ++*/ static int fts3MergeCallback( Fts3Table *p, void *pContext, @@@ -1707,7 -1707,7 +1803,7 @@@ int sqlite3Fts3SegReaderIterate for(i=0; ipOffsetList ){ int j; /* Number of segments that share a docid */ char *pList; @@@ -1749,7 -1749,7 +1845,7 @@@ } } -- fts3SegReaderSort(apSegment, nMerge, j, fts3SegReaderCmp2); ++ fts3SegReaderSort(apSegment, nMerge, j, fts3SegReaderDoclistCmp); } if( nDoclist>0 ){ diff --cc manifest index 9f90bf1e97,99158e45a6..c6aa4ae3cf --- a/manifest +++ b/manifest @@@ -1,5 -1,8 +1,5 @@@ - C Add\sa\stest\sto\smake\ssure\sa\sdatabase\scan\sbe\sattached\sto\sa\ssingle\shandle\stwice\sif\snot\sin\sshared-cache\smode. - D 2009-11-20T10:18:06 ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\sa\sbug\sin\sLIMIT\s0\sfor\scompound\sSELECT\sstatement.\nThe\sproblem\swas\sintroduced\sby\srecent\senhancements\sand\shas\snot\sappeared\nin\sany\srelease. -D 2009-11-20T16:13:15 ++C Merge\sleaf\saccidentally\screated\sby\s[1c4984c62f]. ++D 2009-11-20T10:23:13 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 7f6c6aa7feeeb5e26e01b344161d9aa1b5d64177 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@@ -68,7 -71,7 +68,7 @@@ F ext/fts3/fts3_snippet.c 082f2906deaaa F ext/fts3/fts3_tokenizer.c 36f78d1a43a29b0feaec1ced6da9e56b9c653d1f F ext/fts3/fts3_tokenizer.h 7ff73caa3327589bf6550f60d93ebdd1f6a0fb5c F ext/fts3/fts3_tokenizer1.c 0a5bcc579f35de5d24a9345d7908dc25ae403ee7 --F ext/fts3/fts3_write.c 6b9b4fd998fc2cbc05859b79af559b32792023ab ++F ext/fts3/fts3_write.c 69e6fb5a387aa7eb1f9d89e5bce35d21b879602e F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt 3b130aa66e7a681136f6add198b076a2f90d1e33 F ext/icu/icu.c 12e763d288d23b5a49de37caa30737b971a2f1e2 @@@ -772,7 -775,14 +772,7 @@@ F tool/speedtest2.tcl ee2149167303ba8e9 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f - P 9a429349ccc2fa9acd28365a86578f602e87dafb - R 46119cb7f99f2b8740a6d715a49a25dc -P e493b093f8ca722c3160b32a16fb615023978dc9 -R 5ec1b2582562a57f9f564d3489d61dc3 -U drh -Z 1a324a1c90a5bbddcb009087c1541226 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFLBsAeoxKgR168RlERAjHuAJ9QJtWD6T56mccvLQ1ITcoNvvNpMwCfZr52 -Jqb5eUds3ueWwA0ZJsx59YQ= -=bz6Y ------END PGP SIGNATURE----- ++P 1c4984c62f393f41f9182ea82546c16d02efa46f c6ed7e2a73a7a65cfa914ffcad4f603b6b7a22a8 ++R a4c740bd2d6cd6d5d405c025a9a5ce19 +U dan - Z 45d94d950c686cbe6192e3168ebbb70a ++Z 4d4aca1de07a44952499e25e5fd5b2ca diff --cc manifest.uuid index 96361d7671,85c9ff8d57..24c2c498f1 --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - 1c4984c62f393f41f9182ea82546c16d02efa46f -c6ed7e2a73a7a65cfa914ffcad4f603b6b7a22a8 ++cae949ce971ca216e0f8880b2f93866619fa05be