aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-10-21 11:06:03 +0000
committerdrh <>2023-10-21 11:06:03 +0000
commit266e5d034b14615c56c09efbfafb7b6748b5c971 (patch)
tree380bf7d12627ea8e81016651790d786d35339d04 /src
parent71bae9f19f8c73841c0b4062af7c56bd83271e77 (diff)
downloadsqlite-266e5d034b14615c56c09efbfafb7b6748b5c971.tar.gz
sqlite-266e5d034b14615c56c09efbfafb7b6748b5c971.zip
Avoid an unnecessary malloc() for the page usage bitmap when running
a partial integrity_check. FossilOrigin-Name: 2904fcbeebba9189cebc48e58d12fc46f78ee23d8c4d46644606691f8cabb80c
Diffstat (limited to 'src')
-rw-r--r--src/btree.c28
-rw-r--r--src/btreeInt.h2
2 files changed, 18 insertions, 12 deletions
diff --git a/src/btree.c b/src/btree.c
index 3c4f00d15..ec4d02d19 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -10459,7 +10459,7 @@ static void checkAppendMsg(
** corresponds to page iPg is already set.
*/
static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){
- assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
+ assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 );
return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07)));
}
@@ -10467,7 +10467,7 @@ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){
** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg.
*/
static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
- assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
+ assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 );
pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07));
}
@@ -10481,7 +10481,8 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage){
- if( iPage>pCheck->nPage || iPage==0 ){
+ if( iPage>pCheck->nCkPage || iPage==0 ){
+ if( pCheck->nCkPage==0 ) return 0; /* omit reference counting */
checkAppendMsg(pCheck, "invalid page number %u", iPage);
return 1;
}
@@ -10979,18 +10980,23 @@ int sqlite3BtreeIntegrityCheck(
sCheck.db = db;
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
- sCheck.nPage = btreePagecount(sCheck.pBt);
+ sCheck.nCkPage = btreePagecount(sCheck.pBt);
sCheck.mxErr = mxErr;
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
- if( sCheck.nPage==0 ){
+ if( sCheck.nCkPage==0 ){
goto integrity_ck_cleanup;
}
- sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
- if( !sCheck.aPgRef ){
- checkOom(&sCheck);
- goto integrity_ck_cleanup;
+ if( bPartial ){
+ sCheck.nCkPage = 0;
+ sCheck.aPgRef = 0;
+ }else{
+ sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1);
+ if( !sCheck.aPgRef ){
+ checkOom(&sCheck);
+ goto integrity_ck_cleanup;
+ }
}
sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
if( sCheck.heap==0 ){
@@ -10999,7 +11005,7 @@ int sqlite3BtreeIntegrityCheck(
}
i = PENDING_BYTE_PAGE(pBt);
- if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
+ if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i);
/* Check the integrity of the freelist
*/
@@ -11050,7 +11056,7 @@ int sqlite3BtreeIntegrityCheck(
/* Make sure every page in the file is referenced
*/
if( !bPartial ){
- for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
+ for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
if( getPageReferenced(&sCheck, i)==0 ){
checkAppendMsg(&sCheck, "Page %u: never used", i);
diff --git a/src/btreeInt.h b/src/btreeInt.h
index 26a0bc686..563e15f8a 100644
--- a/src/btreeInt.h
+++ b/src/btreeInt.h
@@ -695,7 +695,7 @@ struct IntegrityCk {
BtShared *pBt; /* The tree being checked out */
Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
u8 *aPgRef; /* 1 bit per page in the db (see above) */
- Pgno nPage; /* Number of pages in the database */
+ Pgno nCkPage; /* Pages in the database. 0 for partial check */
int mxErr; /* Stop accumulating errors when this reaches zero */
int nErr; /* Number of messages written to zErrMsg so far */
int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */