diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-02-09 17:19:27 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-02-10 15:40:20 -0800 |
commit | db3620c58f0c3351e26b0e3bcfd23ff414f829a1 (patch) | |
tree | e8def564e12307a997270b66a4ed46b68f5e13a4 /test | |
parent | 591012401072e63b89071787d90bf5ae4362dca1 (diff) | |
download | qtlocation-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.cpp | 72 |
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")))); +} |