summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-02-09 17:19:27 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-02-10 15:40:20 -0800
commitdb3620c58f0c3351e26b0e3bcfd23ff414f829a1 (patch)
treee8def564e12307a997270b66a4ed46b68f5e13a4 /test
parent591012401072e63b89071787d90bf5ae4362dca1 (diff)
downloadqtlocation-mapboxgl-db3620c58f0c3351e26b0e3bcfd23ff414f829a1.tar.gz
[core] Implement an eviction policy for OfflineDatabase
When inserting an cached resource, or removing a region, remove least-recently used resources and tiles, not used by offline regions, until the used database size, as calculated by multiplying the number of in-use pages by the page size, is less than the maximum cache size minus 5 times the page size. In addition, OfflineDatabase may be configured to ignore cache puts of individual resources larger than a certain size. This policy is similar but not identical to the former SQLiteCache policy: * It accounts for offline, by exempting resources required by offline regions from eviction. * It must delete from two tables (resources and tiles), rather than one. Currently the strategy is naive: evict 50 rows at a time from each table. * It makes maximumCacheSize and maximumCacheEntrySize completely independent. The SQLiteCache implementation evicted when `usedSize > maximumCacheSize - 2 * maximumCacheEntrySize`. This evicts when `usedSize > maximumCacheSize - 5 * pageSize`. * It uses a non-unlimited default value for maximumCacheSize: 50 MB. We should have always had a limit in place; "a cache without an eviction policy is a resource leak".
Diffstat (limited to 'test')
-rw-r--r--test/storage/offline_database.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/test/storage/offline_database.cpp b/test/storage/offline_database.cpp
index 4af262deb1..680a14bb4f 100644
--- a/test/storage/offline_database.cpp
+++ b/test/storage/offline_database.cpp
@@ -4,11 +4,14 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/io.hpp>
+#include <mbgl/util/string.hpp>
#include <gtest/gtest.h>
#include <sqlite3.h>
#include <thread>
+using namespace std::literals::string_literals;
+
namespace {
void createDir(const char* name) {
@@ -480,3 +483,72 @@ TEST(OfflineDatabase, ConcurrentUse) {
thread1.join();
thread2.join();
}
+
+TEST(OfflineDatabase, PutIgnoresOversizedResources) {
+ using namespace mbgl;
+
+ Log::setObserver(std::make_unique<FixtureLogObserver>());
+ OfflineDatabase db(":memory:", 1000, 1);
+
+ Resource resource = Resource::style("http://example.com/");
+ Response response;
+ response.data = std::make_shared<std::string>("data");
+
+ db.put(resource, response);
+ EXPECT_FALSE(bool(db.get(resource)));
+
+ auto observer = Log::removeObserver();
+ auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
+ EXPECT_EQ(1ul, flo->count({ EventSeverity::Warning, Event::Database, -1, "Entry too big for caching" }));
+}
+
+TEST(OfflineDatabase, PutRegionResourceDoesNotIgnoreOversizedResources) {
+ using namespace mbgl;
+
+ OfflineDatabase db(":memory:", 1000, 1);
+
+ OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 };
+ OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata());
+
+ Resource resource = Resource::style("http://example.com/");
+ Response response;
+ response.data = std::make_shared<std::string>("data");
+
+ db.putRegionResource(region.getID(), resource, response);
+ EXPECT_TRUE(bool(db.get(resource)));
+}
+
+TEST(OfflineDatabase, PutEvictsLeastRecentlyUsedResources) {
+ using namespace mbgl;
+
+ OfflineDatabase db(":memory:", 1024 * 20);
+
+ Response response;
+ response.data = std::make_shared<std::string>(1024, '0');
+
+ for (uint32_t i = 1; i <= 20; i++) {
+ db.put(Resource::style("http://example.com/"s + util::toString(i)), response);
+ }
+
+ EXPECT_FALSE(bool(db.get(Resource::style("http://example.com/1"))));
+ EXPECT_TRUE(bool(db.get(Resource::style("http://example.com/20"))));
+}
+
+TEST(OfflineDatabase, PutRegionResourceDoesNotEvict) {
+ using namespace mbgl;
+
+ OfflineDatabase db(":memory:", 1024 * 20);
+
+ OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 };
+ OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata());
+
+ Response response;
+ response.data = std::make_shared<std::string>(1024, '0');
+
+ for (uint32_t i = 1; i <= 20; i++) {
+ db.putRegionResource(region.getID(), Resource::style("http://example.com/"s + util::toString(i)), response);
+ }
+
+ EXPECT_TRUE(bool(db.get(Resource::style("http://example.com/1"))));
+ EXPECT_TRUE(bool(db.get(Resource::style("http://example.com/20"))));
+}