1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Further refinements to the virtual method implementation of

sqlite3PagerGet().

FossilOrigin-Name: 67df44464847b43f8c0b186157e31cc66c1e5796
This commit is contained in:
drh
2016-12-13 15:53:22 +00:00
parent 12e6f68279
commit d5df3ff2cc
3 changed files with 36 additions and 25 deletions

View File

@@ -1022,8 +1022,10 @@ static char *print_pager_state(Pager *p){
/* Forward references to the various page getters */
static int getPageNormal(Pager*,Pgno,DbPage**,int);
static int getPageMMap(Pager*,Pgno,DbPage**,int);
static int getPageError(Pager*,Pgno,DbPage**,int);
#if SQLITE_MAX_MMAP_SIZE>0
static int getPageMMap(Pager*,Pgno,DbPage**,int);
#endif
/*
** Set the Pager.xGet method for the appropriate routine used to fetch
@@ -1032,12 +1034,14 @@ static int getPageError(Pager*,Pgno,DbPage**,int);
static void setGetterMethod(Pager *pPager){
if( pPager->errCode ){
pPager->xGet = getPageError;
#if SQLITE_MAX_MMAP_SIZE>0
}else if( USEFETCH(pPager)
#ifdef SQLITE_HAS_CODEC
&& pPager->xCodec==0
#endif
){
pPager->xGet = getPageMMap;
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
}else{
pPager->xGet = getPageNormal;
}
@@ -5295,10 +5299,17 @@ static void pagerUnlockIfUnused(Pager *pPager){
}
/*
** Acquire a reference to page number pgno in pager pPager (a page
** reference has type DbPage*). If the requested reference is
** The page getter methods each try to acquire a reference to a
** page with page number pgno. If the requested reference is
** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
**
** There are different implementations of the getter method depending
** on the current state of the pager.
**
** getPageNormal() -- The normal getter
** getPageError() -- Used if the pager is in an error state
** getPageMmap() -- Used if memory-mapped I/O is enabled
**
** If the requested page is already in the cache, it is returned.
** Otherwise, a new page object is allocated and populated with data
** read from the database file. In some cases, the pcache module may
@@ -5310,14 +5321,14 @@ static void pagerUnlockIfUnused(Pager *pPager){
** already in the cache when this function is called, then the extra
** data is left as it was when the page object was last used.
**
** If the database image is smaller than the requested page or if a
** non-zero value is passed as the noContent parameter and the
** If the database image is smaller than the requested page or if
** the flags parameter contains the PAGER_GET_NOCONTENT bit and the
** requested page is not already stored in the cache, then no
** actual disk read occurs. In this case the memory image of the
** page is initialized to all zeros.
**
** If noContent is true, it means that we do not care about the contents
** of the page. This occurs in two scenarios:
** If PAGER_GET_NOCONTENT is true, it means that we do not care about
** the contents of the page. This occurs in two scenarios:
**
** a) When reading a free-list leaf page from the database, and
**
@@ -5325,8 +5336,8 @@ static void pagerUnlockIfUnused(Pager *pPager){
** a new page into the cache to be filled with the data read
** from the savepoint journal.
**
** If noContent is true, then the data returned is zeroed instead of
** being read from the database. Additionally, the bits corresponding
** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
** of being read from the database. Additionally, the bits corresponding
** to pgno in Pager.pInJournal (bitvec of pages already written to the
** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
** savepoints are set. This means if the page is made writable at any
@@ -5351,9 +5362,8 @@ static int getPageNormal(
int flags /* PAGER_GET_XXX flags */
){
int rc = SQLITE_OK;
PgHdr *pPg = 0;
u32 iFrame = 0; /* Frame to read from WAL file */
const int noContent = (flags & PAGER_GET_NOCONTENT);
PgHdr *pPg;
u8 noContent; /* True if PAGER_GET_NOCONTENT is set */
sqlite3_pcache_page *pBase;
if( pgno==0 ){
@@ -5367,10 +5377,10 @@ static int getPageNormal(
pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
if( pBase==0 ){
pPg = 0;
rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
if( rc!=SQLITE_OK ) goto pager_acquire_err;
if( pBase==0 ){
pPg = *ppPage = 0;
rc = SQLITE_NOMEM_BKPT;
goto pager_acquire_err;
}
@@ -5380,7 +5390,7 @@ static int getPageNormal(
assert( pPg->pgno==pgno );
assert( pPg->pPager==pPager || pPg->pPager==0 );
if( pPg->pPager && !noContent ){
if( pPg->pPager ){
/* In this case the pcache already contains an initialized copy of
** the page. Return without further ado. */
assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
@@ -5401,6 +5411,7 @@ static int getPageNormal(
}
assert( !isOpen(pPager->fd) || !MEMDB );
noContent = (flags & PAGER_GET_NOCONTENT)!=0;
if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
if( pgno>pPager->mxPgno ){
rc = SQLITE_FULL;
@@ -5425,7 +5436,8 @@ static int getPageNormal(
memset(pPg->pData, 0, pPager->pageSize);
IOTRACE(("ZERO %p %d\n", pPager, pgno));
}else{
if( pagerUseWal(pPager) /*&& bMmapOk==0*/ ){
u32 iFrame = 0; /* Frame to read from WAL file */
if( pagerUseWal(pPager) ){
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
if( rc!=SQLITE_OK ) goto pager_acquire_err;
}
@@ -5450,6 +5462,7 @@ pager_acquire_err:
return rc;
}
#if SQLITE_MAX_MMAP_SIZE>0
/* The page getter for when memory-mapped I/O is enabled */
static int getPageMMap(
Pager *pPager, /* The pager open on the database file */
@@ -5520,6 +5533,7 @@ static int getPageMMap(
}
return getPageNormal(pPager, pgno, ppPage, flags);
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
/* The page getter method for when the pager is an error state */
static int getPageError(