OLD | NEW |
1 /* | 1 /* |
2 ** 2009 Oct 23 | 2 ** 2009 Oct 23 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 /* 25 */ "", | 326 /* 25 */ "", |
327 | 327 |
328 /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", | 328 /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", |
329 /* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", | 329 /* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", |
330 | 330 |
331 /* This statement is used to determine which level to read the input from | 331 /* This statement is used to determine which level to read the input from |
332 ** when performing an incremental merge. It returns the absolute level number | 332 ** when performing an incremental merge. It returns the absolute level number |
333 ** of the oldest level in the db that contains at least ? segments. Or, | 333 ** of the oldest level in the db that contains at least ? segments. Or, |
334 ** if no level in the FTS index contains more than ? segments, the statement | 334 ** if no level in the FTS index contains more than ? segments, the statement |
335 ** returns zero rows. */ | 335 ** returns zero rows. */ |
336 /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" | 336 /* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " |
| 337 " GROUP BY level HAVING cnt>=?" |
337 " ORDER BY (level %% 1024) ASC LIMIT 1", | 338 " ORDER BY (level %% 1024) ASC LIMIT 1", |
338 | 339 |
339 /* Estimate the upper limit on the number of leaf nodes in a new segment | 340 /* Estimate the upper limit on the number of leaf nodes in a new segment |
340 ** created by merging the oldest :2 segments from absolute level :1. See | 341 ** created by merging the oldest :2 segments from absolute level :1. See |
341 ** function sqlite3Fts3Incrmerge() for details. */ | 342 ** function sqlite3Fts3Incrmerge() for details. */ |
342 /* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " | 343 /* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " |
343 " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", | 344 " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", |
344 | 345 |
345 /* SQL_DELETE_SEGDIR_ENTRY | 346 /* SQL_DELETE_SEGDIR_ENTRY |
346 ** Delete the %_segdir entry on absolute level :1 with index :2. */ | 347 ** Delete the %_segdir entry on absolute level :1 with index :2. */ |
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3187 if( iLevel!=FTS3_SEGCURSOR_PENDING ){ | 3188 if( iLevel!=FTS3_SEGCURSOR_PENDING ){ |
3188 rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); | 3189 rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); |
3189 if( rc!=SQLITE_OK ) goto finished; | 3190 if( rc!=SQLITE_OK ) goto finished; |
3190 } | 3191 } |
3191 | 3192 |
3192 if( iLevel==FTS3_SEGCURSOR_ALL ){ | 3193 if( iLevel==FTS3_SEGCURSOR_ALL ){ |
3193 /* This call is to merge all segments in the database to a single | 3194 /* This call is to merge all segments in the database to a single |
3194 ** segment. The level of the new segment is equal to the numerically | 3195 ** segment. The level of the new segment is equal to the numerically |
3195 ** greatest segment level currently present in the database for this | 3196 ** greatest segment level currently present in the database for this |
3196 ** index. The idx of the new segment is always 0. */ | 3197 ** index. The idx of the new segment is always 0. */ |
3197 if( csr.nSegment==1 ){ | 3198 if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){ |
3198 rc = SQLITE_DONE; | 3199 rc = SQLITE_DONE; |
3199 goto finished; | 3200 goto finished; |
3200 } | 3201 } |
3201 iNewLevel = iMaxLevel; | 3202 iNewLevel = iMaxLevel; |
3202 bIgnoreEmpty = 1; | 3203 bIgnoreEmpty = 1; |
3203 | 3204 |
3204 }else{ | 3205 }else{ |
3205 /* This call is to merge all segments at level iLevel. find the next | 3206 /* This call is to merge all segments at level iLevel. find the next |
3206 ** available segment index at level iLevel+1. The call to | 3207 ** available segment index at level iLevel+1. The call to |
3207 ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to | 3208 ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to |
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4829 int bUseHint = 0; /* True if attempting to append */ | 4830 int bUseHint = 0; /* True if attempting to append */ |
4830 int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ | 4831 int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ |
4831 | 4832 |
4832 /* Search the %_segdir table for the absolute level with the smallest | 4833 /* Search the %_segdir table for the absolute level with the smallest |
4833 ** relative level number that contains at least nMin segments, if any. | 4834 ** relative level number that contains at least nMin segments, if any. |
4834 ** If one is found, set iAbsLevel to the absolute level number and | 4835 ** If one is found, set iAbsLevel to the absolute level number and |
4835 ** nSeg to nMin. If no level with at least nMin segments can be found, | 4836 ** nSeg to nMin. If no level with at least nMin segments can be found, |
4836 ** set nSeg to -1. | 4837 ** set nSeg to -1. |
4837 */ | 4838 */ |
4838 rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); | 4839 rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); |
4839 sqlite3_bind_int(pFindLevel, 1, nMin); | 4840 sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); |
4840 if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ | 4841 if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ |
4841 iAbsLevel = sqlite3_column_int64(pFindLevel, 0); | 4842 iAbsLevel = sqlite3_column_int64(pFindLevel, 0); |
4842 nSeg = nMin; | 4843 nSeg = sqlite3_column_int(pFindLevel, 1); |
| 4844 assert( nSeg>=2 ); |
4843 }else{ | 4845 }else{ |
4844 nSeg = -1; | 4846 nSeg = -1; |
4845 } | 4847 } |
4846 rc = sqlite3_reset(pFindLevel); | 4848 rc = sqlite3_reset(pFindLevel); |
4847 | 4849 |
4848 /* If the hint read from the %_stat table is not empty, check if the | 4850 /* If the hint read from the %_stat table is not empty, check if the |
4849 ** last entry in it specifies a relative level smaller than or equal | 4851 ** last entry in it specifies a relative level smaller than or equal |
4850 ** to the level identified by the block above (if any). If so, this | 4852 ** to the level identified by the block above (if any). If so, this |
4851 ** iteration of the loop will work on merging at the hinted level. | 4853 ** iteration of the loop will work on merging at the hinted level. |
4852 */ | 4854 */ |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5667 }else{ | 5669 }else{ |
5668 sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); | 5670 sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); |
5669 sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); | 5671 sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); |
5670 } | 5672 } |
5671 } | 5673 } |
5672 sqlite3Fts3SegmentsClose(p); | 5674 sqlite3Fts3SegmentsClose(p); |
5673 return rc; | 5675 return rc; |
5674 } | 5676 } |
5675 | 5677 |
5676 #endif | 5678 #endif |
OLD | NEW |