From: drh <> Date: Sun, 1 Sep 2024 18:54:31 +0000 (+0000) Subject: Improved sort function in the percentile extension. X-Git-Tag: version-3.47.0~159 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c97ad9b4e156d5551d68d3964babc1841647ffb6;p=thirdparty%2Fsqlite.git Improved sort function in the percentile extension. FossilOrigin-Name: 9f84e8d59bcda642e732565e840f6a880a01b2fc65af2651248f6a8a6e1cb65a --- diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 718be80da6..e0ce576339 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -271,6 +271,11 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ } } +/* +** Interchange two doubles. +*/ +#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} + /* ** Sort an array of doubles. ** @@ -283,49 +288,44 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ ** (2) To avoid the function call to the comparison routine for each ** comparison. */ -static void sortDoubles(double *a, int n){ - int iLt; /* Entries with index less than iLt are less than rPivot */ - int iGt; /* Entries with index iGt or more are greater than rPivot */ +static void percentSort(double *a, unsigned int n){ + int iLt; /* Entries before a[iLt] are less than rPivot */ + int iGt; /* Entries at or after a[iGt] are greater than rPivot */ int i; /* Loop counter */ double rPivot; /* The pivot value */ - double rTmp; /* Temporary used to swap two values */ - - if( n<2 ) return; - if( n>5 ){ - double x[3]; - x[0]= a[0]; - x[1] = a[n/2]; - x[2] = a[n-1]; - sortDoubles(x,3); - rPivot = x[1]; - }else{ - rPivot = a[n/2]; + + assert( n>=2 ); + if( a[0]>a[n-1] ){ + SWAP_DOUBLE(a[0],a[n-1]) + } + if( n==2 ) return; + iGt = n-1; + i = n/2; + if( a[0]>a[i] ){ + SWAP_DOUBLE(a[0],a[i]) + }else if( a[i]>a[iGt] ){ + SWAP_DOUBLE(a[i],a[iGt]) } - iLt = i = 0; - iGt = n; - while( iiLt ){ - rTmp = a[i]; - a[i] = a[iLt]; - a[iLt] = rTmp; - } + if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt]) iLt++; i++; }else if( a[i]>rPivot ){ do{ iGt--; }while( iGt>i && a[iGt]>rPivot ); - rTmp = a[i]; - a[i] = a[iGt]; - a[iGt] = rTmp; + SWAP_DOUBLE(a[i],a[iGt]) }else{ i++; } - } - if( iLt>=2 ) sortDoubles(a, iLt); - if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt); - + }while( i=2 ) percentSort(a, iLt); + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); + /* Uncomment for testing */ #if 0 for(i=0; ibSorted==0 ){ - sortDoubles(p->a, p->nUsed); + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); p->bSorted = 1; }else{ percentAssertSorted(p); @@ -398,7 +399,8 @@ static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ if( p->a==0 ) return; if( p->nUsed ){ if( p->bSorted==0 ){ - sortDoubles(p->a, p->nUsed); + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); p->bSorted = 1; }else{ percentAssertSorted(p); diff --git a/manifest b/manifest index ce1c028952..cec2fd4ce8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\squicksort\salgorithm\sin\sthe\spercentile\sextension. -D 2024-09-01T10:52:20.432 +C Improved\ssort\sfunction\sin\sthe\spercentile\sextension. +D 2024-09-01T18:54:31.153 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -410,7 +410,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58 F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0 F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 -F ext/misc/percentile.c c5ddb86314a0648c510de54a7290b939225b128925d98b02859c47d98f9ec282 +F ext/misc/percentile.c 4560a3a42bab3d867060bb7e80a15fd82f917a58c87739591f0a3d99f18754a8 F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed @@ -2211,8 +2211,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d1d0942a947803d45a1fd9068f3518cf412178b6b9bafcb82db44c52d5820c11 -R 8b4bddb09aaccc6a2b060f365f91dbd1 +P 54313f74b24c46f1afa1ff082ef569fa46938527095be358015e7047e17702ac +R b41846f3df9dc87b92ce32e03786ab20 U drh -Z 1fbd72dda73eb1323c7b4878ebf0259d +Z 1672856efafeb853be5cf9a4114de044 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 67c2b6b886..888095dab4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54313f74b24c46f1afa1ff082ef569fa46938527095be358015e7047e17702ac +9f84e8d59bcda642e732565e840f6a880a01b2fc65af2651248f6a8a6e1cb65a