From 7236583ba08dd523850f0a77dc906a006c5bbb15 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Mar 2007 15:53:44 +0000 Subject: [PATCH] Fixes to the overflow-chain optization of (3672). (CVS 3674) FossilOrigin-Name: d6986d1e7cba1d114fa06c5560ffc6bb1feb7389 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 24 ++++++++++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c3b8675253..b5068ea11b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sheap\sinstead\sof\sstack\sfor\slarge\sbuffers\sin\sthe\spager.\sFix\sfor\s#2262.\s(CVS\s3673) -D 2007-03-06T13:46:00 +C Fixes\sto\sthe\soverflow-chain\soptization\sof\s(3672).\s(CVS\s3674) +D 2007-03-06T15:53:44 F Makefile.in 1fe3d0b46e40fd684e1e61f8e8056cefed16de9f F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -57,7 +57,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3 F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a F src/attach.c b11eb4d5d3fb99a10a626956bccc7215f6b68b16 F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f -F src/btree.c d42d2b634a5099cd6cb92d4482fba980ddc6635f +F src/btree.c f5c1b3d88ad62ab4682de37229168a00b87fc948 F src/btree.h 066444ee25bd6e6accb997bfd2cf5ace14dbcd00 F src/build.c 6bd68dc730b01c1727738f8e4b5c730eb0ddb421 F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558 @@ -435,7 +435,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 6db945f7a7587c8c7adada92f94ac7936b901cf1 -R fd445e52d946f4b2dccfd0401e136fcc -U danielk1977 -Z 899687d498719bea31167b023df14d79 +P dfe1dffa4515ed6494055887d351863fe0cdb87f +R d2acbced061dbbf26fe53e64388781c3 +U drh +Z 244e63934da04ffe6f36fb683b60298b diff --git a/manifest.uuid b/manifest.uuid index a02a6aec97..c381dd1f3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfe1dffa4515ed6494055887d351863fe0cdb87f \ No newline at end of file +d6986d1e7cba1d114fa06c5560ffc6bb1feb7389 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 368b380954..f99277402a 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.337 2007/03/06 11:42:19 drh Exp $ +** $Id: btree.c,v 1.338 2007/03/06 15:53:44 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -365,6 +365,7 @@ struct CellInfo { u8 *pCell; /* Pointer to the start of cell content */ i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ u32 nData; /* Number of bytes of data */ + u32 nPayload; /* Total amount of payload */ u16 nHeader; /* Size of the cell content header in bytes */ u16 nLocal; /* Amount of payload held locally */ u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ @@ -944,6 +945,7 @@ static void parseCellPtr( pInfo->nKey = x; nPayload += x; } + pInfo->nPayload = nPayload; pInfo->nHeader = n; if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits @@ -1020,6 +1022,7 @@ static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ if( pCell ){ CellInfo info; parseCellPtr(pPage, pCell, &info); + assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ Pgno ovfl = get4byte(&pCell[info.iOverflow]); return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); @@ -3876,30 +3879,29 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ int rc; int nOvfl; int ovflPageSize; - int nPayload; parseCellPtr(pPage, pCell, &info); if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } ovflPgno = get4byte(&pCell[info.iOverflow]); - nPayload = pPage->intKey ? info.nData : info.nKey; ovflPageSize = pBt->usableSize - 4; - nOvfl = (nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; - while( ovflPgno!=0 ){ + nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; + assert( ovflPgno==0 || nOvfl>0 ); + while( nOvfl-- ){ MemPage *pOvfl; - nOvfl--; - if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ + if( ovflPgno==0 || ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ return SQLITE_CORRUPT_BKPT; } - rc = getPage(pBt, ovflPgno, &pOvfl, nOvfl==0); + rc = getPage(pBt, ovflPgno, &pOvfl, 0); if( rc ) return rc; - ovflPgno = get4byte(pOvfl->aData); + if( nOvfl ){ + ovflPgno = get4byte(pOvfl->aData); + } rc = freePage(pOvfl); sqlite3pager_unref(pOvfl->aData); if( rc ) return rc; } - assert( nOvfl==0 ); return SQLITE_OK; } @@ -4196,6 +4198,7 @@ static int insertCell( */ CellInfo info; parseCellPtr(pPage, pCell, &info); + assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); @@ -6201,6 +6204,7 @@ static int checkTreePage( parseCellPtr(pPage, pCell, &info); sz = info.nData; if( !pPage->intKey ) sz += info.nKey; + assert( sz==info.nPayload ); if( sz>info.nLocal ){ int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);