/ Check-in [cfa4a2f7]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | multiplex-enhancements
Files: files | file ages | folders
SHA1: cfa4a2f7ea948be0925227efca82baea509249c9
User & Date: shaneh 2011-03-15 04:45:48
Original Comment: 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.
Context
2011-03-29
05:06
In-progress changes - do not use; Removed prefix support; Added file control interface to enable/disable and adjust chunk size; added app-def function for same; check-in: bc02d0c1 user: shaneh tags: multiplex-enhancements
2011-03-15
04:45
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. check-in: cfa4a2f7 user: shaneh tags: multiplex-enhancements
02:55
Fix cut-and-paste typo in debugging print statement in winMutexTry(). check-in: def98fd2 user: shaneh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_multiplex.c.

    35     35   #define sqlite3_mutex_leave(X)
    36     36   #define sqlite3_mutex_held(X)     ((void)(X),1)
    37     37   #define sqlite3_mutex_notheld(X)  ((void)(X),1)
    38     38   #endif /* SQLITE_THREADSAFE==0 */
    39     39   
    40     40   
    41     41   /************************ Shim Definitions ******************************/
           42  +
           43  +#define SQLITE_MULTIPLEX_VFS_NAME "multiplex"
    42     44   
    43     45   /* This is the limit on the chunk size.  It may be changed by calling
    44     46   ** the sqlite3_multiplex_set() interface.
    45     47   */
    46     48   #define SQLITE_MULTIPLEX_CHUNK_SIZE 0x40000000
    47     49   /* Default limit on number of chunks.  Care should be taken
    48     50   ** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT
................................................................................
   186    188       }
   187    189       *rc = SQLITE_OK;
   188    190       return pSubOpen;
   189    191     }
   190    192     *rc = SQLITE_FULL;
   191    193     return NULL;
   192    194   }
          195  +
          196  +/*
          197  +** If the given filename begins with a valid multiplex prefix, return
          198  +** a pointer to the first character past the prefix.  Otherwise
          199  +** return NULL pointer.  If optional chunk size and max chunk
          200  +** values found, return them in int pointers.
          201  +*/
          202  +static const char *multiplexParsePrefix(const char *zName, int *pChunkSize, int *pMaxChunks){
          203  +  int i;
          204  +  int nChunkSize = 0;
          205  +  int nMaxChunks = 0;
          206  +  int lenPrefix = sqlite3Strlen30(SQLITE_MULTIPLEX_VFS_NAME)+2;
          207  +  if( strncmp(zName, ":"SQLITE_MULTIPLEX_VFS_NAME":", lenPrefix)!=0 ) return 0;
          208  +  /* if :multiplex: followed by ':' terminated string of digits, use
          209  +  ** that value for the chunk size. */
          210  +  for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ }
          211  +  if ( zName[i]==':' ){
          212  +    if( pChunkSize ){
          213  +      if( sqlite3GetInt32(&zName[lenPrefix], &nChunkSize) ){
          214  +         *pChunkSize = nChunkSize;
          215  +      }
          216  +    }
          217  +    lenPrefix = i+1;
          218  +    /* if chunksize followed by ':' terminated string of digits, use
          219  +    ** that value for the max chunks. */
          220  +    for(i=lenPrefix; sqlite3Isdigit(zName[i]); i++){ }
          221  +    if ( zName[i]==':' ) {
          222  +      if( pMaxChunks ){
          223  +        if( sqlite3GetInt32(&zName[lenPrefix], &nMaxChunks) ){
          224  +           *pMaxChunks = nMaxChunks;
          225  +        }
          226  +      }
          227  +      lenPrefix = i+1;
          228  +    }
          229  +  }
          230  +  return &zName[lenPrefix];
          231  +}
          232  +
          233  +/*
          234  +** If the given filename that may or may not begin with a CEROD prefix, return
          235  +** a pointer to the first character of the filename past the prefix.
          236  +*/
          237  +static const char *multiplexRootFilename(const char *zName){
          238  +  const char *zRoot = multiplexParsePrefix(zName, NULL, NULL);
          239  +  if( zRoot==0 ) zRoot = zName;
          240  +  return zRoot;
          241  +}
   193    242   
   194    243   /************************* VFS Method Wrappers *****************************/
   195    244   
   196    245   /*
   197    246   ** This is the xOpen method used for the "multiplex" VFS.
   198    247   **
   199    248   ** Most of the work is done by the underlying original VFS.  This method
................................................................................
   301    350       if( i ){
   302    351   #ifdef SQLITE_MULTIPLEX_EXT_OVWR
   303    352           sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
   304    353   #else
   305    354           sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+nName, SQLITE_MULTIPLEX_EXT_FMT, i);
   306    355   #endif
   307    356       }
   308         -    rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists);
          357  +    rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists);
   309    358       if( rc2==SQLITE_OK && exists){
   310    359         /* if it exists, delete it */
   311         -      rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir);
          360  +      rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), syncDir);
   312    361         if( rc2!=SQLITE_OK ) rc = rc2;
   313    362       }else{
   314    363         /* stop at first "gap" */
   315    364         break;
   316    365       }
   317    366     }
   318    367     multiplexLeave();
   319    368     return rc;
   320    369   }
   321    370   
   322         -static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){
   323         -  return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d);
          371  +static int multiplexAccess(sqlite3_vfs *pVfs, const char *zName,int flgs,int *pOut){
          372  +  return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, multiplexRootFilename(zName), flgs, pOut);
   324    373   }
   325         -static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){
   326         -  return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d);
          374  +static int multiplexFullPathname(sqlite3_vfs *pVfs, const char *zName, int nOut, char *zOut){
          375  +  int n;
          376  +  const char *zBase;
          377  +  zBase = multiplexParsePrefix(zName, NULL, NULL);
          378  +  if( zBase==0 ){
          379  +    return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zName, nOut, zOut);
          380  +  }
          381  +  n = (int)(zBase - zName);
          382  +  memcpy(zOut, zName, n);
          383  +  return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, zBase, nOut - n, &zOut[n]);
   327    384   }
   328    385   static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){
   329    386     return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b);
   330    387   }
   331    388   static void multiplexDlError(sqlite3_vfs *a, int b, char *c){
   332    389     gMultiplex.pOrigVfs->xDlError(gMultiplex.pOrigVfs, b, c);
   333    390   }
................................................................................
   479    536         pGroup->bOpen[i] = 0;
   480    537       }
   481    538   #ifdef SQLITE_MULTIPLEX_EXT_OVWR
   482    539       sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
   483    540   #else
   484    541       sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
   485    542   #endif
   486         -    rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, 0);
          543  +    rc2 = pOrigVfs->xDelete(pOrigVfs, multiplexRootFilename(gMultiplex.zName), 0);
   487    544       if( rc2!=SQLITE_OK ) rc = SQLITE_IOERR_TRUNCATE;
   488    545     }
   489    546     pSubOpen = multiplexSubOpen(p, (int)(size/gMultiplex.nChunkSize), &rc2, NULL);
   490    547     if( pSubOpen ){
   491    548       rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size%gMultiplex.nChunkSize);
   492    549       if( rc2!=SQLITE_OK ) rc = rc2;
   493    550     }else{
................................................................................
   540    597         if( i ){
   541    598   #ifdef SQLITE_MULTIPLEX_EXT_OVWR
   542    599           sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName-SQLITE_MULTIPLEX_EXT_SZ, SQLITE_MULTIPLEX_EXT_FMT, i);
   543    600   #else
   544    601           sqlite3_snprintf(SQLITE_MULTIPLEX_EXT_SZ+1, gMultiplex.zName+pGroup->nName, SQLITE_MULTIPLEX_EXT_FMT, i);
   545    602   #endif
   546    603         }
   547         -      rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName, SQLITE_ACCESS_EXISTS, &exists);
          604  +      rc2 = pOrigVfs->xAccess(pOrigVfs, multiplexRootFilename(gMultiplex.zName), SQLITE_ACCESS_EXISTS, &exists);
   548    605         if( rc2==SQLITE_OK && exists){
   549    606           /* if it exists, open it */
   550    607           pSubOpen = multiplexSubOpen(p, i, &rc, NULL);
   551    608         }else{
   552    609           /* stop at first "gap" */
   553    610           break;
   554    611         }
................................................................................
   734    791     gMultiplex.nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE;
   735    792     gMultiplex.nMaxChunks = SQLITE_MULTIPLEX_MAX_CHUNKS;
   736    793     gMultiplex.pGroups = NULL;
   737    794     gMultiplex.isInitialized = 1;
   738    795     gMultiplex.pOrigVfs = pOrigVfs;
   739    796     gMultiplex.sThisVfs = *pOrigVfs;
   740    797     gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn);
   741         -  gMultiplex.sThisVfs.zName = "multiplex";
          798  +  gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME;
   742    799     gMultiplex.sThisVfs.xOpen = multiplexOpen;
   743    800     gMultiplex.sThisVfs.xDelete = multiplexDelete;
   744    801     gMultiplex.sThisVfs.xAccess = multiplexAccess;
   745    802     gMultiplex.sThisVfs.xFullPathname = multiplexFullPathname;
   746    803     gMultiplex.sThisVfs.xDlOpen = multiplexDlOpen;
   747    804     gMultiplex.sThisVfs.xDlError = multiplexDlError;
   748    805     gMultiplex.sThisVfs.xDlSym = multiplexDlSym;