diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/os_unix.c | 1 | ||||
-rw-r--r-- | src/os_win.c | 2 | ||||
-rw-r--r-- | src/pager.c | 20 | ||||
-rw-r--r-- | src/sqlite.h.in | 7 |
4 files changed, 23 insertions, 7 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index f71fa8e02..d99965821 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4128,6 +4128,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + pFd->deviceCharacteristics |= SQLITE_IOCAP_BYPASS; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } diff --git a/src/os_win.c b/src/os_win.c index 442c108e9..47fff58cc 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3660,7 +3660,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_BYPASS | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } diff --git a/src/pager.c b/src/pager.c index 1ac858a07..1b624a300 100644 --- a/src/pager.c +++ b/src/pager.c @@ -808,18 +808,26 @@ static const unsigned char aJournalMagic[] = { ** Return true if page pgno can be read directly from the database file ** by the b-tree layer. This is the case if: ** -** * the database file is open, -** * there are no dirty pages in the cache, and -** * the desired page is not currently in the wal file. +** (1) the database file is open +** (2) the VFS for the database has BYPASS capability +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. */ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ - if( pPager->fd->pMethods==0 ) return 0; - if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_BYPASS)==0 ){ + return 0; /* Case (2) */ + } + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return iRead==0; + return iRead==0; /* Condition (4) */ } #endif return 1; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7097e6bb5..2db643b28 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -652,6 +652,11 @@ int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_BYPASS property means that it is ok for the +** B-tree layer to bypass the pager and VFS and read content directly +** from the filesystem (the SQLITE_DIRECT_OVERFLOW_READ optimization) +** when that is beneficial for performance. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -668,6 +673,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_BYPASS 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -814,6 +820,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_BYPASS] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of |