mirror of https://github.com/sqlite/sqlite
In the pager, cache a pointer to the first page on the freelist that does not
need to be synced. This makes a fetch of a page that is not in cache go a lot faster when the cache is full. This check-in also adds some performance instrumentation to the OS layer. (CVS 842) FossilOrigin-Name: 00f08fc0b5b6b9c5efbf15a62f9a1cc1cfa71283
This commit is contained in:
parent
e78e8284ad
commit
341eae8d35
14
manifest
14
manifest
|
@ -1,5 +1,5 @@
|
|||
C Update\scomments.\s\sNo\schanges\sto\scode.\s(CVS\s841)
|
||||
D 2003-01-19T03:59:46
|
||||
C In\sthe\spager,\scache\sa\spointer\sto\sthe\sfirst\spage\son\sthe\sfreelist\sthat\sdoes\snot\nneed\sto\sbe\ssynced.\s\sThis\smakes\sa\sfetch\sof\sa\spage\sthat\sis\snot\sin\scache\sgo\sa\nlot\sfaster\swhen\sthe\scache\sis\sfull.\s\sThis\scheck-in\salso\sadds\ssome\sperformance\ninstrumentation\sto\sthe\sOS\slayer.\s(CVS\s842)
|
||||
D 2003-01-21T02:39:37
|
||||
F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
|
@ -31,9 +31,9 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
|||
F src/insert.c db954e955970795819145a3649fd2ad116a58890
|
||||
F src/main.c ad3193c56da5acd31bc6cd48aa50dae1962d7c78
|
||||
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
||||
F src/os.c 3a652608c296cf639ce63bd31d255db862e45685
|
||||
F src/os.c ed27e178e0c4b71f2807da81b8851f0fadc50778
|
||||
F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
|
||||
F src/pager.c 081155624cff7bec54590133b69906a23f9b3659
|
||||
F src/pager.c f35799e6c5d9dbb9701f3a8945a557a34b8e4850
|
||||
F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
|
||||
F src/parse.y a4fbfbe3c4254c96dae8c33264fb54af755a3770
|
||||
F src/printf.c e8e9a0605602cb1a3a2dc754e0978fa9064ecee7
|
||||
|
@ -154,7 +154,7 @@ F www/speed.tcl 52759968401d81760fc01f9d3ab6242f6d2a7066
|
|||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P 424cb2edb0c51b911791422ce7a9f5284a57f9ce
|
||||
R c412fddde0211bcedc2c913718bf3cae
|
||||
P f6a8706872c43cee3003b48bb427c7b74b1f89e7
|
||||
R 55e4cf10cd865df3b849840e7c63f464
|
||||
U drh
|
||||
Z 08ec0c344754362c114e2ab7933a5823
|
||||
Z 512b1f62fa409b79d94b59ec53fdbfdf
|
||||
|
|
|
@ -1 +1 @@
|
|||
f6a8706872c43cee3003b48bb427c7b74b1f89e7
|
||||
00f08fc0b5b6b9c5efbf15a62f9a1cc1cfa71283
|
35
src/os.c
35
src/os.c
|
@ -52,15 +52,32 @@
|
|||
*/
|
||||
#if 0
|
||||
static int last_page = 0;
|
||||
#define SEEK(X) last_page=(X)
|
||||
#define TRACE1(X) fprintf(stderr,X)
|
||||
#define TRACE2(X,Y) fprintf(stderr,X,Y)
|
||||
#define TRACE3(X,Y,Z) fprintf(stderr,X,Y,Z)
|
||||
__inline__ unsigned long long int hwtime(void){
|
||||
unsigned long long int x;
|
||||
__asm__("rdtsc\n\t"
|
||||
"mov %%edx, %%ecx\n\t"
|
||||
:"=A" (x));
|
||||
return x;
|
||||
}
|
||||
static unsigned long long int g_start;
|
||||
static unsigned int elapse;
|
||||
#define TIMER_START g_start=hwtime()
|
||||
#define TIMER_END elapse=hwtime()-g_start
|
||||
#define SEEK(X) last_page=(X)
|
||||
#define TRACE1(X) fprintf(stderr,X)
|
||||
#define TRACE2(X,Y) fprintf(stderr,X,Y)
|
||||
#define TRACE3(X,Y,Z) fprintf(stderr,X,Y,Z)
|
||||
#define TRACE4(X,Y,Z,A) fprintf(stderr,X,Y,Z,A)
|
||||
#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
|
||||
#else
|
||||
#define TIMER_START
|
||||
#define TIMER_END
|
||||
#define SEEK(X)
|
||||
#define TRACE1(X)
|
||||
#define TRACE2(X,Y)
|
||||
#define TRACE3(X,Y,Z)
|
||||
#define TRACE4(X,Y,Z,A)
|
||||
#define TRACE5(X,Y,Z,A,B)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -664,8 +681,11 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
|
|||
#if OS_UNIX
|
||||
int got;
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
TRACE3("READ %-3d %d\n", id->fd, last_page);
|
||||
TIMER_START;
|
||||
got = read(id->fd, pBuf, amt);
|
||||
TIMER_END;
|
||||
TRACE4("READ %-3d %7d %d\n", id->fd, last_page, elapse);
|
||||
SEEK(0);
|
||||
/* if( got<0 ) got = 0; */
|
||||
if( got==amt ){
|
||||
return SQLITE_OK;
|
||||
|
@ -712,11 +732,14 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
|
|||
#if OS_UNIX
|
||||
int wrote = 0;
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
TRACE3("WRITE %-3d %d\n", id->fd, last_page);
|
||||
TIMER_START;
|
||||
while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
|
||||
amt -= wrote;
|
||||
pBuf = &((char*)pBuf)[wrote];
|
||||
}
|
||||
TIMER_END;
|
||||
TRACE4("WRITE %-3d %7d %d\n", id->fd, last_page, elapse);
|
||||
SEEK(0);
|
||||
if( amt>0 ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
|
|
48
src/pager.c
48
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.68 2003/01/16 13:42:43 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.69 2003/01/21 02:39:37 drh Exp $
|
||||
*/
|
||||
#include "os.h" /* Must be first to enable large file support */
|
||||
#include "sqliteInt.h"
|
||||
|
@ -162,6 +162,7 @@ struct Pager {
|
|||
u8 *aInJournal; /* One bit for each page in the database file */
|
||||
u8 *aInCkpt; /* One bit for each page in the database */
|
||||
PgHdr *pFirst, *pLast; /* List of free pages */
|
||||
PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
|
||||
PgHdr *pAll; /* List of all pages */
|
||||
PgHdr *pCkpt; /* List of pages in the checkpoint journal */
|
||||
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
|
||||
|
@ -346,6 +347,7 @@ static void pager_reset(Pager *pPager){
|
|||
sqliteFree(pPg);
|
||||
}
|
||||
pPager->pFirst = 0;
|
||||
pPager->pFirstSynced = 0;
|
||||
pPager->pLast = 0;
|
||||
pPager->pAll = 0;
|
||||
memset(pPager->aHash, 0, sizeof(pPager->aHash));
|
||||
|
@ -737,6 +739,7 @@ int sqlitepager_open(
|
|||
pPager->needSync = 0;
|
||||
pPager->noSync = pPager->tempFile || !useJournal;
|
||||
pPager->pFirst = 0;
|
||||
pPager->pFirstSynced = 0;
|
||||
pPager->pLast = 0;
|
||||
pPager->nExtra = nExtra;
|
||||
memset(pPager->aHash, 0, sizeof(pPager->aHash));
|
||||
|
@ -837,6 +840,11 @@ Pgno sqlitepager_pagenumber(void *pData){
|
|||
static void _page_ref(PgHdr *pPg){
|
||||
if( pPg->nRef==0 ){
|
||||
/* The page is currently on the freelist. Remove it. */
|
||||
if( pPg==pPg->pPager->pFirstSynced ){
|
||||
PgHdr *p = pPg->pNextFree;
|
||||
while( p && p->needSync ){ p = p->pNextFree; }
|
||||
pPg->pPager->pFirstSynced = p;
|
||||
}
|
||||
if( pPg->pPrevFree ){
|
||||
pPg->pPrevFree->pNextFree = pPg->pNextFree;
|
||||
}else{
|
||||
|
@ -901,13 +909,29 @@ static int syncAllPages(Pager *pPager){
|
|||
pPager->journalStarted = 1;
|
||||
}
|
||||
pPager->needSync = 0;
|
||||
|
||||
/* Erase the needSync flag from every page.
|
||||
*/
|
||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||
pPg->needSync = 0;
|
||||
}
|
||||
pPager->pFirstSynced = pPager->pFirst;
|
||||
}
|
||||
|
||||
/* Erase the needSync flag from every page.
|
||||
#ifndef NDEBUG
|
||||
/* If the Pager.needSync flag is clear then the PgHdr.needSync
|
||||
** flag must also be clear for all pages. Verify that this
|
||||
** invariant is true.
|
||||
*/
|
||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||
pPg->needSync = 0;
|
||||
else{
|
||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||
assert( pPg->needSync==0 );
|
||||
}
|
||||
assert( pPager->pFirstSynced==pPager->pFirst );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1032,10 +1056,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
/* Find a page to recycle. Try to locate a page that does not
|
||||
** require us to do an fsync() on the journal.
|
||||
*/
|
||||
pPg = pPager->pFirst;
|
||||
while( pPg && pPg->needSync ){
|
||||
pPg = pPg->pNextFree;
|
||||
}
|
||||
pPg = pPager->pFirstSynced;
|
||||
|
||||
/* If we could not find a page that does not require an fsync()
|
||||
** on the journal file then fsync the journal file. This is a
|
||||
|
@ -1083,6 +1104,11 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
|
||||
/* Unlink the old page from the free list and the hash table
|
||||
*/
|
||||
if( pPg==pPager->pFirstSynced ){
|
||||
PgHdr *p = pPg->pNextFree;
|
||||
while( p && p->needSync ){ p = p->pNextFree; }
|
||||
pPager->pFirstSynced = p;
|
||||
}
|
||||
if( pPg->pPrevFree ){
|
||||
pPg->pPrevFree->pNextFree = pPg->pNextFree;
|
||||
}else{
|
||||
|
@ -1226,6 +1252,9 @@ int sqlitepager_unref(void *pData){
|
|||
}else{
|
||||
pPager->pFirst = pPg;
|
||||
}
|
||||
if( pPg->needSync==0 && pPager->pFirstSynced==0 ){
|
||||
pPager->pFirstSynced = pPg;
|
||||
}
|
||||
if( pPager->xDestructor ){
|
||||
pPager->xDestructor(pData);
|
||||
}
|
||||
|
@ -1577,13 +1606,12 @@ int sqlitepager_commit(Pager *pPager){
|
|||
if( pPager->dirtyFile==0 ){
|
||||
/* Exit early (without doing the time-consuming sqliteOsSync() calls)
|
||||
** if there have been no changes to the database file. */
|
||||
assert( pPager->needSync==0 );
|
||||
rc = pager_unwritelock(pPager);
|
||||
pPager->dbSize = -1;
|
||||
return rc;
|
||||
}
|
||||
assert( pPager->journalOpen );
|
||||
if( !pPager->journalStarted && !pPager->noSync ) pPager->needSync = 1;
|
||||
assert( pPager->dirtyFile || !pPager->needSync );
|
||||
if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
|
||||
goto commit_abort;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue