diff options
author | Huyen Chau Nguyen <hello@chau-nguyen.de> | 2018-10-17 20:12:28 +0200 |
---|---|---|
committer | Huyen Chau Nguyen <hello@chau-nguyen.de> | 2018-10-23 12:47:10 +0200 |
commit | 1e3a744d2296feb2fd6b5d7da324bb31b6ee17c6 (patch) | |
tree | 1d3f1975ba993fc4b03caf649190d501eb9e5d41 | |
parent | 9afe75aa76c02db21209e8f92b09be4b596a3983 (diff) | |
download | qtlocation-mapboxgl-1e3a744d2296feb2fd6b5d7da324bb31b6ee17c6.tar.gz |
[core] add priorities to resources
- priorities can be low or regular
- offline downloads should have low priority to not throttle "regular requests"
-rw-r--r-- | include/mbgl/storage/resource.hpp | 26 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_download.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/storage/resource.cpp | 32 | ||||
-rw-r--r-- | src/mbgl/tile/tile_loader_impl.hpp | 1 | ||||
-rw-r--r-- | test/storage/default_file_source.test.cpp | 6 | ||||
-rw-r--r-- | test/storage/offline_download.test.cpp | 60 |
6 files changed, 109 insertions, 25 deletions
diff --git a/include/mbgl/storage/resource.hpp b/include/mbgl/storage/resource.hpp index 318fa389f4..97b9fbcaf0 100644 --- a/include/mbgl/storage/resource.hpp +++ b/include/mbgl/storage/resource.hpp @@ -24,6 +24,11 @@ public: Image }; + enum class Priority : bool { + Regular, + Low + }; + struct TileData { std::string urlTemplate; uint8_t pixelRatio; @@ -44,34 +49,41 @@ public: Resource(Kind kind_, std::string url_, + Priority priority_ = Resource::Priority::Regular, optional<TileData> tileData_ = {}, LoadingMethod loadingMethod_ = LoadingMethod::All) : kind(kind_), loadingMethod(loadingMethod_), + priority(priority_), url(std::move(url_)), tileData(std::move(tileData_)) { } + void setPriority(Priority p) { priority = p; } + bool hasLoadingMethod(LoadingMethod method); - static Resource style(const std::string& url); - static Resource source(const std::string& url); + static Resource style(const std::string& url, const Priority priority = Resource::Priority::Regular); + static Resource source(const std::string& url, const Priority priority = Resource::Priority::Regular); static Resource tile(const std::string& urlTemplate, float pixelRatio, int32_t x, int32_t y, int8_t z, Tileset::Scheme scheme, + const Priority priority = Resource::Priority::Regular, LoadingMethod = LoadingMethod::All); static Resource glyphs(const std::string& urlTemplate, const FontStack& fontStack, - const std::pair<uint16_t, uint16_t>& glyphRange); - static Resource spriteImage(const std::string& base, float pixelRatio); - static Resource spriteJSON(const std::string& base, float pixelRatio); - static Resource image(const std::string& url); - + const std::pair<uint16_t, uint16_t>& glyphRange, + const Priority priority = Resource::Priority::Regular); + static Resource spriteImage(const std::string& base, float pixelRatio, const Priority priority = Resource::Priority::Regular); + static Resource spriteJSON(const std::string& base, float pixelRatio, const Priority priority = Resource::Priority::Regular); + static Resource image(const std::string& url, const Priority priority = Resource::Priority::Regular); + Kind kind; LoadingMethod loadingMethod; + Priority priority; std::string url; // Includes auxiliary data if this is a tile request. diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index 17af0abf3c..6524697546 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -219,7 +219,7 @@ void OfflineDownload::activateDownload() { status = OfflineRegionStatus(); status.downloadState = OfflineRegionDownloadState::Active; status.requiredResourceCount++; - ensureResource(Resource::style(definition.match([](auto& reg){ return reg.styleURL; })), + ensureResource(Resource::style(definition.match([](auto& reg){ return reg.styleURL; }), Resource::Priority::Low), [&](Response styleResponse) { status.requiredResourceCountIsPrecise = true; @@ -238,7 +238,7 @@ void OfflineDownload::activateDownload() { status.requiredResourceCount++; requiredSourceURLs.insert(url); - ensureResource(Resource::source(url), [=](Response sourceResponse) { + ensureResource(Resource::source(url, Resource::Priority::Low), [=](Response sourceResponse) { style::conversion::Error error; optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(*sourceResponse.data, error); if (tileset) { @@ -353,6 +353,7 @@ void OfflineDownload::deactivateDownload() { } void OfflineDownload::queueResource(Resource resource) { + resource.setPriority(Resource::Priority::Low); status.requiredResourceCount++; resourcesRemaining.push_front(std::move(resource)); } @@ -362,12 +363,14 @@ void OfflineDownload::queueTiles(SourceType type, uint16_t tileSize, const Tiles status.requiredResourceCount++; resourcesRemaining.push_back(Resource::tile( tileset.tiles[0], definition.match([](auto& def) { return def.pixelRatio; }), tile.x, - tile.y, tile.z, tileset.scheme)); + tile.y, tile.z, tileset.scheme, Resource::Priority::Low)); }); } void OfflineDownload::ensureResource(const Resource& resource, std::function<void(Response)> callback) { + assert(resource.priority == Resource::Priority::Low); + auto workRequestsIt = requests.insert(requests.begin(), nullptr); *workRequestsIt = util::RunLoop::Get()->invokeCancellable([=]() { requests.erase(workRequestsIt); diff --git a/src/mbgl/storage/resource.cpp b/src/mbgl/storage/resource.cpp index c51db44548..aca53138ff 100644 --- a/src/mbgl/storage/resource.cpp +++ b/src/mbgl/storage/resource.cpp @@ -39,44 +39,49 @@ static std::string getTileBBox(int32_t x, int32_t y, int8_t z) { util::toString(max.x) + "," + util::toString(max.y)); } -Resource Resource::style(const std::string& url) { +Resource Resource::style(const std::string& url, const Priority priority) { return Resource { Resource::Kind::Style, - url + url, + priority }; } -Resource Resource::source(const std::string& url) { +Resource Resource::source(const std::string& url, const Priority priority) { return Resource { Resource::Kind::Source, - url + url, + priority }; } -Resource Resource::image(const std::string& url) { +Resource Resource::image(const std::string& url, const Priority priority) { return Resource { Resource::Kind::Image, - url + url, + priority }; } -Resource Resource::spriteImage(const std::string& base, float pixelRatio) { +Resource Resource::spriteImage(const std::string& base, float pixelRatio, const Priority priority) { util::URL url(base); return Resource{ Resource::Kind::SpriteImage, base.substr(0, url.path.first + url.path.second) + (pixelRatio > 1 ? "@2x" : "") + ".png" + - base.substr(url.query.first, url.query.second) }; + base.substr(url.query.first, url.query.second), + priority }; } -Resource Resource::spriteJSON(const std::string& base, float pixelRatio) { +Resource Resource::spriteJSON(const std::string& base, float pixelRatio, const Priority priority) { util::URL url(base); return Resource{ Resource::Kind::SpriteJSON, base.substr(0, url.path.first + url.path.second) + (pixelRatio > 1 ? "@2x" : "") + ".json" + - base.substr(url.query.first, url.query.second) }; + base.substr(url.query.first, url.query.second), + priority }; } -Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontStack, const std::pair<uint16_t, uint16_t>& glyphRange) { +Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontStack, const std::pair<uint16_t, uint16_t>& glyphRange, const Priority priority) { return Resource { Resource::Kind::Glyphs, util::replaceTokens(urlTemplate, [&](const std::string& token) -> optional<std::string> { @@ -87,7 +92,8 @@ Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontS } else { return {}; } - }) + }), + priority }; } @@ -97,6 +103,7 @@ Resource Resource::tile(const std::string& urlTemplate, int32_t y, int8_t z, Tileset::Scheme scheme, + const Priority priority, LoadingMethod loadingMethod) { bool supportsRatio = urlTemplate.find("{ratio}") != std::string::npos; if (scheme == Tileset::Scheme::TMS) { @@ -126,6 +133,7 @@ Resource Resource::tile(const std::string& urlTemplate, return {}; } }), + priority, Resource::TileData { urlTemplate, uint8_t(supportsRatio && pixelRatio > 1.0 ? 2 : 1), diff --git a/src/mbgl/tile/tile_loader_impl.hpp b/src/mbgl/tile/tile_loader_impl.hpp index 1b29638269..5835858d1a 100644 --- a/src/mbgl/tile/tile_loader_impl.hpp +++ b/src/mbgl/tile/tile_loader_impl.hpp @@ -23,6 +23,7 @@ TileLoader<T>::TileLoader(T& tile_, id.canonical.y, id.canonical.z, tileset.scheme, + Resource::Priority::Regular, Resource::LoadingMethod::CacheOnly)), fileSource(parameters.fileSource) { assert(!request); diff --git a/test/storage/default_file_source.test.cpp b/test/storage/default_file_source.test.cpp index c11d442270..e1c5df6895 100644 --- a/test/storage/default_file_source.test.cpp +++ b/test/storage/default_file_source.test.cpp @@ -251,7 +251,7 @@ TEST(DefaultFileSource, OptionalNonExpired) { util::RunLoop loop; DefaultFileSource fs(":memory:", "."); - const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly }; + const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", Resource::Priority::Regular, {}, Resource::LoadingMethod::CacheOnly }; using namespace std::chrono_literals; @@ -281,7 +281,7 @@ TEST(DefaultFileSource, OptionalExpired) { util::RunLoop loop; DefaultFileSource fs(":memory:", "."); - const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly }; + const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", Resource::Priority::Regular, {}, Resource::LoadingMethod::CacheOnly }; using namespace std::chrono_literals; @@ -327,7 +327,7 @@ TEST(DefaultFileSource, OptionalNotFound) { util::RunLoop loop; DefaultFileSource fs(":memory:", "."); - const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly }; + const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", Resource::Priority::Regular, {}, Resource::LoadingMethod::CacheOnly }; using namespace std::chrono_literals; diff --git a/test/storage/offline_download.test.cpp b/test/storage/offline_download.test.cpp index 5fc0e752df..01baf29592 100644 --- a/test/storage/offline_download.test.cpp +++ b/test/storage/offline_download.test.cpp @@ -662,6 +662,66 @@ TEST(OfflineDownload, Deactivate) { test.loop.run(); } + +TEST(OfflineDownload, LowPriorityRequests) { + OfflineTest test; + auto region = test.createRegion(); + ASSERT_TRUE(region); + OfflineDownload download( + region->getID(), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + test.db, test.fileSource); + + test.fileSource.styleResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("style.json"); + }; + + test.fileSource.spriteImageResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("sprite.png"); + }; + + test.fileSource.imageResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("radar.gif"); + }; + + test.fileSource.spriteJSONResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("sprite.json"); + }; + + test.fileSource.glyphsResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("glyph.pbf"); + }; + + test.fileSource.sourceResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("streets.json"); + }; + + test.fileSource.tileResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + return test.response("0-0-0.vector.pbf"); + }; + + auto observer = std::make_unique<MockObserver>(); + + observer->statusChangedFn = [&] (OfflineRegionStatus status) { + if (status.complete()) { + test.loop.stop(); + } + }; + + download.setObserver(std::move(observer)); + download.setState(OfflineRegionDownloadState::Active); + + test.loop.run(); +} + + #ifndef __QT__ // Qt doesn't expose the ability to register virtual file system handlers. TEST(OfflineDownload, DiskFull) { FixtureLog log; |