Index: sql/connection.cc |
diff --git a/sql/connection.cc b/sql/connection.cc |
index 79264916c0274c3cda466ccee94750b35e3f798d..3d584a65e11095a8e0c86becdcf16486fa3c306b 100644 |
--- a/sql/connection.cc |
+++ b/sql/connection.cc |
@@ -190,6 +190,16 @@ int GetSqlite3File(sqlite3* db, sqlite3_file** file) { |
return rc; |
} |
+// Convenience to get the sqlite3_file* and the size for the "main" database. |
+int GetSqlite3FileAndSize(sqlite3* db, |
+ sqlite3_file** file, sqlite3_int64* db_size) { |
+ int rc = GetSqlite3File(db, file); |
+ if (rc != SQLITE_OK) |
+ return rc; |
+ |
+ return (*file)->pMethods->xFileSize(*file, db_size); |
+} |
+ |
// This should match UMA_HISTOGRAM_MEDIUM_TIMES(). |
base::HistogramBase* GetMediumTimeHistogram(const std::string& name) { |
return base::Histogram::FactoryTimeGet( |
@@ -515,12 +525,8 @@ void Connection::Preload() { |
return; |
sqlite3_file* file = NULL; |
- int rc = GetSqlite3File(db_, &file); |
- if (rc != SQLITE_OK) |
- return; |
- |
sqlite3_int64 file_size = 0; |
- rc = file->pMethods->xFileSize(file, &file_size); |
+ int rc = GetSqlite3FileAndSize(db_, &file, &file_size); |
if (rc != SQLITE_OK) |
return; |
@@ -1656,6 +1662,23 @@ bool Connection::OpenInternal(const std::string& file_name, |
return false; |
} |
+ // Set a reasonable chunk size for larger files. This reduces churn from |
+ // remapping memory on size changes. It also reduces filesystem |
+ // fragmentation. |
+ // TODO(shess): It may make sense to have this be hinted by the client. |
+ // Database sizes seem to be bimodal, some clients have consistently small |
+ // databases (<20k) while other clients have a broad distribution of sizes |
+ // (hundreds of kilobytes to many megabytes). |
+ sqlite3_file* file = NULL; |
+ sqlite3_int64 db_size = 0; |
+ int rc = GetSqlite3FileAndSize(db_, &file, &db_size); |
+ if (rc == SQLITE_OK && db_size > 16 * 1024) { |
+ int chunk_size = 4 * 1024; |
+ if (db_size > 128 * 1024) |
+ chunk_size = 32 * 1024; |
+ sqlite3_file_control(db_, NULL, SQLITE_FCNTL_CHUNK_SIZE, &chunk_size); |
+ } |
+ |
// Enable memory-mapped access. The explicit-disable case is because SQLite |
// can be built to default-enable mmap. This value will be capped by |
// SQLITE_MAX_MMAP_SIZE, which could be different between 32-bit and 64-bit |