Index: third_party/sqlite/sqlite-src-3080704/src/status.c |
diff --git a/third_party/sqlite/sqlite-src-3080704/src/status.c b/third_party/sqlite/sqlite-src-3080704/src/status.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..79a8001b8af07081243bea966c2677e95189ce21 |
--- /dev/null |
+++ b/third_party/sqlite/sqlite-src-3080704/src/status.c |
@@ -0,0 +1,264 @@ |
+/* |
+** 2008 June 18 |
+** |
+** The author disclaims copyright to this source code. In place of |
+** a legal notice, here is a blessing: |
+** |
+** May you do good and not evil. |
+** May you find forgiveness for yourself and forgive others. |
+** May you share freely, never taking more than you give. |
+** |
+************************************************************************* |
+** |
+** This module implements the sqlite3_status() interface and related |
+** functionality. |
+*/ |
+#include "sqliteInt.h" |
+#include "vdbeInt.h" |
+ |
+/* |
+** Variables in which to record status information. |
+*/ |
+typedef struct sqlite3StatType sqlite3StatType; |
+static SQLITE_WSD struct sqlite3StatType { |
+ int nowValue[10]; /* Current value */ |
+ int mxValue[10]; /* Maximum value */ |
+} sqlite3Stat = { {0,}, {0,} }; |
+ |
+ |
+/* The "wsdStat" macro will resolve to the status information |
+** state vector. If writable static data is unsupported on the target, |
+** we have to locate the state vector at run-time. In the more common |
+** case where writable static data is supported, wsdStat can refer directly |
+** to the "sqlite3Stat" state vector declared above. |
+*/ |
+#ifdef SQLITE_OMIT_WSD |
+# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) |
+# define wsdStat x[0] |
+#else |
+# define wsdStatInit |
+# define wsdStat sqlite3Stat |
+#endif |
+ |
+/* |
+** Return the current value of a status parameter. |
+*/ |
+int sqlite3StatusValue(int op){ |
+ wsdStatInit; |
+ assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ return wsdStat.nowValue[op]; |
+} |
+ |
+/* |
+** Add N to the value of a status record. It is assumed that the |
+** caller holds appropriate locks. |
+*/ |
+void sqlite3StatusAdd(int op, int N){ |
+ wsdStatInit; |
+ assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ wsdStat.nowValue[op] += N; |
+ if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
+ wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
+ } |
+} |
+ |
+/* |
+** Set the value of a status to X. |
+*/ |
+void sqlite3StatusSet(int op, int X){ |
+ wsdStatInit; |
+ assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
+ wsdStat.nowValue[op] = X; |
+ if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
+ wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
+ } |
+} |
+ |
+/* |
+** Query status information. |
+** |
+** This implementation assumes that reading or writing an aligned |
+** 32-bit integer is an atomic operation. If that assumption is not true, |
+** then this routine is not threadsafe. |
+*/ |
+int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ |
+ wsdStatInit; |
+ if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ |
+ return SQLITE_MISUSE_BKPT; |
+ } |
+ *pCurrent = wsdStat.nowValue[op]; |
+ *pHighwater = wsdStat.mxValue[op]; |
+ if( resetFlag ){ |
+ wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
+ } |
+ return SQLITE_OK; |
+} |
+ |
+/* |
+** Query status information for a single database connection |
+*/ |
+int sqlite3_db_status( |
+ sqlite3 *db, /* The database connection whose status is desired */ |
+ int op, /* Status verb */ |
+ int *pCurrent, /* Write current value here */ |
+ int *pHighwater, /* Write high-water mark here */ |
+ int resetFlag /* Reset high-water mark if true */ |
+){ |
+ int rc = SQLITE_OK; /* Return code */ |
+ sqlite3_mutex_enter(db->mutex); |
+ switch( op ){ |
+ case SQLITE_DBSTATUS_LOOKASIDE_USED: { |
+ *pCurrent = db->lookaside.nOut; |
+ *pHighwater = db->lookaside.mxOut; |
+ if( resetFlag ){ |
+ db->lookaside.mxOut = db->lookaside.nOut; |
+ } |
+ break; |
+ } |
+ |
+ case SQLITE_DBSTATUS_LOOKASIDE_HIT: |
+ case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: |
+ case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { |
+ testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); |
+ testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); |
+ testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); |
+ assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); |
+ assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); |
+ *pCurrent = 0; |
+ *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; |
+ if( resetFlag ){ |
+ db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; |
+ } |
+ break; |
+ } |
+ |
+ /* |
+ ** Return an approximation for the amount of memory currently used |
+ ** by all pagers associated with the given database connection. The |
+ ** highwater mark is meaningless and is returned as zero. |
+ */ |
+ case SQLITE_DBSTATUS_CACHE_USED: { |
+ int totalUsed = 0; |
+ int i; |
+ sqlite3BtreeEnterAll(db); |
+ for(i=0; i<db->nDb; i++){ |
+ Btree *pBt = db->aDb[i].pBt; |
+ if( pBt ){ |
+ Pager *pPager = sqlite3BtreePager(pBt); |
+ totalUsed += sqlite3PagerMemUsed(pPager); |
+ } |
+ } |
+ sqlite3BtreeLeaveAll(db); |
+ *pCurrent = totalUsed; |
+ *pHighwater = 0; |
+ break; |
+ } |
+ |
+ /* |
+ ** *pCurrent gets an accurate estimate of the amount of memory used |
+ ** to store the schema for all databases (main, temp, and any ATTACHed |
+ ** databases. *pHighwater is set to zero. |
+ */ |
+ case SQLITE_DBSTATUS_SCHEMA_USED: { |
+ int i; /* Used to iterate through schemas */ |
+ int nByte = 0; /* Used to accumulate return value */ |
+ |
+ sqlite3BtreeEnterAll(db); |
+ db->pnBytesFreed = &nByte; |
+ for(i=0; i<db->nDb; i++){ |
+ Schema *pSchema = db->aDb[i].pSchema; |
+ if( ALWAYS(pSchema!=0) ){ |
+ HashElem *p; |
+ |
+ nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( |
+ pSchema->tblHash.count |
+ + pSchema->trigHash.count |
+ + pSchema->idxHash.count |
+ + pSchema->fkeyHash.count |
+ ); |
+ nByte += sqlite3MallocSize(pSchema->tblHash.ht); |
+ nByte += sqlite3MallocSize(pSchema->trigHash.ht); |
+ nByte += sqlite3MallocSize(pSchema->idxHash.ht); |
+ nByte += sqlite3MallocSize(pSchema->fkeyHash.ht); |
+ |
+ for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ |
+ sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); |
+ } |
+ for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ |
+ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); |
+ } |
+ } |
+ } |
+ db->pnBytesFreed = 0; |
+ sqlite3BtreeLeaveAll(db); |
+ |
+ *pHighwater = 0; |
+ *pCurrent = nByte; |
+ break; |
+ } |
+ |
+ /* |
+ ** *pCurrent gets an accurate estimate of the amount of memory used |
+ ** to store all prepared statements. |
+ ** *pHighwater is set to zero. |
+ */ |
+ case SQLITE_DBSTATUS_STMT_USED: { |
+ struct Vdbe *pVdbe; /* Used to iterate through VMs */ |
+ int nByte = 0; /* Used to accumulate return value */ |
+ |
+ db->pnBytesFreed = &nByte; |
+ for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ |
+ sqlite3VdbeClearObject(db, pVdbe); |
+ sqlite3DbFree(db, pVdbe); |
+ } |
+ db->pnBytesFreed = 0; |
+ |
+ *pHighwater = 0; /* IMP: R-64479-57858 */ |
+ *pCurrent = nByte; |
+ |
+ break; |
+ } |
+ |
+ /* |
+ ** Set *pCurrent to the total cache hits or misses encountered by all |
+ ** pagers the database handle is connected to. *pHighwater is always set |
+ ** to zero. |
+ */ |
+ case SQLITE_DBSTATUS_CACHE_HIT: |
+ case SQLITE_DBSTATUS_CACHE_MISS: |
+ case SQLITE_DBSTATUS_CACHE_WRITE:{ |
+ int i; |
+ int nRet = 0; |
+ assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); |
+ assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); |
+ |
+ for(i=0; i<db->nDb; i++){ |
+ if( db->aDb[i].pBt ){ |
+ Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); |
+ sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); |
+ } |
+ } |
+ *pHighwater = 0; /* IMP: R-42420-56072 */ |
+ /* IMP: R-54100-20147 */ |
+ /* IMP: R-29431-39229 */ |
+ *pCurrent = nRet; |
+ break; |
+ } |
+ |
+ /* Set *pCurrent to non-zero if there are unresolved deferred foreign |
+ ** key constraints. Set *pCurrent to zero if all foreign key constraints |
+ ** have been satisfied. The *pHighwater is always set to zero. |
+ */ |
+ case SQLITE_DBSTATUS_DEFERRED_FKS: { |
+ *pHighwater = 0; /* IMP: R-11967-56545 */ |
+ *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; |
+ break; |
+ } |
+ |
+ default: { |
+ rc = SQLITE_ERROR; |
+ } |
+ } |
+ sqlite3_mutex_leave(db->mutex); |
+ return rc; |
+} |