@@ -10,51 +10,51 @@ typedef OnInitError = FutureOr<Null> Function(Object, StackTrace);
10
10
11
11
/// Thread-safe in-memory [JsonCache] decorator.
12
12
///
13
- /// It is a kind of level 1 cache.
13
+ /// It is a kind of _level 1_ cache.
14
14
///
15
15
/// It encapsulates a slower cache and keeps its own data in-memory.
16
16
class JsonCacheMem implements JsonCache {
17
- /// In-memory level1 cache with an optional level2 instance.
17
+ /// In-memory _level 1_ cache with an optional _level 2_ instance.
18
18
///
19
19
/// **Note**: if you do not pass an object to the parameter [level2] , the data
20
20
/// will remain cached in-memory only; that is, no data will be persited to
21
- /// the user's device's local storage area . Indeed, not persisting data on the
21
+ /// the local storage of the user's device. Indeed, not persisting data on the
22
22
/// user's device might be the desired behavior if you are at the prototyping
23
23
/// or mocking phase. However, its unlikely to be the right behavior in
24
24
/// production code.
25
25
JsonCacheMem ([JsonCache ? level2])
26
26
: this .mem (_shrMem, level2: level2, mutex: _shrMutex);
27
27
28
- /// Initializes both the level1 (internal memory) and level2 (user's device's
29
- /// local storage area) caches with data.
28
+ /// Initializes both the internal memory (level 1 cache) and the local storage
29
+ /// of the user's device (level 2 cache — [level2] ) with the contents of
30
+ /// [initData] .
30
31
///
31
- /// It also provides a type of transaction guarantee whereby, if an error
32
- /// occurs while copying [init ] to cache, it will try to revert the cached
33
- /// data to its previous state before rethrowing the exception that signaled
34
- /// the error. Finally, after reverting the cached data, it invokes
35
- /// [onInitError] .
32
+ /// This method also provides a kind of transaction guarantee whereby if an
33
+ /// error occurs while copying [initData ] to the cache, it will attempt to
34
+ /// revert the cache [level2] to its previous state before rethrowing the
35
+ /// exception that signaled the error. Finally, after reverting the cached
36
+ /// data, it will invoke [onInitError] .
36
37
JsonCacheMem .init (
37
- Map <String , Map <String , dynamic >?> init , {
38
+ Map <String , Map <String , dynamic >?> initData , {
38
39
JsonCache ? level2,
39
40
OnInitError ? onInitError,
40
41
}) : _level2 = level2 ?? const JsonCacheHollow (),
41
42
_memory = _shrMem,
42
43
_mutex = _shrMutex {
43
- final copy = Map <String , Map <String , dynamic >?>.of (init);
44
44
final initFut = _mutex.protectWrite (() async {
45
- final writes = < String > []; // the list of written keys.
46
- for (final entry in copy .entries) {
45
+ final cachedKeys = < String > [];
46
+ for (final entry in initData .entries) {
47
47
final key = entry.key;
48
48
final value = entry.value;
49
49
if (value != null ) {
50
- writes .add (key);
50
+ cachedKeys .add (key);
51
51
try {
52
52
await _level2.refresh (key, value);
53
53
_memory[key] = value;
54
54
} catch (error) {
55
- for (final write in writes ) {
56
- await _level2.remove (write );
57
- _memory.remove (write );
55
+ for (final key in cachedKeys ) {
56
+ await _level2.remove (key );
57
+ _memory.remove (key );
58
58
}
59
59
rethrow ;
60
60
}
@@ -77,7 +77,7 @@ class JsonCacheMem implements JsonCache {
77
77
_level2 = level2 ?? const JsonCacheHollow (),
78
78
_mutex = mutex ?? ReadWriteMutex ();
79
79
80
- /// Slower cache level.
80
+ /// Slower level 2 cache .
81
81
final JsonCache _level2;
82
82
83
83
/// In-memory storage.
@@ -93,6 +93,8 @@ class JsonCacheMem implements JsonCache {
93
93
static final _shrMutex = ReadWriteMutex ();
94
94
95
95
/// Frees up storage space in both the level2 cache and in-memory cache.
96
+ ///
97
+ /// Throws [JsonCacheException] to indicate operation failure.
96
98
@override
97
99
Future <void > clear () async {
98
100
await _mutex.protectWrite (() async {
@@ -101,15 +103,17 @@ class JsonCacheMem implements JsonCache {
101
103
});
102
104
}
103
105
104
- /// Updates data located at [key] in both the level2 cache and in-memory
105
- /// cache.
106
+ /// Updates the data located at [key] in both the _level 2_ cache and
107
+ /// in-memory cache.
108
+ ///
109
+ /// Throws [JsonCacheException] to indicate operation failure.
106
110
@override
107
111
Future <void > refresh (String key, Map <String , dynamic > data) async {
108
112
// ATTENTION: It is safer to copy the content of [data] before calling an
109
113
// asynchronous method that will copy it to avoid data races. For example,
110
114
// if the client code clears [data] right after passing it to this method,
111
- // there's a high chance of having _level2 and this object with different
112
- // contents.
115
+ // there's a high chance of having the level 2 cache and this object with
116
+ // different contents.
113
117
//
114
118
// In Dart, synchronous code cannot be interrupted, so there is no need to
115
119
// protect it using mutual exclusion.
@@ -120,8 +124,8 @@ class JsonCacheMem implements JsonCache {
120
124
});
121
125
}
122
126
123
- /// Removes the value located at [key] from both the level2 cache and
124
- /// in -memory cache .
127
+ /// Removes the cached value located at [key] from both the _level 2 cache_
128
+ /// and _in -memory cache_ .
125
129
@override
126
130
Future <void > remove (String key) async {
127
131
await _mutex.protectWrite (() async {
@@ -130,33 +134,30 @@ class JsonCacheMem implements JsonCache {
130
134
});
131
135
}
132
136
133
- /// Retrieves the value at [key] or null if there is no data.
137
+ /// Retrieves the value at [key] or ` null` if there is no data.
134
138
@override
135
139
Future <Map <String , dynamic >?> value (String key) {
136
140
return _mutex.protectRead (() async {
137
- final cachedL1 = _memory[key];
138
- if (cachedL1 != null ) {
139
- return Map <String , dynamic >.of (cachedL1 );
141
+ final inMemoryValue = _memory[key];
142
+ if (inMemoryValue != null ) {
143
+ return Map <String , dynamic >.of (inMemoryValue );
140
144
}
141
- final cachedL2 = await _level2.value (key);
142
- if (cachedL2 != null ) {
143
- _memory[key] = cachedL2 ;
144
- return Map <String , dynamic >.of (cachedL2 );
145
+ final localStorageValue = await _level2.value (key);
146
+ if (localStorageValue != null ) {
147
+ _memory[key] = localStorageValue ;
148
+ return Map <String , dynamic >.of (localStorageValue );
145
149
}
146
150
return null ;
147
151
});
148
152
}
149
153
150
- /// Checks whether the in-memory or the level2 chache contains cached data at
151
- /// [key] .
154
+ /// Checks whether the _in-memory_ or the _level 2 cache_ contains cached data
155
+ /// at [key] .
152
156
@override
153
157
Future <bool > contains (String key) {
154
158
return _mutex.protectRead (() async {
155
- bool found = _memory.containsKey (key);
156
- if (! found) {
157
- found = await _level2.contains (key);
158
- }
159
- return found;
159
+ final bool foundInMemory = _memory.containsKey (key);
160
+ return foundInMemory ? foundInMemory : await _level2.contains (key);
160
161
});
161
162
}
162
163
}
0 commit comments