|
1 /* |
|
2 ** 2008 June 18 |
|
3 ** |
|
4 ** The author disclaims copyright to this source code. In place of |
|
5 ** a legal notice, here is a blessing: |
|
6 ** |
|
7 ** May you do good and not evil. |
|
8 ** May you find forgiveness for yourself and forgive others. |
|
9 ** May you share freely, never taking more than you give. |
|
10 ** |
|
11 ************************************************************************* |
|
12 ** |
|
13 ** This module implements the sqlite3_status() interface and related |
|
14 ** functionality. |
|
15 ** |
|
16 ** $Id: status.c,v 1.9 2008/09/02 00:52:52 drh Exp $ |
|
17 */ |
|
18 #include "sqliteInt.h" |
|
19 |
|
20 /* |
|
21 ** Variables in which to record status information. |
|
22 */ |
|
23 typedef struct sqlite3StatType sqlite3StatType; |
|
24 static SQLITE_WSD struct sqlite3StatType { |
|
25 int nowValue[9]; /* Current value */ |
|
26 int mxValue[9]; /* Maximum value */ |
|
27 } sqlite3Stat = { {0,}, {0,} }; |
|
28 |
|
29 |
|
30 /* The "wsdStat" macro will resolve to the status information |
|
31 ** state vector. If writable static data is unsupported on the target, |
|
32 ** we have to locate the state vector at run-time. In the more common |
|
33 ** case where writable static data is supported, wsdStat can refer directly |
|
34 ** to the "sqlite3Stat" state vector declared above. |
|
35 */ |
|
36 #ifdef SQLITE_OMIT_WSD |
|
37 # define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) |
|
38 # define wsdStat x[0] |
|
39 #else |
|
40 # define wsdStatInit |
|
41 # define wsdStat sqlite3Stat |
|
42 #endif |
|
43 |
|
44 /* |
|
45 ** Return the current value of a status parameter. |
|
46 */ |
|
47 int sqlite3StatusValue(int op){ |
|
48 wsdStatInit; |
|
49 assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
|
50 return wsdStat.nowValue[op]; |
|
51 } |
|
52 |
|
53 /* |
|
54 ** Add N to the value of a status record. It is assumed that the |
|
55 ** caller holds appropriate locks. |
|
56 */ |
|
57 void sqlite3StatusAdd(int op, int N){ |
|
58 wsdStatInit; |
|
59 assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
|
60 wsdStat.nowValue[op] += N; |
|
61 if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
|
62 wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
|
63 } |
|
64 } |
|
65 |
|
66 /* |
|
67 ** Set the value of a status to X. |
|
68 */ |
|
69 void sqlite3StatusSet(int op, int X){ |
|
70 wsdStatInit; |
|
71 assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); |
|
72 wsdStat.nowValue[op] = X; |
|
73 if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ |
|
74 wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
|
75 } |
|
76 } |
|
77 |
|
78 /* |
|
79 ** Query status information. |
|
80 ** |
|
81 ** This implementation assumes that reading or writing an aligned |
|
82 ** 32-bit integer is an atomic operation. If that assumption is not true, |
|
83 ** then this routine is not threadsafe. |
|
84 */ |
|
85 SQLITE_EXPORT int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ |
|
86 wsdStatInit; |
|
87 if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ |
|
88 return SQLITE_MISUSE; |
|
89 } |
|
90 *pCurrent = wsdStat.nowValue[op]; |
|
91 *pHighwater = wsdStat.mxValue[op]; |
|
92 if( resetFlag ){ |
|
93 wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
|
94 } |
|
95 return SQLITE_OK; |
|
96 } |
|
97 |
|
98 /* |
|
99 ** Query status information for a single database connection |
|
100 */ |
|
101 SQLITE_EXPORT int sqlite3_db_status( |
|
102 sqlite3 *db, /* The database connection whose status is desired */ |
|
103 int op, /* Status verb */ |
|
104 int *pCurrent, /* Write current value here */ |
|
105 int *pHighwater, /* Write high-water mark here */ |
|
106 int resetFlag /* Reset high-water mark if true */ |
|
107 ){ |
|
108 switch( op ){ |
|
109 case SQLITE_DBSTATUS_LOOKASIDE_USED: { |
|
110 *pCurrent = db->lookaside.nOut; |
|
111 *pHighwater = db->lookaside.mxOut; |
|
112 if( resetFlag ){ |
|
113 db->lookaside.mxOut = db->lookaside.nOut; |
|
114 } |
|
115 break; |
|
116 } |
|
117 default: { |
|
118 return SQLITE_ERROR; |
|
119 } |
|
120 } |
|
121 return SQLITE_OK; |
|
122 } |