Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | This branch merged with nx-devkit and from there into trunk. Was: In the multiplexor, instead of generating a unique file-name when SQLite opens a temp file, allow the underlying VFS to generate a different temp file for each chunk. Given the changes to the xFileSize method, it is no longer necessary for the different chunks of a temp file to use the same base name. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | experimental |
Files: | files | file ages | folders |
SHA1: |
199f52bceddfb032db8beb301aaa154e |
User & Date: | dan 2011-12-13 12:10:19.009 |
Original Comment: | In the multiplexor, instead of generating a unique file-name when SQLite opens a temp file, allow the underlying VFS to generate a different temp file for each chunk. Given the changes to the xFileSize method, it is no longer necessary for the different chunks of a temp file to use the same base name. |
References
2011-12-13
| ||
15:02 | Move the multiplexor changes in the experimental branch (check-ins [255d21499b] and [199f52bced]) into the nx-devkit branch. (check-in: eb95d2f72c user: drh tags: nx-devkit) | |
Context
2011-12-13
| ||
12:10 | This branch merged with nx-devkit and from there into trunk. Was: In the multiplexor, instead of generating a unique file-name when SQLite opens a temp file, allow the underlying VFS to generate a different temp file for each chunk. Given the changes to the xFileSize method, it is no longer necessary for the different chunks of a temp file to use the same base name. (Closed-Leaf check-in: 199f52bced user: dan tags: experimental) | |
11:15 | Change the way IO errors are handled in the xFileSize method of the multiplexor VFS. Add test file multiplex3.test. (check-in: 255d21499b user: dan tags: experimental) | |
Changes
Changes to src/test_multiplex.c.
︙ | ︙ | |||
209 210 211 212 213 214 215 | static int multiplexStrlen30(const char *z){ const char *z2 = z; if( z==0 ) return 0; while( *z2 ){ z2++; } return 0x3fffffff & (int)(z2 - z); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | static int multiplexStrlen30(const char *z){ const char *z2 = z; if( z==0 ) return 0; while( *z2 ){ z2++; } return 0x3fffffff & (int)(z2 - z); } /* Compute the filename for the iChunk-th chunk */ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( iChunk>=pGroup->nReal ){ struct multiplexReal *p; p = sqlite3_realloc(pGroup->aReal, (iChunk+1)*sizeof(*p)); if( p==0 ){ return SQLITE_NOMEM; } memset(&p[pGroup->nReal], 0, sizeof(p[0])*(iChunk+1-pGroup->nReal)); pGroup->aReal = p; pGroup->nReal = iChunk+1; } if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 ); if( z==0 ){ return SQLITE_NOMEM; } memcpy(z, pGroup->zName, n+1); |
︙ | ︙ | |||
457 458 459 460 461 462 463 464 465 466 467 468 469 470 | sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ int nName; int sz; char *zToFree = 0; UNUSED_PARAMETER(pVfs); memset(pConn, 0, pVfs->szOsFile); /* We need to create a group structure and manage ** access to this group of files. */ multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; | > < < < < < < < < < < < < < < | | < > > > | | | | | | | | | | | | | | | | | | < | | > | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ int nName; int sz; char *zToFree = 0; UNUSED_PARAMETER(pVfs); memset(pConn, 0, pVfs->szOsFile); assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) ); /* We need to create a group structure and manage ** access to this group of files. */ multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; if( rc==SQLITE_OK ){ /* allocate space for group */ nName = zName ? multiplexStrlen30(zName) : 0; sz = sizeof(multiplexGroup) /* multiplexGroup */ + nName + 1; /* zName */ pGroup = sqlite3_malloc( sz ); if( pGroup==0 ){ rc = SQLITE_NOMEM; } } if( rc==SQLITE_OK ){ /* assign pointers to extra space allocated */ memset(pGroup, 0, sz); pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = -1; pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; if( zName ){ char *p = (char *)&pGroup[1]; if( flags & SQLITE_OPEN_URI ){ const char *zChunkSize; zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); if( zChunkSize ){ unsigned int n = 0; int i; for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ n = n*10 + zChunkSize[i] - '0'; } if( n>0 ){ pGroup->szChunk = (n+0xffff)&~0xffff; }else{ /* A zero or negative chunksize disabled the multiplexor */ pGroup->bEnabled = 0; } } } pGroup->zName = p; memcpy(pGroup->zName, zName, nName+1); pGroup->nName = nName; } pGroup->flags = flags; rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags); } if( pSubOpen ){ int exists, rc2, rc3; |
︙ | ︙ | |||
811 812 813 814 815 816 817 | for(i=0; rc==SQLITE_OK; i++){ sqlite3_file *pSubOpen = 0; int exists = 0; rc = multiplexSubFilename(pGroup, i); if( rc!=SQLITE_OK ) break; if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){ exists = 1; | | | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | for(i=0; rc==SQLITE_OK; i++){ sqlite3_file *pSubOpen = 0; int exists = 0; rc = multiplexSubFilename(pGroup, i); if( rc!=SQLITE_OK ) break; if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){ exists = 1; }else if( (pGroup->flags & SQLITE_OPEN_DELETEONCLOSE)==0 ){ const char *zReal = pGroup->aReal[i].z; rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists); } if( exists==0 ){ /* stop at first "gap" or IO error. */ break; } |
︙ | ︙ | |||
1180 1181 1182 1183 1184 1185 1186 | UNUSED_PARAMETER(objv); pResult = Tcl_NewObj(); multiplexEnter(); for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ pGroupTerm = Tcl_NewObj(); | > | | > > > | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 | UNUSED_PARAMETER(objv); pResult = Tcl_NewObj(); multiplexEnter(); for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ pGroupTerm = Tcl_NewObj(); if( pGroup->zName ){ pGroup->zName[pGroup->nName] = '\0'; Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewStringObj(pGroup->zName, -1)); }else{ Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj()); } Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(pGroup->nName)); Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(pGroup->flags)); /* count number of chunks with open handles */ for(i=0; i<pGroup->nReal; i++){ |
︙ | ︙ |