diff --git a/manifest b/manifest index 26524642a9..b8679485a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Speed\simprovements\sfor\sin-memory\sdatabases\sby\somitting\sflag\sclearing\son\spages\nwhere\sit\sis\simpossible\sfor\sthe\sflag\sto\sbe\sset\sand\sby\savoiding\sassert()s\son\nnon-debugging\sbuilds.\s\sTicket\s#3384.\s(CVS\s5715) -D 2008-09-17T20:06:26 +C Performance\simprovements\sin\sgetAndInitPage():\somit\sthe\supper\sbound\scheck\son\npage\snumber\sif\sthe\spage\sis\salready\sin\scache.\s(CVS\s5716) +D 2008-09-18T01:08:16 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -99,7 +99,7 @@ F src/attach.c db3f4a60538733c1e4dcb9d0217a6e0d6ccd615b F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53 -F src/btree.c 5419fcd2faa02b7759051495a5e339444c679205 +F src/btree.c 5db7b54e9d39dddb06e066e993901fc8630c6e49 F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107 F src/btreeInt.h ab18c7b4980314e9e4b402e5dcde09f3c2545576 F src/build.c 160c71acca8f643f436ed6c1ee2f684c88df4dfe @@ -637,7 +637,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 6ef34e9d3118965781c69011deaede1ebbb19b12 -R a27713f2ccd1c6c2e7e56fb7534b72ec +P a7fd9e622bc1050e78f227ec42b6ba90c87c865a +R e81f4600bcea4a2618108ffa41a20258 U drh -Z ee142ff5e27b59538a7c71659e26324f +Z e79e626cd696de5d56149e65cface269 diff --git a/manifest.uuid b/manifest.uuid index 7992787902..1a1397b9b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7fd9e622bc1050e78f227ec42b6ba90c87c865a \ No newline at end of file +badd0873e6dffac9463b06a381b9f797a54d33e9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 41ffd57e42..12d29e25ef 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.511 2008/09/10 17:53:36 danielk1977 Exp $ +** $Id: btree.c,v 1.512 2008/09/18 01:08:16 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1051,6 +1051,21 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->isInit = 1; } + +/* +** Convert a DbPage obtained from the pager into a MemPage used by +** the btree layer. +*/ +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; + return pPage; +} + /* ** Get a page from the pager. Initialize the MemPage.pBt and ** MemPage.aData elements if needed. @@ -1069,19 +1084,12 @@ int sqlite3BtreeGetPage( int noContent /* Do not load page content if true */ ){ int rc; - MemPage *pPage; DbPage *pDbPage; assert( sqlite3_mutex_held(pBt->mutex) ); rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); if( rc ) return rc; - pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage); - pPage->aData = sqlite3PagerGetData(pDbPage); - pPage->pDbPage = pDbPage; - pPage->pBt = pBt; - pPage->pgno = pgno; - pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; - *ppPage = pPage; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); return SQLITE_OK; } @@ -1108,28 +1116,47 @@ static int getAndInitPage( MemPage *pParent /* Parent of the page */ ){ int rc; + DbPage *pDbPage; + MemPage *pPage; + assert( sqlite3_mutex_held(pBt->mutex) ); assert( !pParent || pParent->isInit ); - if( pgno==0 || pgno>pagerPagecount(pBt->pPager) ){ + if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } - rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0); - if( rc==SQLITE_OK ){ - if( (*ppPage)->isInit==0 ){ - rc = sqlite3BtreeInitPage(*ppPage, pParent); - }else if( pParent && ((*ppPage)==pParent || (*ppPage)->pParent!=pParent) ){ - /* This condition indicates a loop in the b-tree structure (the scenario - ** where database corruption has caused a page to be a direct or - ** indirect descendant of itself). - */ - rc = SQLITE_CORRUPT_BKPT; - } - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - *ppPage = 0; - } - } + /* It is often the case that the page we want is already in cache. + ** If so, get it directly. This saves us from having to call + ** pagerPagecount() to make sure pgno is within limits, which results + ** in a measureable performance improvements. + */ + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + /* Page is already in cache */ + *ppPage = pPage = btreePageFromDbPage(pDbPage, pgno, pBt); + rc = SQLITE_OK; + }else{ + /* Page not in cache. Acquire it. */ + if( pgno>pagerPagecount(pBt->pPager) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0); + if( rc ) return rc; + pPage = *ppPage; + } + if( pPage->isInit==0 ){ + rc = sqlite3BtreeInitPage(pPage, pParent); + }else if( pParent && (pPage==pParent || pPage->pParent!=pParent) ){ + /* This condition indicates a loop in the b-tree structure (the scenario + ** where database corruption has caused a page to be a direct or + ** indirect descendant of itself). + */ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ + releasePage(pPage); + *ppPage = 0; + } return rc; }