Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(649)

Side by Side Diff: tools/gardening_tools/base_lib/lib/src/cache.dart

Issue 3005443002: Additional tools for gardening. (Closed)
Patch Set: Removed accidental commit Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:async';
6 import 'dart:io';
7 import 'logger.dart';
8 import 'try.dart';
9
10 typedef Future<String> Call();
Johnni Winther 2017/08/23 12:40:46 Rename to [ReadResultFunction] and variables of th
11 typedef Future<String> WithCache(Call call, [String key]);
12 typedef WithCache PerformWithCache({String overrideKey, Duration duration});
Johnni Winther 2017/08/23 12:40:47 Rename to [CreateCacheFunction] and variables of t
13
14 PerformWithCache initCache(Uri baseUri, [Logger logger]) {
15 if (logger == null) {
16 logger = new StdOutLogger(Level.warning);
Johnni Winther 2017/08/23 12:40:47 Just write this as: logger ??= new StdOutLogger(L
17 }
18
19 final cache = new Cache(baseUri, logger);
20
21 return ({String overrideKey, Duration duration}) {
22 if (duration == null) {
23 duration = new Duration(hours: 24);
24 }
25
26 return (Call call, [String key]) async {
27 if (overrideKey != null) {
28 key = overrideKey;
29 }
30
31 if (key == null || key.isEmpty) {
32 logger.warning("Key is null or empty - cannot cache result");
33 } else {
34 // format key
35 key = key.replaceAll("/", "_").replaceAll(".", "_");
36
37 Try<ReadFromCacheResult> readResult =
Johnni Winther 2017/08/23 12:40:46 Rename to [cacheResult].
38 await cache.tryRead(key, duration);
39 if (!readResult.isError() && readResult.get().hasResult) {
40 logger.debug("Found key $key in cache");
41 return readResult.get().res;
42 }
43 if (readResult.isError()) {
44 logger.error("Error when reading from cache", readResult.getError(),
45 readResult.getStackTrace());
46 }
47 }
48
49 logger.debug("Could not find key $key in cache");
50
51 // we have to make a call
52 String result = await call();
53
54 // insert/update the cache
55 if (key != null && !key.isEmpty) {
56 await cache.write(key, result);
57 }
58
59 return result;
60 };
61 };
62 }
63
64 PerformWithCache noCache() {
65 return ({String overrideKey, Duration duration}) {
66 return (Call call, [String key]) {
67 return call();
68 };
69 };
70 }
71
72 /// Simple cache for caching data.
73 class Cache {
Johnni Winther 2017/08/23 12:40:46 Add a TODO (for me?) to use this instead of the Ca
74 Uri base;
75 Logger logger;
76
77 Cache(this.base, this.logger);
78
79 Map<String, String> memoryCache = <String, String>{};
80
81 /// Checks if key [path] is in cache
82 Future<bool> containsKey(String path, [Duration duration]) async {
83 if (memoryCache.containsKey(path)) return true;
84
85 File file = new File.fromUri(base.resolve(path));
86 if (await file.exists()) {
87 return duration == null
88 ? true
89 : new DateTime.now().difference(await file.lastModified()) <=
90 duration;
91 }
92
93 return false;
94 }
95
96 /// Try reading [path] from cache
97 Future<Try<ReadFromCacheResult>> tryRead(String path,
Johnni Winther 2017/08/23 12:40:46 Rename to [read] (since we always just try)
98 [Duration duration]) async {
99 if (memoryCache.containsKey(path)) {
100 logger.debug('Found $path in memory cache');
101 return new Try.from(new ReadFromCacheResult.result(memoryCache[path]));
102 }
103
104 File file = new File.fromUri(base.resolve(path));
105
106 if (!await file.exists()) {
107 logger.debug('Could not find file $path in file cache');
108 return new Try.from(new ReadFromCacheResult.noResult());
109 }
110
111 if (duration != null &&
112 new DateTime.now().difference(await file.lastModified()) > duration) {
113 logger.debug(
114 'File $path was found but the information is too stale, for the durati on: $duration');
Johnni Winther 2017/08/23 12:40:47 Split long strings manual: logger.debug( 'Fil
115 return new Try.from(new ReadFromCacheResult.noResult());
116 }
117
118 return tryStartAsync(() async {
119 logger.debug('Found $path in file cache');
120 var text = await file.readAsString();
121 memoryCache[path] = text;
122 return new ReadFromCacheResult.result(text);
123 });
124 }
125
126 /// Store [text] as the cache data for [path].
127 Future write(String path, String text) async {
128 logger.debug('Creating $path in file cache');
129 File file = new File.fromUri(base.resolve(path));
130 if (!await file.exists()) {
131 await file.create(recursive: true);
132 }
133 await file.writeAsString(text);
134 memoryCache[path] = text;
135 }
136
137 /// Clears cache
138 Future clearCache(Uri baseUri) async {
139 // needs to be done
Johnni Winther 2017/08/23 12:40:47 Write this as // TODO(mkroghj): Implement this.
140 }
141 }
142
143 class ReadFromCacheResult {
Johnni Winther 2017/08/23 12:40:46 Rename to [CacheResult] (the correctly name reads
144 bool hasResult;
Johnni Winther 2017/08/23 12:40:47 Make the fields final.
145 String res;
Johnni Winther 2017/08/23 12:40:47 Rename to [result]. We generally use unabbreviated
Bill Hesse 2017/08/23 15:41:25 I agree - alway use full, correctly-spelled words
146
147 ReadFromCacheResult.noResult() {
148 hasResult = false;
149 res = null;
150 }
151
152 ReadFromCacheResult.result(String result) {
Johnni Winther 2017/08/23 12:40:47 Rename to the no-name constructor and use initiali
153 hasResult = true;
154 this.res = result;
155 }
156 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698