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