Index: third_party/sqlite/amalgamation/sqlite3.c |
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c |
index b849c15d32fe634b15faae851d4d518cdc395166..db273b2b4f395133a09b8b97d0f6d29e12debaf2 100644 |
--- a/third_party/sqlite/amalgamation/sqlite3.c |
+++ b/third_party/sqlite/amalgamation/sqlite3.c |
@@ -12266,6 +12266,8 @@ SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); |
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); |
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); |
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); |
+SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuumSlackPages(Btree *, int); |
+SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuumSlackPages(Btree *); |
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); |
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); |
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); |
@@ -58368,6 +58370,7 @@ struct BtShared { |
u8 openFlags; /* Flags to sqlite3BtreeOpen() */ |
#ifndef SQLITE_OMIT_AUTOVACUUM |
u8 autoVacuum; /* True if auto-vacuum is enabled */ |
+ u8 autoVacuumSlack; /* Optional pages of slack for auto-vacuum */ |
u8 incrVacuum; /* True if incr-vacuum is enabled */ |
u8 bDoTruncate; /* True to truncate db on commit */ |
#endif |
@@ -61765,6 +61768,46 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ |
#endif |
} |
+/* |
+** Change the 'auto-vacuum-slack-pages' property of the database. If auto vacuum |
+** is enabled, this is the number of chunks of slack to allow before |
+** automatically running an incremental vacuum. |
+*/ |
+SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuumSlackPages(Btree *p, int autoVacuumSlack){ |
+#ifdef SQLITE_OMIT_AUTOVACUUM |
+ return SQLITE_READONLY; |
+#else |
+ BtShared *pBt = p->pBt; |
+ int rc = SQLITE_OK; |
+ u8 avs = (u8)autoVacuumSlack; |
+ if( autoVacuumSlack>avs ){ |
+ avs = 0xFF; |
+ } |
+ |
+ sqlite3BtreeEnter(p); |
+ pBt->autoVacuumSlack = avs; |
+ sqlite3BtreeLeave(p); |
+ return rc; |
+#endif |
+} |
+ |
+/* |
+** Return the value of the 'auto-vacuum-slack-pages' property. |
+*/ |
+SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuumSlackPages(Btree *p){ |
+#ifdef SQLITE_OMIT_AUTOVACUUM |
+ return 0; |
+#else |
+ int rc = 0; |
+ sqlite3BtreeEnter(p); |
+ if( p->pBt->autoVacuum!=0 ){ |
+ rc = p->pBt->autoVacuumSlack; |
+ } |
+ sqlite3BtreeLeave(p); |
+ return rc; |
+#endif |
+} |
+ |
/* |
** Get a reference to pPage1 of the database file. This will |
@@ -62606,13 +62649,27 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ |
*/ |
static int autoVacuumCommit(BtShared *pBt){ |
int rc = SQLITE_OK; |
+ int bShouldVacuum = pBt->autoVacuum && !pBt->incrVacuum; |
Pager *pPager = pBt->pPager; |
VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); ) |
assert( sqlite3_mutex_held(pBt->mutex) ); |
invalidateAllOverflowCache(pBt); |
assert(pBt->autoVacuum); |
- if( !pBt->incrVacuum ){ |
+ if( bShouldVacuum && pBt->autoVacuumSlack ){ |
+ Pgno nOrig; /* Database size before freeing */ |
+ Pgno nFree; /* Number of pages on the freelist initially */ |
+ |
+ nOrig = btreePagecount(pBt); |
+ nFree = get4byte(&pBt->pPage1->aData[36]); |
+ bShouldVacuum = |
+ (nOrig-nFree-1)/pBt->autoVacuumSlack < (nOrig-1)/pBt->autoVacuumSlack; |
+ /* TODO: When integrating this test with the following code, contrive to |
+ ** trim to the integral chunk boundary, rather than trimming the entire free |
+ ** list. |
+ */ |
+ } |
+ if( bShouldVacuum ){ |
Pgno nFin; /* Number of pages in database after autovacuuming */ |
Pgno nFree; /* Number of pages on the freelist initially */ |
Pgno iFree; /* The next page to be freed */ |
@@ -112205,6 +112262,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ |
#define PragTyp_REKEY 40 |
#define PragTyp_LOCK_STATUS 41 |
#define PragTyp_PARSER_TRACE 42 |
+#define PragTyp_AUTO_VACUUM_SLACK_PAGES 43 |
/* Property flags associated with various pragma. */ |
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */ |
@@ -112302,6 +112360,13 @@ static const PragmaName aPragmaName[] = { |
/* ColNames: */ 0, 0, |
/* iArg: */ 0 }, |
#endif |
+#if !defined(SQLITE_OMIT_AUTOVACUUM) |
+ { /* zName: */ "auto_vacuum_slack_pages", |
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM_SLACK_PAGES, |
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, |
+ /* ColNames: */ 0, 0, |
+ /* iArg: */ 0 }, |
+#endif |
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
{/* zName: */ "automatic_index", |
@@ -113472,6 +113537,27 @@ SQLITE_PRIVATE void sqlite3Pragma( |
} |
#endif |
+ /* |
+ ** PRAGMA [schema.]auto_vacuum_slack_pages(N) |
+ ** |
+ ** Control chunk size of auto-vacuum. |
+ */ |
+#ifndef SQLITE_OMIT_AUTOVACUUM |
+ case PragTyp_AUTO_VACUUM_SLACK_PAGES: { |
+ Btree *pBt = pDb->pBt; |
+ assert( pBt!=0 ); |
+ if( !zRight ){ |
+ returnSingleInt(v, sqlite3BtreeGetAutoVacuumSlackPages(pBt)); |
+ }else{ |
+ int nPages = 8; |
+ if( sqlite3GetInt32(zRight, &nPages) ){ |
+ sqlite3BtreeSetAutoVacuumSlackPages(pBt, nPages); |
+ } |
+ } |
+ break; |
+ } |
+#endif |
+ |
#ifndef SQLITE_OMIT_PAGER_PRAGMAS |
/* |
** PRAGMA [schema.]cache_size |