From d9523b97ecc218c2e8428eee636b6a5f557aef47 Mon Sep 17 00:00:00 2001 From: shaneh Date: Tue, 15 Mar 2011 04:45:48 +0000 Subject: [PATCH] Allow multiplex file names to be preceeded by prefix of the form ":multiplex:chunksize:maxchunks:" Still work to be done, though it compiles and prefixes are ignored. FossilOrigin-Name: cfa4a2f7ea948be0925227efca82baea509249c9 --- manifest | 15 +++++---- manifest.uuid | 2 +- src/test_multiplex.c | 75 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index a007a938e2..5ec64793db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scut-and-paste\stypo\sin\sdebugging\sprint\sstatement\sin\swinMutexTry(). -D 2011-03-15T02:55:28.657 +C Allow\smultiplex\sfile\snames\sto\sbe\spreceeded\sby\sprefix\sof\sthe\sform\s":multiplex:chunksize:maxchunks:"\s\nStill\swork\sto\sbe\sdone,\sthough\sit\scompiles\sand\sprefixes\sare\signored. +D 2011-03-15T04:45:48.735 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c fd6188b1501c0010fb4241ddc9f0d5ac402c688d -F src/test_multiplex.c 655cb3b663f87db7d3d2427ea127c9daacae4abc +F src/test_multiplex.c cf01141845d29639de2b6cdd6d7ef9dc0bce2888 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c @@ -913,7 +913,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3934b004e93852c89b937ec20431de96a2e99440 -R a3bacb1f22d0b4cfa6cea5cf5efe9cdf +P def98fd23e42bda13547e38ab13fed0e6554ce99 +R 324244b8e2a2e32cd06c5dbee5aab290 +T *branch * experimental +T *sym-experimental * +T -sym-trunk * U shaneh -Z 62a7f6dd55f1de5255b8d7f88e967001 +Z b5732ca362c3f4ec7a64142aa2707561 diff --git a/manifest.uuid b/manifest.uuid index 03da2a631d..ad05a9f286 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -def98fd23e42bda13547e38ab13fed0e6554ce99 \ No newline at end of file +cfa4a2f7ea948be0925227efca82baea509249c9 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 72a71621b4..694f7b4cb6 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -40,6 +40,8 @@ /************************ Shim Definitions ******************************/ +#define SQLITE_MULTIPLEX_VFS_NAME "multiplex" + /* This is the limit on the chunk size. It may be changed by calling ** the sqlite3_multiplex_set() interface. */ @@ -191,6 +193,53 @@ static sqlite3_file *multiplexSubOpen(multiplexConn *pConn, int iChunk, int *rc, return NULL; } +/* +** If the given filename begins with a valid multiplex prefix, return +** a pointer to the first character past the prefix. Otherwise +** return NULL pointer. If optional chunk size and max chunk +** values found, return them in int pointers. +*/ +static const char *multiplexParsePrefix(const char *zName, int *pChunkSize, int *pMaxChunks){ + int i; + int nChunkSize = 0; + int nMaxChunks = 0; + int lenPrefix = sqlite3Strlen30(SQLITE_MULTIPLEX_VFS_NAME)+2; + if( strncmp(zName, ":"SQLITE_MULTIPLEX_VFS_NAME":", lenPrefix)!=0 ) return 0; + /* if :multiplex: followed by ':' terminated string of digits, use + ** that value for the chunk size. */ + for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } + if ( zName[i]==':' ){ + if( pChunkSize ){ + if( sqlite3GetInt32(&zName[lenPrefix], &nChunkSize) ){ + *pChunkSize = nChunkSize; + } + } + lenPrefix = i+1; + /* if chunksize followed by ':' terminated string of digits, use + ** that value for the max chunks. */ + for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ } + if ( zName[i]==':' ) { + if( pMaxChunks ){ + if( sqlite3GetInt32(&zName[lenPrefix], &nMaxChunks) ){ + *pMaxChunks = nMaxChunks; + } + } + lenPrefix = i+1; + } + } + return &zName[lenPrefix]; +} + +/* +** If the given filename that may or may not begin with a CEROD prefix, return +** a pointer to the first character of the filename past the prefix. +*/ +static const char *multiplexRootFilename(const char *zName){ + const char *zRoot = multiplexParsePrefix(zName, NULL, NULL); + if( zRoot==0 ) zRoot = zName; + return zRoot; +} + /************************* VFS Method Wrappers *****************************/ /* @@ -305,10 +354,10 @@ static int multiplexDelete( sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, delete it */ - rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir); + rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), syncDir); if( rc2!=SQLITE_OK ) rc = rc2; }else{ /* stop at first "gap" */ @@ -319,11 +368,19 @@ static int multiplexDelete( return rc; } -static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){ - return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d); +static int multiplexAccess(sqlite3_vfs *pVfs, const char *zName,int flgs,int *pOut){ + return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, multiplexRootFilename(zName), flgs, pOut); } -static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){ - return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d); +static int multiplexFullPathname(sqlite3_vfs *pVfs, const char *zName, int nOut, char *zOut){ + int n; + const char *zBase; + zBase = multiplexParsePrefix(zName, NULL, NULL); + if( zBase==0 ){ + return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zName, nOut, zOut); + } + n = (int)(zBase - zName); + memcpy(zOut, zName, n); + return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zBase, nOut - n, &zOut[n]); } static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){ return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b); @@ -483,7 +540,7 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ #else sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif - rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0); + rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), 0); if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE; } pSubOpen = multiplexSubOpen(p, (int)(size/gMultiplex.nChunkSize), &rc2, NULL); @@ -544,7 +601,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i); #endif } - rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists); + rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists); if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(p, i, &rc, NULL); @@ -738,7 +795,7 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ gMultiplex.pOrigVfs = pOrigVfs; gMultiplex.sThisVfs = *pOrigVfs; gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn); - gMultiplex.sThisVfs.zName = "multiplex"; + gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME; gMultiplex.sThisVfs.xOpen = multiplexOpen; gMultiplex.sThisVfs.xDelete = multiplexDelete; gMultiplex.sThisVfs.xAccess = multiplexAccess;