diff options
Diffstat (limited to 'store/src/main/java/tools/refinery/data/map/VersionedMapStoreImpl.java')
-rw-r--r-- | store/src/main/java/tools/refinery/data/map/VersionedMapStoreImpl.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/store/src/main/java/tools/refinery/data/map/VersionedMapStoreImpl.java b/store/src/main/java/tools/refinery/data/map/VersionedMapStoreImpl.java new file mode 100644 index 00000000..c194faf8 --- /dev/null +++ b/store/src/main/java/tools/refinery/data/map/VersionedMapStoreImpl.java | |||
@@ -0,0 +1,135 @@ | |||
1 | package tools.refinery.data.map; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Arrays; | ||
5 | import java.util.Collections; | ||
6 | import java.util.HashMap; | ||
7 | import java.util.HashSet; | ||
8 | import java.util.List; | ||
9 | import java.util.Map; | ||
10 | import java.util.Set; | ||
11 | |||
12 | import tools.refinery.data.map.internal.ImmutableNode; | ||
13 | import tools.refinery.data.map.internal.MapDiffCursor; | ||
14 | import tools.refinery.data.map.internal.Node; | ||
15 | import tools.refinery.data.map.internal.VersionedMapImpl; | ||
16 | |||
17 | public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> { | ||
18 | // Configuration | ||
19 | private final boolean immutableWhenCommiting; | ||
20 | |||
21 | // Static data | ||
22 | protected final ContinousHashProvider<K> hashProvider; | ||
23 | protected final V defaultValue; | ||
24 | |||
25 | // Dynamic data | ||
26 | protected final Map<Long, ImmutableNode<K, V>> states = new HashMap<>(); | ||
27 | protected final Map<Node<K, V>, ImmutableNode<K, V>> nodeCache; | ||
28 | protected long nextID = 0; | ||
29 | |||
30 | public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, | ||
31 | VersionedMapStoreConfiguration config) { | ||
32 | this.immutableWhenCommiting = config.isImmutableWhenCommiting(); | ||
33 | this.hashProvider = hashProvider; | ||
34 | this.defaultValue = defaultValue; | ||
35 | if (config.isSharedNodeCacheInStore()) { | ||
36 | nodeCache = new HashMap<>(); | ||
37 | } else { | ||
38 | nodeCache = null; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | private VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, | ||
43 | Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreConfiguration config) { | ||
44 | this.immutableWhenCommiting = config.isImmutableWhenCommiting(); | ||
45 | this.hashProvider = hashProvider; | ||
46 | this.defaultValue = defaultValue; | ||
47 | this.nodeCache = nodeCache; | ||
48 | } | ||
49 | |||
50 | public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue) { | ||
51 | this(hashProvider, defaultValue, new VersionedMapStoreConfiguration()); | ||
52 | } | ||
53 | |||
54 | public static <K, V> List<VersionedMapStore<K, V>> createSharedVersionedMapStores(int amount, | ||
55 | ContinousHashProvider<K> hashProvider, V defaultValue, | ||
56 | VersionedMapStoreConfiguration config) { | ||
57 | List<VersionedMapStore<K, V>> result = new ArrayList<>(amount); | ||
58 | if (config.isSharedNodeCacheInStoreGroups()) { | ||
59 | Map<Node<K, V>, ImmutableNode<K, V>> nodeCache; | ||
60 | if (config.isSharedNodeCacheInStore()) { | ||
61 | nodeCache = new HashMap<>(); | ||
62 | } else { | ||
63 | nodeCache = null; | ||
64 | } | ||
65 | for (int i = 0; i < amount; i++) { | ||
66 | result.add(new VersionedMapStoreImpl<>(hashProvider, defaultValue, nodeCache, config)); | ||
67 | } | ||
68 | } else { | ||
69 | for (int i = 0; i < amount; i++) { | ||
70 | result.add(new VersionedMapStoreImpl<>(hashProvider, defaultValue, config)); | ||
71 | } | ||
72 | } | ||
73 | return result; | ||
74 | } | ||
75 | |||
76 | public static <K, V> List<VersionedMapStore<K, V>> createSharedVersionedMapStores(int amount, | ||
77 | ContinousHashProvider<K> hashProvider, V defaultValue) { | ||
78 | return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreConfiguration()); | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public synchronized Set<Long> getStates() { | ||
83 | return new HashSet<>(states.keySet()); | ||
84 | } | ||
85 | |||
86 | @Override | ||
87 | public VersionedMap<K, V> createMap() { | ||
88 | return new VersionedMapImpl<>(this, hashProvider, defaultValue); | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public VersionedMap<K, V> createMap(long state) { | ||
93 | ImmutableNode<K, V> data = revert(state); | ||
94 | return new VersionedMapImpl<>(this, hashProvider, defaultValue, data); | ||
95 | } | ||
96 | |||
97 | |||
98 | public synchronized ImmutableNode<K, V> revert(long state) { | ||
99 | if (states.containsKey(state)) { | ||
100 | return states.get(state); | ||
101 | } else { | ||
102 | ArrayList<Long> existingKeys = new ArrayList<>(states.keySet()); | ||
103 | Collections.sort(existingKeys); | ||
104 | throw new IllegalArgumentException("Store does not contain state " + state + "! Avaliable states: " | ||
105 | + Arrays.toString(existingKeys.toArray())); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | public synchronized long commit(Node<K, V> data, VersionedMapImpl<K, V> mapToUpdateRoot) { | ||
110 | ImmutableNode<K, V> immutable; | ||
111 | if (data != null) { | ||
112 | immutable = data.toImmutable(this.nodeCache); | ||
113 | } else { | ||
114 | immutable = null; | ||
115 | } | ||
116 | |||
117 | if (nextID == Long.MAX_VALUE) | ||
118 | throw new IllegalStateException("Map store run out of Id-s"); | ||
119 | long id = nextID++; | ||
120 | this.states.put(id, immutable); | ||
121 | if (this.immutableWhenCommiting) { | ||
122 | mapToUpdateRoot.setRoot(immutable); | ||
123 | } | ||
124 | return id; | ||
125 | } | ||
126 | |||
127 | @Override | ||
128 | public DiffCursor<K, V> getDiffCursor(long fromState, long toState) { | ||
129 | VersionedMap<K, V> map1 = createMap(fromState); | ||
130 | VersionedMap<K, V> map2 = createMap(toState); | ||
131 | Cursor<K, V> cursor1 = map1.getAll(); | ||
132 | Cursor<K, V> cursor2 = map2.getAll(); | ||
133 | return new MapDiffCursor<>(this.hashProvider, this.defaultValue, cursor1, cursor2); | ||
134 | } | ||
135 | } | ||