/ Check-in [43a12640]
Login

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

Overview
Comment:Add a hard limit to the number of chunks a multiplexed database may consist of if ENABLE_8_3_NAMES is defined.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nx-devkit
Files: files | file ages | folders
SHA1: 43a1264088c57bf598787b7a9f5d7a2536603d67
User & Date: dan 2011-12-13 19:03:34
Context
2011-12-14
01:38
Improvements to comments. No code changes. check-in: 08bbbd8e user: drh tags: nx-devkit
2011-12-13
19:03
Add a hard limit to the number of chunks a multiplexed database may consist of if ENABLE_8_3_NAMES is defined. check-in: 43a12640 user: dan tags: nx-devkit
18:22
Change the SQLITE_EXTRA_INIT routine to take a single argument which is a pointer to a string. Call SQLITE_EXTRA_INIT with a NULL argument. Fixes to multiplexor to treat the VFS properly in corner cases. Fix the initialization of multiplex3.test. check-in: 8e65b913 user: drh tags: nx-devkit
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_multiplex.c.

    77     77   #define sqlite3_mutex_enter(X)
    78     78   #define sqlite3_mutex_try(X)      SQLITE_OK
    79     79   #define sqlite3_mutex_leave(X)
    80     80   #define sqlite3_mutex_held(X)     ((void)(X),1)
    81     81   #define sqlite3_mutex_notheld(X)  ((void)(X),1)
    82     82   #endif /* SQLITE_THREADSAFE==0 */
    83     83   
           84  +#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
           85  +
    84     86   
    85     87   /************************ Shim Definitions ******************************/
    86     88   
    87     89   #ifndef SQLITE_MULTIPLEX_VFS_NAME
    88     90   # define SQLITE_MULTIPLEX_VFS_NAME "multiplex"
    89     91   #endif
    90     92   
................................................................................
    93     95   ** multiple of MAX_PAGE_SIZE.  We default it here to 2GiB less 64KiB.
    94     96   */
    95     97   #ifndef SQLITE_MULTIPLEX_CHUNK_SIZE
    96     98   # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112
    97     99   #endif
    98    100   
    99    101   /* This used to be the default limit on number of chunks, but
   100         -** it is no longer enforced.  There is currently no limit to the
          102  +** it is no longer enforced. There is currently no limit to the
   101    103   ** number of chunks.
   102    104   **
   103    105   ** May be changed by calling the xFileControl() interface.
   104    106   */
   105    107   #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS
   106    108   # define SQLITE_MULTIPLEX_MAX_CHUNKS 12
   107    109   #endif
................................................................................
   240    242         for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){}
   241    243         if( i>=n-4 ) n = i+1;
   242    244         if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){
   243    245           /* The extensions on overflow files for main databases are 001, 002,
   244    246           ** 003 and so forth.  To avoid name collisions, add 100 to the 
   245    247           ** extensions of journal files so that they are 101, 102, 103, ....
   246    248           */
   247         -        iChunk += 100;
          249  +        iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET;
   248    250         }
   249    251   #endif
   250    252         sqlite3_snprintf(4,&z[n],"%03d",iChunk);
   251    253       }
   252    254     }
   253    255     return SQLITE_OK;
   254    256   }
................................................................................
   260    262     multiplexGroup *pGroup,
   261    263     int iChunk,
   262    264     int *rc,
   263    265     int *pOutFlags
   264    266   ){
   265    267     sqlite3_file *pSubOpen = 0;
   266    268     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;        /* Real VFS */
          269  +
          270  +#ifdef SQLITE_ENABLE_8_3_NAMES
          271  +  /* If JOURNAL_8_3_OFFSET is set to (say) 500, then any overflow files are 
          272  +  ** part of a database journal are named db.501, db.502, and so on. A 
          273  +  ** database may therefore not grow to larger than 500 chunks. Attempting
          274  +  ** to open chunk 501 indicates the database is full. */
          275  +  if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
          276  +    *rc = SQLITE_FULL;
          277  +    return 0;
          278  +  }
          279  +#endif
          280  +
   267    281     *rc = multiplexSubFilename(pGroup, iChunk);
   268    282     if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
   269    283       pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
   270    284       if( pSubOpen==0 ){
   271    285         *rc = SQLITE_NOMEM;
   272    286         return 0;
   273    287       }
................................................................................
   629    643       sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
   630    644       if( pSubOpen==0 ){
   631    645         rc = SQLITE_IOERR_WRITE;
   632    646       }else{
   633    647         rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
   634    648       }
   635    649     }else{
   636         -    while( iAmt > 0 ){
          650  +    while( rc==SQLITE_OK && iAmt>0 ){
   637    651         int i = (int)(iOfst / pGroup->szChunk);
   638    652         sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
   639    653         if( pSubOpen ){
   640    654           int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) -
   641    655                       pGroup->szChunk;
   642    656           if( extra<0 ) extra = 0;
   643    657           iAmt -= extra;
   644    658           rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
   645    659                                           iOfst % pGroup->szChunk);
   646         -        if( rc!=SQLITE_OK ) break;
   647    660           pBuf = (char *)pBuf + iAmt;
   648    661           iOfst += iAmt;
   649    662           iAmt = extra;
   650         -      }else{
   651         -        rc = SQLITE_IOERR_WRITE;
   652         -        break;
   653    663         }
   654    664       }
   655    665     }
   656    666     multiplexLeave();
   657    667     return rc;
   658    668   }
   659    669   

Changes to test/multiplex2.test.

    10     10   #***********************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/malloc_common.tcl
    16     16   source $testdir/lock_common.tcl
           17  +set testprefix multiplex2
    17     18   db close
    18     19   
    19     20   do_multiclient_test tn {
    20     21     foreach f [glob -nocomplain test.*] { forcedelete $f }
    21     22   
    22     23     code1 { catch { sqlite3_multiplex_initialize "" 0 } }
    23     24     code2 { catch { sqlite3_multiplex_initialize "" 0 } }
................................................................................
    42     43       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
    43     44       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
    44     45       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
    45     46       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
    46     47       SELECT count(*) FROM t1;
    47     48     } 
    48     49   
    49         -  do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512
    50         -  do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512
           50  +  do_test 1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512
           51  +  do_test 1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512
    51     52     sql2 { DELETE FROM t1 ; VACUUM }
    52         -  do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0
           53  +  do_test 1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0
    53     54   
    54     55     sql1 {
    55     56       INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
    56     57       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    2
    57     58       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    4
    58     59       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    8
    59     60       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   16
................................................................................
    61     62       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
    62     63       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
    63     64       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
    64     65       INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
    65     66       SELECT count(*) FROM t1;
    66     67     }
    67     68   
    68         -  do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512
           69  +  do_test 1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512
           70  +}
           71  +
           72  +catch {db close}
           73  +foreach f [glob -nocomplain test.*] { forcedelete $f }
           74  +
           75  +ifcapable 8_3_names {
           76  +  sqlite3 db test.db -vfs multiplex
           77  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
           78  +
           79  +  # Insert 512 * 256K (128MB) of data. If each row is around 4K, this means
           80  +  # we need 32768 rows.
           81  +  do_catchsql_test 2.1 {
           82  +    CREATE TABLE t1(a, b);
           83  +    INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
           84  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    2
           85  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    4
           86  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    8
           87  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   16
           88  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   32
           89  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
           90  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
           91  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
           92  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
           93  +
           94  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   1K
           95  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   2K
           96  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   4K
           97  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   8K
           98  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  16K
           99  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  32K
          100  +  
          101  +  } {1 {database or disk is full}}
          102  +
          103  +  do_execsql_test 2.2 {
          104  +    UPDATE t1 SET a=randomblob(9), b=randomblob(3900);
          105  +    PRAGMA integrity_check;
          106  +  } ok
          107  +
          108  +  db close
          109  +  sqlite3 db test.db -vfs multiplex
          110  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
          111  +
          112  +  do_execsql_test 2.3 {
          113  +    PRAGMA integrity_check;
          114  +  } ok
    69    115   }
    70    116   
          117  +catch { db close }
    71    118   catch { sqlite3_multiplex_shutdown }
    72    119   finish_test