Speed up base64 conversions, and add test with more data for the baseNN conversion to grind.

FossilOrigin-Name: 6c84ae4ba83713c751fddff8be41686bbcb525ac8135e1520436c62d0bc23d2c
This commit is contained in:
larrybr 2022-11-24 02:59:33 +00:00
parent 809be56218
commit 9b9017def4
4 changed files with 62 additions and 38 deletions

70
ext/misc/base64.c Normal file → Executable file
View File

@ -92,42 +92,46 @@ static const char b64Numerals[64+1]
#define IS_BX_DIGIT(bdp) (((ubyte)(bdp))<0x80)
#define IS_BX_WS(bdp) ((bdp)==WS)
#define IS_BX_PAD(bdp) ((bdp)==PC)
#define BX_NUMERAL(dv) (b64Numerals[dv])
#define BX_NUMERAL(dv) (b64Numerals[(ubyte)(dv)])
/* Width of base64 lines. Should be an integer multiple of 4. */
#define B64_DARK_MAX 72
/* Encode a byte buffer into base64 text. If pSep!=0, it's a C string
** to be appended to encoded groups to limit their length to B64_DARK_MAX
** or to terminate the last group (to aid concatenation.)
/* Encode a byte buffer into base64 text with linefeeds appended to limit
** encoded group lengths to B64_DARK_MAX or to terminate the last group.
*/
static char* toBase64( ubyte *pIn, int nbIn, char *pOut, char *pSep ){
static char* toBase64( ubyte *pIn, int nbIn, char *pOut ){
int nCol = 0;
*pOut = 0;
while( nbIn > 0 ){
static signed char ncio[] = { 0, 2, 3, 4 };
int nbi = (nbIn > 3)? 3 : nbIn;
signed char nc;
int nbe;
unsigned long qv = (ubyte)*pIn++;
for( nbe=1; nbe<3; ++nbe ){
ubyte b = (nbe<nbi)? *pIn++ : 0;
qv = (qv<<8) | b;
while( nbIn >= 3 ){
/* Do the bit-shuffle, exploiting unsigned input to avoid masking. */
pOut[0] = BX_NUMERAL(pIn[0]>>2);
pOut[1] = BX_NUMERAL(((pIn[0]<<4)|(pIn[1]>>4))&0x3f);
pOut[2] = BX_NUMERAL(((pIn[1]&0xf)<<2)|(pIn[2]>>6));
pOut[3] = BX_NUMERAL(pIn[2]&0x3f);
pOut += 4;
nbIn -= 3;
pIn += 3;
if( (nCol += 4)>=B64_DARK_MAX || nbIn<=0 ){
*pOut++ = '\n';
nCol = 0;
}
}
if( nbIn > 0 ){
signed char nco = nbIn+1;
int nbe;
unsigned long qv = *pIn++;
for( nbe=1; nbe<3; ++nbe ){
qv <<= 8;
if( nbe<nbIn ) qv |= *pIn++;
}
nc = ncio[nbi];
nbIn -= nbi;
for( nbe=3; nbe>=0; --nbe ){
char ce = (nbe<nc)? BX_NUMERAL((ubyte)(qv & 0x3f)) : PAD_CHAR;
char ce = (nbe<nco)? BX_NUMERAL((ubyte)(qv & 0x3f)) : PAD_CHAR;
qv >>= 6;
pOut[nbe] = ce;
}
pOut += 4;
if( pSep && ((nCol += 4)>=B64_DARK_MAX || nbIn<=0) ){
char *p = pSep;
while( *p ) *pOut++ = *p++;
nCol = 0;
}
*pOut = 0;
*pOut++ = '\n';
}
*pOut = 0;
return pOut;
}
@ -157,11 +161,12 @@ static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){
ubyte bdp = BX_DV_PROTO(c);
switch( bdp ){
case ND:
/* Treat non-digits as pad, but they terminate decode too. */
/* Treat dark non-digits as pad, but they terminate decode too. */
ncIn = 0;
/* fall thru */
case WS:
/* Treat whitespace as pad */
/* Treat whitespace as pad and terminate this group.*/
nti = nac;
/* fall thru */
case PC:
bdp = 0;
@ -172,10 +177,15 @@ static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){
break;
}
}
nti = 2;
while( nbo-- > 0 ){
*pOut++ = (qv >> (8*nti--))&0xff;
switch( nbo ){
case 3:
pOut[2] = (qv) & 0xff;
case 2:
pOut[1] = (qv>>8) & 0xff;
case 1:
pOut[0] = (qv>>16) & 0xff;
}
pOut += nbo;
}
return pOut;
}
@ -200,7 +210,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
cBuf = sqlite3_malloc(nc);
if( !cBuf ) goto memFail;
bBuf = (ubyte*)sqlite3_value_blob(av[0]);
nc = (int)(toBase64(bBuf, nb, cBuf, "\n") - cBuf);
nc = (int)(toBase64(bBuf, nb, cBuf) - cBuf);
sqlite3_result_text(context, cBuf, nc, sqlite3_free);
break;
case SQLITE_TEXT:

View File

@ -1,5 +1,5 @@
C Add\smore\sbaseNN\stests,\sget\soversize\serror\strapping\sworking,\sand\ssync\sw/trunk
D 2022-11-22T22:46:41.866
C Speed\sup\sbase64\sconversions,\sand\sadd\stest\swith\smore\sdata\sfor\sthe\sbaseNN\sconversion\sto\sgrind.
D 2022-11-24T02:59:33.748
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -289,7 +289,7 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23
F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824
F ext/misc/base64.c 0472f388e1a6c168912a363dfbe88d2d588325fba7ce6101f726d01b54fe6d3b
F ext/misc/base64.c 6333194e5c2e85b0748116ad4004bf3e070347cc09984aaa8d462fb3fc0566b6 x
F ext/misc/base85.c 9005549904fc06ec2f3ff96970709f92f76e2d9ec2b785553ac32908ddc1baa0
F ext/misc/basexx.c 678dcc83894f78c26fd3662b322886777cc26bf2b40809236cd2abdad532a33c
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
@ -816,7 +816,7 @@ F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f310fd3b24a491b6b77bccdf14923b85d6ebcce751068c180d93a6b8ff854399
F test/basexx1.test 9b12557d2b5bd017f9f8a8698239438ced5899c3ee55d9a549f74d90b16e51a6
F test/basexx1.test d8a50f0744b93dca656625597bcd3499ff4b9a4ea2a82432b119b7d46e3e0c08
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
F test/bestindex1.test 856a453dff8c68b4568601eed5a8b5e20b4763af9229f3947c215729ed878db0
F test/bestindex2.test 394ff8fbf34703391247116d6a44e1c50ee7282236ee77909044573cefc37bc0
@ -2063,8 +2063,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P ff67460e1a3d21c9ca7cbd171fbc5e6cbdb3797de359887f851776b73b732fdf 9ec923b5dc24d6082da8d42bc0ee8ab1c418912625c0c56de9627be2c818ef98
R 36565c16629af64673142ebb24820a85
P 03819e9368fd9f78f351147a1dc865743f9634893e43a9d1e3d7cbaf4c966069
R f94c977ea1969bc60efbcf2158a80ba4
U larrybr
Z 3e47c0e49ec42d7b0a58333b563577b4
Z 312bc23355f0a0c3b5b7524b3c0fa709
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
03819e9368fd9f78f351147a1dc865743f9634893e43a9d1e3d7cbaf4c966069
6c84ae4ba83713c751fddff8be41686bbcb525ac8135e1520436c62d0bc23d2c

View File

@ -138,4 +138,18 @@ do_catchsql_test 116 {
SELECT is_base85(x'00');
} {1 {is_base85 accepts only text or NULL}}
# Round-trip many bigger random blobs.
do_execsql_test 117 {
CREATE TABLE bs(b blob, num);
INSERT INTO bs SELECT randomblob(4000 + n%3), n
FROM (
WITH RECURSIVE seq(n) AS (
VALUES(1) UNION ALL SELECT n+1
FROM seq WHERE n<100
) SELECT n FROM seq);
SELECT num FROM bs WHERE base64(base64(b))!=b;
SELECT num FROM bs WHERE base85(base85(b))!=b;
} {}
finish_test