Modify the merge-sort in wal.c so that it does not use recursion.
FossilOrigin-Name: daea6c054cee3564d8460d876b78a325ebc382dd
This commit is contained in:
parent
ec6ffc1a6a
commit
f544b4c4b8
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Add\stest\scases\sto\spager1.test\sand\spagerfault.test.
|
||||
D 2010-06-24T19:16:06
|
||||
C Modify\sthe\smerge-sort\sin\swal.c\sso\sthat\sit\sdoes\snot\suse\srecursion.
|
||||
D 2010-06-25T11:35:52
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -226,7 +226,7 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
|
||||
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
|
||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
|
||||
F src/wal.c 40e6d0acde18a0d4796310db4d6382a12340388c
|
||||
F src/wal.c a6648b66a8990439d5d5c124191590b00929b9e4
|
||||
F src/wal.h 4ace25262452d17e7d3ec970c89ee17794004008
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
F src/where.c 1c895bef33d0dfc7ed90fb1f74120435d210ea56
|
||||
@ -825,7 +825,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 7d83fbae9802a56b2121d0775de54fccd743d971
|
||||
R 43cdd6cd887c3657632da5d79f140434
|
||||
P 4941e437d2638f36ac8510d4a5b4c780afc798bb
|
||||
R 758d45a862d61942569f7b92d886b198
|
||||
U dan
|
||||
Z 18163dae6e1dc526dfe07de5a30526c2
|
||||
Z 787d6dd7a1ce6e802a68550ea5002b17
|
||||
|
@ -1 +1 @@
|
||||
4941e437d2638f36ac8510d4a5b4c780afc798bb
|
||||
daea6c054cee3564d8460d876b78a325ebc382dd
|
113
src/wal.c
113
src/wal.c
@ -1287,50 +1287,96 @@ static int walIteratorNext(
|
||||
return (iRet==0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function merges two sorted lists into a single sorted list.
|
||||
*/
|
||||
static void walMerge(
|
||||
u32 *aContent, /* Pages in wal */
|
||||
ht_slot *aLeft, /* IN: Left hand input list */
|
||||
int nLeft, /* IN: Elements in array *paLeft */
|
||||
ht_slot **paRight, /* IN/OUT: Right hand input list */
|
||||
int *pnRight, /* IN/OUT: Elements in *paRight */
|
||||
ht_slot *aTmp /* Temporary buffer */
|
||||
){
|
||||
int iLeft = 0; /* Current index in aLeft */
|
||||
int iRight = 0; /* Current index in aRight */
|
||||
int iOut = 0; /* Current index in output buffer */
|
||||
int nRight = *pnRight;
|
||||
ht_slot *aRight = *paRight;
|
||||
|
||||
assert( nLeft>0 && nRight>0 );
|
||||
while( iRight<nRight || iLeft<nLeft ){
|
||||
ht_slot logpage;
|
||||
Pgno dbpage;
|
||||
|
||||
if( (iLeft<nLeft)
|
||||
&& (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
|
||||
){
|
||||
logpage = aLeft[iLeft++];
|
||||
}else{
|
||||
logpage = aRight[iRight++];
|
||||
}
|
||||
dbpage = aContent[logpage];
|
||||
|
||||
aTmp[iOut++] = logpage;
|
||||
if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
|
||||
|
||||
assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
|
||||
assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
|
||||
}
|
||||
|
||||
*paRight = aLeft;
|
||||
*pnRight = iOut;
|
||||
memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
|
||||
}
|
||||
|
||||
/*
|
||||
** Sort the elements in list aList, removing any duplicates.
|
||||
*/
|
||||
static void walMergesort(
|
||||
u32 *aContent, /* Pages in wal */
|
||||
ht_slot *aBuffer, /* Buffer of at least *pnList items to use */
|
||||
ht_slot *aList, /* IN/OUT: List to sort */
|
||||
int *pnList /* IN/OUT: Number of elements in aList[] */
|
||||
){
|
||||
int nList = *pnList;
|
||||
if( nList>1 ){
|
||||
int nLeft = nList / 2; /* Elements in left list */
|
||||
int nRight = nList - nLeft; /* Elements in right list */
|
||||
int iLeft = 0; /* Current index in aLeft */
|
||||
int iRight = 0; /* Current index in aright */
|
||||
int iOut = 0; /* Current index in output buffer */
|
||||
ht_slot *aLeft = aList; /* Left list */
|
||||
ht_slot *aRight = aList+nLeft;/* Right list */
|
||||
struct Sublist {
|
||||
int nList; /* Number of elements in aList */
|
||||
ht_slot *aList; /* Pointer to sub-list content */
|
||||
};
|
||||
|
||||
/* TODO: Change to non-recursive version. */
|
||||
walMergesort(aContent, aBuffer, aLeft, &nLeft);
|
||||
walMergesort(aContent, aBuffer, aRight, &nRight);
|
||||
const int nList = *pnList; /* Size of input list */
|
||||
int nMerge; /* Number of elements in list aMerge */
|
||||
ht_slot *aMerge; /* List to be merged */
|
||||
int iList; /* Index into input list */
|
||||
int iSub; /* Index into aSub array */
|
||||
struct Sublist aSub[13]; /* Array of sub-lists */
|
||||
|
||||
while( iRight<nRight || iLeft<nLeft ){
|
||||
ht_slot logpage;
|
||||
Pgno dbpage;
|
||||
memset(aSub, 0, sizeof(aSub));
|
||||
assert( nList<=HASHTABLE_NPAGE && nList>0 );
|
||||
assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
|
||||
|
||||
if( (iLeft<nLeft)
|
||||
&& (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
|
||||
){
|
||||
logpage = aLeft[iLeft++];
|
||||
}else{
|
||||
logpage = aRight[iRight++];
|
||||
}
|
||||
dbpage = aContent[logpage];
|
||||
|
||||
aBuffer[iOut++] = logpage;
|
||||
if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
|
||||
|
||||
assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
|
||||
assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
|
||||
for(iList=0; iList<nList; iList++){
|
||||
nMerge = 1;
|
||||
aMerge = &aList[iList];
|
||||
for(iSub=0; iList & (1<<iSub); iSub++){
|
||||
struct Sublist *p = &aSub[iSub];
|
||||
assert( p->aList && p->nList<=(1<<iSub) );
|
||||
walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
|
||||
}
|
||||
memcpy(aList, aBuffer, sizeof(aList[0])*iOut);
|
||||
*pnList = iOut;
|
||||
aSub[iSub].aList = aMerge;
|
||||
aSub[iSub].nList = nMerge;
|
||||
}
|
||||
|
||||
for(iSub++; iSub<ArraySize(aSub); iSub++){
|
||||
if( nList & (1<<iSub) ){
|
||||
struct Sublist *p = &aSub[iSub];
|
||||
assert( p->nList<=(2<<iSub) );
|
||||
walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
|
||||
}
|
||||
}
|
||||
assert( aMerge==aList );
|
||||
*pnList = nMerge;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
{
|
||||
int i;
|
||||
@ -1474,11 +1520,14 @@ static int walCheckpoint(
|
||||
int i; /* Loop counter */
|
||||
volatile WalCkptInfo *pInfo; /* The checkpoint status information */
|
||||
|
||||
if( pWal->hdr.mxFrame==0 ) return SQLITE_OK;
|
||||
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK || pWal->hdr.mxFrame==0 ){
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto walcheckpoint_out;
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
/*** TODO: Move this test out to the caller. Make it an assert() here ***/
|
||||
if( pWal->hdr.szPage!=nBuf ){
|
||||
|
Loading…
x
Reference in New Issue
Block a user