mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Faster :memory: database COMMITs. Ticket #1790. (CVS 3178)
FossilOrigin-Name: 8f820e435272c0a4861421508c7e6f2979c2750f
This commit is contained in:
80
src/pager.c
80
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.266 2006/04/07 13:54:47 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.267 2006/05/03 23:34:06 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@@ -161,7 +161,8 @@ struct PgHdr {
|
||||
u8 needSync; /* Sync journal before writing this page */
|
||||
u8 alwaysRollback; /* Disable dont_rollback() for this page */
|
||||
short int nRef; /* Number of users of this page */
|
||||
PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */
|
||||
PgHdr *pDirty, *pPrevDirty; /* Dirty pages sorted by PgHdr.pgno */
|
||||
u32 notUsed; /* Buffer space */
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
u32 pageHash;
|
||||
#endif
|
||||
@@ -280,6 +281,7 @@ struct Pager {
|
||||
PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
|
||||
PgHdr *pAll; /* List of all pages */
|
||||
PgHdr *pStmt; /* List of pages in the statement subjournal */
|
||||
PgHdr *pDirty; /* List of all dirty pages */
|
||||
i64 journalOff; /* Current byte offset in the journal file */
|
||||
i64 journalHdr; /* Byte offset to previous journal header */
|
||||
i64 stmtHdrOff; /* First journal header written this statement */
|
||||
@@ -892,6 +894,7 @@ static int pager_unwritelock(Pager *pPager){
|
||||
pPg->pageHash = pager_pagehash(pPg);
|
||||
#endif
|
||||
}
|
||||
pPager->pDirty = 0;
|
||||
pPager->dirtyCache = 0;
|
||||
pPager->nRec = 0;
|
||||
}else{
|
||||
@@ -937,6 +940,9 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){
|
||||
return cksum;
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static void makeClean(PgHdr*);
|
||||
|
||||
/*
|
||||
** Read a single page from the journal file opened on file descriptor
|
||||
** jfd. Playback this one page.
|
||||
@@ -1014,7 +1020,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize);
|
||||
}
|
||||
if( pPg ) pPg->dirty = 0;
|
||||
if( pPg ){
|
||||
makeClean(pPg);
|
||||
}
|
||||
}
|
||||
if( pPg ){
|
||||
/* No page should ever be explicitly rolled back that is in use, except
|
||||
@@ -1164,6 +1172,7 @@ static int pager_reload_cache(Pager *pPager){
|
||||
pPg->pageHash = pager_pagehash(pPg);
|
||||
#endif
|
||||
}
|
||||
pPager->pDirty = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1908,6 +1917,7 @@ static void memoryTruncate(Pager *pPager){
|
||||
}else{
|
||||
*ppPg = pPg->pNextAll;
|
||||
unlinkPage(pPg);
|
||||
makeClean(pPg);
|
||||
sqliteFree(pPg);
|
||||
pPager->nPage--;
|
||||
}
|
||||
@@ -2305,15 +2315,7 @@ static int pager_write_pagelist(PgHdr *pList){
|
||||
** collected even if they are still in use.
|
||||
*/
|
||||
static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
|
||||
PgHdr *p, *pList;
|
||||
pList = 0;
|
||||
for(p=pPager->pAll; p; p=p->pNextAll){
|
||||
if( p->dirty ){
|
||||
p->pDirty = pList;
|
||||
pList = p;
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
return pPager->pDirty;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2388,6 +2390,8 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
|
||||
if( pPg->dirty ){
|
||||
int rc;
|
||||
assert( pPg->needSync==0 );
|
||||
makeClean(pPg);
|
||||
pPg->dirty = 1;
|
||||
pPg->pDirty = 0;
|
||||
rc = pager_write_pagelist( pPg );
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -2659,7 +2663,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
}else{
|
||||
page_remove_from_stmt_list(pPg);
|
||||
}
|
||||
pPg->dirty = 0;
|
||||
makeClean(pPg);
|
||||
pPg->nRef = 1;
|
||||
REFINFO(pPg);
|
||||
|
||||
@@ -2935,6 +2939,42 @@ int sqlite3pager_begin(void *pData, int exFlag){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a page dirty. Set its dirty flag and add it to the dirty
|
||||
** page list.
|
||||
*/
|
||||
static void makeDirty(PgHdr *pPg){
|
||||
if( pPg->dirty==0 ){
|
||||
Pager *pPager = pPg->pPager;
|
||||
pPg->dirty = 1;
|
||||
pPg->pDirty = pPager->pDirty;
|
||||
if( pPager->pDirty ){
|
||||
pPager->pDirty->pPrevDirty = pPg;
|
||||
}
|
||||
pPg->pPrevDirty = 0;
|
||||
pPager->pDirty = pPg;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a page clean. Clear its dirty bit and remove it from the
|
||||
** dirty page list.
|
||||
*/
|
||||
static void makeClean(PgHdr *pPg){
|
||||
if( pPg->dirty ){
|
||||
pPg->dirty = 0;
|
||||
if( pPg->pDirty ){
|
||||
pPg->pDirty->pPrevDirty = pPg->pPrevDirty;
|
||||
}
|
||||
if( pPg->pPrevDirty ){
|
||||
pPg->pPrevDirty->pDirty = pPg->pDirty;
|
||||
}else{
|
||||
pPg->pPager->pDirty = pPg->pDirty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Mark a data page as writeable. The page is written into the journal
|
||||
** if it is not there already. This routine must be called before making
|
||||
@@ -2973,7 +3013,7 @@ int sqlite3pager_write(void *pData){
|
||||
/* Mark the page as dirty. If the page has already been written
|
||||
** to the journal then we can return right away.
|
||||
*/
|
||||
pPg->dirty = 1;
|
||||
makeDirty(pPg);
|
||||
if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){
|
||||
pPager->dirtyCache = 1;
|
||||
}else{
|
||||
@@ -3180,7 +3220,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
|
||||
*/
|
||||
}else{
|
||||
TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager));
|
||||
pPg->dirty = 0;
|
||||
makeClean(pPg);
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
pPg->pageHash = pager_pagehash(pPg);
|
||||
#endif
|
||||
@@ -3248,6 +3288,7 @@ int sqlite3pager_commit(Pager *pPager){
|
||||
pPg->pPrevStmt = pPg->pNextStmt = 0;
|
||||
pPg = pPg->pDirty;
|
||||
}
|
||||
pPager->pDirty = 0;
|
||||
#ifndef NDEBUG
|
||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||
PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
|
||||
@@ -3315,12 +3356,11 @@ int sqlite3pager_rollback(Pager *pPager){
|
||||
p->inJournal = 0;
|
||||
p->inStmt = 0;
|
||||
p->pPrevStmt = p->pNextStmt = 0;
|
||||
|
||||
if( pPager->xReiniter ){
|
||||
pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize);
|
||||
}
|
||||
|
||||
}
|
||||
pPager->pDirty = 0;
|
||||
pPager->pStmt = 0;
|
||||
pPager->dbSize = pPager->origDbSize;
|
||||
memoryTruncate(pPager);
|
||||
@@ -3715,7 +3755,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
|
||||
if( pPgOld ){
|
||||
assert( pPgOld->nRef==0 );
|
||||
unlinkHashChain(pPager, pPgOld);
|
||||
pPgOld->dirty = 0;
|
||||
makeClean(pPgOld);
|
||||
if( pPgOld->needSync ){
|
||||
assert( pPgOld->inJournal );
|
||||
pPg->inJournal = 1;
|
||||
@@ -3735,7 +3775,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
|
||||
pPager->aHash[h] = pPg;
|
||||
pPg->pPrevHash = 0;
|
||||
|
||||
pPg->dirty = 1;
|
||||
makeDirty(pPg);
|
||||
pPager->dirtyCache = 1;
|
||||
|
||||
if( needSyncPgno ){
|
||||
@@ -3756,7 +3796,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
|
||||
pPager->needSync = 1;
|
||||
DATA_TO_PGHDR(pNeedSync)->needSync = 1;
|
||||
DATA_TO_PGHDR(pNeedSync)->inJournal = 1;
|
||||
DATA_TO_PGHDR(pNeedSync)->dirty = 1;
|
||||
makeDirty(DATA_TO_PGHDR(pNeedSync));
|
||||
sqlite3pager_unref(pNeedSync);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user