1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

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. 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-18T14:34:28.967 D 2017-08-18T16:09:52.797
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -440,7 +440,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 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.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 6f2ae58c0d4ddf510d324cb2ec38f471b5cff8f3e061afd32717ad790685cc7f F src/pager.c 6f2ae58c0d4ddf510d324cb2ec38f471b5cff8f3e061afd32717ad790685cc7f
@@ -1649,7 +1649,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a P eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3
R 590c7fe86e3ddb105e4572bf5c63dff2 R 75fd277ce5c40358998ed365a587d991
U drh 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 */ unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
int lastErrno; /* The unix errno from last I/O error */ int lastErrno; /* The unix errno from last I/O error */
void *lockingContext; /* Locking style specific state */ void *lockingContext; /* Locking style specific state */
UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
const char *zPath; /* Name of the file */ const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */ unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
@@ -1120,7 +1120,8 @@ struct unixInodeInfo {
/* /*
** A lists of all unixInodeInfo objects. ** 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; pNext = p->pNext;
robust_close(pFile, p->fd, __LINE__); robust_close(pFile, p->fd, __LINE__);
sqlite3_free(p); sqlite3_free(p);
nUnusedFd--;
} }
pInode->pUnused = 0; pInode->pUnused = 0;
} }
@@ -1262,6 +1264,7 @@ static void releaseInodeInfo(unixFile *pFile){
sqlite3_free(pInode); sqlite3_free(pInode);
} }
} }
assert( inodeList!=0 || nUnusedFd==0 );
} }
/* /*
@@ -1331,6 +1334,7 @@ static int findInodeInfo(
#else #else
fileId.ino = (u64)statbuf.st_ino; fileId.ino = (u64)statbuf.st_ino;
#endif #endif
assert( inodeList!=0 || nUnusedFd==0 );
pInode = inodeList; pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext; pInode = pInode->pNext;
@@ -1750,11 +1754,12 @@ end_lock:
*/ */
static void setPendingFd(unixFile *pFile){ static void setPendingFd(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode; unixInodeInfo *pInode = pFile->pInode;
UnixUnusedFd *p = pFile->pUnused; UnixUnusedFd *p = pFile->pPreallocatedUnused;
p->pNext = pInode->pUnused; p->pNext = pInode->pUnused;
pInode->pUnused = p; pInode->pUnused = p;
pFile->h = -1; pFile->h = -1;
pFile->pUnused = 0; pFile->pPreallocatedUnused = 0;
nUnusedFd++;
} }
/* /*
@@ -1979,7 +1984,7 @@ static int closeUnixFile(sqlite3_file *id){
#endif #endif
OSTRACE(("CLOSE %-3d\n", pFile->h)); OSTRACE(("CLOSE %-3d\n", pFile->h));
OpenCounter(-1); OpenCounter(-1);
sqlite3_free(pFile->pUnused); sqlite3_free(pFile->pPreallocatedUnused);
memset(pFile, 0, sizeof(unixFile)); memset(pFile, 0, sizeof(unixFile));
return SQLITE_OK; return SQLITE_OK;
} }
@@ -3200,7 +3205,7 @@ static int unixRead(
/* If this is a database file (not a journal, master-journal or temp /* 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. */ ** file), the bytes in the locking range should never be read or written. */
#if 0 #if 0
assert( pFile->pUnused==0 assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512 || offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE || offset+amt<=PENDING_BYTE
); );
@@ -3313,7 +3318,7 @@ static int unixWrite(
/* If this is a database file (not a journal, master-journal or temp /* 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. */ ** file), the bytes in the locking range should never be read or written. */
#if 0 #if 0
assert( pFile->pUnused==0 assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512 || offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE || offset+amt<=PENDING_BYTE
); );
@@ -5564,6 +5569,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
#if !OS_VXWORKS #if !OS_VXWORKS
struct stat sStat; /* Results of stat() call */ struct stat sStat; /* Results of stat() call */
unixEnterMutex();
/* A stat() call may fail for various reasons. If this happens, it is /* 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. ** 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 ** 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 ** Even if a subsequent open() call does succeed, the consequences of
** not searching for a reusable file descriptor are not dire. */ ** not searching for a reusable file descriptor are not dire. */
if( 0==osStat(zPath, &sStat) ){ if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){
unixInodeInfo *pInode; unixInodeInfo *pInode;
unixEnterMutex();
pInode = inodeList; pInode = inodeList;
while( pInode && (pInode->fileId.dev!=sStat.st_dev while( pInode && (pInode->fileId.dev!=sStat.st_dev
|| pInode->fileId.ino!=(u64)sStat.st_ino) ){ || 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)); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
pUnused = *pp; pUnused = *pp;
if( pUnused ){ if( pUnused ){
nUnusedFd--;
*pp = pUnused->pNext; *pp = pUnused->pNext;
} }
} }
unixLeaveMutex();
} }
unixLeaveMutex();
#endif /* if !OS_VXWORKS */ #endif /* if !OS_VXWORKS */
return pUnused; return pUnused;
} }
@@ -5811,7 +5818,7 @@ static int unixOpen(
return SQLITE_NOMEM_BKPT; return SQLITE_NOMEM_BKPT;
} }
} }
p->pUnused = pUnused; p->pPreallocatedUnused = pUnused;
/* Database filenames are double-zero terminated if they are not /* Database filenames are double-zero terminated if they are not
** URIs with parameters. Hence, they can always be passed into ** URIs with parameters. Hence, they can always be passed into
@@ -5848,7 +5855,7 @@ static int unixOpen(
gid_t gid; /* Groupid for the file */ gid_t gid; /* Groupid for the file */
rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
assert( !p->pUnused ); assert( !p->pPreallocatedUnused );
assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
return rc; return rc;
} }
@@ -5882,9 +5889,9 @@ static int unixOpen(
*pOutFlags = flags; *pOutFlags = flags;
} }
if( p->pUnused ){ if( p->pPreallocatedUnused ){
p->pUnused->fd = fd; p->pPreallocatedUnused->fd = fd;
p->pUnused->flags = flags; p->pPreallocatedUnused->flags = flags;
} }
if( isDelete ){ if( isDelete ){
@@ -5965,7 +5972,7 @@ static int unixOpen(
open_finished: open_finished:
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
sqlite3_free(p->pUnused); sqlite3_free(p->pPreallocatedUnused);
} }
return rc; return rc;
} }
@@ -6706,7 +6713,7 @@ static int proxyCreateUnixFile(
dummyVfs.zName = "dummy"; dummyVfs.zName = "dummy";
pUnused->fd = fd; pUnused->fd = fd;
pUnused->flags = openFlags; pUnused->flags = openFlags;
pNew->pUnused = pUnused; pNew->pPreallocatedUnused = pUnused;
rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){