2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
- import 'dart:async' ;
6
5
import 'dart:convert' ;
7
6
import 'dart:typed_data' ;
8
7
9
- import 'package:pool/pool.dart' ;
10
-
11
8
import '../../build.dart' ;
12
9
13
10
/// Cache for file existence and contents.
@@ -17,101 +14,90 @@ abstract interface class FilesystemCache {
17
14
/// Clears all [ids] from all caches.
18
15
///
19
16
/// Waits for any pending reads to complete first.
20
- Future < void > invalidate (Iterable <AssetId > ids);
17
+ void invalidate (Iterable <AssetId > ids);
21
18
22
- Future < void > flush ();
19
+ void flush ();
23
20
24
21
/// Whether [id] exists.
25
22
///
26
23
/// Returns a cached result if available, or caches and returns `ifAbsent()` .
27
- Future < bool > exists (AssetId id, {required Future < bool > Function () ifAbsent});
24
+ bool exists (AssetId id, {required bool Function () ifAbsent});
28
25
29
26
/// Reads [id] as bytes.
30
27
///
31
28
/// Returns a cached result if available, or caches and returns `ifAbsent()` .
32
- Future <Uint8List > readAsBytes (
33
- AssetId id, {
34
- required Future <Uint8List > Function () ifAbsent,
35
- });
29
+ Uint8List readAsBytes (AssetId id, {required Uint8List Function () ifAbsent});
36
30
37
- Future < void > writeAsBytes (
31
+ void writeAsBytes (
38
32
AssetId id,
39
33
List <int > contents, {
40
- required Future < void > Function () writer,
34
+ required void Function () writer,
41
35
});
42
36
43
37
/// Reads [id] as a `String` .
44
38
///
45
39
/// Returns a cached result if available, or caches and returns `ifAbsent()` .
46
- Future < String > readAsString (
40
+ String readAsString (
47
41
AssetId id, {
48
42
Encoding encoding = utf8,
49
- required Future < Uint8List > Function () ifAbsent,
43
+ required Uint8List Function () ifAbsent,
50
44
});
51
45
52
- Future < void > writeAsString (
46
+ void writeAsString (
53
47
AssetId id,
54
48
String contents, {
55
49
Encoding encoding = utf8,
56
- required Future < void > Function () writer,
50
+ required void Function () writer,
57
51
});
58
52
59
- Future < void > delete (AssetId id, {required Future < void > Function () deleter});
53
+ void delete (AssetId id, {required void Function () deleter});
60
54
}
61
55
62
56
/// [FilesystemCache] that always reads from the underlying source.
63
57
class PassthroughFilesystemCache implements FilesystemCache {
64
58
const PassthroughFilesystemCache ();
65
59
66
60
@override
67
- Future < void > invalidate (Iterable <AssetId > ids) async {}
61
+ void invalidate (Iterable <AssetId > ids) {}
68
62
69
63
@override
70
- Future < void > flush () => Future < void >. value ();
64
+ void flush () {}
71
65
72
66
@override
73
- Future <bool > exists (
74
- AssetId id, {
75
- required Future <bool > Function () ifAbsent,
76
- }) => ifAbsent ();
67
+ bool exists (AssetId id, {required bool Function () ifAbsent}) => ifAbsent ();
77
68
78
69
@override
79
- Future <Uint8List > readAsBytes (
80
- AssetId id, {
81
- required Future <Uint8List > Function () ifAbsent,
82
- }) => ifAbsent ();
70
+ Uint8List readAsBytes (AssetId id, {required Uint8List Function () ifAbsent}) =>
71
+ ifAbsent ();
83
72
84
73
@override
85
- Future < String > readAsString (
74
+ String readAsString (
86
75
AssetId id, {
87
76
Encoding encoding = utf8,
88
- required Future < Uint8List > Function () ifAbsent,
89
- }) async => encoding.decode (await ifAbsent ());
77
+ required Uint8List Function () ifAbsent,
78
+ }) => encoding.decode (ifAbsent ());
90
79
91
80
@override
92
- Future < void > writeAsBytes (
81
+ void writeAsBytes (
93
82
AssetId id,
94
83
List <int > contents, {
95
- required Future < void > Function () writer,
84
+ required void Function () writer,
96
85
}) => writer ();
97
86
98
87
@override
99
- Future < void > writeAsString (
88
+ void writeAsString (
100
89
AssetId id,
101
90
String contents, {
102
91
Encoding encoding = utf8,
103
- required Future < void > Function () writer,
92
+ required void Function () writer,
104
93
}) => writer ();
105
94
106
95
@override
107
- Future <void > delete (AssetId id, {required Future <void > Function () deleter}) =>
108
- deleter ();
96
+ void delete (AssetId id, {required void Function () deleter}) => deleter ();
109
97
}
110
98
111
99
/// [FilesystemCache] that stores data in memory.
112
100
class InMemoryFilesystemCache implements FilesystemCache {
113
- final _pool = Pool (1 );
114
-
115
101
/// Cached results of [readAsBytes] .
116
102
final _bytesContentCache = < AssetId , Uint8List > {};
117
103
@@ -127,138 +113,116 @@ class InMemoryFilesystemCache implements FilesystemCache {
127
113
/// Only files read with [utf8] encoding (the default) will ever be cached.
128
114
final _stringContentCache = < AssetId , String > {};
129
115
130
- final _pendingWrites = < AssetId , Future < void > Function ()> {};
131
- final _pendingDeletes = < AssetId , Future < void > Function ()> {};
116
+ final _pendingWrites = < AssetId , void Function ()> {};
117
+ final _pendingDeletes = < AssetId , void Function ()> {};
132
118
133
119
@override
134
- Future <void > invalidate (Iterable <AssetId > ids) async {
135
- await _pool.withResource (() {
136
- for (var id in ids) {
137
- _canReadCache.remove (id);
138
- _bytesContentCache.remove (id);
139
- _stringContentCache.remove (id);
140
- }
141
- });
120
+ void invalidate (Iterable <AssetId > ids) {
121
+ for (var id in ids) {
122
+ _canReadCache.remove (id);
123
+ _bytesContentCache.remove (id);
124
+ _stringContentCache.remove (id);
125
+ }
142
126
}
143
127
144
128
@override
145
- Future <void > flush () async {
146
- await _pool.withResource (() async {
147
- for (final write in _pendingWrites.values) {
148
- await write ();
149
- }
150
- _pendingWrites.clear ();
151
- });
129
+ void flush () {
130
+ for (final write in _pendingWrites.values) {
131
+ write ();
132
+ }
133
+ for (final delete in _pendingDeletes.values) {
134
+ delete ();
135
+ }
136
+ _pendingWrites.clear ();
152
137
}
153
138
154
139
@override
155
- Future <bool > exists (
156
- AssetId id, {
157
- required Future <bool > Function () ifAbsent,
158
- }) async {
159
- return await _pool.withResource (() async {
160
- final maybeResult = _canReadCache[id];
161
- if (maybeResult != null ) return maybeResult;
162
- return _canReadCache[id] = await ifAbsent ();
163
- });
140
+ bool exists (AssetId id, {required bool Function () ifAbsent}) {
141
+ final maybeResult = _canReadCache[id];
142
+ if (maybeResult != null ) return maybeResult;
143
+ return _canReadCache[id] = ifAbsent ();
164
144
}
165
145
166
146
@override
167
- Future <Uint8List > readAsBytes (
168
- AssetId id, {
169
- required Future <Uint8List > Function () ifAbsent,
170
- }) async {
171
- return await _pool.withResource (() async {
172
- final maybeResult = _bytesContentCache[id];
173
- if (maybeResult != null ) return maybeResult;
174
-
175
- // check canRead first?
176
- if (_pendingDeletes.containsKey (id)) throw AssetNotFoundException (id);
177
- if (_pendingWrites.containsKey (id)) {
178
- throw StateError ('Whoops, should have been cached: $id ' );
179
- }
147
+ Uint8List readAsBytes (AssetId id, {required Uint8List Function () ifAbsent}) {
148
+ final maybeResult = _bytesContentCache[id];
149
+ if (maybeResult != null ) return maybeResult;
180
150
181
- return _bytesContentCache[id] = await ifAbsent ();
182
- });
151
+ // check canRead first?
152
+ if (_pendingDeletes.containsKey (id)) throw AssetNotFoundException (id);
153
+ if (_pendingWrites.containsKey (id)) {
154
+ throw StateError ('Whoops, should have been cached: $id ' );
155
+ }
156
+
157
+ return _bytesContentCache[id] = ifAbsent ();
183
158
}
184
159
185
160
@override
186
- Future < String > readAsString (
161
+ String readAsString (
187
162
AssetId id, {
188
163
Encoding encoding = utf8,
189
- required Future < Uint8List > Function () ifAbsent,
190
- }) async {
164
+ required Uint8List Function () ifAbsent,
165
+ }) {
191
166
if (encoding != utf8) {
192
- final bytes = await readAsBytes (id, ifAbsent: ifAbsent);
167
+ final bytes = readAsBytes (id, ifAbsent: ifAbsent);
193
168
return encoding.decode (bytes);
194
169
}
195
170
196
- return await _pool.withResource (() async {
197
- final maybeResult = _stringContentCache[id];
198
- if (maybeResult != null ) return maybeResult;
199
-
200
- // check canRead first?
201
- if (_pendingDeletes.containsKey (id)) throw AssetNotFoundException (id);
202
- if (_pendingWrites.containsKey (id)) {
203
- final bytes = _bytesContentCache[id];
204
- if (bytes == null ) {
205
- throw StateError ('Whoops, should have been cached: $id ' );
206
- } else {
207
- return _stringContentCache[id] = utf8.decode (_bytesContentCache[id]! );
208
- }
171
+ final maybeResult = _stringContentCache[id];
172
+ if (maybeResult != null ) return maybeResult;
173
+
174
+ // check canRead first?
175
+ if (_pendingDeletes.containsKey (id)) throw AssetNotFoundException (id);
176
+ if (_pendingWrites.containsKey (id)) {
177
+ final bytes = _bytesContentCache[id];
178
+ if (bytes == null ) {
179
+ throw StateError ('Whoops, should have been cached: $id ' );
180
+ } else {
181
+ return _stringContentCache[id] = utf8.decode (_bytesContentCache[id]! );
209
182
}
183
+ }
210
184
211
- final bytes = await ifAbsent ();
212
- return _stringContentCache[id] = utf8.decode (bytes);
213
- });
185
+ final bytes = ifAbsent ();
186
+ return _stringContentCache[id] = utf8.decode (bytes);
214
187
}
215
188
216
189
@override
217
- Future < void > writeAsBytes (
190
+ void writeAsBytes (
218
191
AssetId id,
219
192
List <int > contents, {
220
- required Future < void > Function () writer,
193
+ required void Function () writer,
221
194
}) {
222
- return _pool.withResource (() {
223
- _bytesContentCache[id] =
224
- (contents is Uint8List ? contents : Uint8List .fromList (contents));
225
- // [contents] might not be a valid string so defer trying to
226
- // decode it until if/when it's read as a string.
227
- _stringContentCache.remove (id);
228
- _canReadCache[id] = true ;
229
-
230
- _pendingDeletes.remove (id);
231
- _pendingWrites[id] = writer;
232
- return Future .value (null );
233
- });
195
+ _bytesContentCache[id] =
196
+ (contents is Uint8List ? contents : Uint8List .fromList (contents));
197
+ // [contents] might not be a valid string so defer trying to
198
+ // decode it until if/when it's read as a string.
199
+ _stringContentCache.remove (id);
200
+ _canReadCache[id] = true ;
201
+
202
+ _pendingDeletes.remove (id);
203
+ _pendingWrites[id] = writer;
234
204
}
235
205
236
206
@override
237
- Future < void > writeAsString (
207
+ void writeAsString (
238
208
AssetId id,
239
209
String contents, {
240
210
Encoding encoding = utf8,
241
- required Future < void > Function () writer,
211
+ required void Function () writer,
242
212
}) {
243
- return _pool.withResource (() {
244
- // TODO: encoding?
245
- _stringContentCache[id] = contents;
246
- _bytesContentCache[id] = utf8.encode (contents);
247
- _canReadCache[id] = true ;
248
-
249
- _pendingDeletes.remove (id);
250
- _pendingWrites[id] = writer;
251
- return Future .value (null );
252
- });
213
+ // TODO: encoding?
214
+ _stringContentCache[id] = contents;
215
+ _bytesContentCache[id] = utf8.encode (contents);
216
+ _canReadCache[id] = true ;
217
+
218
+ _pendingDeletes.remove (id);
219
+ _pendingWrites[id] = writer;
253
220
}
254
221
255
222
@override
256
- Future <void > delete (AssetId id, {required Future <void > Function () deleter}) {
257
- return _pool.withResource (() {
258
- _pendingWrites.remove (id);
259
- _pendingDeletes[id] = deleter;
260
- _canReadCache[id] = false ;
261
- return Future .value (null );
262
- });
223
+ void delete (AssetId id, {required void Function () deleter}) {
224
+ _pendingWrites.remove (id);
225
+ _pendingDeletes[id] = deleter;
226
+ _canReadCache[id] = false ;
263
227
}
264
228
}
0 commit comments