| 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 |