diff options
Diffstat (limited to 'subprojects/store/src/main/java/tools/refinery/store/map/internal/state/VersionedMapStoreStateImpl.java')
-rw-r--r-- | subprojects/store/src/main/java/tools/refinery/store/map/internal/state/VersionedMapStoreStateImpl.java | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/state/VersionedMapStoreStateImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/state/VersionedMapStoreStateImpl.java new file mode 100644 index 00000000..8ff3f8e7 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/state/VersionedMapStoreStateImpl.java | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.map.internal.state; | ||
7 | |||
8 | import tools.refinery.store.map.*; | ||
9 | |||
10 | import java.util.*; | ||
11 | |||
12 | public class VersionedMapStoreStateImpl<K, V> implements VersionedMapStore<K, V> { | ||
13 | // Configuration | ||
14 | private final boolean immutableWhenCommitting; | ||
15 | |||
16 | // Static data | ||
17 | protected final ContinuousHashProvider<K> hashProvider; | ||
18 | protected final V defaultValue; | ||
19 | |||
20 | protected final Map<Node<K, V>, ImmutableNode<K, V>> nodeCache; | ||
21 | |||
22 | public VersionedMapStoreStateImpl(ContinuousHashProvider<K> hashProvider, V defaultValue, | ||
23 | VersionedMapStoreStateConfiguration config) { | ||
24 | this.immutableWhenCommitting = config.isImmutableWhenCommitting(); | ||
25 | this.hashProvider = hashProvider; | ||
26 | this.defaultValue = defaultValue; | ||
27 | if (config.isSharedNodeCacheInStore()) { | ||
28 | nodeCache = createNoteCache(config); | ||
29 | } else { | ||
30 | nodeCache = null; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | private VersionedMapStoreStateImpl(ContinuousHashProvider<K> hashProvider, V defaultValue, | ||
35 | Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreStateConfiguration config) { | ||
36 | this.immutableWhenCommitting = config.isImmutableWhenCommitting(); | ||
37 | this.hashProvider = hashProvider; | ||
38 | this.defaultValue = defaultValue; | ||
39 | this.nodeCache = nodeCache; | ||
40 | } | ||
41 | |||
42 | public VersionedMapStoreStateImpl(ContinuousHashProvider<K> hashProvider, V defaultValue) { | ||
43 | this(hashProvider, defaultValue, new VersionedMapStoreStateConfiguration()); | ||
44 | } | ||
45 | |||
46 | public static <K, V> List<VersionedMapStore<K, V>> createSharedVersionedMapStores(int amount, | ||
47 | ContinuousHashProvider<K> hashProvider, V defaultValue, | ||
48 | VersionedMapStoreStateConfiguration config) { | ||
49 | List<VersionedMapStore<K, V>> result = new ArrayList<>(amount); | ||
50 | if (config.isSharedNodeCacheInStoreGroups()) { | ||
51 | Map<Node<K, V>, ImmutableNode<K, V>> nodeCache; | ||
52 | if (config.isSharedNodeCacheInStore()) { | ||
53 | nodeCache = createNoteCache(config); | ||
54 | } else { | ||
55 | nodeCache = null; | ||
56 | } | ||
57 | for (int i = 0; i < amount; i++) { | ||
58 | result.add(new VersionedMapStoreStateImpl<>(hashProvider, defaultValue, nodeCache, config)); | ||
59 | } | ||
60 | } else { | ||
61 | for (int i = 0; i < amount; i++) { | ||
62 | result.add(new VersionedMapStoreStateImpl<>(hashProvider, defaultValue, config)); | ||
63 | } | ||
64 | } | ||
65 | return result; | ||
66 | } | ||
67 | |||
68 | private static <K,V> Map<K,V> createNoteCache(VersionedMapStoreStateConfiguration config) { | ||
69 | if(config.isVersionFreeingEnabled()) { | ||
70 | return new WeakHashMap<>(); | ||
71 | } else { | ||
72 | return new HashMap<>(); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public static <K, V> List<VersionedMapStore<K, V>> createSharedVersionedMapStores(int amount, | ||
77 | ContinuousHashProvider<K> hashProvider, V defaultValue) { | ||
78 | return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreStateConfiguration()); | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public VersionedMap<K, V> createMap() { | ||
83 | return new VersionedMapStateImpl<>(this, hashProvider, defaultValue); | ||
84 | } | ||
85 | |||
86 | @Override | ||
87 | public VersionedMap<K, V> createMap(Version state) { | ||
88 | ImmutableNode<K, V> data = revert(state); | ||
89 | return new VersionedMapStateImpl<>(this, hashProvider, defaultValue, data); | ||
90 | } | ||
91 | |||
92 | @SuppressWarnings("unchecked") | ||
93 | public synchronized ImmutableNode<K, V> revert(Version state) { | ||
94 | return (ImmutableNode<K, V>) state; | ||
95 | } | ||
96 | |||
97 | public synchronized Version commit(Node<K, V> data, VersionedMapStateImpl<K, V> mapToUpdateRoot) { | ||
98 | ImmutableNode<K, V> immutable; | ||
99 | if (data != null) { | ||
100 | immutable = data.toImmutable(this.nodeCache); | ||
101 | } else { | ||
102 | immutable = null; | ||
103 | } | ||
104 | |||
105 | if (this.immutableWhenCommitting) { | ||
106 | mapToUpdateRoot.setRoot(immutable); | ||
107 | } | ||
108 | return immutable; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public DiffCursor<K, V> getDiffCursor(Version fromState, Version toState) { | ||
113 | VersionedMapStateImpl<K, V> map1 = (VersionedMapStateImpl<K, V>) createMap(fromState); | ||
114 | VersionedMapStateImpl<K, V> map2 = (VersionedMapStateImpl<K, V>) createMap(toState); | ||
115 | InOrderMapCursor<K, V> cursor1 = new InOrderMapCursor<>(map1); | ||
116 | InOrderMapCursor<K, V> cursor2 = new InOrderMapCursor<>(map2); | ||
117 | return new MapDiffCursor<>(this.defaultValue, cursor1, cursor2); | ||
118 | } | ||
119 | } | ||