Repository navigation
Expand file tree
/
Copy pathCache.java
More file actions
75 lines (62 loc) · 2.04 KB
/
Copy pathCache.java
File metadata and controls
75 lines (62 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package org.javacs;
import java.nio.file.Path;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/** Cache maps a file + an arbitrary key to a value. When the file is modified, the mapping expires. */
class Cache<K, V> {
private static class Key<K> {
final Path file;
final K key;
Key(Path file, K key) {
this.file = file;
this.key = key;
}
@Override
public boolean equals(Object other) {
if (other.getClass() != Cache.Key.class) return false;
var that = (Cache.Key) other;
return Objects.equals(this.key, that.key) && Objects.equals(this.file, that.file);
}
@Override
public int hashCode() {
return Objects.hash(file, key);
}
}
private class Value {
final V value;
final Instant created = Instant.now();
Value(V value) {
this.value = value;
}
}
private final Map<Key, Value> map = new HashMap<>();
boolean has(Path file, K k) {
return !needs(file, k);
}
boolean needs(Path file, K k) {
// If key is not in map, it needs to be loaded
var key = new Key<K>(file, k);
if (!map.containsKey(key)) return true;
// If key was loaded before file was last modified, it needs to be reloaded
var value = map.get(key);
var modified = FileStore.modified(file);
if (modified == null) return true;
// TODO remove all keys associated with file when file changes
return value.created.isBefore(modified);
}
void load(Path file, K k, V v) {
// TODO limit total size of cache
var key = new Key<K>(file, k);
var value = new Value(v);
map.put(key, value);
}
V get(Path file, K k) {
var key = new Key<K>(file, k);
if (!map.containsKey(key)) {
throw new IllegalArgumentException(k + " is not in map " + map);
}
return map.get(key).value;
}
}