summaryrefslogtreecommitdiffstats
path: root/www/c3ref/pcache_methods2.html
blob: d4d7b98c7f791f974b31db784e4317adcc0d4a35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<!DOCTYPE html>
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href="../sqlite.css" rel="stylesheet">
<title>Application Defined Page Cache.</title>
<!-- path=../ -->
</head>
<body>
<div class=nosearch>
<a href="../index.html">
<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite" border="0">
</a>
<div><!-- IE hack to prevent disappearing logo --></div>
<div class="tagline desktoponly">
Small. Fast. Reliable.<br>Choose any three.
</div>
<div class="menu mainmenu">
<ul>
<li><a href="../index.html">Home</a>
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
<li class='wideonly'><a href='../about.html'>About</a>
<li class='desktoponly'><a href="../docs.html">Documentation</a>
<li class='desktoponly'><a href="../download.html">Download</a>
<li class='wideonly'><a href='../copyright.html'>License</a>
<li class='desktoponly'><a href="../support.html">Support</a>
<li class='desktoponly'><a href="../prosupport.html">Purchase</a>
<li class='search' id='search_menubutton'>
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
</ul>
</div>
<div class="menu submenu" id="submenu">
<ul>
<li><a href='../about.html'>About</a>
<li><a href='../docs.html'>Documentation</a>
<li><a href='../download.html'>Download</a>
<li><a href='../support.html'>Support</a>
<li><a href='../prosupport.html'>Purchase</a>
</ul>
</div>
<div class="searchmenu" id="searchmenu">
<form method="GET" action="../search">
<select name="s" id="searchtype">
<option value="d">Search Documentation</option>
<option value="c">Search Changelog</option>
</select>
<input type="text" name="q" id="searchbox" value="">
<input type="submit" value="Go">
</form>
</div>
</div>
<script>
function toggle_div(nm) {
var w = document.getElementById(nm);
if( w.style.display=="block" ){
w.style.display = "none";
}else{
w.style.display = "block";
}
}
function toggle_search() {
var w = document.getElementById("searchmenu");
if( w.style.display=="block" ){
w.style.display = "none";
} else {
w.style.display = "block";
setTimeout(function(){
document.getElementById("searchbox").focus()
}, 30);
}
}
function div_off(nm){document.getElementById(nm).style.display="none";}
window.onbeforeunload = function(e){div_off("submenu");}
/* Disable the Search feature if we are not operating from CGI, since */
/* Search is accomplished using CGI and will not work without it. */
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
document.getElementById("search_menubutton").style.display = "none";
}
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
function hideorshow(btn,obj){
var x = document.getElementById(obj);
var b = document.getElementById(btn);
if( x.style.display!='none' ){
x.style.display = 'none';
b.innerHTML='show';
}else{
x.style.display = '';
b.innerHTML='hide';
}
return false;
}
var antiRobot = 0;
function antiRobotGo(){
if( antiRobot!=3 ) return;
antiRobot = 7;
var j = document.getElementById("mtimelink");
if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
}
function antiRobotDefense(){
document.body.onmousedown=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousedown=null;
}
document.body.onmousemove=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousemove=null;
}
setTimeout(function(){
antiRobot |= 1;
antiRobotGo();
}, 100)
antiRobotGo();
}
antiRobotDefense();
</script>
<!-- keywords: {page cache} sqlite3_pcache_methods2 -->
<div class=nosearch>
<a href="../c3ref/intro.html"><h2>SQLite C Interface</h2></a>
<h2>Application Defined Page Cache.</h2>
</div>
<blockquote><pre>
typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
struct sqlite3_pcache_methods2 {
  int iVersion;
  void *pArg;
  int (*xInit)(void*);
  void (*xShutdown)(void*);
  sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
  int (*xPagecount)(sqlite3_pcache*);
  sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
  void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
  void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
      unsigned oldKey, unsigned newKey);
  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
  void (*xDestroy)(sqlite3_pcache*);
  void (*xShrink)(sqlite3_pcache*);
};
</pre></blockquote>
<p>
The <a href="../c3ref/config.html">sqlite3_config</a>(<a href="../c3ref/c_config_covering_index_scan.html#sqliteconfigpcache2">SQLITE_CONFIG_PCACHE2</a>, ...) interface can
register an alternative page cache implementation by passing in an
instance of the sqlite3_pcache_methods2 structure.
In many applications, most of the heap memory allocated by
SQLite is used for the page cache.
By implementing a
custom page cache using this API, an application can better control
the amount of memory consumed by SQLite, the way in which
that memory is allocated and released, and the policies used to
determine exactly which parts of a database file are cached and for
how long.</p>

<p>The alternative page cache mechanism is an
extreme measure that is only needed by the most demanding applications.
The built-in page cache is recommended for most uses.</p>

<p>The contents of the sqlite3_pcache_methods2 structure are copied to an
internal buffer by SQLite within the call to <a href="../c3ref/config.html">sqlite3_config</a>.  Hence
the application may discard the parameter after the call to
<a href="../c3ref/config.html">sqlite3_config()</a> returns.</p>

<p><a name="thexinitpagecachemethod"></a>

The xInit() method is called once for each effective
call to <a href="../c3ref/initialize.html">sqlite3_initialize()</a>
(usually only once during the lifetime of the process). The xInit()
method is passed a copy of the sqlite3_pcache_methods2.pArg value.
The intent of the xInit() method is to set up global data structures
required by the custom page cache implementation.
If the xInit() method is NULL, then the
built-in default page cache is used instead of the application defined
page cache.</p>

<p><a name="thexshutdownpagecachemethod"></a>

The xShutdown() method is called by <a href="../c3ref/initialize.html">sqlite3_shutdown()</a>.
It can be used to clean up
any outstanding resources before process shutdown, if required.
The xShutdown() method may be NULL.</p>

<p>SQLite automatically serializes calls to the xInit method,
so the xInit method need not be threadsafe.  The
xShutdown method is only called from <a href="../c3ref/initialize.html">sqlite3_shutdown()</a> so it does
not need to be threadsafe either.  All other methods must be threadsafe
in multithreaded applications.</p>

<p>SQLite will never invoke xInit() more than once without an intervening
call to xShutdown().</p>

<p><a name="thexcreatepagecachemethods"></a>

SQLite invokes the xCreate() method to construct a new cache instance.
SQLite will typically create one cache instance for each open database file,
though this is not guaranteed. The
first parameter, szPage, is the size in bytes of the pages that must
be allocated by the cache.  szPage will always a power of two.  The
second parameter szExtra is a number of bytes of extra storage
associated with each page cache entry.  The szExtra parameter will
a number less than 250.  SQLite will use the
extra szExtra bytes on each page to store metadata about the underlying
database page on disk.  The value passed into szExtra depends
on the SQLite version, the target platform, and how SQLite was compiled.
The third argument to xCreate(), bPurgeable, is true if the cache being
created will be used to cache database pages of a file stored on disk, or
false if it is used for an in-memory database. The cache implementation
does not have to do anything special based with the value of bPurgeable;
it is purely advisory.  On a cache where bPurgeable is false, SQLite will
never invoke xUnpin() except to deliberately delete a page.
In other words, calls to xUnpin() on a cache with bPurgeable set to
false will always have the "discard" flag set to true.
Hence, a cache created with bPurgeable false will
never contain any unpinned pages.</p>

<p><a name="thexcachesizepagecachemethod"></a>

The xCachesize() method may be called at any time by SQLite to set the
suggested maximum cache-size (number of pages stored by) the cache
instance passed as the first argument. This is the value configured using
the SQLite "<a href="../pragma.html#pragma_cache_size">PRAGMA cache_size</a>" command.  As with the bPurgeable
parameter, the implementation is not required to do anything with this
value; it is advisory only.</p>

<p><a name="thexpagecountpagecachemethods"></a>

The xPagecount() method must return the number of pages currently
stored in the cache, both pinned and unpinned.</p>

<p><a name="thexfetchpagecachemethods"></a>

The xFetch() method locates a page in the cache and returns a pointer to
an sqlite3_pcache_page object associated with that page, or a NULL pointer.
The pBuf element of the returned sqlite3_pcache_page object will be a
pointer to a buffer of szPage bytes used to store the content of a
single database page.  The pExtra element of sqlite3_pcache_page will be
a pointer to the szExtra bytes of extra storage that SQLite has requested
for each entry in the page cache.</p>

<p>The page to be fetched is determined by the key. The minimum key value
is 1.  After it has been retrieved using xFetch, the page is considered
to be "pinned".</p>

<p>If the requested page is already in the page cache, then the page cache
implementation must return a pointer to the page buffer with its content
intact.  If the requested page is not already in the cache, then the
cache implementation should use the value of the createFlag
parameter to help it determined what action to take:</p>

<p><table border=1 width=85% align=center>
<tr><th> createFlag <th> Behavior when page is not already in cache
<tr><td> 0 <td> Do not allocate a new page.  Return NULL.
<tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
Otherwise return NULL.
<tr><td> 2 <td> Make every effort to allocate a new page.  Only return
NULL if allocating a new page is effectively impossible.
</table></p>

<p>SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
will only use a createFlag of 2 after a prior call with a createFlag of 1
failed.  In between the xFetch() calls, SQLite may
attempt to unpin one or more cache pages by spilling the content of
pinned pages to disk and synching the operating system disk cache.</p>

<p><a name="thexunpinpagecachemethod"></a>

xUnpin() is called by SQLite with a pointer to a currently pinned page
as its second argument.  If the third parameter, discard, is non-zero,
then the page must be evicted from the cache.
If the discard parameter is
zero, then the page may be discarded or retained at the discretion of
page cache implementation. The page cache implementation
may choose to evict unpinned pages at any time.</p>

<p>The cache must not perform any reference counting. A single
call to xUnpin() unpins the page regardless of the number of prior calls
to xFetch().</p>

<p><a name="thexrekeypagecachemethods"></a>

The xRekey() method is used to change the key value associated with the
page passed as the second argument. If the cache
previously contains an entry associated with newKey, it must be
discarded. Any prior cache entry associated with newKey is guaranteed not
to be pinned.</p>

<p>When SQLite calls the xTruncate() method, the cache must discard all
existing cache entries with page numbers (keys) greater than or equal
to the value of the iLimit parameter passed to xTruncate(). If any
of these pages are pinned, they are implicitly unpinned, meaning that
they can be safely discarded.</p>

<p><a name="thexdestroypagecachemethod"></a>

The xDestroy() method is used to delete a cache allocated by xCreate().
All resources associated with the specified cache should be freed. After
calling the xDestroy() method, SQLite considers the <a href="../c3ref/pcache.html">sqlite3_pcache*</a>
handle invalid, and will not use it with any other sqlite3_pcache_methods2
functions.</p>

<p><a name="thexshrinkpagecachemethod"></a>

SQLite invokes the xShrink() method when it wants the page cache to
free up as much of heap memory as possible.  The page cache implementation
is not obligated to free any memory, but well-behaved implementations should
do their best.
</p><p>See also lists of
  <a href="../c3ref/objlist.html">Objects</a>,
  <a href="../c3ref/constlist.html">Constants</a>, and
  <a href="../c3ref/funclist.html">Functions</a>.</p>