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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package org.eclipse.viatra.solver.data.map;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.viatra.solver.data.map.internal.ImmutableNode;
import org.eclipse.viatra.solver.data.map.internal.MapDiffCursor;
import org.eclipse.viatra.solver.data.map.internal.Node;
import org.eclipse.viatra.solver.data.map.internal.VersionedMapImpl;
public class VersionedMapStoreImpl<KEY,VALUE> implements VersionedMapStore<KEY, VALUE> {
// Configuration
final private boolean immutableWhenCommiting;
// Static data
protected final ContinousHashProvider<? super KEY> hashProvider;
protected final VALUE defaultValue;
// Dynamic data
final protected Map<Long, ImmutableNode<KEY,VALUE>> states;
final protected Map<Node<KEY,VALUE>, ImmutableNode<KEY,VALUE>> nodeCache;
protected long nextID;
public VersionedMapStoreImpl(ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, VersionedMapStoreConfiguration config) {
this.immutableWhenCommiting = config.immutableWhenCommiting;
this.hashProvider = hashProvider;
this.defaultValue = defaultValue;
states = new HashMap<>();
nextID = 0;
if(config.sharedNodeCache) {
nodeCache = new HashMap<>();
} else {
nodeCache = null;
}
}
public VersionedMapStoreImpl(ContinousHashProvider<KEY> hashProvider, VALUE defaultValue) {
this(hashProvider,defaultValue,new VersionedMapStoreConfiguration());
}
synchronized Set<Long> getStates() {
return states.keySet();
}
@Override
public VersionedMap<KEY,VALUE> createMap() {
return new VersionedMapImpl<KEY,VALUE>(this,hashProvider,defaultValue);
}
@Override
public VersionedMap<KEY,VALUE> createMap(long state) {
ImmutableNode<KEY, VALUE> data = revert(state);
return new VersionedMapImpl<KEY,VALUE>(this,hashProvider,defaultValue,data);
}
synchronized public ImmutableNode<KEY,VALUE> revert(long state) {
if(states.containsKey(state)) {
return states.get(state);
} else {
ArrayList<Long> existingKeys = new ArrayList<Long>(states.keySet());
Collections.sort(existingKeys);
throw new IllegalArgumentException(
"Store does not contain state "+state+"! Avaliable states: "+existingKeys.toArray().toString());
}
}
synchronized public long commit(Node<KEY,VALUE> data, VersionedMapImpl<KEY, VALUE> mapToUpdateRoot) {
ImmutableNode<KEY,VALUE> immutable;
if(data != null) {
if(this.nodeCache != null) {
immutable = data.toImmutable(this.nodeCache);
} else {
immutable = data.toImmutable();
}
} else {
immutable = null;
}
if(nextID == Long.MAX_VALUE) throw new IllegalStateException(
"Map store run out of Id-s");
long id = nextID++;
this.states.put(id, immutable);
if(this.immutableWhenCommiting) {
mapToUpdateRoot.setRoot(immutable);
}
return id;
}
// public Map<Node<KEY,VALUE>, ImmutableNode<KEY,VALUE>> getStore() {
// return this.nodeCache;
// }
// public long addState(ImmutableNode<KEY,VALUE> data) {
//
// states.put(id,data);
// return id;
// }
@Override
public DiffCursor<KEY, VALUE> getDiffCursor(long fromState, long toState) {
VersionedMap<KEY, VALUE> map1 = createMap(fromState);
VersionedMap<KEY, VALUE> map2 = createMap(toState);
Cursor<KEY, VALUE> cursor1 = map1.getCursor();
Cursor<KEY, VALUE> cursor2 = map2.getCursor();
return new MapDiffCursor<KEY, VALUE>(this.hashProvider,this.defaultValue,cursor1,cursor2);
}
}
|