Skip to content

Commit e6ba6d8

Browse files
committed
Minor improvements & bug fixes
1 parent 3b350dc commit e6ba6d8

File tree

8 files changed

+132
-122
lines changed

8 files changed

+132
-122
lines changed

lib/src/layer/tile_layer/tile_provider/network/caching/built_in/built_in_caching_provider.dart

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,53 +19,64 @@ import 'package:flutter_map/src/layer/tile_layer/tile_provider/network/caching/b
1919
/// For more information, see the online documentation.
2020
abstract interface class BuiltInMapCachingProvider
2121
implements MapCachingProvider {
22-
/// if a singleton instance exists, return it, otherwise create a new
23-
/// singleton instance (and start asynchronously initialising it)
22+
/// If an instance exists, return it, otherwise create a new instance
2423
///
25-
/// If an instance already exists, the provided configuration will be ignored.
24+
/// The provided configuration will only be respected if an instance does not
25+
/// already exist.
2626
///
2727
/// See individual properties for more information about configuration.
2828
factory BuiltInMapCachingProvider.getOrCreateInstance({
29-
/// Path to the caching directory to use
29+
/// Path to the directory to use to store cached tiles & other related files
3030
///
31-
/// This must be accessible to the program.
31+
/// The provider actually uses the 'fm_cache' directory created as a child
32+
/// of the path specified here.
33+
///
34+
/// The program must have rights/permissions to access the path.
35+
///
36+
/// The path does not have to exist, it will be recursively created if
37+
/// missing.
38+
///
39+
/// All files and directories within the path will be liable to deletion by
40+
/// the size reducer.
3241
///
3342
/// Defaults to a platform provided cache directory, which may be cleared by
3443
/// the OS at any time.
3544
String? cacheDirectory,
3645

37-
/// Preferred maximum size (in bytes) of the cache
46+
/// Maximum total size of cached tiles, in bytes
3847
///
39-
/// This is applied when the internal caching mechanism is created (on the
40-
/// first tile load in the main memory space for the app). It is not an
41-
/// absolute limit.
48+
/// This is applied only when the instance is created, by running the size
49+
/// reducer. This runs in the background (and so does not delay reads or
50+
/// writes). The cache size may exceed this limit while the program is
51+
/// running.
52+
///
53+
/// Disabling the size limit may improve write performance.
4254
///
4355
/// Defaults to 1 GB. Set to `null` to disable.
4456
int? maxCacheSize = 1_000_000_000,
4557

46-
/// Override the duration of time a tile is considered fresh for
58+
/// Function to convert a tile's URL to a key used to uniquely identify the
59+
/// tile
4760
///
48-
/// Defaults to `null`: use duration calculated from each tile's HTTP
49-
/// headers.
50-
Duration? overrideFreshAge,
51-
52-
/// Function to convert a tile URL to a key used in the cache
61+
/// Where parts of the URL are volatile or do not represent the tile's
62+
/// contents/image - for example, API keys contained with the query
63+
/// parameters - this should be modified to remove the volatile portions.
5364
///
54-
/// This may be useful where parts of the URL are volatile or do not
55-
/// represent the tile image, for example, API keys contained with the query
56-
/// parameters.
57-
///
58-
/// The resulting key should be unique to that tile URL. Keys must be usable
59-
/// as filenames on all intended platform filesystems.
65+
/// Keys must be usable as filenames on all intended platform filesystems.
66+
/// The callback should not throw.
6067
///
6168
/// Defaults to generating a UUID from the entire URL string.
69+
String Function(String url)? tileKeyGenerator,
70+
71+
/// Override the duration of time a tile is considered fresh for
6272
///
63-
/// The callback should not throw.
64-
String Function(String url)? cacheKeyGenerator,
73+
/// Defaults to `null`: use duration calculated from each tile's HTTP
74+
/// headers.
75+
Duration? overrideFreshAge,
6576

6677
/// Prevent any tiles from being added or updated
6778
///
68-
/// Does not disable the size limiter if the cache size is larger than
79+
/// Does not disable the size reducer if the cache size is larger than
6980
/// `maxCacheSize`.
7081
///
7182
/// Defaults to `false`.
@@ -83,7 +94,7 @@ abstract interface class BuiltInMapCachingProvider
8394
cacheDirectory: cacheDirectory,
8495
maxCacheSize: maxCacheSize,
8596
overrideFreshAge: overrideFreshAge,
86-
cacheKeyGenerator: cacheKeyGenerator,
97+
tileKeyGenerator: tileKeyGenerator,
8798
readOnly: readOnly,
8899
);
89100
}

lib/src/layer/tile_layer/tile_provider/network/caching/built_in/impl/native/native.dart

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,29 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
2020

2121
final String? cacheDirectory;
2222
final int? maxCacheSize;
23+
final String Function(String url)? tileKeyGenerator;
2324
final Duration? overrideFreshAge;
24-
final String Function(String url)? cacheKeyGenerator;
2525
final bool readOnly;
2626

2727
@internal
2828
BuiltInMapCachingProviderImpl.createAndInitialise({
2929
required this.cacheDirectory,
3030
required this.maxCacheSize,
3131
required this.overrideFreshAge,
32-
required this.cacheKeyGenerator,
32+
required this.tileKeyGenerator,
3333
required this.readOnly,
3434
}) {
3535
// This should only be called/constructed once
3636
() async {
37-
if (cacheKeyGenerator == null) {
37+
if (tileKeyGenerator == null) {
3838
_uuid = Uuid(goptions: GlobalOptions(MathRNG()));
3939
}
4040

4141
final cacheDirectoryPath = p.join(
42-
this.cacheDirectory ??
43-
(await getApplicationCacheDirectory()).absolute.path,
42+
cacheDirectory ?? (await getApplicationCacheDirectory()).absolute.path,
4443
'fm_cache',
4544
);
46-
final cacheDirectory = Directory(cacheDirectoryPath);
47-
await cacheDirectory.create(recursive: true);
45+
await Directory(cacheDirectoryPath).create(recursive: true);
4846

4947
final sizeMonitorFilePath =
5048
p.join(cacheDirectoryPath, sizeMonitorFileName);
@@ -59,16 +57,13 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
5957
// monitoring (and potentially run the reducer) if necessary
6058
// Reading does not depend on this.
6159
void sendMessageToWriter(Object message) {
62-
if (writerPort != null) {
63-
writerPort.send(message);
64-
} else {
65-
writerPortReady.future.then((port) => port.send(message));
66-
}
60+
if (writerPort != null) return writerPort.send(message);
61+
writerPortReady.future.then((port) => port.send(message));
6762
}
6863

69-
_writeTileFile = ({required path, required metadata, tileBytes}) =>
70-
sendMessageToWriter(
71-
(path: path, metadata: metadata, tileBytes: tileBytes));
64+
_writeTileFile = (path, metadata, tileBytes) => sendMessageToWriter(
65+
(path: path, metadata: metadata, tileBytes: tileBytes),
66+
);
7267
_reportReadFailure = () => sendMessageToWriter(false);
7368

7469
final writerReceivePort = ReceivePort();
@@ -78,7 +73,7 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
7873
port: writerReceivePort.sendPort,
7974
cacheDirectoryPath: cacheDirectoryPath,
8075
sizeMonitorFilePath: sizeMonitorFilePath,
81-
sizeLimit: maxCacheSize,
76+
maxCacheSize: maxCacheSize,
8277
),
8378
debugName: '[flutter_map: cache] Tile & Size Monitor Writer',
8479
);
@@ -93,14 +88,14 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
9388

9489
late final Uuid _uuid; // left un-inited if provided generator
9590

96-
late final void Function({
97-
required String path,
98-
required CachedMapTileMetadata metadata,
91+
late final void Function(
92+
String path,
93+
CachedMapTileMetadata metadata,
9994
Uint8List? tileBytes,
100-
}) _writeTileFile;
95+
) _writeTileFile;
10196

102-
/// See `disableSizeMonitor` in worker
103-
late final void Function() _reportReadFailure;
97+
late final void Function()
98+
_reportReadFailure; // See `disableSizeMonitor` in worker
10499

105100
@override
106101
bool get isSupported => true;
@@ -110,7 +105,7 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
110105
String url,
111106
) async {
112107
final key =
113-
cacheKeyGenerator?.call(url) ?? _uuid.v5(Namespace.url.value, url);
108+
tileKeyGenerator?.call(url) ?? _uuid.v5(Namespace.url.value, url);
114109
final tileFile = File(
115110
p.join(_cacheDirectoryPath ?? await _cacheDirectoryPathReady.future, key),
116111
);
@@ -121,7 +116,7 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
121116
final bytes = await tileFile.readAsBytes();
122117

123118
if (bytes.lengthInBytes < 22) {
124-
throw CachedMapTileReadFailureException(
119+
throw CachedMapTileReadFailure(
125120
url: url,
126121
description:
127122
'cache file (${bytes.lengthInBytes}) was shorter than the '
@@ -145,14 +140,13 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
145140
etag = const AsciiDecoder().convert(etagBytes);
146141
}
147142

148-
// Performing an unaligned read is a hassle
149-
final tileBytesExpectedLength =
143+
final tileBytesExpectedLength = // Perform an unaligned read
150144
bytes.buffer.asByteData(18 + etagLength, 4).getUint32(0, Endian.host);
151145

152146
final tileBytes = Uint8List.sublistView(bytes, 18 + etagLength + 4);
153147

154148
if (tileBytes.lengthInBytes != tileBytesExpectedLength) {
155-
throw CachedMapTileReadFailureException(
149+
throw CachedMapTileReadFailure(
156150
url: url,
157151
description:
158152
'tile image bytes (${tileBytes.lengthInBytes}) were not of '
@@ -168,13 +162,13 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
168162
),
169163
bytes: tileBytes,
170164
);
171-
} on CachedMapTileReadFailureException {
165+
} on CachedMapTileReadFailure {
172166
_reportReadFailure();
173167
rethrow;
174168
} catch (error, stackTrace) {
175169
_reportReadFailure();
176170
Error.throwWithStackTrace(
177-
CachedMapTileReadFailureException(url: url, originalError: error),
171+
CachedMapTileReadFailure(url: url, originalError: error),
178172
stackTrace,
179173
);
180174
}
@@ -189,20 +183,22 @@ class BuiltInMapCachingProviderImpl implements BuiltInMapCachingProvider {
189183
if (readOnly) return;
190184

191185
final key =
192-
cacheKeyGenerator?.call(url) ?? _uuid.v5(Namespace.url.value, url);
186+
tileKeyGenerator?.call(url) ?? _uuid.v5(Namespace.url.value, url);
193187
final path = p.join(
194188
_cacheDirectoryPath ?? await _cacheDirectoryPathReady.future,
195189
key,
196190
);
197191

198-
final resolvedMetadata = overrideFreshAge != null
199-
? CachedMapTileMetadata(
200-
staleAt: DateTime.timestamp().add(overrideFreshAge!),
201-
lastModified: metadata.lastModified,
202-
etag: metadata.etag,
203-
)
204-
: metadata;
205-
206-
_writeTileFile(path: path, metadata: resolvedMetadata, tileBytes: bytes);
192+
_writeTileFile(
193+
path,
194+
overrideFreshAge != null
195+
? CachedMapTileMetadata(
196+
staleAt: DateTime.timestamp().add(overrideFreshAge!),
197+
lastModified: metadata.lastModified,
198+
etag: metadata.etag,
199+
)
200+
: metadata,
201+
bytes,
202+
);
207203
}
208204
}

0 commit comments

Comments
 (0)