From: dan Date: Fri, 25 Jun 2010 11:35:52 +0000 (+0000) Subject: Modify the merge-sort in wal.c so that it does not use recursion. X-Git-Tag: version-3.7.2~233 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f544b4c4b8de7458e22d639b74387f1b29daab7c;p=thirdparty%2Fsqlite.git Modify the merge-sort in wal.c so that it does not use recursion. FossilOrigin-Name: daea6c054cee3564d8460d876b78a325ebc382dd --- diff --git a/manifest b/manifest index b53c071180..d82e932aea 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 35ecaf6fcd..2c14a71f4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4941e437d2638f36ac8510d4a5b4c780afc798bb \ No newline at end of file +daea6c054cee3564d8460d876b78a325ebc382dd \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 3f976329f6..30ec85906b 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1287,49 +1287,95 @@ 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 || aContent[aLeft[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 */ - - /* TODO: Change to non-recursive version. */ - walMergesort(aContent, aBuffer, aLeft, &nLeft); - walMergesort(aContent, aBuffer, aRight, &nRight); - - while( iRight=nRight || aContent[aLeft[iLeft]]0 ); + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); + + for(iList=0; iListaList && p->nList<=(1<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + aSub[iSub].aList = aMerge; + aSub[iSub].nList = nMerge; + } - assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); - assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); + for(iSub++; iSubnList<=(2<aList, p->nList, &aMerge, &nMerge, aBuffer); } - memcpy(aList, aBuffer, sizeof(aList[0])*iOut); - *pnList = iOut; } + assert( aMerge==aList ); + *pnList = nMerge; #ifdef SQLITE_DEBUG { @@ -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 ){