1 Adds a new API function sqlite3_preload(). This fills the page cache
2 with the first pages of the database.
5 ===================================================================
6 --- src/build.c 2009-09-11 07:02:46.000000000 -0700
7 +++ src/build.c 2009-09-14 18:16:46.000000000 -0700
10 #include "sqliteInt.h"
16 ** This routine is called when a new SQL statement is beginning to
17 ** be parsed. Initialize the pParse structure as needed.
18 @@ -3659,3 +3662,30 @@
23 +/* Begin preload-cache.patch for Chromium */
24 +/* See declaration in sqlite3.h for information */
25 +int sqlite3_preload(sqlite3 *db)
33 + for(i=0; i<db->nDb; i++) {
34 + pBt = db->aDb[i].pBt;
37 + pPager = sqlite3BtreePager(pBt);
39 + rc = sqlite3PagerLoadall(pPager);
40 + if (rc == SQLITE_OK)
45 + return SQLITE_ERROR;
48 +/* End preload-cache.patch for Chromium */
49 Index: src/sqlite3.h.in
50 ===================================================================
51 --- src/sqlite.h.in 2009-09-09 07:03:20.000000000 -0700
52 +++ src/sqlite.h.in 2009-09-15 11:34:26.000000000 -0700
53 @@ -4677,6 +4677,21 @@
55 int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
57 +/* Begin preload-cache.patch for Chromium */
59 +** Preload the databases into the pager cache, up to the maximum size of the
62 +** For a database to be loaded successfully, the pager must be active. That is,
63 +** there must be an open statement on that database. See sqlite3pager_loadall
65 +** There might be many databases attached to the given connection. We iterate
66 +** them all and try to load them. If none are loadable successfully, we return
67 +** an error. Otherwise, we return OK.
69 +int sqlite3_preload(sqlite3 *db);
70 +/* End preload-cache.patch for Chromium */
73 ** CAPI3REF: Virtual File System Objects {H11200} <S20100>
76 ===================================================================
77 --- src/pager.c 2009-09-07 08:58:09.000000000 -0700
78 +++ src/pager.c 2009-09-15 16:43:07.000000000 -0700
81 #define PAGER_MAX_PGNO 2147483647
83 +/* Begin preload-cache.patch for Chromium */
84 +/* See comments above the definition. */
85 +int sqlite3PagerAcquire2(
90 + unsigned char *pDataToFill);
91 +/* End preload-cache.patch for Chromium */
96 @@ -3788,6 +3798,25 @@
97 DbPage **ppPage, /* Write a pointer to the page here */
98 int noContent /* Do not bother reading content from disk if true */
100 + /* This just passes through to our modified version with NULL data. */
101 + return sqlite3PagerAcquire2(pPager, pgno, ppPage, noContent, 0);
105 +** This is an internal version of sqlite3PagerAcquire that takes an extra
106 +** parameter of data to use to fill the page with. This allows more efficient
107 +** filling for preloaded data. If this extra parameter is NULL, we'll go to
110 +** See sqlite3PagerLoadall which uses this function.
112 +int sqlite3PagerAcquire2(
113 + Pager *pPager, /* The pager open on the database file */
114 + Pgno pgno, /* Page number to fetch */
115 + DbPage **ppPage, /* Write a pointer to the page here */
116 + int noContent, /* Do not bother reading content from disk if true */
117 + unsigned char* pDataToFill
122 @@ -3870,9 +3899,17 @@
123 IOTRACE(("ZERO %p %d\n", pPager, pgno));
125 assert( pPg->pPager==pPager );
126 - rc = readDbPage(pPg);
127 - if( rc!=SQLITE_OK ){
128 - goto pager_acquire_err;
130 + /* Just copy from the given memory */
131 + memcpy(pPg->pData, pDataToFill, pPager->pageSize);
132 + CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM;
133 + goto pager_acquire_err);
135 + /* Load from disk (old regular sqlite code path) */
136 + rc = readDbPage(pPg);
137 + if( rc!=SQLITE_OK ){
138 + goto pager_acquire_err;
142 #ifdef SQLITE_CHECK_PAGES
143 @@ -5221,6 +5258,91 @@
147 +/* Begin preload-cache.patch for Chromium */
149 +** When making large allocations, there is no need to stress the heap and
150 +** potentially hold its lock while we allocate a bunch of memory. If we know
151 +** the allocation will be large, go directly to the OS instead of the heap.
153 +static void* allocLarge(size_t size) {
155 + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
157 + return sqlite3Malloc(size);
161 +static void freeLarge(void* ptr) {
163 + VirtualFree(ptr, 0, MEM_RELEASE);
170 +** Addition: This will attempt to populate the database cache with
171 +** the first N bytes of the file, where N is the total size of the cache.
172 +** Because we can load this as one chunk from the disk, this is much faster
173 +** than loading a subset of the pages one at a time in random order.
175 +** The pager must be initialized before this function is called. This means a
176 +* statement must be open that has initialized the pager and is keeping the
179 +int sqlite3PagerLoadall(Pager* pPager)
186 + unsigned char *fileData;
188 + if (pPager->dbSize < 0 || pPager->pageSize < 0) {
189 + /* pager not initialized, this means a statement is not open */
190 + return SQLITE_MISUSE;
193 + /* compute sizes */
194 + nMax = sqlite3PcacheGetCachesize(pPager->pPCache);
195 + if (nMax < pPager->dbSize)
198 + loadPages = pPager->dbSize;
199 + loadSize = loadPages * pPager->pageSize;
201 + /* load the file as one chunk */
202 + fileData = allocLarge(loadSize);
204 + return SQLITE_NOMEM;
205 + rc = sqlite3OsRead(pPager->fd, fileData, loadSize, 0);
206 + if (rc != SQLITE_OK) {
207 + freeLarge(fileData);
211 + /* Copy the data to each page. Note that the page numbers we pass to _get
212 + * are one-based, 0 is a marker for no page. We also need to check that we
213 + * haven't loaded more pages than the cache can hold total. There may have
214 + * already been a few pages loaded before, so we may fill the cache before
215 + * loading all of the pages we want to.
218 + i <= loadPages && sqlite3PcachePagecount(pPager->pPCache) < nMax;
221 + rc = sqlite3PagerAcquire2(pPager, i, &pPage, 0,
222 + &fileData[(i-1)*(i64)pPager->pageSize]);
223 + if (rc != SQLITE_OK)
225 + sqlite3PagerUnref(pPage);
227 + freeLarge(fileData);
230 +/* End preload-cache.patch for Chromium */
233 ** Return a pointer to the data for the specified page.
236 ===================================================================
237 --- src/pager.h 2009-09-04 13:37:42.000000000 -0700
238 +++ src/pager.h 2009-09-15 11:31:55.000000000 -0700
240 sqlite3_file *sqlite3PagerFile(Pager*);
241 const char *sqlite3PagerJournalname(Pager*);
242 int sqlite3PagerNosync(Pager*);
243 +/* This function is for preload-cache.patch for Chromium: */
244 +int sqlite3PagerLoadall(Pager*);
245 void *sqlite3PagerTempSpace(Pager*);
246 int sqlite3PagerIsMemdb(Pager*);
249 ===================================================================
250 --- src/pcache.c 2009-09-04 13:37:42.000000000 -0700
251 +++ src/pcache.c 2009-09-15 16:41:55.000000000 -0700
252 @@ -542,14 +542,12 @@
258 ** Get the suggested cache-size value.
260 int sqlite3PcacheGetCachesize(PCache *pCache){
266 ** Set the suggested cache-size value.
268 ===================================================================
269 --- src/pcache.h 2009-09-04 13:37:42.000000000 -0700
270 +++ src/pcache.h 2009-09-15 16:41:52.000000000 -0700
272 ** of the suggested cache-sizes.
274 void sqlite3PcacheSetCachesize(PCache *, int);
276 int sqlite3PcacheGetCachesize(PCache *);
279 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
280 /* Try to return memory used by the pcache module to the main memory heap */