summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-03-15 15:23:25 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-03-17 14:17:59 -0700
commit5130ca8843a342a1b708bb63263fd44c6c908120 (patch)
tree125ce7af31e47b603459977ddea0e8aaf9146bf1
parentaa60d295346871bad0884238d13dcd9995d97151 (diff)
downloadqtlocation-mapboxgl-5130ca8843a342a1b708bb63263fd44c6c908120.tar.gz
[core] Implement a vacuum strategy for the offline database
Enable `PRAGMA auto_vacuum = INCREMENTAL`, and perform a `PRAGMA incremental_vacuum` when deleting an offline region.
-rw-r--r--.gitignore1
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp39
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp2
-rw-r--r--test/fixtures/offline/v2.dbbin0 -> 43008 bytes
-rw-r--r--test/storage/offline_database.cpp28
5 files changed, 53 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 1b6ed5386b..68e242a31b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ offline.db
/test/fixtures/api/1.png
/test/fixtures/api/2.png
/test/fixtures/database/*.db
+/test/fixtures/offline/v3.db
/test/fixtures/**/actual.png
/test/fixtures/**/diff.png
/test/output
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index a42591d60e..e1cd693662 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -14,9 +14,6 @@ namespace mbgl {
using namespace mapbox::sqlite;
-// If you change the schema you must write a migration from the previous version.
-static const uint32_t schemaVersion = 2;
-
OfflineDatabase::Statement::~Statement() {
stmt.reset();
stmt.clearBindings();
@@ -50,15 +47,12 @@ void OfflineDatabase::ensureSchema() {
try {
connect(ReadWrite);
- {
- auto userVersionStmt = db->prepare("PRAGMA user_version");
- userVersionStmt.run();
- switch (userVersionStmt.get<int>(0)) {
- case 0: break; // cache-only database; ok to delete
- case 1: break; // cache-only database; ok to delete
- case 2: return;
- default: throw std::runtime_error("unknown schema version");
- }
+ switch (userVersion()) {
+ case 0: break; // cache-only database; ok to delete
+ case 1: break; // cache-only database; ok to delete
+ case 2: migrateToVersion3(); // fall through
+ case 3: return;
+ default: throw std::runtime_error("unknown schema version");
}
removeExisting();
@@ -76,8 +70,17 @@ void OfflineDatabase::ensureSchema() {
#include "offline_schema.cpp.include"
connect(ReadWrite | Create);
+
+ // If you change the schema you must write a migration from the previous version.
+ db->exec("PRAGMA auto_vacuum = INCREMENTAL");
db->exec(schema);
- db->exec("PRAGMA user_version = " + util::toString(schemaVersion));
+ db->exec("PRAGMA user_version = 3");
+}
+
+int OfflineDatabase::userVersion() {
+ auto stmt = db->prepare("PRAGMA user_version");
+ stmt.run();
+ return stmt.get<int>(0);
}
void OfflineDatabase::removeExisting() {
@@ -92,6 +95,11 @@ void OfflineDatabase::removeExisting() {
}
}
+void OfflineDatabase::migrateToVersion3() {
+ db->exec("PRAGMA auto_vacuum = INCREMENTAL");
+ db->exec("VACUUM");
+}
+
OfflineDatabase::Statement OfflineDatabase::getStatement(const char * sql) {
auto it = statements.find(sql);
@@ -458,6 +466,7 @@ void OfflineDatabase::deleteRegion(OfflineRegion&& region) {
stmt->run();
evict(0);
+ db->exec("PRAGMA incremental_vacuum");
// Ensure that the cached offlineTileCount value is recalculated.
offlineMapboxTileCount = {};
@@ -614,10 +623,6 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) {
uint64_t pageSize = getPragma<int64_t>("PRAGMA page_size");
uint64_t pageCount = getPragma<int64_t>("PRAGMA page_count");
- if (pageSize * pageCount > maximumCacheSize) {
- Log::Warning(mbgl::Event::Database, "Current size is larger than the maximum size. Database won't get truncated.");
- }
-
auto usedSize = [&] {
return pageSize * (pageCount - getPragma<int64_t>("PRAGMA freelist_count"));
};
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index eb18cc18d2..1e77d560d4 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -58,8 +58,10 @@ public:
private:
void connect(int flags);
+ int userVersion();
void ensureSchema();
void removeExisting();
+ void migrateToVersion3();
class Statement {
public:
diff --git a/test/fixtures/offline/v2.db b/test/fixtures/offline/v2.db
new file mode 100644
index 0000000000..8fadec4abe
--- /dev/null
+++ b/test/fixtures/offline/v2.db
Binary files differ
diff --git a/test/storage/offline_database.cpp b/test/storage/offline_database.cpp
index 23269a98ed..11d56c237b 100644
--- a/test/storage/offline_database.cpp
+++ b/test/storage/offline_database.cpp
@@ -7,6 +7,7 @@
#include <mbgl/util/string.hpp>
#include <gtest/gtest.h>
+#include <sqlite3.hpp>
#include <sqlite3.h>
#include <thread>
#include <random>
@@ -660,3 +661,30 @@ TEST(OfflineDatabase, OfflineMapboxTileCount) {
db.deleteRegion(std::move(region1));
EXPECT_EQ(0, db.getOfflineMapboxTileCount());
}
+
+static int databasePageCount(const std::string& path) {
+ mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly);
+ mapbox::sqlite::Statement stmt = db.prepare("pragma page_count");
+ stmt.run();
+ return stmt.get<int>(0);
+}
+
+TEST(OfflineDatabase, MigrateFromV2Schema) {
+ using namespace mbgl;
+
+ // v2.db is a v2 database containing a single offline region with a small number of resources.
+
+ deleteFile("test/fixtures/offline/v3.db");
+ writeFile("test/fixtures/offline/v3.db", util::read_file("test/fixtures/offline/v2.db"));
+
+ {
+ OfflineDatabase db("test/fixtures/offline/v3.db", 0);
+ auto regions = db.listRegions();
+ for (auto& region : regions) {
+ db.deleteRegion(std::move(region));
+ }
+ }
+
+ EXPECT_LT(databasePageCount("test/fixtures/offline/v3.db"),
+ databasePageCount("test/fixtures/offline/v2.db"));
+}