Index: src/threads.c ================================================================== --- src/threads.c +++ src/threads.c @@ -35,13 +35,15 @@ #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ #include /* A running thread */ struct SQLiteThread { - pthread_t tid; - int done; - void *pOut; + pthread_t tid; /* Thread ID */ + int done; /* Set to true when thread finishes */ + void *pOut; /* Result returned by the thread */ + void *(*xTask)(void*); /* The thread routine */ + void *pIn; /* Argument to the thread */ }; /* Create a new thread */ int sqlite3ThreadCreate( SQLiteThread **ppThread, /* OUT: Write the thread object here */ @@ -54,10 +56,12 @@ assert( xTask!=0 ); *ppThread = 0; p = sqlite3Malloc(sizeof(*p)); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); + p->xTask = xTask; + p->pIn = pIn; if( sqlite3GlobalConfig.bCoreMutex==0 || pthread_create(&p->tid, 0, xTask, pIn)!=0 ){ p->done = 1; p->pOut = xTask(pIn); Index: src/vdbesort.c ================================================================== --- src/vdbesort.c +++ src/vdbesort.c @@ -13,11 +13,11 @@ ** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements ** or by SELECT statements with ORDER BY clauses that cannot be satisfied ** using indexes and without LIMIT clauses. ** ** The VdbeSorter object implements a multi-threaded external merge sort -** algorithm that is efficient even if the number of element being sorted +** algorithm that is efficient even if the number of elements being sorted ** exceeds the available memory. ** ** Here is the (internal, non-API) interface between this module and the ** rest of the SQLite system: ** @@ -102,13 +102,11 @@ ** than zero, and (b) worker threads have been enabled at runtime by calling ** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...). ** ** When Rewind() is called, any data remaining in memory is flushed to a ** final PMA. So at this point the data is stored in some number of sorted -** PMAs within temporary files on disk. Within a single file sorter is -** running in single threaded mode, or distributed between one or more files -** for multi-threaded sorters. +** PMAs within temporary files on disk. ** ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the ** sorter is running in single-threaded mode, then these PMAs are merged ** incrementally as keys are retreived from the sorter by the VDBE. See ** comments above object MergeEngine below for details. @@ -156,11 +154,11 @@ typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ typedef struct SorterRecord SorterRecord; /* A record being sorted */ typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ typedef struct SorterList SorterList; /* In-memory list of records */ -typedef struct IncrMerger IncrMerger; +typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ /* ** A container for a temp file handle and the current amount of data ** stored in the file. */ @@ -168,15 +166,20 @@ sqlite3_file *pFd; /* File handle */ i64 iEof; /* Bytes of data stored in pFd */ }; /* -** In memory linked list of records. +** An in-memory list of objects to be sorted. +** +** If aMemory==0 then each object is allocated separately and the objects +** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects +** are stored in the aMemory[] bulk memory, one right after the other, and +** are connected using SorterRecord.u.iNext. */ struct SorterList { SorterRecord *pList; /* Linked list of records */ - u8 *aMemory; /* If non-NULL, blob of memory for pList */ + u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ int szPMA; /* Size of pList as PMA in bytes */ }; /* ** The MergeEngine object is used to combine two or more smaller PMAs into