/ Check-in [83191ad6]
Login

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

Overview
Comment:All multiplexor chunk sizes up to 4GiB. Disable the multiplexor if the chunk size is set to 0.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 83191ad6f31536b0c1929938e1fbeb4cf6121ab0
User & Date: drh 2011-07-21 20:59:58
Context
2011-07-21
21:29
Compile with the SQLITE_ENABLE_8_3_NAME macro set to 2 to force 8+3 filenames to be on all the time. check-in: ae83dac7 user: drh tags: trunk
20:59
All multiplexor chunk sizes up to 4GiB. Disable the multiplexor if the chunk size is set to 0. check-in: 83191ad6 user: drh tags: trunk
2011-07-20
17:59
For an existing multiplexed database, try to set the chunk size automatically based on the sizes of the preexisting pieces. check-in: 427a9a51 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_multiplex.c.

   130    130       sqlite3_file *p;                  /* Handle for the chunk */
   131    131       char *z;                          /* Name of this chunk */
   132    132     } *aReal;                        /* list of all chunks */
   133    133     int nReal;                       /* Number of chunks */
   134    134     char *zName;                     /* Base filename of this group */
   135    135     int nName;                       /* Length of base filename */
   136    136     int flags;                       /* Flags used for original opening */
   137         -  int nChunkSize;                  /* Chunk size used for this group */
          137  +  unsigned int szChunk;            /* Chunk size used for this group */
   138    138     int bEnabled;                    /* TRUE to use Multiplex VFS for this file */
   139    139     multiplexGroup *pNext, *pPrev;   /* Doubly linked list of all group objects */
   140    140   };
   141    141   
   142    142   /*
   143    143   ** An instance of the following object represents each open connection
   144    144   ** to a file that is multiplex'ed.  This object is a 
................................................................................
   490    490       pGroup = sqlite3_malloc( sz );
   491    491       if( pGroup==0 ){
   492    492         rc = SQLITE_NOMEM;
   493    493       }
   494    494     }
   495    495   
   496    496     if( rc==SQLITE_OK ){
   497         -    const char *zChunkSize;
   498    497       /* assign pointers to extra space allocated */
   499    498       char *p = (char *)&pGroup[1];
   500    499       pMultiplexOpen->pGroup = pGroup;
   501    500       memset(pGroup, 0, sz);
   502    501       pGroup->bEnabled = -1;
   503         -    pGroup->nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE;
          502  +    pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE;
   504    503       if( flags & SQLITE_OPEN_URI ){
          504  +      const char *zChunkSize;
   505    505         zChunkSize = sqlite3_uri_parameter(zName, "chunksize");
   506    506         if( zChunkSize ){
   507         -        int n = atoi(zChunkSize);
   508         -        if( n>0 ) pGroup->nChunkSize = (n+0xffff)&~0xffff;
          507  +        unsigned int n = 0;
          508  +        int i;
          509  +        for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){
          510  +          n = n*10 + zChunkSize[i] - '0';
          511  +        }
          512  +        if( n>0 ){
          513  +          pGroup->szChunk = (n+0xffff)&~0xffff;
          514  +        }else{
          515  +          /* A zero or negative chunksize disabled the multiplexor */
          516  +          pGroup->bEnabled = 0;
          517  +        }
   509    518         }
   510    519       }
   511    520       pGroup->zName = p;
   512    521       /* save off base filename, name length, and original open flags  */
   513    522       memcpy(pGroup->zName, zName, nName+1);
   514    523       pGroup->nName = nName;
   515    524       pGroup->flags = flags;
................................................................................
   531    540           ** larger than the chunk size, that means the chunk size is too small.
   532    541           ** But we have no way of determining the intended chunk size, so 
   533    542           ** just disable the multiplexor all togethre.
   534    543           */
   535    544           rc3 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
   536    545               SQLITE_ACCESS_EXISTS, &exists);
   537    546           if( rc3==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0
   538         -            && sz!=pGroup->nChunkSize ){
   539         -          pGroup->nChunkSize = sz;
   540         -        }else if( rc3==SQLITE_OK && !exists && sz>pGroup->nChunkSize ){
          547  +            && sz!=pGroup->szChunk ){
          548  +          pGroup->szChunk = sz;
          549  +        }else if( rc3==SQLITE_OK && !exists && sz>pGroup->szChunk ){
   541    550             pGroup->bEnabled = 0;
   542    551           }
   543    552         }
   544    553   
   545    554         if( pSubOpen->pMethods->iVersion==1 ){
   546    555           pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1;
   547    556         }else{
................................................................................
   652    661       if( pSubOpen==0 ){
   653    662         rc = SQLITE_IOERR_READ;
   654    663       }else{
   655    664         rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst);
   656    665       }
   657    666     }else{
   658    667       while( iAmt > 0 ){
   659         -      int i = (int)(iOfst / pGroup->nChunkSize);
          668  +      int i = (int)(iOfst / pGroup->szChunk);
   660    669         sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
   661    670         if( pSubOpen ){
   662         -        int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) -
   663         -                                                        pGroup->nChunkSize;
          671  +        int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
   664    672           if( extra<0 ) extra = 0;
   665    673           iAmt -= extra;
   666    674           rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt,
   667         -                                       iOfst % pGroup->nChunkSize);
          675  +                                       iOfst % pGroup->szChunk);
   668    676           if( rc!=SQLITE_OK ) break;
   669    677           pBuf = (char *)pBuf + iAmt;
   670    678           iOfst += iAmt;
   671    679           iAmt = extra;
   672    680         }else{
   673    681           rc = SQLITE_IOERR_READ;
   674    682           break;
................................................................................
   698    706       if( pSubOpen==0 ){
   699    707         rc = SQLITE_IOERR_WRITE;
   700    708       }else{
   701    709         rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
   702    710       }
   703    711     }else{
   704    712       while( iAmt > 0 ){
   705         -      int i = (int)(iOfst / pGroup->nChunkSize);
          713  +      int i = (int)(iOfst / pGroup->szChunk);
   706    714         sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
   707    715         if( pSubOpen ){
   708         -        int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) -
   709         -                    pGroup->nChunkSize;
          716  +        int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) -
          717  +                    pGroup->szChunk;
   710    718           if( extra<0 ) extra = 0;
   711    719           iAmt -= extra;
   712    720           rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
   713         -                                        iOfst % pGroup->nChunkSize);
          721  +                                        iOfst % pGroup->szChunk);
   714    722           if( rc!=SQLITE_OK ) break;
   715    723           pBuf = (char *)pBuf + iAmt;
   716    724           iOfst += iAmt;
   717    725           iAmt = extra;
   718    726         }else{
   719    727           rc = SQLITE_IOERR_WRITE;
   720    728           break;
................................................................................
   743    751       }
   744    752     }else{
   745    753       int rc2;
   746    754       int i;
   747    755       sqlite3_file *pSubOpen;
   748    756       sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   749    757       /* delete the chunks above the truncate limit */
   750         -    for(i=(int)(size / pGroup->nChunkSize)+1; i<pGroup->nReal; i++){
          758  +    for(i=(int)(size / pGroup->szChunk)+1; i<pGroup->nReal; i++){
   751    759         multiplexSubClose(pGroup, i, pOrigVfs);
   752    760       }
   753         -    pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->nChunkSize), &rc2,0);
          761  +    pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->szChunk), &rc2,0);
   754    762       if( pSubOpen ){
   755         -      rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->nChunkSize);
          763  +      rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
   756    764         if( rc2!=SQLITE_OK ) rc = rc2;
   757    765       }else{
   758    766         rc = SQLITE_IOERR_TRUNCATE;
   759    767       }
   760    768     }
   761    769     multiplexLeave();
   762    770     return rc;
................................................................................
   817    825         }
   818    826         if( pSubOpen ){
   819    827           sqlite3_int64 sz;
   820    828           rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
   821    829           if( rc2!=SQLITE_OK ){
   822    830             rc = rc2;
   823    831           }else{
   824         -          if( sz>pGroup->nChunkSize ){
          832  +          if( sz>pGroup->szChunk ){
   825    833               rc = SQLITE_IOERR_FSTAT;
   826    834             }
   827    835             *pSize += sz;
   828    836           }
   829    837         }else{
   830    838           break;
   831    839         }
................................................................................
   887    895           int bEnabled = *(int *)pArg;
   888    896           pGroup->bEnabled = bEnabled;
   889    897           rc = SQLITE_OK;
   890    898         }
   891    899         break;
   892    900       case MULTIPLEX_CTRL_SET_CHUNK_SIZE:
   893    901         if( pArg ) {
   894         -        int nChunkSize = *(int *)pArg;
   895         -        if( nChunkSize<1 ){
          902  +        unsigned int szChunk = *(unsigned*)pArg;
          903  +        if( szChunk<1 ){
   896    904             rc = SQLITE_MISUSE;
   897    905           }else{
   898    906             /* Round up to nearest multiple of MAX_PAGE_SIZE. */
   899         -          nChunkSize = (nChunkSize + (MAX_PAGE_SIZE-1));
   900         -          nChunkSize &= ~(MAX_PAGE_SIZE-1);
   901         -          pGroup->nChunkSize = nChunkSize;
          907  +          szChunk = (szChunk + (MAX_PAGE_SIZE-1));
          908  +          szChunk &= ~(MAX_PAGE_SIZE-1);
          909  +          pGroup->szChunk = szChunk;
   902    910             rc = SQLITE_OK;
   903    911           }
   904    912         }
   905    913         break;
   906    914       case MULTIPLEX_CTRL_SET_MAX_CHUNKS:
   907    915         rc = SQLITE_OK;
   908    916         break;
................................................................................
  1190   1198       for(i=0; i<pGroup->nReal; i++){
  1191   1199         if( pGroup->aReal[i].p!=0 ) nChunks++;
  1192   1200       }
  1193   1201       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1194   1202             Tcl_NewIntObj(nChunks));
  1195   1203   
  1196   1204       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1197         -          Tcl_NewIntObj(pGroup->nChunkSize));
         1205  +          Tcl_NewIntObj(pGroup->szChunk));
  1198   1206       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1199   1207             Tcl_NewIntObj(pGroup->nReal));
  1200   1208   
  1201   1209       Tcl_ListObjAppendElement(interp, pResult, pGroupTerm);
  1202   1210     }
  1203   1211     multiplexLeave();
  1204   1212     Tcl_SetObjResult(interp, pResult);

Changes to test/multiplex.test.

    76     76   do_test multiplex-1.8 { sqlite3_multiplex_shutdown }               {SQLITE_OK}
    77     77   
    78     78   
    79     79   do_test multiplex-1.9.1  { sqlite3_multiplex_initialize "" 1 }     {SQLITE_OK}
    80     80   do_test multiplex-1.9.2  { sqlite3 db test.db }                    {}
    81     81   do_test multiplex-1.9.3  { multiplex_set db main 32768 16 }        {SQLITE_OK}
    82     82   do_test multiplex-1.9.4  { multiplex_set db main 32768 -1 }        {SQLITE_OK}
    83         -do_test multiplex-1.9.5  { multiplex_set db main -1 16 }           {SQLITE_MISUSE}
    84     83   do_test multiplex-1.9.6  { multiplex_set db main 31 16 }           {SQLITE_OK}
    85     84   do_test multiplex-1.9.7  { multiplex_set db main 32768 100 }       {SQLITE_OK}
    86     85   do_test multiplex-1.9.8  { multiplex_set db main 1073741824 1 }    {SQLITE_OK}
    87     86   do_test multiplex-1.9.9  { db close }                              {}
    88     87   do_test multiplex-1.9.10 { sqlite3_multiplex_shutdown }            {SQLITE_OK}
    89     88   
    90     89   do_test multiplex-1.10.1  { sqlite3_multiplex_initialize "" 1 }                                  {SQLITE_OK}
    91     90   do_test multiplex-1.10.2  { sqlite3 db test.db }                                                 {}
    92     91   do_test multiplex-1.10.3  { lindex [ catchsql { SELECT multiplex_control(2, 32768); } ] 0 }      {0}
    93     92   do_test multiplex-1.10.4  { lindex [ catchsql { SELECT multiplex_control(3, -1); } ] 0 }         {0}
    94         -do_test multiplex-1.10.5  { lindex [ catchsql { SELECT multiplex_control(2, -1); } ] 0 }         {1}
    95     93   do_test multiplex-1.10.6  { lindex [ catchsql { SELECT multiplex_control(2, 31); } ] 0 }         {0}
    96     94   do_test multiplex-1.10.7  { lindex [ catchsql { SELECT multiplex_control(3, 100); } ] 0 }        {0}
    97     95   do_test multiplex-1.10.8  { lindex [ catchsql { SELECT multiplex_control(2, 1073741824); } ] 0 } {0}
    98     96   do_test multiplex-1.10.9  { db close }                                                           {}
    99     97   do_test multiplex-1.10.10 { sqlite3_multiplex_shutdown }                                         {SQLITE_OK}
   100     98   
   101     99   do_test multiplex-1.11.1  { sqlite3_multiplex_initialize "" 1 }               {SQLITE_OK}