Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/src/vdbesort.c

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2011-07-09 2 ** 2011-07-09
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 ** multi-threaded mode then up to (N+1) temporary files may be opened, where 93 ** multi-threaded mode then up to (N+1) temporary files may be opened, where
94 ** N is the configured number of worker threads. In this case, instead of 94 ** N is the configured number of worker threads. In this case, instead of
95 ** sorting the records and writing the PMA to a temporary file itself, the 95 ** sorting the records and writing the PMA to a temporary file itself, the
96 ** calling thread usually launches a worker thread to do so. Except, if 96 ** calling thread usually launches a worker thread to do so. Except, if
97 ** there are already N worker threads running, the main thread does the work 97 ** there are already N worker threads running, the main thread does the work
98 ** itself. 98 ** itself.
99 ** 99 **
100 ** The sorter is running in multi-threaded mode if (a) the library was built 100 ** The sorter is running in multi-threaded mode if (a) the library was built
101 ** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater 101 ** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
102 ** than zero, and (b) worker threads have been enabled at runtime by calling 102 ** than zero, and (b) worker threads have been enabled at runtime by calling
103 ** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...). 103 ** "PRAGMA threads=N" with some value of N greater than 0.
104 ** 104 **
105 ** When Rewind() is called, any data remaining in memory is flushed to a 105 ** When Rewind() is called, any data remaining in memory is flushed to a
106 ** final PMA. So at this point the data is stored in some number of sorted 106 ** final PMA. So at this point the data is stored in some number of sorted
107 ** PMAs within temporary files on disk. 107 ** PMAs within temporary files on disk.
108 ** 108 **
109 ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the 109 ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
110 ** sorter is running in single-threaded mode, then these PMAs are merged 110 ** sorter is running in single-threaded mode, then these PMAs are merged
111 ** incrementally as keys are retreived from the sorter by the VDBE. The 111 ** incrementally as keys are retreived from the sorter by the VDBE. The
112 ** MergeEngine object, described in further detail below, performs this 112 ** MergeEngine object, described in further detail below, performs this
113 ** merge. 113 ** merge.
(...skipping 27 matching lines...) Expand all
141 /* 141 /*
142 ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various 142 ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
143 ** messages to stderr that may be helpful in understanding the performance 143 ** messages to stderr that may be helpful in understanding the performance
144 ** characteristics of the sorter in multi-threaded mode. 144 ** characteristics of the sorter in multi-threaded mode.
145 */ 145 */
146 #if 0 146 #if 0
147 # define SQLITE_DEBUG_SORTER_THREADS 1 147 # define SQLITE_DEBUG_SORTER_THREADS 1
148 #endif 148 #endif
149 149
150 /* 150 /*
151 ** Hard-coded maximum amount of data to accumulate in memory before flushing
152 ** to a level 0 PMA. The purpose of this limit is to prevent various integer
153 ** overflows. 512MiB.
154 */
155 #define SQLITE_MAX_PMASZ (1<<29)
156
157 /*
151 ** Private objects used by the sorter 158 ** Private objects used by the sorter
152 */ 159 */
153 typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ 160 typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
154 typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ 161 typedef struct PmaReader PmaReader; /* Incrementally read one PMA */
155 typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ 162 typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */
156 typedef struct SorterRecord SorterRecord; /* A record being sorted */ 163 typedef struct SorterRecord SorterRecord; /* A record being sorted */
157 typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ 164 typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */
158 typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ 165 typedef struct SorterFile SorterFile; /* Temporary file object wrapper */
159 typedef struct SorterList SorterList; /* In-memory list of records */ 166 typedef struct SorterList SorterList; /* In-memory list of records */
160 typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ 167 typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 ** to block until it finishes). 284 ** to block until it finishes).
278 ** 285 **
279 ** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call 286 ** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call
280 ** to sqlite3ThreadJoin() is likely to block. Cases that are likely to 287 ** to sqlite3ThreadJoin() is likely to block. Cases that are likely to
281 ** block provoke debugging output. 288 ** block provoke debugging output.
282 ** 289 **
283 ** In both cases, the effects of the main thread seeing (bDone==0) even 290 ** In both cases, the effects of the main thread seeing (bDone==0) even
284 ** after the thread has finished are not dire. So we don't worry about 291 ** after the thread has finished are not dire. So we don't worry about
285 ** memory barriers and such here. 292 ** memory barriers and such here.
286 */ 293 */
294 typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
287 struct SortSubtask { 295 struct SortSubtask {
288 SQLiteThread *pThread; /* Background thread, if any */ 296 SQLiteThread *pThread; /* Background thread, if any */
289 int bDone; /* Set if thread is finished but not joined */ 297 int bDone; /* Set if thread is finished but not joined */
290 VdbeSorter *pSorter; /* Sorter that owns this sub-task */ 298 VdbeSorter *pSorter; /* Sorter that owns this sub-task */
291 UnpackedRecord *pUnpacked; /* Space to unpack a record */ 299 UnpackedRecord *pUnpacked; /* Space to unpack a record */
292 SorterList list; /* List for thread to write to a PMA */ 300 SorterList list; /* List for thread to write to a PMA */
293 int nPMA; /* Number of PMAs currently in file */ 301 int nPMA; /* Number of PMAs currently in file */
302 SorterCompare xCompare; /* Compare function to use */
294 SorterFile file; /* Temp file for level-0 PMAs */ 303 SorterFile file; /* Temp file for level-0 PMAs */
295 SorterFile file2; /* Space for other PMAs */ 304 SorterFile file2; /* Space for other PMAs */
296 }; 305 };
297 306
307
298 /* 308 /*
299 ** Main sorter structure. A single instance of this is allocated for each 309 ** Main sorter structure. A single instance of this is allocated for each
300 ** sorter cursor created by the VDBE. 310 ** sorter cursor created by the VDBE.
301 ** 311 **
302 ** mxKeysize: 312 ** mxKeysize:
303 ** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(), 313 ** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
304 ** this variable is updated so as to be set to the size on disk of the 314 ** this variable is updated so as to be set to the size on disk of the
305 ** largest record in the sorter. 315 ** largest record in the sorter.
306 */ 316 */
307 struct VdbeSorter { 317 struct VdbeSorter {
308 int mnPmaSize; /* Minimum PMA size, in bytes */ 318 int mnPmaSize; /* Minimum PMA size, in bytes */
309 int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ 319 int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */
310 int mxKeysize; /* Largest serialized key seen so far */ 320 int mxKeysize; /* Largest serialized key seen so far */
311 int pgsz; /* Main database page size */ 321 int pgsz; /* Main database page size */
312 PmaReader *pReader; /* Readr data from here after Rewind() */ 322 PmaReader *pReader; /* Readr data from here after Rewind() */
313 MergeEngine *pMerger; /* Or here, if bUseThreads==0 */ 323 MergeEngine *pMerger; /* Or here, if bUseThreads==0 */
314 sqlite3 *db; /* Database connection */ 324 sqlite3 *db; /* Database connection */
315 KeyInfo *pKeyInfo; /* How to compare records */ 325 KeyInfo *pKeyInfo; /* How to compare records */
316 UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */ 326 UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */
317 SorterList list; /* List of in-memory records */ 327 SorterList list; /* List of in-memory records */
318 int iMemory; /* Offset of free space in list.aMemory */ 328 int iMemory; /* Offset of free space in list.aMemory */
319 int nMemory; /* Size of list.aMemory allocation in bytes */ 329 int nMemory; /* Size of list.aMemory allocation in bytes */
320 u8 bUsePMA; /* True if one or more PMAs created */ 330 u8 bUsePMA; /* True if one or more PMAs created */
321 u8 bUseThreads; /* True to use background threads */ 331 u8 bUseThreads; /* True to use background threads */
322 u8 iPrev; /* Previous thread used to flush PMA */ 332 u8 iPrev; /* Previous thread used to flush PMA */
323 u8 nTask; /* Size of aTask[] array */ 333 u8 nTask; /* Size of aTask[] array */
334 u8 typeMask;
324 SortSubtask aTask[1]; /* One or more subtasks */ 335 SortSubtask aTask[1]; /* One or more subtasks */
325 }; 336 };
326 337
338 #define SORTER_TYPE_INTEGER 0x01
339 #define SORTER_TYPE_TEXT 0x02
340
327 /* 341 /*
328 ** An instance of the following object is used to read records out of a 342 ** An instance of the following object is used to read records out of a
329 ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. 343 ** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
330 ** aKey might point into aMap or into aBuffer. If neither of those locations 344 ** aKey might point into aMap or into aBuffer. If neither of those locations
331 ** contain a contiguous representation of the key, then aAlloc is allocated 345 ** contain a contiguous representation of the key, then aAlloc is allocated
332 ** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. 346 ** and the key is copied into aAlloc and aKey is made to poitn to aAlloc.
333 ** 347 **
334 ** pFd==0 at EOF. 348 ** pFd==0 at EOF.
335 */ 349 */
336 struct PmaReader { 350 struct PmaReader {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 /* The data for the record immediately follows this header */ 448 /* The data for the record immediately follows this header */
435 }; 449 };
436 450
437 /* Return a pointer to the buffer containing the record data for SorterRecord 451 /* Return a pointer to the buffer containing the record data for SorterRecord
438 ** object p. Should be used as if: 452 ** object p. Should be used as if:
439 ** 453 **
440 ** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } 454 ** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
441 */ 455 */
442 #define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) 456 #define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
443 457
444 /* The minimum PMA size is set to this value multiplied by the database
445 ** page size in bytes. */
446 #define SORTER_MIN_WORKING 10
447 458
448 /* Maximum number of PMAs that a single MergeEngine can merge */ 459 /* Maximum number of PMAs that a single MergeEngine can merge */
449 #define SORTER_MAX_MERGE_COUNT 16 460 #define SORTER_MAX_MERGE_COUNT 16
450 461
451 static int vdbeIncrSwap(IncrMerger*); 462 static int vdbeIncrSwap(IncrMerger*);
452 static void vdbeIncrFree(IncrMerger *); 463 static void vdbeIncrFree(IncrMerger *);
453 464
454 /* 465 /*
455 ** Free all memory belonging to the PmaReader object passed as the 466 ** Free all memory belonging to the PmaReader object passed as the
456 ** argument. All structure fields are set to zero before returning. 467 ** argument. All structure fields are set to zero before returning.
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 pReadr->iEof = pReadr->iReadOff + nByte; 742 pReadr->iEof = pReadr->iReadOff + nByte;
732 *pnByte += nByte; 743 *pnByte += nByte;
733 } 744 }
734 745
735 if( rc==SQLITE_OK ){ 746 if( rc==SQLITE_OK ){
736 rc = vdbePmaReaderNext(pReadr); 747 rc = vdbePmaReaderNext(pReadr);
737 } 748 }
738 return rc; 749 return rc;
739 } 750 }
740 751
752 /*
753 ** A version of vdbeSorterCompare() that assumes that it has already been
754 ** determined that the first field of key1 is equal to the first field of
755 ** key2.
756 */
757 static int vdbeSorterCompareTail(
758 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
759 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
760 const void *pKey1, int nKey1, /* Left side of comparison */
761 const void *pKey2, int nKey2 /* Right side of comparison */
762 ){
763 UnpackedRecord *r2 = pTask->pUnpacked;
764 if( *pbKey2Cached==0 ){
765 sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
766 *pbKey2Cached = 1;
767 }
768 return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
769 }
741 770
742 /* 771 /*
743 ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, 772 ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
744 ** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences 773 ** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
745 ** used by the comparison. Return the result of the comparison. 774 ** used by the comparison. Return the result of the comparison.
746 ** 775 **
747 ** Before returning, object (pTask->pUnpacked) is populated with the 776 ** If IN/OUT parameter *pbKey2Cached is true when this function is called,
748 ** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it 777 ** it is assumed that (pTask->pUnpacked) contains the unpacked version
749 ** is assumed that the (pTask->pUnpacked) structure already contains the 778 ** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
750 ** unpacked key to use as key2. 779 ** version of key2 and *pbKey2Cached set to true before returning.
751 ** 780 **
752 ** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set 781 ** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
753 ** to SQLITE_NOMEM. 782 ** to SQLITE_NOMEM.
754 */ 783 */
755 static int vdbeSorterCompare( 784 static int vdbeSorterCompare(
756 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ 785 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
786 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
757 const void *pKey1, int nKey1, /* Left side of comparison */ 787 const void *pKey1, int nKey1, /* Left side of comparison */
758 const void *pKey2, int nKey2 /* Right side of comparison */ 788 const void *pKey2, int nKey2 /* Right side of comparison */
759 ){ 789 ){
760 UnpackedRecord *r2 = pTask->pUnpacked; 790 UnpackedRecord *r2 = pTask->pUnpacked;
761 if( pKey2 ){ 791 if( !*pbKey2Cached ){
762 sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); 792 sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
793 *pbKey2Cached = 1;
763 } 794 }
764 return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); 795 return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
765 } 796 }
766 797
767 /* 798 /*
799 ** A specially optimized version of vdbeSorterCompare() that assumes that
800 ** the first field of each key is a TEXT value and that the collation
801 ** sequence to compare them with is BINARY.
802 */
803 static int vdbeSorterCompareText(
804 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
805 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
806 const void *pKey1, int nKey1, /* Left side of comparison */
807 const void *pKey2, int nKey2 /* Right side of comparison */
808 ){
809 const u8 * const p1 = (const u8 * const)pKey1;
810 const u8 * const p2 = (const u8 * const)pKey2;
811 const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
812 const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
813
814 int n1;
815 int n2;
816 int res;
817
818 getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
819 getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
820 res = memcmp(v1, v2, MIN(n1, n2));
821 if( res==0 ){
822 res = n1 - n2;
823 }
824
825 if( res==0 ){
826 if( pTask->pSorter->pKeyInfo->nField>1 ){
827 res = vdbeSorterCompareTail(
828 pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
829 );
830 }
831 }else{
832 if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
833 res = res * -1;
834 }
835 }
836
837 return res;
838 }
839
840 /*
841 ** A specially optimized version of vdbeSorterCompare() that assumes that
842 ** the first field of each key is an INTEGER value.
843 */
844 static int vdbeSorterCompareInt(
845 SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
846 int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
847 const void *pKey1, int nKey1, /* Left side of comparison */
848 const void *pKey2, int nKey2 /* Right side of comparison */
849 ){
850 const u8 * const p1 = (const u8 * const)pKey1;
851 const u8 * const p2 = (const u8 * const)pKey2;
852 const int s1 = p1[1]; /* Left hand serial type */
853 const int s2 = p2[1]; /* Right hand serial type */
854 const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
855 const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
856 int res; /* Return value */
857
858 assert( (s1>0 && s1<7) || s1==8 || s1==9 );
859 assert( (s2>0 && s2<7) || s2==8 || s2==9 );
860
861 if( s1>7 && s2>7 ){
862 res = s1 - s2;
863 }else{
864 if( s1==s2 ){
865 if( (*v1 ^ *v2) & 0x80 ){
866 /* The two values have different signs */
867 res = (*v1 & 0x80) ? -1 : +1;
868 }else{
869 /* The two values have the same sign. Compare using memcmp(). */
870 static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
871 int i;
872 res = 0;
873 for(i=0; i<aLen[s1]; i++){
874 if( (res = v1[i] - v2[i]) ) break;
875 }
876 }
877 }else{
878 if( s2>7 ){
879 res = +1;
880 }else if( s1>7 ){
881 res = -1;
882 }else{
883 res = s1 - s2;
884 }
885 assert( res!=0 );
886
887 if( res>0 ){
888 if( *v1 & 0x80 ) res = -1;
889 }else{
890 if( *v2 & 0x80 ) res = +1;
891 }
892 }
893 }
894
895 if( res==0 ){
896 if( pTask->pSorter->pKeyInfo->nField>1 ){
897 res = vdbeSorterCompareTail(
898 pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
899 );
900 }
901 }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
902 res = res * -1;
903 }
904
905 return res;
906 }
907
908 /*
768 ** Initialize the temporary index cursor just opened as a sorter cursor. 909 ** Initialize the temporary index cursor just opened as a sorter cursor.
769 ** 910 **
770 ** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField) 911 ** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
771 ** to determine the number of fields that should be compared from the 912 ** to determine the number of fields that should be compared from the
772 ** records being sorted. However, if the value passed as argument nField 913 ** records being sorted. However, if the value passed as argument nField
773 ** is non-zero and the sorter is able to guarantee a stable sort, nField 914 ** is non-zero and the sorter is able to guarantee a stable sort, nField
774 ** is used instead. This is used when sorting records for a CREATE INDEX 915 ** is used instead. This is used when sorting records for a CREATE INDEX
775 ** statement. In this case, keys are always delivered to the sorter in 916 ** statement. In this case, keys are always delivered to the sorter in
776 ** order of the primary key, which happens to be make up the final part 917 ** order of the primary key, which happens to be make up the final part
777 ** of the records being sorted. So if the sort is stable, there is never 918 ** of the records being sorted. So if the sort is stable, there is never
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 954
814 /* Do not allow the total number of threads (main thread + all workers) 955 /* Do not allow the total number of threads (main thread + all workers)
815 ** to exceed the maximum merge count */ 956 ** to exceed the maximum merge count */
816 #if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT 957 #if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT
817 if( nWorker>=SORTER_MAX_MERGE_COUNT ){ 958 if( nWorker>=SORTER_MAX_MERGE_COUNT ){
818 nWorker = SORTER_MAX_MERGE_COUNT-1; 959 nWorker = SORTER_MAX_MERGE_COUNT-1;
819 } 960 }
820 #endif 961 #endif
821 962
822 assert( pCsr->pKeyInfo && pCsr->pBt==0 ); 963 assert( pCsr->pKeyInfo && pCsr->pBt==0 );
964 assert( pCsr->eCurType==CURTYPE_SORTER );
823 szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); 965 szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
824 sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); 966 sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
825 967
826 pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); 968 pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
827 pCsr->pSorter = pSorter; 969 pCsr->uc.pSorter = pSorter;
828 if( pSorter==0 ){ 970 if( pSorter==0 ){
829 rc = SQLITE_NOMEM; 971 rc = SQLITE_NOMEM;
830 }else{ 972 }else{
831 pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); 973 pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
832 memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); 974 memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
833 pKeyInfo->db = 0; 975 pKeyInfo->db = 0;
834 if( nField && nWorker==0 ) pKeyInfo->nField = nField; 976 if( nField && nWorker==0 ){
977 pKeyInfo->nXField += (pKeyInfo->nField - nField);
978 pKeyInfo->nField = nField;
979 }
835 pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); 980 pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
836 pSorter->nTask = nWorker + 1; 981 pSorter->nTask = nWorker + 1;
982 pSorter->iPrev = (u8)(nWorker - 1);
837 pSorter->bUseThreads = (pSorter->nTask>1); 983 pSorter->bUseThreads = (pSorter->nTask>1);
838 pSorter->db = db; 984 pSorter->db = db;
839 for(i=0; i<pSorter->nTask; i++){ 985 for(i=0; i<pSorter->nTask; i++){
840 SortSubtask *pTask = &pSorter->aTask[i]; 986 SortSubtask *pTask = &pSorter->aTask[i];
841 pTask->pSorter = pSorter; 987 pTask->pSorter = pSorter;
842 } 988 }
843 989
844 if( !sqlite3TempInMemory(db) ){ 990 if( !sqlite3TempInMemory(db) ){
845 pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; 991 u32 szPma = sqlite3GlobalConfig.szPma;
992 pSorter->mnPmaSize = szPma * pgsz;
846 mxCache = db->aDb[0].pSchema->cache_size; 993 mxCache = db->aDb[0].pSchema->cache_size;
847 if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; 994 if( mxCache<(int)szPma ) mxCache = (int)szPma;
848 pSorter->mxPmaSize = mxCache * pgsz; 995 pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
849 996
850 /* If the application has not configure scratch memory using 997 /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
851 ** SQLITE_CONFIG_SCRATCH then we assume it is OK to do large memory 998 ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
852 ** allocations. If scratch memory has been configured, then assume 999 ** large heap allocations.
853 ** large memory allocations should be avoided to prevent heap
854 ** fragmentation.
855 */ 1000 */
856 if( sqlite3GlobalConfig.pScratch==0 ){ 1001 if( sqlite3GlobalConfig.pScratch==0 ){
857 assert( pSorter->iMemory==0 ); 1002 assert( pSorter->iMemory==0 );
858 pSorter->nMemory = pgsz; 1003 pSorter->nMemory = pgsz;
859 pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); 1004 pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
860 if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM; 1005 if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
861 } 1006 }
862 } 1007 }
1008
1009 if( (pKeyInfo->nField+pKeyInfo->nXField)<13
1010 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
1011 ){
1012 pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
1013 }
863 } 1014 }
864 1015
865 return rc; 1016 return rc;
866 } 1017 }
867 #undef nWorker /* Defined at the top of this function */ 1018 #undef nWorker /* Defined at the top of this function */
868 1019
869 /* 1020 /*
870 ** Free the list of sorted records starting at pRecord. 1021 ** Free the list of sorted records starting at pRecord.
871 */ 1022 */
872 static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ 1023 static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
873 SorterRecord *p; 1024 SorterRecord *p;
874 SorterRecord *pNext; 1025 SorterRecord *pNext;
875 for(p=pRecord; p; p=pNext){ 1026 for(p=pRecord; p; p=pNext){
876 pNext = p->u.pNext; 1027 pNext = p->u.pNext;
877 sqlite3DbFree(db, p); 1028 sqlite3DbFree(db, p);
878 } 1029 }
879 } 1030 }
880 1031
881 /* 1032 /*
882 ** Free all resources owned by the object indicated by argument pTask. All 1033 ** Free all resources owned by the object indicated by argument pTask. All
883 ** fields of *pTask are zeroed before returning. 1034 ** fields of *pTask are zeroed before returning.
884 */ 1035 */
885 static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ 1036 static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
886 sqlite3DbFree(db, pTask->pUnpacked); 1037 sqlite3DbFree(db, pTask->pUnpacked);
887 pTask->pUnpacked = 0;
888 #if SQLITE_MAX_WORKER_THREADS>0 1038 #if SQLITE_MAX_WORKER_THREADS>0
889 /* pTask->list.aMemory can only be non-zero if it was handed memory 1039 /* pTask->list.aMemory can only be non-zero if it was handed memory
890 ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ 1040 ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
891 if( pTask->list.aMemory ){ 1041 if( pTask->list.aMemory ){
892 sqlite3_free(pTask->list.aMemory); 1042 sqlite3_free(pTask->list.aMemory);
893 pTask->list.aMemory = 0;
894 }else 1043 }else
895 #endif 1044 #endif
896 { 1045 {
897 assert( pTask->list.aMemory==0 ); 1046 assert( pTask->list.aMemory==0 );
898 vdbeSorterRecordFree(0, pTask->list.pList); 1047 vdbeSorterRecordFree(0, pTask->list.pList);
899 } 1048 }
900 pTask->list.pList = 0;
901 if( pTask->file.pFd ){ 1049 if( pTask->file.pFd ){
902 sqlite3OsCloseFree(pTask->file.pFd); 1050 sqlite3OsCloseFree(pTask->file.pFd);
903 pTask->file.pFd = 0;
904 pTask->file.iEof = 0;
905 } 1051 }
906 if( pTask->file2.pFd ){ 1052 if( pTask->file2.pFd ){
907 sqlite3OsCloseFree(pTask->file2.pFd); 1053 sqlite3OsCloseFree(pTask->file2.pFd);
908 pTask->file2.pFd = 0;
909 pTask->file2.iEof = 0;
910 } 1054 }
1055 memset(pTask, 0, sizeof(SortSubtask));
911 } 1056 }
912 1057
913 #ifdef SQLITE_DEBUG_SORTER_THREADS 1058 #ifdef SQLITE_DEBUG_SORTER_THREADS
914 static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ 1059 static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
915 i64 t; 1060 i64 t;
916 int iTask = (pTask - pTask->pSorter->aTask); 1061 int iTask = (pTask - pTask->pSorter->aTask);
917 sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); 1062 sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
918 fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); 1063 fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent);
919 } 1064 }
920 static void vdbeSorterRewindDebug(const char *zEvent){ 1065 static void vdbeSorterRewindDebug(const char *zEvent){
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 vdbePmaReaderClear(pSorter->pReader); 1225 vdbePmaReaderClear(pSorter->pReader);
1081 sqlite3DbFree(db, pSorter->pReader); 1226 sqlite3DbFree(db, pSorter->pReader);
1082 pSorter->pReader = 0; 1227 pSorter->pReader = 0;
1083 } 1228 }
1084 #endif 1229 #endif
1085 vdbeMergeEngineFree(pSorter->pMerger); 1230 vdbeMergeEngineFree(pSorter->pMerger);
1086 pSorter->pMerger = 0; 1231 pSorter->pMerger = 0;
1087 for(i=0; i<pSorter->nTask; i++){ 1232 for(i=0; i<pSorter->nTask; i++){
1088 SortSubtask *pTask = &pSorter->aTask[i]; 1233 SortSubtask *pTask = &pSorter->aTask[i];
1089 vdbeSortSubtaskCleanup(db, pTask); 1234 vdbeSortSubtaskCleanup(db, pTask);
1235 pTask->pSorter = pSorter;
1090 } 1236 }
1091 if( pSorter->list.aMemory==0 ){ 1237 if( pSorter->list.aMemory==0 ){
1092 vdbeSorterRecordFree(0, pSorter->list.pList); 1238 vdbeSorterRecordFree(0, pSorter->list.pList);
1093 } 1239 }
1094 pSorter->list.pList = 0; 1240 pSorter->list.pList = 0;
1095 pSorter->list.szPMA = 0; 1241 pSorter->list.szPMA = 0;
1096 pSorter->bUsePMA = 0; 1242 pSorter->bUsePMA = 0;
1097 pSorter->iMemory = 0; 1243 pSorter->iMemory = 0;
1098 pSorter->mxKeysize = 0; 1244 pSorter->mxKeysize = 0;
1099 sqlite3DbFree(db, pSorter->pUnpacked); 1245 sqlite3DbFree(db, pSorter->pUnpacked);
1100 pSorter->pUnpacked = 0; 1246 pSorter->pUnpacked = 0;
1101 } 1247 }
1102 1248
1103 /* 1249 /*
1104 ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. 1250 ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
1105 */ 1251 */
1106 void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ 1252 void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
1107 VdbeSorter *pSorter = pCsr->pSorter; 1253 VdbeSorter *pSorter;
1254 assert( pCsr->eCurType==CURTYPE_SORTER );
1255 pSorter = pCsr->uc.pSorter;
1108 if( pSorter ){ 1256 if( pSorter ){
1109 sqlite3VdbeSorterReset(db, pSorter); 1257 sqlite3VdbeSorterReset(db, pSorter);
1110 sqlite3_free(pSorter->list.aMemory); 1258 sqlite3_free(pSorter->list.aMemory);
1111 sqlite3DbFree(db, pSorter); 1259 sqlite3DbFree(db, pSorter);
1112 pCsr->pSorter = 0; 1260 pCsr->uc.pSorter = 0;
1113 } 1261 }
1114 } 1262 }
1115 1263
1116 #if SQLITE_MAX_MMAP_SIZE>0 1264 #if SQLITE_MAX_MMAP_SIZE>0
1117 /* 1265 /*
1118 ** The first argument is a file-handle open on a temporary file. The file 1266 ** The first argument is a file-handle open on a temporary file. The file
1119 ** is guaranteed to be nByte bytes or smaller in size. This function 1267 ** is guaranteed to be nByte bytes or smaller in size. This function
1120 ** attempts to extend the file to nByte bytes in size and to ensure that 1268 ** attempts to extend the file to nByte bytes in size and to ensure that
1121 ** the VFS has memory mapped it. 1269 ** the VFS has memory mapped it.
1122 ** 1270 **
1123 ** Whether or not the file does end up memory mapped of course depends on 1271 ** Whether or not the file does end up memory mapped of course depends on
1124 ** the specific VFS implementation. 1272 ** the specific VFS implementation.
1125 */ 1273 */
1126 static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ 1274 static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
1127 if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ 1275 if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
1128 int rc = sqlite3OsTruncate(pFd, nByte); 1276 void *p = 0;
1129 if( rc==SQLITE_OK ){ 1277 int chunksize = 4*1024;
1130 void *p = 0; 1278 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
1131 sqlite3OsFetch(pFd, 0, (int)nByte, &p); 1279 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
1132 sqlite3OsUnfetch(pFd, 0, p); 1280 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
1133 } 1281 sqlite3OsUnfetch(pFd, 0, p);
1134 } 1282 }
1135 } 1283 }
1136 #else 1284 #else
1137 # define vdbeSorterExtendFile(x,y,z) 1285 # define vdbeSorterExtendFile(x,y,z)
1138 #endif 1286 #endif
1139 1287
1140 /* 1288 /*
1141 ** Allocate space for a file-handle and open a temporary file. If successful, 1289 ** Allocate space for a file-handle and open a temporary file. If successful,
1142 ** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. 1290 ** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK.
1143 ** Otherwise, set *ppFd to 0 and return an SQLite error code. 1291 ** Otherwise, set *ppFd to 0 and return an SQLite error code.
1144 */ 1292 */
1145 static int vdbeSorterOpenTempFile( 1293 static int vdbeSorterOpenTempFile(
1146 sqlite3 *db, /* Database handle doing sort */ 1294 sqlite3 *db, /* Database handle doing sort */
1147 i64 nExtend, /* Attempt to extend file to this size */ 1295 i64 nExtend, /* Attempt to extend file to this size */
1148 sqlite3_file **ppFd 1296 sqlite3_file **ppFd
1149 ){ 1297 ){
1150 int rc; 1298 int rc;
1299 if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS;
1151 rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, 1300 rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd,
1152 SQLITE_OPEN_TEMP_JOURNAL | 1301 SQLITE_OPEN_TEMP_JOURNAL |
1153 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | 1302 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
1154 SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc 1303 SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc
1155 ); 1304 );
1156 if( rc==SQLITE_OK ){ 1305 if( rc==SQLITE_OK ){
1157 i64 max = SQLITE_MAX_MMAP_SIZE; 1306 i64 max = SQLITE_MAX_MMAP_SIZE;
1158 sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); 1307 sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max);
1159 if( nExtend>0 ){ 1308 if( nExtend>0 ){
1160 vdbeSorterExtendFile(db, *ppFd, nExtend); 1309 vdbeSorterExtendFile(db, *ppFd, nExtend);
(...skipping 27 matching lines...) Expand all
1188 ** Set *ppOut to the head of the new list. 1337 ** Set *ppOut to the head of the new list.
1189 */ 1338 */
1190 static void vdbeSorterMerge( 1339 static void vdbeSorterMerge(
1191 SortSubtask *pTask, /* Calling thread context */ 1340 SortSubtask *pTask, /* Calling thread context */
1192 SorterRecord *p1, /* First list to merge */ 1341 SorterRecord *p1, /* First list to merge */
1193 SorterRecord *p2, /* Second list to merge */ 1342 SorterRecord *p2, /* Second list to merge */
1194 SorterRecord **ppOut /* OUT: Head of merged list */ 1343 SorterRecord **ppOut /* OUT: Head of merged list */
1195 ){ 1344 ){
1196 SorterRecord *pFinal = 0; 1345 SorterRecord *pFinal = 0;
1197 SorterRecord **pp = &pFinal; 1346 SorterRecord **pp = &pFinal;
1198 void *pVal2 = p2 ? SRVAL(p2) : 0; 1347 int bCached = 0;
1199 1348
1200 while( p1 && p2 ){ 1349 while( p1 && p2 ){
1201 int res; 1350 int res;
1202 res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal); 1351 res = pTask->xCompare(
1352 pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
1353 );
1354
1203 if( res<=0 ){ 1355 if( res<=0 ){
1204 *pp = p1; 1356 *pp = p1;
1205 pp = &p1->u.pNext; 1357 pp = &p1->u.pNext;
1206 p1 = p1->u.pNext; 1358 p1 = p1->u.pNext;
1207 pVal2 = 0;
1208 }else{ 1359 }else{
1209 *pp = p2; 1360 *pp = p2;
1210 pp = &p2->u.pNext; 1361 pp = &p2->u.pNext;
1211 p2 = p2->u.pNext; 1362 p2 = p2->u.pNext;
1212 if( p2==0 ) break; 1363 bCached = 0;
1213 pVal2 = SRVAL(p2);
1214 } 1364 }
1215 } 1365 }
1216 *pp = p1 ? p1 : p2; 1366 *pp = p1 ? p1 : p2;
1217 *ppOut = pFinal; 1367 *ppOut = pFinal;
1218 } 1368 }
1219 1369
1220 /* 1370 /*
1371 ** Return the SorterCompare function to compare values collected by the
1372 ** sorter object passed as the only argument.
1373 */
1374 static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
1375 if( p->typeMask==SORTER_TYPE_INTEGER ){
1376 return vdbeSorterCompareInt;
1377 }else if( p->typeMask==SORTER_TYPE_TEXT ){
1378 return vdbeSorterCompareText;
1379 }
1380 return vdbeSorterCompare;
1381 }
1382
1383 /*
1221 ** Sort the linked list of records headed at pTask->pList. Return 1384 ** Sort the linked list of records headed at pTask->pList. Return
1222 ** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if 1385 ** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
1223 ** an error occurs. 1386 ** an error occurs.
1224 */ 1387 */
1225 static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ 1388 static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
1226 int i; 1389 int i;
1227 SorterRecord **aSlot; 1390 SorterRecord **aSlot;
1228 SorterRecord *p; 1391 SorterRecord *p;
1229 int rc; 1392 int rc;
1230 1393
1231 rc = vdbeSortAllocUnpacked(pTask); 1394 rc = vdbeSortAllocUnpacked(pTask);
1232 if( rc!=SQLITE_OK ) return rc; 1395 if( rc!=SQLITE_OK ) return rc;
1233 1396
1397 p = pList->pList;
1398 pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
1399
1234 aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); 1400 aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
1235 if( !aSlot ){ 1401 if( !aSlot ){
1236 return SQLITE_NOMEM; 1402 return SQLITE_NOMEM;
1237 } 1403 }
1238 1404
1239 p = pList->pList;
1240 while( p ){ 1405 while( p ){
1241 SorterRecord *pNext; 1406 SorterRecord *pNext;
1242 if( pList->aMemory ){ 1407 if( pList->aMemory ){
1243 if( (u8*)p==pList->aMemory ){ 1408 if( (u8*)p==pList->aMemory ){
1244 pNext = 0; 1409 pNext = 0;
1245 }else{ 1410 }else{
1246 assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) ); 1411 assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) );
1247 pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; 1412 pNext = (SorterRecord*)&pList->aMemory[p->u.iNext];
1248 } 1413 }
1249 }else{ 1414 }else{
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 SortSubtask *pTask = pMerger->pTask; 1608 SortSubtask *pTask = pMerger->pTask;
1444 1609
1445 /* Advance the current PmaReader */ 1610 /* Advance the current PmaReader */
1446 rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); 1611 rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
1447 1612
1448 /* Update contents of aTree[] */ 1613 /* Update contents of aTree[] */
1449 if( rc==SQLITE_OK ){ 1614 if( rc==SQLITE_OK ){
1450 int i; /* Index of aTree[] to recalculate */ 1615 int i; /* Index of aTree[] to recalculate */
1451 PmaReader *pReadr1; /* First PmaReader to compare */ 1616 PmaReader *pReadr1; /* First PmaReader to compare */
1452 PmaReader *pReadr2; /* Second PmaReader to compare */ 1617 PmaReader *pReadr2; /* Second PmaReader to compare */
1453 u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */ 1618 int bCached = 0;
1454 1619
1455 /* Find the first two PmaReaders to compare. The one that was just 1620 /* Find the first two PmaReaders to compare. The one that was just
1456 ** advanced (iPrev) and the one next to it in the array. */ 1621 ** advanced (iPrev) and the one next to it in the array. */
1457 pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; 1622 pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
1458 pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; 1623 pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
1459 pKey2 = pReadr2->aKey;
1460 1624
1461 for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ 1625 for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
1462 /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ 1626 /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
1463 int iRes; 1627 int iRes;
1464 if( pReadr1->pFd==0 ){ 1628 if( pReadr1->pFd==0 ){
1465 iRes = +1; 1629 iRes = +1;
1466 }else if( pReadr2->pFd==0 ){ 1630 }else if( pReadr2->pFd==0 ){
1467 iRes = -1; 1631 iRes = -1;
1468 }else{ 1632 }else{
1469 iRes = vdbeSorterCompare(pTask, 1633 iRes = pTask->xCompare(pTask, &bCached,
1470 pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey 1634 pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
1471 ); 1635 );
1472 } 1636 }
1473 1637
1474 /* If pReadr1 contained the smaller value, set aTree[i] to its index. 1638 /* If pReadr1 contained the smaller value, set aTree[i] to its index.
1475 ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this 1639 ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
1476 ** case there is no cache of pReadr2 in pTask->pUnpacked, so set 1640 ** case there is no cache of pReadr2 in pTask->pUnpacked, so set
1477 ** pKey2 to point to the record belonging to pReadr2. 1641 ** pKey2 to point to the record belonging to pReadr2.
1478 ** 1642 **
1479 ** Alternatively, if pReadr2 contains the smaller of the two values, 1643 ** Alternatively, if pReadr2 contains the smaller of the two values,
1480 ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() 1644 ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare()
1481 ** was actually called above, then pTask->pUnpacked now contains 1645 ** was actually called above, then pTask->pUnpacked now contains
1482 ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent 1646 ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent
1483 ** vdbeSorterCompare() from decoding pReadr2 again. 1647 ** vdbeSorterCompare() from decoding pReadr2 again.
1484 ** 1648 **
1485 ** If the two values were equal, then the value from the oldest 1649 ** If the two values were equal, then the value from the oldest
1486 ** PMA should be considered smaller. The VdbeSorter.aReadr[] array 1650 ** PMA should be considered smaller. The VdbeSorter.aReadr[] array
1487 ** is sorted from oldest to newest, so pReadr1 contains older values 1651 ** is sorted from oldest to newest, so pReadr1 contains older values
1488 ** than pReadr2 iff (pReadr1<pReadr2). */ 1652 ** than pReadr2 iff (pReadr1<pReadr2). */
1489 if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){ 1653 if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
1490 pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr); 1654 pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
1491 pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; 1655 pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
1492 pKey2 = pReadr2->aKey; 1656 bCached = 0;
1493 }else{ 1657 }else{
1494 if( pReadr1->pFd ) pKey2 = 0; 1658 if( pReadr1->pFd ) bCached = 0;
1495 pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); 1659 pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
1496 pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; 1660 pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
1497 } 1661 }
1498 } 1662 }
1499 *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); 1663 *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
1500 } 1664 }
1501 1665
1502 return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); 1666 return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc);
1503 } 1667 }
1504 1668
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 #endif /* SQLITE_MAX_WORKER_THREADS!=0 */ 1748 #endif /* SQLITE_MAX_WORKER_THREADS!=0 */
1585 } 1749 }
1586 1750
1587 /* 1751 /*
1588 ** Add a record to the sorter. 1752 ** Add a record to the sorter.
1589 */ 1753 */
1590 int sqlite3VdbeSorterWrite( 1754 int sqlite3VdbeSorterWrite(
1591 const VdbeCursor *pCsr, /* Sorter cursor */ 1755 const VdbeCursor *pCsr, /* Sorter cursor */
1592 Mem *pVal /* Memory cell containing record */ 1756 Mem *pVal /* Memory cell containing record */
1593 ){ 1757 ){
1594 VdbeSorter *pSorter = pCsr->pSorter; 1758 VdbeSorter *pSorter;
1595 int rc = SQLITE_OK; /* Return Code */ 1759 int rc = SQLITE_OK; /* Return Code */
1596 SorterRecord *pNew; /* New list element */ 1760 SorterRecord *pNew; /* New list element */
1597
1598 int bFlush; /* True to flush contents of memory to PMA */ 1761 int bFlush; /* True to flush contents of memory to PMA */
1599 int nReq; /* Bytes of memory required */ 1762 int nReq; /* Bytes of memory required */
1600 int nPMA; /* Bytes of PMA space required */ 1763 int nPMA; /* Bytes of PMA space required */
1764 int t; /* serial type of first record field */
1765
1766 assert( pCsr->eCurType==CURTYPE_SORTER );
1767 pSorter = pCsr->uc.pSorter;
1768 getVarint32((const u8*)&pVal->z[1], t);
1769 if( t>0 && t<10 && t!=7 ){
1770 pSorter->typeMask &= SORTER_TYPE_INTEGER;
1771 }else if( t>10 && (t & 0x01) ){
1772 pSorter->typeMask &= SORTER_TYPE_TEXT;
1773 }else{
1774 pSorter->typeMask = 0;
1775 }
1601 1776
1602 assert( pSorter ); 1777 assert( pSorter );
1603 1778
1604 /* Figure out whether or not the current contents of memory should be 1779 /* Figure out whether or not the current contents of memory should be
1605 ** flushed to a PMA before continuing. If so, do so. 1780 ** flushed to a PMA before continuing. If so, do so.
1606 ** 1781 **
1607 ** If using the single large allocation mode (pSorter->aMemory!=0), then 1782 ** If using the single large allocation mode (pSorter->aMemory!=0), then
1608 ** flush the contents of memory to a new PMA if (a) at least one value is 1783 ** flush the contents of memory to a new PMA if (a) at least one value is
1609 ** already in memory and (b) the new value will not fit in memory. 1784 ** already in memory and (b) the new value will not fit in memory.
1610 ** 1785 **
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 } 2031 }
1857 2032
1858 p1 = &pMerger->aReadr[i1]; 2033 p1 = &pMerger->aReadr[i1];
1859 p2 = &pMerger->aReadr[i2]; 2034 p2 = &pMerger->aReadr[i2];
1860 2035
1861 if( p1->pFd==0 ){ 2036 if( p1->pFd==0 ){
1862 iRes = i2; 2037 iRes = i2;
1863 }else if( p2->pFd==0 ){ 2038 }else if( p2->pFd==0 ){
1864 iRes = i1; 2039 iRes = i1;
1865 }else{ 2040 }else{
2041 SortSubtask *pTask = pMerger->pTask;
2042 int bCached = 0;
1866 int res; 2043 int res;
1867 assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ 2044 assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
1868 res = vdbeSorterCompare( 2045 res = pTask->xCompare(
1869 pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey 2046 pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
1870 ); 2047 );
1871 if( res<=0 ){ 2048 if( res<=0 ){
1872 iRes = i1; 2049 iRes = i1;
1873 }else{ 2050 }else{
1874 iRes = i2; 2051 iRes = i2;
1875 } 2052 }
1876 } 2053 }
1877 2054
1878 pMerger->aTree[iOut] = iRes; 2055 pMerger->aTree[iOut] = iRes;
1879 } 2056 }
1880 2057
1881 /* 2058 /*
1882 ** Allowed values for the eMode parameter to vdbeMergeEngineInit() 2059 ** Allowed values for the eMode parameter to vdbeMergeEngineInit()
1883 ** and vdbePmaReaderIncrMergeInit(). 2060 ** and vdbePmaReaderIncrMergeInit().
1884 ** 2061 **
1885 ** Only INCRINIT_NORMAL is valid in single-threaded builds (when 2062 ** Only INCRINIT_NORMAL is valid in single-threaded builds (when
1886 ** SQLITE_MAX_WORKER_THREADS==0). The other values are only used 2063 ** SQLITE_MAX_WORKER_THREADS==0). The other values are only used
1887 ** when there exists one or more separate worker threads. 2064 ** when there exists one or more separate worker threads.
1888 */ 2065 */
1889 #define INCRINIT_NORMAL 0 2066 #define INCRINIT_NORMAL 0
1890 #define INCRINIT_TASK 1 2067 #define INCRINIT_TASK 1
1891 #define INCRINIT_ROOT 2 2068 #define INCRINIT_ROOT 2
1892 2069
1893 /* Forward reference. 2070 /*
1894 ** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each 2071 ** Forward reference required as the vdbeIncrMergeInit() and
1895 ** other (when building a merge tree). 2072 ** vdbePmaReaderIncrInit() routines are called mutually recursively when
2073 ** building a merge tree.
1896 */ 2074 */
1897 static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode); 2075 static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
1898 2076
1899 /* 2077 /*
1900 ** Initialize the MergeEngine object passed as the second argument. Once this 2078 ** Initialize the MergeEngine object passed as the second argument. Once this
1901 ** function returns, the first key of merged data may be read from the 2079 ** function returns, the first key of merged data may be read from the
1902 ** MergeEngine object in the usual fashion. 2080 ** MergeEngine object in the usual fashion.
1903 ** 2081 **
1904 ** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge 2082 ** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
1905 ** objects attached to the PmaReader objects that the merger reads from have 2083 ** objects attached to the PmaReader objects that the merger reads from have
1906 ** already been populated, but that they have not yet populated aFile[0] and 2084 ** already been populated, but that they have not yet populated aFile[0] and
1907 ** set the PmaReader objects up to read from it. In this case all that is 2085 ** set the PmaReader objects up to read from it. In this case all that is
(...skipping 26 matching lines...) Expand all
1934 if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){ 2112 if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
1935 /* PmaReaders should be normally initialized in order, as if they are 2113 /* PmaReaders should be normally initialized in order, as if they are
1936 ** reading from the same temp file this makes for more linear file IO. 2114 ** reading from the same temp file this makes for more linear file IO.
1937 ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is 2115 ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
1938 ** in use it will block the vdbePmaReaderNext() call while it uses 2116 ** in use it will block the vdbePmaReaderNext() call while it uses
1939 ** the main thread to fill its buffer. So calling PmaReaderNext() 2117 ** the main thread to fill its buffer. So calling PmaReaderNext()
1940 ** on this PmaReader before any of the multi-threaded PmaReaders takes 2118 ** on this PmaReader before any of the multi-threaded PmaReaders takes
1941 ** better advantage of multi-processor hardware. */ 2119 ** better advantage of multi-processor hardware. */
1942 rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); 2120 rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
1943 }else{ 2121 }else{
1944 rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL); 2122 rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
1945 } 2123 }
1946 if( rc!=SQLITE_OK ) return rc; 2124 if( rc!=SQLITE_OK ) return rc;
1947 } 2125 }
1948 2126
1949 for(i=pMerger->nTree-1; i>0; i--){ 2127 for(i=pMerger->nTree-1; i>0; i--){
1950 vdbeMergeEngineCompare(pMerger, i); 2128 vdbeMergeEngineCompare(pMerger, i);
1951 } 2129 }
1952 return pTask->pUnpacked->errCode; 2130 return pTask->pUnpacked->errCode;
1953 } 2131 }
1954 2132
1955 /* 2133 /*
1956 ** Initialize the IncrMerge field of a PmaReader. 2134 ** The PmaReader passed as the first argument is guaranteed to be an
1957 ** 2135 ** incremental-reader (pReadr->pIncr!=0). This function serves to open
1958 ** If the PmaReader passed as the first argument is not an incremental-reader 2136 ** and/or initialize the temp file related fields of the IncrMerge
1959 ** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
1960 ** to open and/or initialize the temp file related fields of the IncrMerge
1961 ** object at (pReadr->pIncr). 2137 ** object at (pReadr->pIncr).
1962 ** 2138 **
1963 ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders 2139 ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
1964 ** in the sub-tree headed by pReadr are also initialized. Data is then loaded 2140 ** in the sub-tree headed by pReadr are also initialized. Data is then
1965 ** into the buffers belonging to pReadr and it is set to 2141 ** loaded into the buffers belonging to pReadr and it is set to point to
1966 ** point to the first key in its range. 2142 ** the first key in its range.
1967 ** 2143 **
1968 ** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed 2144 ** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
1969 ** to be a multi-threaded PmaReader and this function is being called in a 2145 ** to be a multi-threaded PmaReader and this function is being called in a
1970 ** background thread. In this case all PmaReaders in the sub-tree are 2146 ** background thread. In this case all PmaReaders in the sub-tree are
1971 ** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to 2147 ** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
1972 ** pReadr is populated. However, pReadr itself is not set up to point 2148 ** pReadr is populated. However, pReadr itself is not set up to point
1973 ** to its first key. A call to vdbePmaReaderNext() is still required to do 2149 ** to its first key. A call to vdbePmaReaderNext() is still required to do
1974 ** that. 2150 ** that.
1975 ** 2151 **
1976 ** The reason this function does not call vdbePmaReaderNext() immediately 2152 ** The reason this function does not call vdbePmaReaderNext() immediately
1977 ** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has 2153 ** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
1978 ** to block on thread (pTask->thread) before accessing aFile[1]. But, since 2154 ** to block on thread (pTask->thread) before accessing aFile[1]. But, since
1979 ** this entire function is being run by thread (pTask->thread), that will 2155 ** this entire function is being run by thread (pTask->thread), that will
1980 ** lead to the current background thread attempting to join itself. 2156 ** lead to the current background thread attempting to join itself.
1981 ** 2157 **
1982 ** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed 2158 ** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
1983 ** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all 2159 ** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
1984 ** child-trees have already been initialized using IncrInit(INCRINIT_TASK). 2160 ** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
1985 ** In this case vdbePmaReaderNext() is called on all child PmaReaders and 2161 ** In this case vdbePmaReaderNext() is called on all child PmaReaders and
1986 ** the current PmaReader set to point to the first key in its range. 2162 ** the current PmaReader set to point to the first key in its range.
1987 ** 2163 **
1988 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. 2164 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
1989 */ 2165 */
1990 static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ 2166 static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
1991 int rc = SQLITE_OK; 2167 int rc = SQLITE_OK;
1992 IncrMerger *pIncr = pReadr->pIncr; 2168 IncrMerger *pIncr = pReadr->pIncr;
2169 SortSubtask *pTask = pIncr->pTask;
2170 sqlite3 *db = pTask->pSorter->db;
1993 2171
1994 /* eMode is always INCRINIT_NORMAL in single-threaded mode */ 2172 /* eMode is always INCRINIT_NORMAL in single-threaded mode */
1995 assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); 2173 assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
1996 2174
1997 if( pIncr ){ 2175 rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
1998 SortSubtask *pTask = pIncr->pTask;
1999 sqlite3 *db = pTask->pSorter->db;
2000 2176
2001 rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); 2177 /* Set up the required files for pIncr. A multi-theaded IncrMerge object
2002 2178 ** requires two temp files to itself, whereas a single-threaded object
2003 /* Set up the required files for pIncr. A multi-theaded IncrMerge object 2179 ** only requires a region of pTask->file2. */
2004 ** requires two temp files to itself, whereas a single-threaded object 2180 if( rc==SQLITE_OK ){
2005 ** only requires a region of pTask->file2. */ 2181 int mxSz = pIncr->mxSz;
2006 if( rc==SQLITE_OK ){
2007 int mxSz = pIncr->mxSz;
2008 #if SQLITE_MAX_WORKER_THREADS>0 2182 #if SQLITE_MAX_WORKER_THREADS>0
2009 if( pIncr->bUseThread ){ 2183 if( pIncr->bUseThread ){
2010 rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); 2184 rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
2011 if( rc==SQLITE_OK ){ 2185 if( rc==SQLITE_OK ){
2012 rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); 2186 rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
2013 } 2187 }
2014 }else 2188 }else
2015 #endif 2189 #endif
2016 /*if( !pIncr->bUseThread )*/{ 2190 /*if( !pIncr->bUseThread )*/{
2017 if( pTask->file2.pFd==0 ){ 2191 if( pTask->file2.pFd==0 ){
2018 assert( pTask->file2.iEof>0 ); 2192 assert( pTask->file2.iEof>0 );
2019 rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); 2193 rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
2020 pTask->file2.iEof = 0; 2194 pTask->file2.iEof = 0;
2021 } 2195 }
2022 if( rc==SQLITE_OK ){ 2196 if( rc==SQLITE_OK ){
2023 pIncr->aFile[1].pFd = pTask->file2.pFd; 2197 pIncr->aFile[1].pFd = pTask->file2.pFd;
2024 pIncr->iStartOff = pTask->file2.iEof; 2198 pIncr->iStartOff = pTask->file2.iEof;
2025 pTask->file2.iEof += mxSz; 2199 pTask->file2.iEof += mxSz;
2026 }
2027 } 2200 }
2028 } 2201 }
2202 }
2029 2203
2030 #if SQLITE_MAX_WORKER_THREADS>0 2204 #if SQLITE_MAX_WORKER_THREADS>0
2031 if( rc==SQLITE_OK && pIncr->bUseThread ){ 2205 if( rc==SQLITE_OK && pIncr->bUseThread ){
2032 /* Use the current thread to populate aFile[1], even though this 2206 /* Use the current thread to populate aFile[1], even though this
2033 ** PmaReader is multi-threaded. The reason being that this function 2207 ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
2034 ** is already running in background thread pIncr->pTask->thread. */ 2208 ** then this function is already running in background thread
2035 assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); 2209 ** pIncr->pTask->thread.
2036 rc = vdbeIncrPopulate(pIncr); 2210 **
2037 } 2211 ** If this is the INCRINIT_ROOT object, then it is running in the
2212 ** main VDBE thread. But that is Ok, as that thread cannot return
2213 ** control to the VDBE or proceed with anything useful until the
2214 ** first results are ready from this merger object anyway.
2215 */
2216 assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
2217 rc = vdbeIncrPopulate(pIncr);
2218 }
2038 #endif 2219 #endif
2039 2220
2040 if( rc==SQLITE_OK 2221 if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
2041 && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) 2222 rc = vdbePmaReaderNext(pReadr);
2042 ){
2043 rc = vdbePmaReaderNext(pReadr);
2044 }
2045 } 2223 }
2224
2046 return rc; 2225 return rc;
2047 } 2226 }
2048 2227
2049 #if SQLITE_MAX_WORKER_THREADS>0 2228 #if SQLITE_MAX_WORKER_THREADS>0
2050 /* 2229 /*
2051 ** The main routine for vdbePmaReaderIncrMergeInit() operations run in 2230 ** The main routine for vdbePmaReaderIncrMergeInit() operations run in
2052 ** background threads. 2231 ** background threads.
2053 */ 2232 */
2054 static void *vdbePmaReaderBgInit(void *pCtx){ 2233 static void *vdbePmaReaderBgIncrInit(void *pCtx){
2055 PmaReader *pReader = (PmaReader*)pCtx; 2234 PmaReader *pReader = (PmaReader*)pCtx;
2056 void *pRet = SQLITE_INT_TO_PTR( 2235 void *pRet = SQLITE_INT_TO_PTR(
2057 vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) 2236 vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
2058 ); 2237 );
2059 pReader->pIncr->pTask->bDone = 1; 2238 pReader->pIncr->pTask->bDone = 1;
2060 return pRet; 2239 return pRet;
2061 } 2240 }
2062
2063 /*
2064 ** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK)
2065 ** on the PmaReader object passed as the first argument.
2066 **
2067 ** This call will initialize the various fields of the pReadr->pIncr
2068 ** structure and, if it is a multi-threaded IncrMerger, launch a
2069 ** background thread to populate aFile[1].
2070 */
2071 static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
2072 void *pCtx = (void*)pReadr;
2073 return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx) ;
2074 }
2075 #endif 2241 #endif
2076 2242
2077 /* 2243 /*
2244 ** If the PmaReader passed as the first argument is not an incremental-reader
2245 ** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
2246 ** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
2247 ** this routine to initialize the incremental merge.
2248 **
2249 ** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
2250 ** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
2251 ** Or, if the IncrMerger is single threaded, the same function is called
2252 ** using the current thread.
2253 */
2254 static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
2255 IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
2256 int rc = SQLITE_OK; /* Return code */
2257 if( pIncr ){
2258 #if SQLITE_MAX_WORKER_THREADS>0
2259 assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
2260 if( pIncr->bUseThread ){
2261 void *pCtx = (void*)pReadr;
2262 rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
2263 }else
2264 #endif
2265 {
2266 rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
2267 }
2268 }
2269 return rc;
2270 }
2271
2272 /*
2078 ** Allocate a new MergeEngine object to merge the contents of nPMA level-0 2273 ** Allocate a new MergeEngine object to merge the contents of nPMA level-0
2079 ** PMAs from pTask->file. If no error occurs, set *ppOut to point to 2274 ** PMAs from pTask->file. If no error occurs, set *ppOut to point to
2080 ** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut 2275 ** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
2081 ** to NULL and return an SQLite error code. 2276 ** to NULL and return an SQLite error code.
2082 ** 2277 **
2083 ** When this function is called, *piOffset is set to the offset of the 2278 ** When this function is called, *piOffset is set to the offset of the
2084 ** first PMA to read from pTask->file. Assuming no error occurs, it is 2279 ** first PMA to read from pTask->file. Assuming no error occurs, it is
2085 ** set to the offset immediately following the last byte of the last 2280 ** set to the offset immediately following the last byte of the last
2086 ** PMA before returning. If an error does occur, then the final value of 2281 ** PMA before returning. If an error does occur, then the final value of
2087 ** *piOffset is undefined. 2282 ** *piOffset is undefined.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 ** all records stored in the sorter. 2472 ** all records stored in the sorter.
2278 ** 2473 **
2279 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. 2474 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
2280 */ 2475 */
2281 static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ 2476 static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
2282 int rc; /* Return code */ 2477 int rc; /* Return code */
2283 SortSubtask *pTask0 = &pSorter->aTask[0]; 2478 SortSubtask *pTask0 = &pSorter->aTask[0];
2284 MergeEngine *pMain = 0; 2479 MergeEngine *pMain = 0;
2285 #if SQLITE_MAX_WORKER_THREADS 2480 #if SQLITE_MAX_WORKER_THREADS
2286 sqlite3 *db = pTask0->pSorter->db; 2481 sqlite3 *db = pTask0->pSorter->db;
2482 int i;
2483 SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
2484 for(i=0; i<pSorter->nTask; i++){
2485 pSorter->aTask[i].xCompare = xCompare;
2486 }
2287 #endif 2487 #endif
2288 2488
2289 rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); 2489 rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
2290 if( rc==SQLITE_OK ){ 2490 if( rc==SQLITE_OK ){
2291 #if SQLITE_MAX_WORKER_THREADS 2491 #if SQLITE_MAX_WORKER_THREADS
2292 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); 2492 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
2293 if( pSorter->bUseThreads ){ 2493 if( pSorter->bUseThreads ){
2294 int iTask; 2494 int iTask;
2295 PmaReader *pReadr = 0; 2495 PmaReader *pReadr = 0;
2296 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; 2496 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
2297 rc = vdbeSortAllocUnpacked(pLast); 2497 rc = vdbeSortAllocUnpacked(pLast);
2298 if( rc==SQLITE_OK ){ 2498 if( rc==SQLITE_OK ){
2299 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); 2499 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
2300 pSorter->pReader = pReadr; 2500 pSorter->pReader = pReadr;
2301 if( pReadr==0 ) rc = SQLITE_NOMEM; 2501 if( pReadr==0 ) rc = SQLITE_NOMEM;
2302 } 2502 }
2303 if( rc==SQLITE_OK ){ 2503 if( rc==SQLITE_OK ){
2304 rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); 2504 rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
2305 if( rc==SQLITE_OK ){ 2505 if( rc==SQLITE_OK ){
2306 vdbeIncrMergerSetThreads(pReadr->pIncr); 2506 vdbeIncrMergerSetThreads(pReadr->pIncr);
2307 for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ 2507 for(iTask=0; iTask<(pSorter->nTask-1); iTask++){
2308 IncrMerger *pIncr; 2508 IncrMerger *pIncr;
2309 if( (pIncr = pMain->aReadr[iTask].pIncr) ){ 2509 if( (pIncr = pMain->aReadr[iTask].pIncr) ){
2310 vdbeIncrMergerSetThreads(pIncr); 2510 vdbeIncrMergerSetThreads(pIncr);
2311 assert( pIncr->pTask!=pLast ); 2511 assert( pIncr->pTask!=pLast );
2312 } 2512 }
2313 } 2513 }
2314 for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){ 2514 for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
2515 /* Check that:
2516 **
2517 ** a) The incremental merge object is configured to use the
2518 ** right task, and
2519 ** b) If it is using task (nTask-1), it is configured to run
2520 ** in single-threaded mode. This is important, as the
2521 ** root merge (INCRINIT_ROOT) will be using the same task
2522 ** object.
2523 */
2315 PmaReader *p = &pMain->aReadr[iTask]; 2524 PmaReader *p = &pMain->aReadr[iTask];
2316 assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] ); 2525 assert( p->pIncr==0 || (
2317 if( p->pIncr ){ 2526 (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
2318 if( iTask==pSorter->nTask-1 ){ 2527 && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
2319 rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK); 2528 ));
2320 }else{ 2529 rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
2321 rc = vdbePmaReaderBgIncrInit(p);
2322 }
2323 }
2324 } 2530 }
2325 } 2531 }
2326 pMain = 0; 2532 pMain = 0;
2327 } 2533 }
2328 if( rc==SQLITE_OK ){ 2534 if( rc==SQLITE_OK ){
2329 rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); 2535 rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
2330 } 2536 }
2331 }else 2537 }else
2332 #endif 2538 #endif
2333 { 2539 {
2334 rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); 2540 rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL);
2335 pSorter->pMerger = pMain; 2541 pSorter->pMerger = pMain;
2336 pMain = 0; 2542 pMain = 0;
2337 } 2543 }
2338 } 2544 }
2339 2545
2340 if( rc!=SQLITE_OK ){ 2546 if( rc!=SQLITE_OK ){
2341 vdbeMergeEngineFree(pMain); 2547 vdbeMergeEngineFree(pMain);
2342 } 2548 }
2343 return rc; 2549 return rc;
2344 } 2550 }
2345 2551
2346 2552
2347 /* 2553 /*
2348 ** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, 2554 ** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite,
2349 ** this function is called to prepare for iterating through the records 2555 ** this function is called to prepare for iterating through the records
2350 ** in sorted order. 2556 ** in sorted order.
2351 */ 2557 */
2352 int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ 2558 int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
2353 VdbeSorter *pSorter = pCsr->pSorter; 2559 VdbeSorter *pSorter;
2354 int rc = SQLITE_OK; /* Return code */ 2560 int rc = SQLITE_OK; /* Return code */
2355 2561
2562 assert( pCsr->eCurType==CURTYPE_SORTER );
2563 pSorter = pCsr->uc.pSorter;
2356 assert( pSorter ); 2564 assert( pSorter );
2357 2565
2358 /* If no data has been written to disk, then do not do so now. Instead, 2566 /* If no data has been written to disk, then do not do so now. Instead,
2359 ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly 2567 ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
2360 ** from the in-memory list. */ 2568 ** from the in-memory list. */
2361 if( pSorter->bUsePMA==0 ){ 2569 if( pSorter->bUsePMA==0 ){
2362 if( pSorter->list.pList ){ 2570 if( pSorter->list.pList ){
2363 *pbEof = 0; 2571 *pbEof = 0;
2364 rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); 2572 rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list);
2365 }else{ 2573 }else{
(...skipping 23 matching lines...) Expand all
2389 } 2597 }
2390 2598
2391 vdbeSorterRewindDebug("rewinddone"); 2599 vdbeSorterRewindDebug("rewinddone");
2392 return rc; 2600 return rc;
2393 } 2601 }
2394 2602
2395 /* 2603 /*
2396 ** Advance to the next element in the sorter. 2604 ** Advance to the next element in the sorter.
2397 */ 2605 */
2398 int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ 2606 int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
2399 VdbeSorter *pSorter = pCsr->pSorter; 2607 VdbeSorter *pSorter;
2400 int rc; /* Return code */ 2608 int rc; /* Return code */
2401 2609
2610 assert( pCsr->eCurType==CURTYPE_SORTER );
2611 pSorter = pCsr->uc.pSorter;
2402 assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); 2612 assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
2403 if( pSorter->bUsePMA ){ 2613 if( pSorter->bUsePMA ){
2404 assert( pSorter->pReader==0 || pSorter->pMerger==0 ); 2614 assert( pSorter->pReader==0 || pSorter->pMerger==0 );
2405 assert( pSorter->bUseThreads==0 || pSorter->pReader ); 2615 assert( pSorter->bUseThreads==0 || pSorter->pReader );
2406 assert( pSorter->bUseThreads==1 || pSorter->pMerger ); 2616 assert( pSorter->bUseThreads==1 || pSorter->pMerger );
2407 #if SQLITE_MAX_WORKER_THREADS>0 2617 #if SQLITE_MAX_WORKER_THREADS>0
2408 if( pSorter->bUseThreads ){ 2618 if( pSorter->bUseThreads ){
2409 rc = vdbePmaReaderNext(pSorter->pReader); 2619 rc = vdbePmaReaderNext(pSorter->pReader);
2410 *pbEof = (pSorter->pReader->pFd==0); 2620 *pbEof = (pSorter->pReader->pFd==0);
2411 }else 2621 }else
2412 #endif 2622 #endif
2413 /*if( !pSorter->bUseThreads )*/ { 2623 /*if( !pSorter->bUseThreads )*/ {
2624 assert( pSorter->pMerger!=0 );
2414 assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); 2625 assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
2415 rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); 2626 rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof);
2416 } 2627 }
2417 }else{ 2628 }else{
2418 SorterRecord *pFree = pSorter->list.pList; 2629 SorterRecord *pFree = pSorter->list.pList;
2419 pSorter->list.pList = pFree->u.pNext; 2630 pSorter->list.pList = pFree->u.pNext;
2420 pFree->u.pNext = 0; 2631 pFree->u.pNext = 0;
2421 if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); 2632 if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
2422 *pbEof = !pSorter->list.pList; 2633 *pbEof = !pSorter->list.pList;
2423 rc = SQLITE_OK; 2634 rc = SQLITE_OK;
(...skipping 26 matching lines...) Expand all
2450 *pnKey = pSorter->list.pList->nVal; 2661 *pnKey = pSorter->list.pList->nVal;
2451 pKey = SRVAL(pSorter->list.pList); 2662 pKey = SRVAL(pSorter->list.pList);
2452 } 2663 }
2453 return pKey; 2664 return pKey;
2454 } 2665 }
2455 2666
2456 /* 2667 /*
2457 ** Copy the current sorter key into the memory cell pOut. 2668 ** Copy the current sorter key into the memory cell pOut.
2458 */ 2669 */
2459 int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ 2670 int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
2460 VdbeSorter *pSorter = pCsr->pSorter; 2671 VdbeSorter *pSorter;
2461 void *pKey; int nKey; /* Sorter key to copy into pOut */ 2672 void *pKey; int nKey; /* Sorter key to copy into pOut */
2462 2673
2674 assert( pCsr->eCurType==CURTYPE_SORTER );
2675 pSorter = pCsr->uc.pSorter;
2463 pKey = vdbeSorterRowkey(pSorter, &nKey); 2676 pKey = vdbeSorterRowkey(pSorter, &nKey);
2464 if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ 2677 if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
2465 return SQLITE_NOMEM; 2678 return SQLITE_NOMEM;
2466 } 2679 }
2467 pOut->n = nKey; 2680 pOut->n = nKey;
2468 MemSetTypeFlag(pOut, MEM_Blob); 2681 MemSetTypeFlag(pOut, MEM_Blob);
2469 memcpy(pOut->z, pKey, nKey); 2682 memcpy(pOut->z, pKey, nKey);
2470 2683
2471 return SQLITE_OK; 2684 return SQLITE_OK;
2472 } 2685 }
(...skipping 13 matching lines...) Expand all
2486 ** 2699 **
2487 ** This routine forms the core of the OP_SorterCompare opcode, which in 2700 ** This routine forms the core of the OP_SorterCompare opcode, which in
2488 ** turn is used to verify uniqueness when constructing a UNIQUE INDEX. 2701 ** turn is used to verify uniqueness when constructing a UNIQUE INDEX.
2489 */ 2702 */
2490 int sqlite3VdbeSorterCompare( 2703 int sqlite3VdbeSorterCompare(
2491 const VdbeCursor *pCsr, /* Sorter cursor */ 2704 const VdbeCursor *pCsr, /* Sorter cursor */
2492 Mem *pVal, /* Value to compare to current sorter key */ 2705 Mem *pVal, /* Value to compare to current sorter key */
2493 int nKeyCol, /* Compare this many columns */ 2706 int nKeyCol, /* Compare this many columns */
2494 int *pRes /* OUT: Result of comparison */ 2707 int *pRes /* OUT: Result of comparison */
2495 ){ 2708 ){
2496 VdbeSorter *pSorter = pCsr->pSorter; 2709 VdbeSorter *pSorter;
2497 UnpackedRecord *r2 = pSorter->pUnpacked; 2710 UnpackedRecord *r2;
2498 KeyInfo *pKeyInfo = pCsr->pKeyInfo; 2711 KeyInfo *pKeyInfo;
2499 int i; 2712 int i;
2500 void *pKey; int nKey; /* Sorter key to compare pVal with */ 2713 void *pKey; int nKey; /* Sorter key to compare pVal with */
2501 2714
2715 assert( pCsr->eCurType==CURTYPE_SORTER );
2716 pSorter = pCsr->uc.pSorter;
2717 r2 = pSorter->pUnpacked;
2718 pKeyInfo = pCsr->pKeyInfo;
2502 if( r2==0 ){ 2719 if( r2==0 ){
2503 char *p; 2720 char *p;
2504 r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); 2721 r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
2505 assert( pSorter->pUnpacked==(UnpackedRecord*)p ); 2722 assert( pSorter->pUnpacked==(UnpackedRecord*)p );
2506 if( r2==0 ) return SQLITE_NOMEM; 2723 if( r2==0 ) return SQLITE_NOMEM;
2507 r2->nField = nKeyCol; 2724 r2->nField = nKeyCol;
2508 } 2725 }
2509 assert( r2->nField==nKeyCol ); 2726 assert( r2->nField==nKeyCol );
2510 2727
2511 pKey = vdbeSorterRowkey(pSorter, &nKey); 2728 pKey = vdbeSorterRowkey(pSorter, &nKey);
2512 sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); 2729 sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2);
2513 for(i=0; i<nKeyCol; i++){ 2730 for(i=0; i<nKeyCol; i++){
2514 if( r2->aMem[i].flags & MEM_Null ){ 2731 if( r2->aMem[i].flags & MEM_Null ){
2515 *pRes = -1; 2732 *pRes = -1;
2516 return SQLITE_OK; 2733 return SQLITE_OK;
2517 } 2734 }
2518 } 2735 }
2519 2736
2520 *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); 2737 *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
2521 return SQLITE_OK; 2738 return SQLITE_OK;
2522 } 2739 }
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3100200/src/vdbemem.c ('k') | third_party/sqlite/sqlite-src-3100200/src/vdbetrace.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698