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 |
Timelines: | family | ancestors | descendants | both | nx-devkit |
Files: | files | file ages | folders |
SHA1: |
43a1264088c57bf598787b7a9f5d7a25 |
User & Date: | dan 2011-12-13 19:03:34.498 |
Context
2011-12-14
| ||
01:38 | Improvements to comments. No code changes. (check-in: 08bbbd8e38 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: 43a1264088 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: 8e65b91325 user: drh tags: nx-devkit) | |
Changes
Changes to src/test_multiplex.c.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #define sqlite3_mutex_enter(X) #define sqlite3_mutex_try(X) SQLITE_OK #define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) ((void)(X),1) #define sqlite3_mutex_notheld(X) ((void)(X),1) #endif /* SQLITE_THREADSAFE==0 */ /************************ Shim Definitions ******************************/ #ifndef SQLITE_MULTIPLEX_VFS_NAME # define SQLITE_MULTIPLEX_VFS_NAME "multiplex" #endif /* This is the limit on the chunk size. It may be changed by calling ** the xFileControl() interface. It will be rounded up to a ** multiple of MAX_PAGE_SIZE. We default it here to 2GiB less 64KiB. */ #ifndef SQLITE_MULTIPLEX_CHUNK_SIZE # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112 #endif /* This used to be the default limit on number of chunks, but | > > | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #define sqlite3_mutex_enter(X) #define sqlite3_mutex_try(X) SQLITE_OK #define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) ((void)(X),1) #define sqlite3_mutex_notheld(X) ((void)(X),1) #endif /* SQLITE_THREADSAFE==0 */ #define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 /************************ Shim Definitions ******************************/ #ifndef SQLITE_MULTIPLEX_VFS_NAME # define SQLITE_MULTIPLEX_VFS_NAME "multiplex" #endif /* This is the limit on the chunk size. It may be changed by calling ** the xFileControl() interface. It will be rounded up to a ** multiple of MAX_PAGE_SIZE. We default it here to 2GiB less 64KiB. */ #ifndef SQLITE_MULTIPLEX_CHUNK_SIZE # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112 #endif /* This used to be the default limit on number of chunks, but ** it is no longer enforced. There is currently no limit to the ** number of chunks. ** ** May be changed by calling the xFileControl() interface. */ #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS # define SQLITE_MULTIPLEX_MAX_CHUNKS 12 #endif |
︙ | ︙ | |||
240 241 242 243 244 245 246 | for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} if( i>=n-4 ) n = i+1; if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ /* The extensions on overflow files for main databases are 001, 002, ** 003 and so forth. To avoid name collisions, add 100 to the ** extensions of journal files so that they are 101, 102, 103, .... */ | | > > > > > > > > > > > > | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} if( i>=n-4 ) n = i+1; if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ /* The extensions on overflow files for main databases are 001, 002, ** 003 and so forth. To avoid name collisions, add 100 to the ** extensions of journal files so that they are 101, 102, 103, .... */ iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; } #endif sqlite3_snprintf(4,&z[n],"%03d",iChunk); } } return SQLITE_OK; } /* Translate an sqlite3_file* that is really a multiplexGroup* into ** the sqlite3_file* for the underlying original VFS. */ static sqlite3_file *multiplexSubOpen( multiplexGroup *pGroup, int iChunk, int *rc, int *pOutFlags ){ sqlite3_file *pSubOpen = 0; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ #ifdef SQLITE_ENABLE_8_3_NAMES /* If JOURNAL_8_3_OFFSET is set to (say) 500, then any overflow files are ** part of a database journal are named db.501, db.502, and so on. A ** database may therefore not grow to larger than 500 chunks. Attempting ** to open chunk 501 indicates the database is full. */ if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ *rc = SQLITE_FULL; return 0; } #endif *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile ); if( pSubOpen==0 ){ *rc = SQLITE_NOMEM; return 0; } |
︙ | ︙ | |||
629 630 631 632 633 634 635 | sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); if( pSubOpen==0 ){ rc = SQLITE_IOERR_WRITE; }else{ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); } }else{ | | < < < < | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); if( pSubOpen==0 ){ rc = SQLITE_IOERR_WRITE; }else{ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); } }else{ while( rc==SQLITE_OK && iAmt>0 ){ int i = (int)(iOfst / pGroup->szChunk); sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); if( pSubOpen ){ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; if( extra<0 ) extra = 0; iAmt -= extra; rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->szChunk); pBuf = (char *)pBuf + iAmt; iOfst += iAmt; iAmt = extra; } } } multiplexLeave(); return rc; } |
︙ | ︙ |
Changes to test/multiplex2.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl source $testdir/lock_common.tcl db close do_multiclient_test tn { foreach f [glob -nocomplain test.*] { forcedelete $f } code1 { catch { sqlite3_multiplex_initialize "" 0 } } code2 { catch { sqlite3_multiplex_initialize "" 0 } } | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl source $testdir/lock_common.tcl set testprefix multiplex2 db close do_multiclient_test tn { foreach f [glob -nocomplain test.*] { forcedelete $f } code1 { catch { sqlite3_multiplex_initialize "" 0 } } code2 { catch { sqlite3_multiplex_initialize "" 0 } } |
︙ | ︙ | |||
42 43 44 45 46 47 48 | INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 SELECT count(*) FROM t1; } | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 SELECT count(*) FROM t1; } do_test 1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 do_test 1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 sql2 { DELETE FROM t1 ; VACUUM } do_test 1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 sql1 { INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 SELECT count(*) FROM t1; } do_test 1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 } catch {db close} foreach f [glob -nocomplain test.*] { forcedelete $f } ifcapable 8_3_names { sqlite3 db test.db -vfs multiplex sqlite3_multiplex_control db main chunk_size [expr 256*1024] # Insert 512 * 256K (128MB) of data. If each row is around 4K, this means # we need 32768 rows. do_catchsql_test 2.1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 1K INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2K INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4K INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8K INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16K INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32K } {1 {database or disk is full}} do_execsql_test 2.2 { UPDATE t1 SET a=randomblob(9), b=randomblob(3900); PRAGMA integrity_check; } ok db close sqlite3 db test.db -vfs multiplex sqlite3_multiplex_control db main chunk_size [expr 256*1024] do_execsql_test 2.3 { PRAGMA integrity_check; } ok } catch { db close } catch { sqlite3_multiplex_shutdown } finish_test |