1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Speed up xAccess() calls made on an RBU VFS when there are lots of open

connections.

FossilOrigin-Name: 310b4b65b8c8ee080760c7efb4c7e20244c6063a5dba37a4f40490105aafd29f
This commit is contained in:
dan
2018-10-01 17:33:35 +00:00
parent 44d068532e
commit 49f84ce1cd
3 changed files with 82 additions and 34 deletions

View File

@ -405,7 +405,8 @@ struct rbu_vfs {
sqlite3_vfs *pRealVfs; /* Underlying VFS */
sqlite3_mutex *mutex; /* Mutex to protect pMain */
sqlite3rbu *pRbu; /* Owner RBU object */
rbu_file *pMain; /* Linked list of main db files */
rbu_file *pMain; /* List of main db files */
rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
};
/*
@ -434,6 +435,7 @@ struct rbu_file {
const char *zWal; /* Wal filename for this main db file */
rbu_file *pWalFd; /* Wal file descriptor for this main db */
rbu_file *pMainNext; /* Next MAIN_DB file */
rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
};
/*
@ -4030,6 +4032,69 @@ static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
return SQLITE_OK;
}
/*
** Add an item to the main-db lists, if it is not already present.
**
** There are two main-db lists. One for all file descriptors, and one
** for all file descriptors with rbu_file.pDb!=0. If the argument has
** rbu_file.pDb!=0, then it is assumed to already be present on the
** main list and is only added to the pDb!=0 list.
*/
static void rbuMainlistAdd(rbu_file *p){
rbu_vfs *pRbuVfs = p->pRbuVfs;
rbu_file *pIter;
assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
sqlite3_mutex_enter(pRbuVfs->mutex);
if( p->pRbu==0 ){
for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
p->pMainNext = pRbuVfs->pMain;
pRbuVfs->pMain = p;
}else{
for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
if( pIter==0 ){
p->pMainRbuNext = pRbuVfs->pMainRbu;
pRbuVfs->pMainRbu = p;
}
}
sqlite3_mutex_leave(pRbuVfs->mutex);
}
/*
** Remove an item from the main-db lists.
*/
static void rbuMainlistRemove(rbu_file *p){
rbu_file **pp;
sqlite3_mutex_enter(p->pRbuVfs->mutex);
for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
if( *pp ) *pp = p->pMainNext;
p->pMainNext = 0;
for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
if( *pp ) *pp = p->pMainRbuNext;
p->pMainRbuNext = 0;
sqlite3_mutex_leave(p->pRbuVfs->mutex);
}
/*
** Given that zWal points to a buffer containing a wal file name passed to
** either the xOpen() or xAccess() VFS method, search the main-db list for
** a file-handle opened by the same database connection on the corresponding
** database file.
**
** If parameter bRbu is true, only search for file-descriptors with
** rbu_file.pDb!=0.
*/
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
rbu_file *pDb;
sqlite3_mutex_enter(pRbuVfs->mutex);
if( bRbu ){
for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
}else{
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
}
sqlite3_mutex_leave(pRbuVfs->mutex);
return pDb;
}
/*
** Close an rbu file.
*/
@ -4047,17 +4112,14 @@ static int rbuVfsClose(sqlite3_file *pFile){
sqlite3_free(p->zDel);
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbu_file **pp;
sqlite3_mutex_enter(p->pRbuVfs->mutex);
for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
*pp = p->pMainNext;
sqlite3_mutex_leave(p->pRbuVfs->mutex);
rbuMainlistRemove(p);
rbuUnlockShm(p);
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
rbuUpdateTempSize(p, 0);
}
assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
/* Close the underlying file handle */
rc = p->pReal->pMethods->xClose(p->pReal);
@ -4316,6 +4378,9 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistAdd(p);
}
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
@ -4477,20 +4542,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
return rc;
}
/*
** Given that zWal points to a buffer containing a wal file name passed to
** either the xOpen() or xAccess() VFS method, return a pointer to the
** file-handle opened by the same database connection on the corresponding
** database file.
*/
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
rbu_file *pDb;
sqlite3_mutex_enter(pRbuVfs->mutex);
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
sqlite3_mutex_leave(pRbuVfs->mutex);
return pDb;
}
/*
** A main database named zName has just been opened. The following
** function returns a pointer to a buffer owned by SQLite that contains
@ -4569,7 +4620,7 @@ static int rbuVfsOpen(
pFd->zWal = rbuMainToWal(zName, flags);
}
else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. This
@ -4621,10 +4672,7 @@ static int rbuVfsOpen(
** mutex protected linked list of all such files. */
pFile->pMethods = &rbuvfs_io_methods;
if( flags & SQLITE_OPEN_MAIN_DB ){
sqlite3_mutex_enter(pRbuVfs->mutex);
pFd->pMainNext = pRbuVfs->pMain;
pRbuVfs->pMain = pFd;
sqlite3_mutex_leave(pRbuVfs->mutex);
rbuMainlistAdd(pFd);
}
}else{
sqlite3_free(pFd->zDel);
@ -4672,7 +4720,7 @@ static int rbuVfsAccess(
** file opened instead.
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( *pResOut ){
rc = SQLITE_CANTOPEN;