mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Pager performance enhancements. (CVS 3125)
FossilOrigin-Name: 9c26570743d878dee963e37728969fb30a2fb436
This commit is contained in:
70
src/pager.c
70
src/pager.c
@@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.260 2006/02/24 03:09:37 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.261 2006/03/06 18:23:17 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@@ -52,8 +52,8 @@
|
||||
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
|
||||
** struct as it's argument.
|
||||
*/
|
||||
#define PAGERID(p) FILEHANDLEID(&(p)->fd)
|
||||
#define FILEHANDLEID(fd) (sqlite3OsFileHandle(&fd))
|
||||
#define PAGERID(p) ((int)(p->fd))
|
||||
#define FILEHANDLEID(fd) ((int)fd)
|
||||
|
||||
/*
|
||||
** The page cache as a whole is always in one of the following
|
||||
@@ -190,9 +190,11 @@ struct PgHistory {
|
||||
** A macro used for invoking the codec if there is one
|
||||
*/
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
|
||||
# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
|
||||
# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
|
||||
#else
|
||||
# define CODEC(P,D,N,X)
|
||||
# define CODEC1(P,D,N,X) /* NO-OP */
|
||||
# define CODEC2(P,D,N,X) ((char*)D)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -290,7 +292,7 @@ struct Pager {
|
||||
#endif
|
||||
void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
|
||||
void (*xReiniter)(void*,int); /* Call this routine when reloading pages */
|
||||
void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
|
||||
void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
|
||||
void *pCodecArg; /* First argument to xCodec() */
|
||||
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
@@ -435,16 +437,6 @@ static int write32bits(OsFile *fd, u32 val){
|
||||
return sqlite3OsWrite(fd, ac, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
** Write the 32-bit integer 'val' into the page identified by page header
|
||||
** 'p' at offset 'offset'.
|
||||
*/
|
||||
static void store32bits(u32 val, PgHdr *p, int offset){
|
||||
char *ac;
|
||||
ac = &((char*)PGHDR_TO_DATA(p))[offset];
|
||||
put32bits(ac, val);
|
||||
}
|
||||
|
||||
/*
|
||||
** Read a 32-bit integer at offset 'offset' from the page identified by
|
||||
** page header 'p'.
|
||||
@@ -1041,7 +1033,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
pPg->pageHash = pager_pagehash(pPg);
|
||||
#endif
|
||||
CODEC(pPager, pData, pPg->pgno, 3);
|
||||
CODEC1(pPager, pData, pPg->pgno, 3);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1154,7 +1146,7 @@ static int pager_reload_cache(Pager *pPager){
|
||||
}
|
||||
TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||
if( rc ) break;
|
||||
CODEC(pPager, zBuf, pPg->pgno, 2);
|
||||
CODEC1(pPager, zBuf, pPg->pgno, 2);
|
||||
}else{
|
||||
memset(zBuf, 0, pPager->pageSize);
|
||||
}
|
||||
@@ -2274,11 +2266,9 @@ static int pager_write_pagelist(PgHdr *pList){
|
||||
** any such pages to the file.
|
||||
*/
|
||||
if( pList->pgno<=pPager->dbSize ){
|
||||
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
|
||||
char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
|
||||
TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
|
||||
rc = sqlite3OsWrite(pPager->fd, PGHDR_TO_DATA(pList),
|
||||
pPager->pageSize);
|
||||
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
|
||||
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize);
|
||||
TEST_INCR(pPager->nWrite);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
@@ -2683,7 +2673,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
pPager->pageSize);
|
||||
}
|
||||
TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||
CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
|
||||
CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
|
||||
if( rc!=SQLITE_OK ){
|
||||
i64 fileSize;
|
||||
int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
|
||||
@@ -3002,7 +2992,6 @@ int sqlite3pager_write(void *pData){
|
||||
if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
|
||||
if( (int)pPg->pgno <= pPager->origDbSize ){
|
||||
int szPg;
|
||||
u32 saved;
|
||||
if( MEMDB ){
|
||||
PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
|
||||
TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||
@@ -3012,24 +3001,25 @@ int sqlite3pager_write(void *pData){
|
||||
memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
|
||||
}
|
||||
}else{
|
||||
u32 cksum;
|
||||
u32 cksum, saved;
|
||||
char *pData2, *pEnd;
|
||||
/* We should never write to the journal file the page that
|
||||
** contains the database locks. The following assert verifies
|
||||
** that we do not. */
|
||||
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
|
||||
CODEC(pPager, pData, pPg->pgno, 7);
|
||||
cksum = pager_cksum(pPager, pData);
|
||||
saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
|
||||
store32bits(cksum, pPg, pPager->pageSize);
|
||||
pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
|
||||
cksum = pager_cksum(pPager, pData2);
|
||||
pEnd = pData2 + pPager->pageSize;
|
||||
pData2 -= 4;
|
||||
saved = *(u32*)pEnd;
|
||||
put32bits(pEnd, cksum);
|
||||
szPg = pPager->pageSize+8;
|
||||
store32bits(pPg->pgno, pPg, -4);
|
||||
|
||||
rc = sqlite3OsWrite(pPager->jfd, &((char*)pData)[-4], szPg);
|
||||
put32bits(pData2, pPg->pgno);
|
||||
rc = sqlite3OsWrite(pPager->jfd, pData2, szPg);
|
||||
pPager->journalOff += szPg;
|
||||
TRACE4("JOURNAL %d page %d needSync=%d\n",
|
||||
PAGERID(pPager), pPg->pgno, pPg->needSync);
|
||||
CODEC(pPager, pData, pPg->pgno, 0);
|
||||
*(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
|
||||
*(u32*)pEnd = saved;
|
||||
|
||||
/* An error has occured writing to the journal file. The
|
||||
** transaction will be rolled back by the layer above.
|
||||
@@ -3074,12 +3064,10 @@ int sqlite3pager_write(void *pData){
|
||||
}
|
||||
TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||
}else{
|
||||
store32bits(pPg->pgno, pPg, -4);
|
||||
CODEC(pPager, pData, pPg->pgno, 7);
|
||||
rc = sqlite3OsWrite(pPager->stfd,((char*)pData)-4,
|
||||
pPager->pageSize+4);
|
||||
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4;
|
||||
put32bits(pData2, pPg->pgno);
|
||||
rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize+4);
|
||||
TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||
CODEC(pPager, pData, pPg->pgno, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -3551,7 +3539,7 @@ int sqlite3pager_nosync(Pager *pPager){
|
||||
*/
|
||||
void sqlite3pager_set_codec(
|
||||
Pager *pPager,
|
||||
void (*xCodec)(void*,void*,Pgno,int),
|
||||
void *(*xCodec)(void*,void*,Pgno,int),
|
||||
void *pCodecArg
|
||||
){
|
||||
pPager->xCodec = xCodec;
|
||||
@@ -3580,7 +3568,7 @@ static int pager_incr_changecounter(Pager *pPager){
|
||||
|
||||
/* Increment the value just read and write it back to byte 24. */
|
||||
change_counter++;
|
||||
store32bits(change_counter, pPgHdr, 24);
|
||||
put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
|
||||
|
||||
/* Release the page reference. */
|
||||
sqlite3pager_unref(pPage);
|
||||
|
Reference in New Issue
Block a user