Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Offline (mbgl-core implementation) #3715

Merged
merged 20 commits into from
Feb 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7d6c6c0
[core] Refactor tileCover
jfirebaugh Jan 29, 2016
f3d4107
[core] Add a method for statically evaluating font stacks used by a s…
jfirebaugh Feb 2, 2016
dbb8e58
[core] Moving caching logic to DefaultFileSource
jfirebaugh Jan 14, 2016
025375a
[core] Cache with mapbox:// tile URLs
jfirebaugh Jan 30, 2016
cdedb66
[core] Reimplement existing caching within an offline-capable databas…
jfirebaugh Jan 26, 2016
7eb1a91
[all] Do not set Response data for 404s
jfirebaugh Feb 4, 2016
e9302c7
[all] Don't interpret 404s on non-tile resources as "no content"
jfirebaugh Feb 6, 2016
c3c4c7b
[core] Interface and implementation for offline
jfirebaugh Feb 6, 2016
c91b44b
Add binary for smoke-testing offline downloads
jfirebaugh Feb 8, 2016
4bde1b0
[core] Explicit operator bool
jfirebaugh Feb 8, 2016
96e0e52
[core] Disable SQLite busy timeouts so that multiple readers can acce…
jfirebaugh Feb 8, 2016
5d42321
[core] Make {Default,Online}FileSource::Impl more similar
jfirebaugh Feb 9, 2016
ff15bd5
[core] Throttle the number of concurrent requests to 20
jfirebaugh Feb 9, 2016
5910124
[core] Reset SQLite statements after use in order to release locks
jfirebaugh Feb 9, 2016
db3620c
[core] Implement an eviction policy for OfflineDatabase
jfirebaugh Feb 10, 2016
a9e0c1b
[core] Eliminate maximumCacheEntrySize
jfirebaugh Feb 10, 2016
0cf450e
[core] Retry errors encountered during offline downloads
jfirebaugh Feb 10, 2016
40ecdeb
[core] Optimize offline database schema
jfirebaugh Feb 10, 2016
7e287ca
[core] Eliminate tilesets table
jfirebaugh Feb 11, 2016
20be32f
[core] Always store tiles without ratio support with ratio = 1
jfirebaugh Feb 11, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.actual.png
*.diff.png
*.pyc
offline.db
/platform/android/debug
/platform/android/sdk
/platform/android/**/.classpath
Expand All @@ -23,8 +24,8 @@
/test/fixtures/api/1.png
/test/fixtures/api/2.png
/test/fixtures/database/*.db
/test/fixtures/*/*/actual.png
/test/fixtures/*/*/diff.png
/test/fixtures/**/actual.png
/test/fixtures/**/diff.png
/test/output
/include/mbgl/shader/shaders.hpp
/src/shader/shaders_gl.cpp
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ ifeq ($(BUILD),osx)
xtest: ; $(RUN) HOST=osx HOST_VERSION=x86_64 Xcode/test
endif

.PHONY: render xrender
.PHONY: render
render: ; $(RUN) Makefile/mbgl-render
ifeq ($(BUILD),osx)
xrender: ; $(RUN) HOST=osx HOST_VERSION=x86_64 Xcode/mbgl-render
endif

.PHONY: offline
offline: ; $(RUN) Makefile/mbgl-offline


##### Maintenace operations ####################################################
Expand Down
76 changes: 76 additions & 0 deletions bin/offline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/io.hpp>

#include <mbgl/storage/default_file_source.hpp>

#include <cstdlib>
#include <iostream>

using namespace std::literals::chrono_literals;

int main(int, char * []) {
using namespace mbgl;

unlink("offline.db");

util::RunLoop loop;
DefaultFileSource fileSource("offline.db", ".");

fileSource.setAccessToken(getenv("MAPBOX_ACCESS_TOKEN"));

LatLngBounds bayArea = LatLngBounds::hull(LatLng(37.2, -122.8), LatLng(38.1, -121.7));
OfflineTilePyramidRegionDefinition definition("mapbox://styles/mapbox/streets-v8", bayArea, 0, 15, 1.0);
OfflineRegionMetadata metadata;

class Observer : public OfflineRegionObserver {
public:
Observer(util::RunLoop& loop_)
: loop(loop_),
start(SystemClock::now()) {
}

void statusChanged(OfflineRegionStatus status) override {
std::string bytesPerSecond = "-";

auto elapsedSeconds = (SystemClock::now() - start) / 1s;
if (elapsedSeconds != 0) {
bytesPerSecond = util::toString(status.completedResourceSize / elapsedSeconds);
}

std::cout << status.completedResourceCount << " / " << status.requiredResourceCount
<< " resources"
<< (status.requiredResourceCountIsIndeterminate ? " (indeterminate); " : "; ")
<< status.completedResourceSize << " bytes downloaded"
<< " (" << bytesPerSecond << " bytes/sec)"
<< std::endl;

if (status.complete()) {
std::cout << "Finished" << std::endl;
loop.stop();
}
}

void responseError(Response::Error error) override {
std::cerr << error.reason << " downloading resource: " << error.message << std::endl;
}

util::RunLoop& loop;
SystemTimePoint start;
};

fileSource.createOfflineRegion(definition, metadata, [&] (std::exception_ptr error, optional<OfflineRegion> region) {
if (error) {
std::cerr << "Error creating region: " << util::toString(error) << std::endl;
loop.stop();
exit(1);
} else {
assert(region);
fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(loop));
fileSource.setOfflineRegionDownloadState(*region, OfflineRegionDownloadState::Active);
}
});

loop.run();
return 0;
}
44 changes: 44 additions & 0 deletions bin/offline.gypi
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
'includes': [
'../gyp/common.gypi',
],
'targets': [
{ 'target_name': 'mbgl-offline',
'product_name': 'mbgl-offline',
'type': 'executable',

'dependencies': [
'mbgl.gyp:core',
'mbgl.gyp:platform-<(platform_lib)',
'mbgl.gyp:headless-<(headless_lib)',
'mbgl.gyp:http-<(http_lib)',
'mbgl.gyp:asset-<(asset_lib)',
'mbgl.gyp:copy_certificate_bundle',
],

'include_dirs': [
'../src',
],

'sources': [
'./offline.cpp',
],

'variables' : {
'cflags_cc': [
'<@(boost_cflags)',
],
},

'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
}
}, {
'cflags_cc': [ '<@(cflags_cc)' ],
}]
],
},
],
}
1 change: 1 addition & 0 deletions gyp/osx.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
'../platform/linux/mapboxgl-app.gypi',
'../test/test.gypi',
'../bin/render.gypi',
'../bin/offline.gypi',
],
}
9 changes: 8 additions & 1 deletion gyp/platform-android.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
'../platform/default/timer.cpp',
'../platform/default/default_file_source.cpp',
'../platform/default/online_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/default/mbgl/storage/offline.hpp',
'../platform/default/mbgl/storage/offline.cpp',
'../platform/default/mbgl/storage/offline_database.hpp',
'../platform/default/mbgl/storage/offline_database.cpp',
'../platform/default/mbgl/storage/offline_download.hpp',
'../platform/default/mbgl/storage/offline_download.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
],
Expand All @@ -34,6 +39,7 @@
'<@(nunicode_cflags)',
'<@(boost_cflags)',
'<@(sqlite_cflags)',
'<@(rapidjson_cflags)',
],
'ldflags': [
'<@(libpng_ldflags)',
Expand All @@ -56,6 +62,7 @@
'include_dirs': [
'../include',
'../src',
'../platform/default',
],

'conditions': [
Expand Down
9 changes: 8 additions & 1 deletion gyp/platform-ios.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
'../platform/default/timer.cpp',
'../platform/default/default_file_source.cpp',
'../platform/default/online_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/default/mbgl/storage/offline.hpp',
'../platform/default/mbgl/storage/offline.cpp',
'../platform/default/mbgl/storage/offline_database.hpp',
'../platform/default/mbgl/storage/offline_database.cpp',
'../platform/default/mbgl/storage/offline_download.hpp',
'../platform/default/mbgl/storage/offline_download.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
'../platform/darwin/log_nslog.mm',
Expand Down Expand Up @@ -71,6 +76,7 @@
'<@(boost_cflags)',
'<@(sqlite_cflags)',
'<@(zlib_cflags)',
'<@(rapidjson_cflags)',
],
'ldflags': [
'<@(sqlite_ldflags)',
Expand Down Expand Up @@ -98,6 +104,7 @@
'../include/mbgl/darwin',
'../include',
'../src',
'../platform/default',
],

'xcode_settings': {
Expand Down
9 changes: 8 additions & 1 deletion gyp/platform-linux.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
'../platform/default/timer.cpp',
'../platform/default/default_file_source.cpp',
'../platform/default/online_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/default/mbgl/storage/offline.hpp',
'../platform/default/mbgl/storage/offline.cpp',
'../platform/default/mbgl/storage/offline_database.hpp',
'../platform/default/mbgl/storage/offline_database.cpp',
'../platform/default/mbgl/storage/offline_download.hpp',
'../platform/default/mbgl/storage/offline_download.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
],
Expand All @@ -37,6 +42,7 @@
'<@(boost_cflags)',
'<@(sqlite_cflags)',
'<@(webp_cflags)',
'<@(rapidjson_cflags)',
],
'ldflags': [
'<@(libpng_ldflags)',
Expand All @@ -61,6 +67,7 @@
'include_dirs': [
'../include',
'../src',
'../platform/default',
],

'conditions': [
Expand Down
9 changes: 8 additions & 1 deletion gyp/platform-osx.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
'../platform/default/timer.cpp',
'../platform/default/default_file_source.cpp',
'../platform/default/online_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/default/mbgl/storage/offline.hpp',
'../platform/default/mbgl/storage/offline.cpp',
'../platform/default/mbgl/storage/offline_database.hpp',
'../platform/default/mbgl/storage/offline_database.cpp',
'../platform/default/mbgl/storage/offline_download.hpp',
'../platform/default/mbgl/storage/offline_download.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
'../platform/darwin/log_nslog.mm',
Expand Down Expand Up @@ -62,6 +67,7 @@
'<@(boost_cflags)',
'<@(sqlite_cflags)',
'<@(zlib_cflags)',
'<@(rapidjson_cflags)',
],
'ldflags': [
'<@(zlib_ldflags)',
Expand All @@ -83,6 +89,7 @@
'../include/mbgl/darwin',
'../include',
'../src',
'../platform/default',
],

'xcode_settings': {
Expand Down
87 changes: 81 additions & 6 deletions include/mbgl/storage/default_file_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,100 @@
#define MBGL_STORAGE_DEFAULT_FILE_SOURCE

#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/offline.hpp>
#include <mbgl/util/constants.hpp>

#include <vector>

namespace mbgl {

namespace util {
template <typename T> class Thread;
} // namespace util

class DefaultFileSource : public FileSource {
public:
DefaultFileSource(const std::string& cachePath, const std::string& assetRoot);
DefaultFileSource(const std::string& cachePath,
const std::string& assetRoot,
uint64_t maximumCacheSize = util::DEFAULT_MAX_CACHE_SIZE);
~DefaultFileSource() override;

void setAccessToken(const std::string&);
std::string getAccessToken() const;

void setMaximumCacheSize(uint64_t size);
void setMaximumCacheEntrySize(uint64_t size);

std::unique_ptr<FileRequest> request(const Resource&, Callback) override;

private:
/*
* Retrieve all regions in the offline database.
*
* The query will be executed asynchronously and the results passed to the given
* callback, which will be executed on the database thread; it is the responsibility
* of the SDK bindings to re-execute a user-provided callback on the main thread.
*/
void listOfflineRegions(std::function<void (std::exception_ptr,
optional<std::vector<OfflineRegion>>)>);

/*
* Create an offline region in the database.
*
* When the initial database queries have completed, the provided callback will be
* executed on the database thread; it is the responsibility of the SDK bindings
* to re-execute a user-provided callback on the main thread.
*
* Note that the resulting region will be in an inactive download state; to begin
* downloading resources, call `setOfflineRegionDownloadState(OfflineRegionDownloadState::Active)`,
* optionally registering an `OfflineRegionObserver` beforehand.
*/
void createOfflineRegion(const OfflineRegionDefinition& definition,
const OfflineRegionMetadata& metadata,
std::function<void (std::exception_ptr,
optional<OfflineRegion>)>);

/*
* Register an observer to be notified when the state of the region changes.
*/
void setOfflineRegionObserver(OfflineRegion&, std::unique_ptr<OfflineRegionObserver>);

/*
* Pause or resume downloading of regional resources.
*/
void setOfflineRegionDownloadState(OfflineRegion&, OfflineRegionDownloadState);

/*
* Retrieve the current status of the region. The query will be executed
* asynchronously and the results passed to the given callback, which will be
* executed on the database thread; it is the responsibility of the SDK bindings
* to re-execute a user-provided callback on the main thread.
*/
void getOfflineRegionStatus(OfflineRegion&, std::function<void (std::exception_ptr,
optional<OfflineRegionStatus>)>) const;

/*
* Remove an offline region from the database and perform any resources evictions
* necessary as a result.
*
* Eviction works by removing the least-recently requested resources not also required
* by other regions, until the database shrinks below a certain size.
*
* Note that this method takes ownership of the input, reflecting the fact that once
* region deletion is initiated, it is not legal to perform further actions with the
* region.
*
* When the operation is complete or encounters an error, the given callback will be
* executed on the database thread; it is the responsibility of the SDK bindings
* to re-execute a user-provided callback on the main thread.
*/
void deleteOfflineRegion(OfflineRegion&&, std::function<void (std::exception_ptr)>);

// For testing only.
void put(const Resource&, const Response&);
void goOffline();

class Impl;
const std::unique_ptr<Impl> impl;

private:
const std::unique_ptr<util::Thread<Impl>> thread;
const std::unique_ptr<FileSource> assetFileSource;
};

} // namespace mbgl
Expand Down
Loading