Adds a new API function sqlite3_preload().  This fills the page cache
with the first pages of the database.

Index: src/build.c
===================================================================
--- src/build.c	2009-09-11 07:02:46.000000000 -0700
+++ src/build.c	2009-09-14 18:16:46.000000000 -0700
@@ -26,6 +26,9 @@
 */
 #include "sqliteInt.h"
 
+#include "pager.h"
+#include "btree.h"
+
 /*
 ** This routine is called when a new SQL statement is beginning to
 ** be parsed.  Initialize the pParse structure as needed.
@@ -3659,3 +3662,30 @@
   }
   return pKey;
 }
+
+/* Begin preload-cache.patch for Chromium */
+/* See declaration in sqlite3.h for information */
+int sqlite3_preload(sqlite3 *db)
+{
+  Pager *pPager;
+  Btree *pBt;
+  int rc;
+  int i;
+  int dbsLoaded = 0;
+
+  for(i=0; i<db->nDb; i++) {
+    pBt = db->aDb[i].pBt;
+    if( !pBt )
+      continue;
+    pPager = sqlite3BtreePager(pBt);
+    if( pPager ) {
+      rc = sqlite3PagerLoadall(pPager);
+      if (rc == SQLITE_OK)
+        dbsLoaded++;
+    }
+  }
+  if (dbsLoaded == 0)
+    return SQLITE_ERROR;
+  return SQLITE_OK;
+}
+/* End preload-cache.patch for Chromium */
Index: src/sqlite3.h.in
===================================================================
--- src/sqlite.h.in	2009-09-09 07:03:20.000000000 -0700
+++ src/sqlite.h.in	2009-09-15 11:34:26.000000000 -0700
@@ -4677,6 +4677,21 @@
 */
 int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
 
+/* Begin preload-cache.patch for Chromium */
+/*
+** Preload the databases into the pager cache, up to the maximum size of the
+** pager cache.
+**
+** For a database to be loaded successfully, the pager must be active. That is,
+** there must be an open statement on that database. See sqlite3pager_loadall
+**
+** There might be many databases attached to the given connection. We iterate
+** them all and try to load them. If none are loadable successfully, we return
+** an error. Otherwise, we return OK.
+*/
+int sqlite3_preload(sqlite3 *db);
+/* End preload-cache.patch for Chromium */
+
 /*
 ** CAPI3REF: Virtual File System Objects {H11200} <S20100>
 **
Index: src/pager.c
===================================================================
--- src/pager.c	2009-09-07 08:58:09.000000000 -0700
+++ src/pager.c	2009-09-15 16:43:07.000000000 -0700
@@ -388,6 +388,16 @@
 */
 #define PAGER_MAX_PGNO 2147483647
 
+/* Begin preload-cache.patch for Chromium */
+/* See comments above the definition. */
+int sqlite3PagerAcquire2(
+  Pager *pPager,
+  Pgno pgno,
+  DbPage **ppPage,
+  int noContent,
+  unsigned char *pDataToFill);
+/* End preload-cache.patch for Chromium */
+
 #ifndef NDEBUG 
 /*
 ** Usage:
@@ -3788,6 +3798,25 @@
   DbPage **ppPage,    /* Write a pointer to the page here */
   int noContent       /* Do not bother reading content from disk if true */
 ){
+  /* This just passes through to our modified version with NULL data. */
+  return sqlite3PagerAcquire2(pPager, pgno, ppPage, noContent, 0);
+}
+
+/*
+** This is an internal version of sqlite3PagerAcquire that takes an extra
+** parameter of data to use to fill the page with. This allows more efficient
+** filling for preloaded data. If this extra parameter is NULL, we'll go to
+** the file.
+**
+** See sqlite3PagerLoadall which uses this function.
+*/
+int sqlite3PagerAcquire2(
+  Pager *pPager,      /* The pager open on the database file */
+  Pgno pgno,          /* Page number to fetch */
+  DbPage **ppPage,    /* Write a pointer to the page here */
+  int noContent,      /* Do not bother reading content from disk if true */
+  unsigned char* pDataToFill
+){
   int rc;
   PgHdr *pPg;
 
@@ -3870,9 +3899,17 @@
       IOTRACE(("ZERO %p %d\n", pPager, pgno));
     }else{
       assert( pPg->pPager==pPager );
-      rc = readDbPage(pPg);
-      if( rc!=SQLITE_OK ){
-        goto pager_acquire_err;
+      if( pDataToFill ){
+        /* Just copy from the given memory */
+        memcpy(pPg->pData, pDataToFill, pPager->pageSize);
+        CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM;
+                                                 goto pager_acquire_err);
+      }else{
+        /* Load from disk (old regular sqlite code path) */
+        rc = readDbPage(pPg);
+        if( rc!=SQLITE_OK ){
+          goto pager_acquire_err;
+        }
       }
     }
 #ifdef SQLITE_CHECK_PAGES
@@ -5221,6 +5258,91 @@
 }
 #endif
 
+/* Begin preload-cache.patch for Chromium */
+/**
+** When making large allocations, there is no need to stress the heap and
+** potentially hold its lock while we allocate a bunch of memory.  If we know
+** the allocation will be large, go directly to the OS instead of the heap.
+**/
+static void* allocLarge(size_t size) {
+#if SQLITE_OS_WIN
+  return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+#else
+  return sqlite3Malloc(size);
+#endif
+}
+
+static void freeLarge(void* ptr) {
+#if SQLITE_OS_WIN
+  VirtualFree(ptr, 0, MEM_RELEASE);
+#else
+  sqlite3_free(ptr);
+#endif
+}
+
+/**
+** Addition: This will attempt to populate the database cache with
+** the first N bytes of the file, where N is the total size of the cache.
+** Because we can load this as one chunk from the disk, this is much faster
+** than loading a subset of the pages one at a time in random order.
+**
+** The pager must be initialized before this function is called. This means a
+* statement must be open that has initialized the pager and is keeping the
+** cache in memory.
+**/
+int sqlite3PagerLoadall(Pager* pPager)
+{
+  int i;
+  int rc;
+  int nMax;
+  int loadSize;
+  int loadPages;
+  unsigned char *fileData;
+
+  if (pPager->dbSize < 0 || pPager->pageSize < 0) {
+    /* pager not initialized, this means a statement is not open */
+    return SQLITE_MISUSE;
+  }
+
+  /* compute sizes */
+  nMax = sqlite3PcacheGetCachesize(pPager->pPCache);
+  if (nMax < pPager->dbSize)
+    loadPages = nMax;
+  else
+    loadPages = pPager->dbSize;
+  loadSize = loadPages * pPager->pageSize;
+
+  /* load the file as one chunk */
+  fileData = allocLarge(loadSize);
+  if (! fileData)
+    return SQLITE_NOMEM;
+  rc = sqlite3OsRead(pPager->fd, fileData, loadSize, 0);
+  if (rc != SQLITE_OK) {
+    freeLarge(fileData);
+    return rc;
+  }
+
+  /* Copy the data to each page. Note that the page numbers we pass to _get
+   * are one-based, 0 is a marker for no page. We also need to check that we
+   * haven't loaded more pages than the cache can hold total. There may have
+   * already been a few pages loaded before, so we may fill the cache before
+   * loading all of the pages we want to.
+   */
+  for(i=1;
+      i <= loadPages && sqlite3PcachePagecount(pPager->pPCache) < nMax;
+      i++) {
+    DbPage *pPage = 0;
+    rc = sqlite3PagerAcquire2(pPager, i, &pPage, 0,
+                              &fileData[(i-1)*(i64)pPager->pageSize]);
+    if (rc != SQLITE_OK)
+      break;
+    sqlite3PagerUnref(pPage);
+  }
+  freeLarge(fileData);
+  return SQLITE_OK;
+}
+/* End preload-cache.patch for Chromium */
+
 /*
 ** Return a pointer to the data for the specified page.
 */
Index: src/pager.h
===================================================================
--- src/pager.h	2009-09-04 13:37:42.000000000 -0700
+++ src/pager.h	2009-09-15 11:31:55.000000000 -0700
@@ -143,6 +143,8 @@
 sqlite3_file *sqlite3PagerFile(Pager*);
 const char *sqlite3PagerJournalname(Pager*);
 int sqlite3PagerNosync(Pager*);
+/* This function is for preload-cache.patch for Chromium: */
+int sqlite3PagerLoadall(Pager*);
 void *sqlite3PagerTempSpace(Pager*);
 int sqlite3PagerIsMemdb(Pager*);
 
Index: src/pcache.c
===================================================================
--- src/pcache.c	2009-09-04 13:37:42.000000000 -0700
+++ src/pcache.c	2009-09-15 16:41:55.000000000 -0700
@@ -542,14 +542,12 @@
   return nPage;
 }
 
-#ifdef SQLITE_TEST
 /*
 ** Get the suggested cache-size value.
 */
 int sqlite3PcacheGetCachesize(PCache *pCache){
   return pCache->nMax;
 }
-#endif
 
 /*
 ** Set the suggested cache-size value.
Index: src/pcache.h
===================================================================
--- src/pcache.h	2009-09-04 13:37:42.000000000 -0700
+++ src/pcache.h	2009-09-15 16:41:52.000000000 -0700
@@ -139,9 +139,7 @@
 ** of the suggested cache-sizes.
 */
 void sqlite3PcacheSetCachesize(PCache *, int);
-#ifdef SQLITE_TEST
 int sqlite3PcacheGetCachesize(PCache *);
-#endif
 
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 /* Try to return memory used by the pcache module to the main memory heap */