4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
13 ** This file implements an extension that uses the SQLITE_CONFIG_PCACHE2
14 ** mechanism to add a tracing layer on top of pluggable page cache of
15 ** SQLite. If this extension is registered prior to sqlite3_initialize(),
16 ** it will cause all page cache activities to be logged on standard output,
17 ** or to some other FILE specified by the initializer.
19 ** This file needs to be compiled into the application that uses it.
21 ** This extension is used to implement the --pcachetrace option of the
22 ** command-line shell.
28 /* The original page cache routines */
29 static sqlite3_pcache_methods2 pcacheBase
;
30 static FILE *pcachetraceOut
;
32 /* Methods that trace pcache activity */
33 static int pcachetraceInit(void *pArg
){
36 fprintf(pcachetraceOut
, "PCACHETRACE: xInit(%p)\n", pArg
);
38 nRes
= pcacheBase
.xInit(pArg
);
40 fprintf(pcachetraceOut
, "PCACHETRACE: xInit(%p) -> %d\n", pArg
, nRes
);
44 static void pcachetraceShutdown(void *pArg
){
46 fprintf(pcachetraceOut
, "PCACHETRACE: xShutdown(%p)\n", pArg
);
48 pcacheBase
.xShutdown(pArg
);
50 static sqlite3_pcache
*pcachetraceCreate(int szPage
, int szExtra
, int bPurge
){
53 fprintf(pcachetraceOut
, "PCACHETRACE: xCreate(%d,%d,%d)\n",
54 szPage
, szExtra
, bPurge
);
56 pRes
= pcacheBase
.xCreate(szPage
, szExtra
, bPurge
);
58 fprintf(pcachetraceOut
, "PCACHETRACE: xCreate(%d,%d,%d) -> %p\n",
59 szPage
, szExtra
, bPurge
, pRes
);
63 static void pcachetraceCachesize(sqlite3_pcache
*p
, int nCachesize
){
65 fprintf(pcachetraceOut
, "PCACHETRACE: xCachesize(%p, %d)\n", p
, nCachesize
);
67 pcacheBase
.xCachesize(p
, nCachesize
);
69 static int pcachetracePagecount(sqlite3_pcache
*p
){
72 fprintf(pcachetraceOut
, "PCACHETRACE: xPagecount(%p)\n", p
);
74 nRes
= pcacheBase
.xPagecount(p
);
76 fprintf(pcachetraceOut
, "PCACHETRACE: xPagecount(%p) -> %d\n", p
, nRes
);
80 static sqlite3_pcache_page
*pcachetraceFetch(
85 sqlite3_pcache_page
*pRes
;
87 fprintf(pcachetraceOut
, "PCACHETRACE: xFetch(%p,%u,%d)\n", p
, key
, crFg
);
89 pRes
= pcacheBase
.xFetch(p
, key
, crFg
);
91 fprintf(pcachetraceOut
, "PCACHETRACE: xFetch(%p,%u,%d) -> %p\n",
96 static void pcachetraceUnpin(
98 sqlite3_pcache_page
*pPg
,
101 if( pcachetraceOut
){
102 fprintf(pcachetraceOut
, "PCACHETRACE: xUnpin(%p, %p, %d)\n",
105 pcacheBase
.xUnpin(p
, pPg
, bDiscard
);
107 static void pcachetraceRekey(
109 sqlite3_pcache_page
*pPg
,
113 if( pcachetraceOut
){
114 fprintf(pcachetraceOut
, "PCACHETRACE: xRekey(%p, %p, %u, %u)\n",
115 p
, pPg
, oldKey
, newKey
);
117 pcacheBase
.xRekey(p
, pPg
, oldKey
, newKey
);
119 static void pcachetraceTruncate(sqlite3_pcache
*p
, unsigned n
){
120 if( pcachetraceOut
){
121 fprintf(pcachetraceOut
, "PCACHETRACE: xTruncate(%p, %u)\n", p
, n
);
123 pcacheBase
.xTruncate(p
, n
);
125 static void pcachetraceDestroy(sqlite3_pcache
*p
){
126 if( pcachetraceOut
){
127 fprintf(pcachetraceOut
, "PCACHETRACE: xDestroy(%p)\n", p
);
129 pcacheBase
.xDestroy(p
);
131 static void pcachetraceShrink(sqlite3_pcache
*p
){
132 if( pcachetraceOut
){
133 fprintf(pcachetraceOut
, "PCACHETRACE: xShrink(%p)\n", p
);
135 pcacheBase
.xShrink(p
);
138 /* The substitute pcache methods */
139 static sqlite3_pcache_methods2 ersaztPcacheMethods
= {
145 pcachetraceCachesize
,
146 pcachetracePagecount
,
155 /* Begin tracing memory allocations to out. */
156 int sqlite3PcacheTraceActivate(FILE *out
){
158 if( pcacheBase
.xFetch
==0 ){
159 rc
= sqlite3_config(SQLITE_CONFIG_GETPCACHE2
, &pcacheBase
);
161 rc
= sqlite3_config(SQLITE_CONFIG_PCACHE2
, &ersaztPcacheMethods
);
164 pcachetraceOut
= out
;
168 /* Deactivate memory tracing */
169 int sqlite3PcacheTraceDeactivate(void){
171 if( pcacheBase
.xFetch
!=0 ){
172 rc
= sqlite3_config(SQLITE_CONFIG_PCACHE2
, &pcacheBase
);
174 memset(&pcacheBase
, 0, sizeof(pcacheBase
));