For the unix VFS, avoid an unnecessary stat() system call prior to opening

any file in the common case where there are no unused file descriptors.

FossilOrigin-Name: 3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f
This commit is contained in:
drh 2017-08-18 16:09:52 +00:00
parent 0f3f7664f0
commit c68886bb9e
3 changed files with 31 additions and 24 deletions

View File

@ -1,5 +1,5 @@
C Combine\sthe\sOP_CreateTable\sand\sOP_CreateIndex\sopcodes\sof\sthe\sbytecode\sengine\ninto\sa\ssingle\sOP_CreateBtree\sopcode.\s\sThis\ssimplifies\sthe\simplementation\sand\nmakes\sthe\sbytecode\sprograms\sclearer.
D 2017-08-18T14:34:28.967
C For\sthe\sunix\sVFS,\savoid\san\sunnecessary\sstat()\ssystem\scall\sprior\sto\sopening\nany\sfile\sin\sthe\scommon\scase\swhere\sthere\sare\sno\sunused\sfile\sdescriptors.
D 2017-08-18T16:09:52.797
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@ -440,7 +440,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c a361273749229755f92c8f0e3e4855054ad39bbc5c65773e8db5d0b79afa632c
F src/os_unix.c 0a7730f6cb797ba1fd12825e4ea751e1325041410c063c258e30089ca71f9a88
F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 6f2ae58c0d4ddf510d324cb2ec38f471b5cff8f3e061afd32717ad790685cc7f
@ -1649,7 +1649,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a
R 590c7fe86e3ddb105e4572bf5c63dff2
P eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3
R 75fd277ce5c40358998ed365a587d991
U drh
Z 553a5b087246c1036f2341d36a71efe3
Z 8da9bd8ec0af0fa3e80213d960cc13a7

View File

@ -1 +1 @@
eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3
3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f

View File

@ -210,7 +210,7 @@ struct unixFile {
unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
int lastErrno; /* The unix errno from last I/O error */
void *lockingContext; /* Locking style specific state */
UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
@ -1120,7 +1120,8 @@ struct unixInodeInfo {
/*
** A lists of all unixInodeInfo objects.
*/
static unixInodeInfo *inodeList = 0;
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
static unsigned int nUnusedFd = 0; /* Total unused file descriptors */
/*
**
@ -1230,6 +1231,7 @@ static void closePendingFds(unixFile *pFile){
pNext = p->pNext;
robust_close(pFile, p->fd, __LINE__);
sqlite3_free(p);
nUnusedFd--;
}
pInode->pUnused = 0;
}
@ -1262,6 +1264,7 @@ static void releaseInodeInfo(unixFile *pFile){
sqlite3_free(pInode);
}
}
assert( inodeList!=0 || nUnusedFd==0 );
}
/*
@ -1331,6 +1334,7 @@ static int findInodeInfo(
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
assert( inodeList!=0 || nUnusedFd==0 );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
@ -1750,11 +1754,12 @@ end_lock:
*/
static void setPendingFd(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
UnixUnusedFd *p = pFile->pUnused;
UnixUnusedFd *p = pFile->pPreallocatedUnused;
p->pNext = pInode->pUnused;
pInode->pUnused = p;
pFile->h = -1;
pFile->pUnused = 0;
pFile->pPreallocatedUnused = 0;
nUnusedFd++;
}
/*
@ -1979,7 +1984,7 @@ static int closeUnixFile(sqlite3_file *id){
#endif
OSTRACE(("CLOSE %-3d\n", pFile->h));
OpenCounter(-1);
sqlite3_free(pFile->pUnused);
sqlite3_free(pFile->pPreallocatedUnused);
memset(pFile, 0, sizeof(unixFile));
return SQLITE_OK;
}
@ -3200,7 +3205,7 @@ static int unixRead(
/* If this is a database file (not a journal, master-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
assert( pFile->pUnused==0
assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@ -3313,7 +3318,7 @@ static int unixWrite(
/* If this is a database file (not a journal, master-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
assert( pFile->pUnused==0
assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@ -5564,6 +5569,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
#if !OS_VXWORKS
struct stat sStat; /* Results of stat() call */
unixEnterMutex();
/* A stat() call may fail for various reasons. If this happens, it is
** almost certain that an open() call on the same path will also fail.
** For this reason, if an error occurs in the stat() call here, it is
@ -5572,10 +5579,9 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
**
** Even if a subsequent open() call does succeed, the consequences of
** not searching for a reusable file descriptor are not dire. */
if( 0==osStat(zPath, &sStat) ){
if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){
unixInodeInfo *pInode;
unixEnterMutex();
pInode = inodeList;
while( pInode && (pInode->fileId.dev!=sStat.st_dev
|| pInode->fileId.ino!=(u64)sStat.st_ino) ){
@ -5586,11 +5592,12 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
pUnused = *pp;
if( pUnused ){
nUnusedFd--;
*pp = pUnused->pNext;
}
}
unixLeaveMutex();
}
unixLeaveMutex();
#endif /* if !OS_VXWORKS */
return pUnused;
}
@ -5811,7 +5818,7 @@ static int unixOpen(
return SQLITE_NOMEM_BKPT;
}
}
p->pUnused = pUnused;
p->pPreallocatedUnused = pUnused;
/* Database filenames are double-zero terminated if they are not
** URIs with parameters. Hence, they can always be passed into
@ -5848,7 +5855,7 @@ static int unixOpen(
gid_t gid; /* Groupid for the file */
rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
if( rc!=SQLITE_OK ){
assert( !p->pUnused );
assert( !p->pPreallocatedUnused );
assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
return rc;
}
@ -5882,9 +5889,9 @@ static int unixOpen(
*pOutFlags = flags;
}
if( p->pUnused ){
p->pUnused->fd = fd;
p->pUnused->flags = flags;
if( p->pPreallocatedUnused ){
p->pPreallocatedUnused->fd = fd;
p->pPreallocatedUnused->flags = flags;
}
if( isDelete ){
@ -5965,7 +5972,7 @@ static int unixOpen(
open_finished:
if( rc!=SQLITE_OK ){
sqlite3_free(p->pUnused);
sqlite3_free(p->pPreallocatedUnused);
}
return rc;
}
@ -6706,7 +6713,7 @@ static int proxyCreateUnixFile(
dummyVfs.zName = "dummy";
pUnused->fd = fd;
pUnused->flags = openFlags;
pNew->pUnused = pUnused;
pNew->pPreallocatedUnused = pUnused;
rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
if( rc==SQLITE_OK ){