diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-01-26 12:19:04 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-02-10 15:40:20 -0800 |
commit | cdedb66387065680efd318dacb61572c920b81b1 (patch) | |
tree | 3cc2676e15fac4c7b024cd17603c46e341f5a589 /platform/default/default_file_source.cpp | |
parent | 025375ad0b365a06e0742b92fecc9bc538b5a6e0 (diff) | |
download | qtlocation-mapboxgl-cdedb66387065680efd318dacb61572c920b81b1.tar.gz |
[core] Reimplement existing caching within an offline-capable database schema
Diffstat (limited to 'platform/default/default_file_source.cpp')
-rw-r--r-- | platform/default/default_file_source.cpp | 136 |
1 files changed, 89 insertions, 47 deletions
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp index 56b47539b1..efe893d49b 100644 --- a/platform/default/default_file_source.cpp +++ b/platform/default/default_file_source.cpp @@ -1,10 +1,11 @@ #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/asset_file_source.hpp> #include <mbgl/storage/online_file_source.hpp> -#include <mbgl/storage/sqlite_cache.hpp> +#include <mbgl/storage/offline_database.hpp> #include <mbgl/platform/platform.hpp> #include <mbgl/util/url.hpp> +#include <mbgl/util/thread.hpp> #include <mbgl/util/work_request.hpp> #include <cassert> @@ -23,76 +24,117 @@ namespace mbgl { class DefaultFileSource::Impl { public: - Impl(const std::string& cachePath, const std::string& assetRoot) - : assetFileSource(assetRoot), - cache(SQLiteCache::getShared(cachePath)) { + class Task { + public: + Task(Resource resource, FileSource::Callback callback, DefaultFileSource::Impl* impl) { + auto offlineResponse = impl->offlineDatabase.get(resource); + + Resource revalidation = resource; + + if (offlineResponse) { + revalidation.priorModified = offlineResponse->modified; + revalidation.priorExpires = offlineResponse->expires; + revalidation.priorEtag = offlineResponse->etag; + callback(*offlineResponse); + } + + if (!impl->offline) { + onlineRequest = impl->onlineFileSource.request(revalidation, [=] (Response onlineResponse) { + impl->offlineDatabase.put(revalidation, onlineResponse); + callback(onlineResponse); + }); + } + } + + std::unique_ptr<FileRequest> onlineRequest; + }; + + Impl(const std::string& cachePath) + : offlineDatabase(cachePath) { + } + + void setAccessToken(const std::string& accessToken) { + onlineFileSource.setAccessToken(accessToken); + } + + std::string getAccessToken() const { + return onlineFileSource.getAccessToken(); + } + + void add(FileRequest* req, Resource resource, Callback callback) { + tasks[req] = std::make_unique<Task>(resource, callback, this); } - AssetFileSource assetFileSource; - std::shared_ptr<SQLiteCache> cache; + void cancel(FileRequest* req) { + tasks.erase(req); + } + + void put(const Resource& resource, const Response& response) { + offlineDatabase.put(resource, response); + } + + void goOffline() { + offline = true; + } + + OfflineDatabase offlineDatabase; OnlineFileSource onlineFileSource; + std::unordered_map<FileRequest*, std::unique_ptr<Task>> tasks; + bool offline = false; +}; + +class DefaultFileRequest : public FileRequest { +public: + DefaultFileRequest(Resource resource, FileSource::Callback callback, util::Thread<DefaultFileSource::Impl>& thread_) + : thread(thread_), + workRequest(thread.invokeWithCallback(&DefaultFileSource::Impl::add, callback, this, resource)) { + } + + ~DefaultFileRequest() { + thread.invoke(&DefaultFileSource::Impl::cancel, this); + } + + util::Thread<DefaultFileSource::Impl>& thread; + std::unique_ptr<WorkRequest> workRequest; }; DefaultFileSource::DefaultFileSource(const std::string& cachePath, const std::string& assetRoot) - : impl(std::make_unique<DefaultFileSource::Impl>(cachePath, assetRoot)) { + : thread(std::make_unique<util::Thread<DefaultFileSource::Impl>>(util::ThreadContext{"DefaultFileSource", util::ThreadType::Unknown, util::ThreadPriority::Low}, cachePath)), + assetFileSource(std::make_unique<AssetFileSource>(assetRoot)) { } DefaultFileSource::~DefaultFileSource() = default; void DefaultFileSource::setAccessToken(const std::string& accessToken) { - impl->onlineFileSource.setAccessToken(accessToken); + thread->invokeSync(&Impl::setAccessToken, accessToken); } std::string DefaultFileSource::getAccessToken() const { - return impl->onlineFileSource.getAccessToken(); -} - -void DefaultFileSource::setMaximumCacheSize(uint64_t size) { - impl->cache->setMaximumCacheSize(size); + return thread->invokeSync<std::string>(&Impl::getAccessToken); } -void DefaultFileSource::setMaximumCacheEntrySize(uint64_t size) { - impl->cache->setMaximumCacheEntrySize(size); +void DefaultFileSource::setMaximumCacheSize(uint64_t) { + // TODO } -SQLiteCache& DefaultFileSource::getCache() { - return *impl->cache; +void DefaultFileSource::setMaximumCacheEntrySize(uint64_t) { + // TODO } -class DefaultFileRequest : public FileRequest { -public: - DefaultFileRequest(Resource resource, FileSource::Callback callback, DefaultFileSource::Impl* impl) { - cacheRequest = impl->cache->get(resource, [=](std::shared_ptr<Response> cacheResponse) mutable { - cacheRequest.reset(); - - if (cacheResponse) { - resource.priorModified = cacheResponse->modified; - resource.priorExpires = cacheResponse->expires; - resource.priorEtag = cacheResponse->etag; - } - - onlineRequest = impl->onlineFileSource.request(resource, [=] (Response onlineResponse) { - impl->cache->put(resource, onlineResponse); - callback(onlineResponse); - }); - - // Do this last because it may result in deleting this DefaultFileRequest. - if (cacheResponse) { - callback(*cacheResponse); - } - }); - } - - std::unique_ptr<WorkRequest> cacheRequest; - std::unique_ptr<FileRequest> onlineRequest; -}; - std::unique_ptr<FileRequest> DefaultFileSource::request(const Resource& resource, Callback callback) { if (isAssetURL(resource.url)) { - return impl->assetFileSource.request(resource, callback); + return assetFileSource->request(resource, callback); } else { - return std::make_unique<DefaultFileRequest>(resource, callback, impl.get()); + return std::make_unique<DefaultFileRequest>(resource, callback, *thread); } } +void DefaultFileSource::put(const Resource& resource, const Response& response) { + thread->invokeSync(&Impl::put, resource, response); +} + +void DefaultFileSource::goOffline() { + thread->invokeSync(&Impl::goOffline); +} + } // namespace mbgl |