Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1174)

Unified Diff: sql/connection.cc

Issue 2397753005: [sql] Allow storing mmap status in a VIEW instead of meta table. (Closed)
Patch Set: OK, its an older SQLite on iOS. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sql/connection.cc
diff --git a/sql/connection.cc b/sql/connection.cc
index 073b032cde62157b69a91512a357ce450eb1e4d5..788329bafd33632c6a27d9f81f3ab760cabe4c59 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -318,6 +318,7 @@ Connection::Connection()
needs_rollback_(false),
in_memory_(false),
poisoned_(false),
+ mmap_alt_status_(false),
mmap_disabled_(false),
mmap_enabled_(false),
total_changes_at_last_release_(0),
@@ -840,6 +841,49 @@ std::string Connection::CollectCorruptionInfo() {
return debug_info;
}
+bool Connection::GetMmapAltStatus(int64_t* status) {
+ // The [meta] version uses a missing table as a signal for a fresh database.
+ // That will not work for the view, which would not exist in either a new or
+ // an existing database. A new database _should_ be only one page long, so
+ // just don't bother optimizing this case (start at offset 0).
+ // TODO(shess): Could the [meta] case also get simpler, then?
+ if (!DoesViewExist("MmapStatus")) {
+ *status = 0;
+ return true;
+ }
+
+ const char* kMmapStatusSql = "SELECT * FROM MmapStatus";
+ Statement s(GetUniqueStatement(kMmapStatusSql));
+ if (s.Step())
+ *status = s.ColumnInt64(0);
+ return s.Succeeded();
+}
+
+bool Connection::SetMmapAltStatus(int64_t status) {
+ if (!BeginTransaction())
+ return false;
+
+ // View may not exist on first run.
+ if (!Execute("DROP VIEW IF EXISTS MmapStatus")) {
+ RollbackTransaction();
+ return false;
+ }
+
+ // Views live in the schema, so they cannot be parameterized. For an integer
+ // value, this construct should be safe from SQL injection, if the value
+ // becomes more complicated use "SELECT quote(?)" to generate a safe quoted
+ // value.
+ const std::string createViewSql =
+ base::StringPrintf("CREATE VIEW MmapStatus (value) AS SELECT %" PRId64,
+ status);
+ if (!Execute(createViewSql.c_str())) {
+ RollbackTransaction();
+ return false;
+ }
+
+ return CommitTransaction();
+}
+
size_t Connection::GetAppropriateMmapSize() {
AssertIOAllowed();
@@ -854,27 +898,27 @@ size_t Connection::GetAppropriateMmapSize() {
// percentile of Chrome databases in the wild, so this should be good.
const size_t kMmapEverything = 256 * 1024 * 1024;
- // If the database doesn't have a place to track progress, assume the best.
- // This will happen when new databases are created, or if a database doesn't
- // use a meta table. sql::MetaTable::Init() will preload kMmapSuccess.
- // TODO(shess): Databases not using meta include:
- // DOMStorageDatabase (localstorage)
- // ActivityDatabase (extensions activity log)
- // PredictorDatabase (prefetch and autocomplete predictor data)
- // SyncDirectory (sync metadata storage)
- // For now, these all have mmap disabled to allow other databases to get the
- // default-enable path. sqlite-diag could be an alternative for all but
- // DOMStorageDatabase, which creates many small databases.
- // http://crbug.com/537742
- if (!MetaTable::DoesTableExist(this)) {
- RecordOneEvent(EVENT_MMAP_META_MISSING);
- return kMmapEverything;
- }
-
+ // Progress information is tracked in the [meta] table for databases which use
+ // sql::MetaTable, otherwise it is tracked in a special view.
+ // TODO(shess): Move all cases to the view implementation.
int64_t mmap_ofs = 0;
- if (!MetaTable::GetMmapStatus(this, &mmap_ofs)) {
- RecordOneEvent(EVENT_MMAP_META_FAILURE_READ);
- return 0;
+ if (mmap_alt_status_) {
+ if (!GetMmapAltStatus(&mmap_ofs)) {
+ RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_READ);
+ return 0;
+ }
+ } else {
+ // If [meta] doesn't exist, yet, it's a new database, assume the best.
+ // sql::MetaTable::Init() will preload kMmapSuccess.
+ if (!MetaTable::DoesTableExist(this)) {
+ RecordOneEvent(EVENT_MMAP_META_MISSING);
+ return kMmapEverything;
+ }
+
+ if (!MetaTable::GetMmapStatus(this, &mmap_ofs)) {
+ RecordOneEvent(EVENT_MMAP_META_FAILURE_READ);
+ return 0;
+ }
}
// Database read failed in the past, don't memory map.
@@ -949,9 +993,16 @@ size_t Connection::GetAppropriateMmapSize() {
event = EVENT_MMAP_FAILED_NEW;
}
- if (!MetaTable::SetMmapStatus(this, mmap_ofs)) {
- RecordOneEvent(EVENT_MMAP_META_FAILURE_UPDATE);
- return 0;
+ if (mmap_alt_status_) {
+ if (!SetMmapAltStatus(mmap_ofs)) {
+ RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_UPDATE);
+ return 0;
+ }
+ } else {
+ if (!MetaTable::SetMmapStatus(this, mmap_ofs)) {
+ RecordOneEvent(EVENT_MMAP_META_FAILURE_UPDATE);
+ return 0;
+ }
}
RecordOneEvent(event);
@@ -1503,15 +1554,19 @@ bool Connection::IsSQLValid(const char* sql) {
return true;
}
+bool Connection::DoesIndexExist(const char* index_name) const {
+ return DoesSchemaItemExist(index_name, "index");
+}
+
bool Connection::DoesTableExist(const char* table_name) const {
- return DoesTableOrIndexExist(table_name, "table");
+ return DoesSchemaItemExist(table_name, "table");
}
-bool Connection::DoesIndexExist(const char* index_name) const {
- return DoesTableOrIndexExist(index_name, "index");
+bool Connection::DoesViewExist(const char* view_name) const {
+ return DoesSchemaItemExist(view_name, "view");
}
-bool Connection::DoesTableOrIndexExist(
+bool Connection::DoesSchemaItemExist(
const char* name, const char* type) const {
const char* kSql =
"SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE";
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698