-C Fix\sa\scomment\sin\svdbesort.c.
-D 2011-08-04T18:43:37.790
+C Minor\sinternal\schanges\sto\svdbesort.c.\sAlso,\sdefault\sto\smerging\slists\stogether\s16\sat\sa\stime.
+D 2011-08-05T11:49:12.597
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/vdbeaux.c 8fb978eb73a97b34d352dd3ef3bff35b1b3fa7e9
F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
-F src/vdbesort.c 87c3b2921cbfd29a7fd0ef834f29b5a4fd8be56e
+F src/vdbesort.c f17fa625dbe19bfb8f0a0cb728cf9d73cab6ed1e
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582
F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262
-P a4770d079c1b236eb54751e75a44cccc997c6b93
-R ec95e9bd54ef30cddfc95ab39fec1eee
+P db8518cab8e329b1dbe4cd6c81b21ef3ea69fcb1
+R 82f4652664dbb6f6efbe2830f0e7593b
U dan
-Z 35780c1186756c8599cb8966b7d9180f
+Z 838a8014a1d3a0c9d59ff3654d53daf0
*/
struct VdbeSorter {
int nWorking; /* Start a new b-tree after this many pages */
- int nAlloc; /* Allocated size of aIter[] and aTree[] */
int nTree; /* Used size of aTree/aIter (power of 2) */
VdbeSorterIter *aIter; /* Array of iterators to merge */
int *aTree; /* Current state of incremental merge */
#define SORTER_MIN_SEGMENT_SIZE 10
/* Maximum number of segments to merge in a single go */
-#define SORTER_MAX_MERGE_COUNT 2
+#define SORTER_MAX_MERGE_COUNT 16
/*
** Append integer iOff to the VdbeSorter.aOffset[] array of the sorter object
** TODO: The aOffset[] array may grow indefinitely. Fix this.
*/
static int vdbeSorterAppendOffset(sqlite3 *db, VdbeSorter *p, i64 iOff){
- int *aNew; /* New VdbeSorter.aRoot[] array */
p->aOffset = sqlite3DbReallocOrFree(
db, p->aOffset, (p->nOffset+1)*sizeof(i64)
);
if( pSorter ){
if( pSorter->aIter ){
int i;
- for(i=0; i<pSorter->nAlloc; i++){
+ for(i=0; i<pSorter->nTree; i++){
vdbeSorterIterZero(db, &pSorter->aIter[i]);
}
sqlite3DbFree(db, pSorter->aIter);
- sqlite3DbFree(db, pSorter->aTree);
}
if( pSorter->pTemp1 ){
sqlite3OsCloseFree(pSorter->pTemp1);
return rc;
}
-/*
-** Extend the pSorter->aIter[] and pSorter->aTree[] arrays using DbRealloc().
-** Return SQLITE_OK if successful, or SQLITE_NOMEM otherwise.
-*/
-static int vdbeSorterGrowArrays(sqlite3* db, VdbeSorter *pSorter){
- int *aTree; /* New aTree[] allocation */
- VdbeSorterIter *aIter; /* New aIter[] allocation */
- int nOld = pSorter->nAlloc; /* Current size of arrays */
- int nNew = (nOld?nOld*2:4); /* Size of arrays after reallocation */
-
- /* Realloc aTree[]. */
- aTree = sqlite3DbRealloc(db, pSorter->aTree, sizeof(int)*nNew);
- if( !aTree ) return SQLITE_NOMEM;
- memset(&aTree[nOld], 0, (nNew-nOld) * sizeof(int));
- pSorter->aTree = aTree;
-
- /* Realloc aIter[]. */
- aIter = sqlite3DbRealloc(db, pSorter->aIter, sizeof(VdbeSorterIter)*nNew);
- if( !aIter ) return SQLITE_NOMEM;
- memset(&aIter[nOld], 0, (nNew-nOld) * sizeof(VdbeSorterIter));
- pSorter->aIter = aIter;
-
- /* Set VdbeSorter.nAlloc to the new size of the arrays and return OK. */
- pSorter->nAlloc = nNew;
- return SQLITE_OK;
-}
-
/*
** Helper function for sqlite3VdbeSorterRewind().
*/
int iFirst,
int *piNext
){
- Pager *pPager = sqlite3BtreePager(pCsr->pBt);
VdbeSorter *pSorter = pCsr->pSorter;
int rc = SQLITE_OK;
int i;
- int nMaxRef = (pSorter->nWorking * 9/10);
int N = 2;
+ int nIter; /* Number of iterators to initialize. */
- assert( iFirst<pSorter->nOffset );
+ nIter = pSorter->nOffset - iFirst;
+ if( nIter>SORTER_MAX_MERGE_COUNT ){
+ nIter = SORTER_MAX_MERGE_COUNT;
+ }
+ assert( nIter>0 );
+ while( N<nIter ) N += N;
+
+ /* Allocate aIter[] and aTree[], if required. */
+ if( pSorter->aIter==0 ){
+ int nByte = N * (sizeof(int) + sizeof(VdbeSorterIter));
+ pSorter->aIter = (VdbeSorterIter *)sqlite3DbMallocZero(db, nByte);
+ if( !pSorter->aIter ) return SQLITE_NOMEM;
+ pSorter->aTree = (int *)&pSorter->aIter[N];
+ }
/* Initialize as many iterators as possible. */
for(i=iFirst;
){
int iIter = i - iFirst;
- assert( iIter<=pSorter->nAlloc );
- if( iIter==pSorter->nAlloc ){
- rc = vdbeSorterGrowArrays(db, pSorter);
- }
-
if( rc==SQLITE_OK ){
VdbeSorterIter *pIter = &pSorter->aIter[iIter];
i64 iStart = pSorter->aOffset[i];
iEof = pSorter->aOffset[i+1];
}
rc = vdbeSorterIterInit(db, pSorter->pTemp1, iStart, iEof, pIter);
- if( i>iFirst+1 ){
- int nRef = (i-iFirst)*10;
- if( nRef>=nMaxRef ){
- i++;
- break;
- }
- }
}
}
*piNext = i;
assert( i>iFirst );
- while( (i-iFirst)>N ) N += N;
pSorter->nTree = N;
/* Populate the aTree[] array. */
}
while( rc==SQLITE_OK ){
- int iRoot = 0;
int iNext = 0; /* Index of next segment to open */
int iNew = 0; /* Index of new, merged, PMA */
assert( iNext>0 );
assert( rc!=SQLITE_OK || pSorter->aIter[ pSorter->aTree[1] ].pFile );
- if( rc==SQLITE_OK && (iRoot>0 || iNext<pSorter->nOffset) ){
- int pgno;
+ if( rc==SQLITE_OK && (iNew>0 || iNext<pSorter->nOffset) ){
int bEof = 0;
if( pTemp2==0 ){
rc = vdbeSorterOpenTempFile(db, &pTemp2);
}
if( rc==SQLITE_OK ){
- pSorter->aOffset[iRoot] = iWrite2;
+ pSorter->aOffset[iNew] = iWrite2;
}
while( rc==SQLITE_OK && bEof==0 ){
rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
}
}
- iRoot++;
+ iNew++;
}
}while( rc==SQLITE_OK && iNext<pSorter->nOffset );
- if( iRoot==0 ){
+ if( iNew==0 ){
break;
}else{
sqlite3_file *pTmp = pSorter->pTemp1;
- pSorter->nOffset = iRoot;
+ pSorter->nOffset = iNew;
pSorter->pTemp1 = pTemp2;
pTemp2 = pTmp;
pSorter->iWriteOff = iWrite2;