diff options
author | 2023-02-02 17:20:35 +0100 | |
---|---|---|
committer | 2023-02-02 17:20:35 +0100 | |
commit | f062947f68e79dc866fc0d8d1f9b8874fd00b51e (patch) | |
tree | 9719e020fd3a9c0fa5a3fe7877937a81dad45b35 /subprojects/store/src/main | |
parent | feat: track ModelQuery pending changes (diff) | |
download | refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.gz refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.zst refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.zip |
feat: track uncommitted Model changes
Diffstat (limited to 'subprojects/store/src/main')
5 files changed, 41 insertions, 13 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java index 8d2a4614..6ca1ac7b 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java | |||
@@ -9,10 +9,14 @@ import tools.refinery.store.representation.Symbol; | |||
9 | import java.util.Optional; | 9 | import java.util.Optional; |
10 | 10 | ||
11 | public interface Model extends Versioned { | 11 | public interface Model extends Versioned { |
12 | long NO_STATE_ID = -1; | ||
13 | |||
12 | ModelStore getStore(); | 14 | ModelStore getStore(); |
13 | 15 | ||
14 | long getState(); | 16 | long getState(); |
15 | 17 | ||
18 | boolean hasUncommittedChanges(); | ||
19 | |||
16 | default AnyInterpretation getInterpretation(AnySymbol symbol) { | 20 | default AnyInterpretation getInterpretation(AnySymbol symbol) { |
17 | return getInterpretation((Symbol<?>) symbol); | 21 | return getInterpretation((Symbol<?>) symbol); |
18 | } | 22 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java index bc863d4b..2e7e62c3 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java | |||
@@ -12,9 +12,9 @@ import java.util.Set; | |||
12 | public interface ModelStore { | 12 | public interface ModelStore { |
13 | Collection<AnySymbol> getSymbols(); | 13 | Collection<AnySymbol> getSymbols(); |
14 | 14 | ||
15 | Model createModel(); | 15 | Model createEmptyModel(); |
16 | 16 | ||
17 | Model createModel(long state); | 17 | Model createModelForState(long state); |
18 | 18 | ||
19 | Set<Long> getStates(); | 19 | Set<Long> getStates(); |
20 | 20 | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java index 10331e28..9eb438c4 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java | |||
@@ -18,8 +18,9 @@ public class ModelImpl implements Model { | |||
18 | private Map<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations; | 18 | private Map<? extends AnySymbol, ? extends VersionedInterpretation<?>> interpretations; |
19 | private final AdapterList<ModelAdapter> adapters; | 19 | private final AdapterList<ModelAdapter> adapters; |
20 | private final List<ModelListener> listeners = new ArrayList<>(); | 20 | private final List<ModelListener> listeners = new ArrayList<>(); |
21 | private boolean uncommittedChanges; | ||
21 | private ModelAction pendingAction = ModelAction.NONE; | 22 | private ModelAction pendingAction = ModelAction.NONE; |
22 | private long restoringToState = -1; | 23 | private long restoringToState = NO_STATE_ID; |
23 | 24 | ||
24 | ModelImpl(ModelStore store, long state, int adapterCount) { | 25 | ModelImpl(ModelStore store, long state, int adapterCount) { |
25 | this.store = store; | 26 | this.store = store; |
@@ -61,9 +62,29 @@ public class ModelImpl implements Model { | |||
61 | return new ModelDiffCursor(diffCursors); | 62 | return new ModelDiffCursor(diffCursors); |
62 | } | 63 | } |
63 | 64 | ||
65 | private void setState(long state) { | ||
66 | this.state = state; | ||
67 | uncommittedChanges = false; | ||
68 | } | ||
69 | |||
70 | void markAsChanged() { | ||
71 | if (!uncommittedChanges) { | ||
72 | uncommittedChanges = true; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | @Override | ||
77 | public boolean hasUncommittedChanges() { | ||
78 | return uncommittedChanges; | ||
79 | } | ||
80 | |||
81 | private boolean hasPendingAction() { | ||
82 | return pendingAction != ModelAction.NONE || restoringToState != NO_STATE_ID; | ||
83 | } | ||
84 | |||
64 | @Override | 85 | @Override |
65 | public long commit() { | 86 | public long commit() { |
66 | if (pendingAction != ModelAction.NONE) { | 87 | if (hasPendingAction()) { |
67 | throw pendingActionError("commit"); | 88 | throw pendingActionError("commit"); |
68 | } | 89 | } |
69 | pendingAction = ModelAction.COMMIT; | 90 | pendingAction = ModelAction.COMMIT; |
@@ -88,7 +109,7 @@ public class ModelImpl implements Model { | |||
88 | versionSet = true; | 109 | versionSet = true; |
89 | } | 110 | } |
90 | } | 111 | } |
91 | state = version; | 112 | setState(version); |
92 | while (i < listenerCount) { | 113 | while (i < listenerCount) { |
93 | listeners.get(i).afterCommit(); | 114 | listeners.get(i).afterCommit(); |
94 | i++; | 115 | i++; |
@@ -101,7 +122,7 @@ public class ModelImpl implements Model { | |||
101 | 122 | ||
102 | @Override | 123 | @Override |
103 | public void restore(long version) { | 124 | public void restore(long version) { |
104 | if (pendingAction != ModelAction.NONE) { | 125 | if (hasPendingAction()) { |
105 | throw pendingActionError("restore to %d".formatted(version)); | 126 | throw pendingActionError("restore to %d".formatted(version)); |
106 | } | 127 | } |
107 | if (!store.getStates().contains(version)) { | 128 | if (!store.getStates().contains(version)) { |
@@ -119,14 +140,14 @@ public class ModelImpl implements Model { | |||
119 | for (var interpretation : interpretations.values()) { | 140 | for (var interpretation : interpretations.values()) { |
120 | interpretation.restore(version); | 141 | interpretation.restore(version); |
121 | } | 142 | } |
122 | state = version; | 143 | setState(version); |
123 | while (i < listenerCount) { | 144 | while (i < listenerCount) { |
124 | listeners.get(i).afterRestore(); | 145 | listeners.get(i).afterRestore(); |
125 | i++; | 146 | i++; |
126 | } | 147 | } |
127 | } finally { | 148 | } finally { |
128 | pendingAction = ModelAction.NONE; | 149 | pendingAction = ModelAction.NONE; |
129 | restoringToState = -1; | 150 | restoringToState = NO_STATE_ID; |
130 | } | 151 | } |
131 | } | 152 | } |
132 | 153 | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java index 8aab57af..e8c205e4 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java | |||
@@ -6,6 +6,7 @@ import tools.refinery.store.adapter.ModelAdapterType; | |||
6 | import tools.refinery.store.adapter.ModelStoreAdapter; | 6 | import tools.refinery.store.adapter.ModelStoreAdapter; |
7 | import tools.refinery.store.map.DiffCursor; | 7 | import tools.refinery.store.map.DiffCursor; |
8 | import tools.refinery.store.map.VersionedMapStore; | 8 | import tools.refinery.store.map.VersionedMapStore; |
9 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.model.ModelDiffCursor; | 10 | import tools.refinery.store.model.ModelDiffCursor; |
10 | import tools.refinery.store.model.ModelStore; | 11 | import tools.refinery.store.model.ModelStore; |
11 | import tools.refinery.store.representation.AnySymbol; | 12 | import tools.refinery.store.representation.AnySymbol; |
@@ -27,13 +28,13 @@ public class ModelStoreImpl implements ModelStore { | |||
27 | return Collections.unmodifiableCollection(stores.keySet()); | 28 | return Collections.unmodifiableCollection(stores.keySet()); |
28 | } | 29 | } |
29 | 30 | ||
30 | private ModelImpl createEmptyModel(long state) { | 31 | private ModelImpl createModelWithoutInterpretations(long state) { |
31 | return new ModelImpl(this, state, adapters.size()); | 32 | return new ModelImpl(this, state, adapters.size()); |
32 | } | 33 | } |
33 | 34 | ||
34 | @Override | 35 | @Override |
35 | public ModelImpl createModel() { | 36 | public ModelImpl createEmptyModel() { |
36 | var model = createEmptyModel(-1); | 37 | var model = createModelWithoutInterpretations(Model.NO_STATE_ID); |
37 | var interpretations = new HashMap<AnySymbol, VersionedInterpretation<?>>(stores.size()); | 38 | var interpretations = new HashMap<AnySymbol, VersionedInterpretation<?>>(stores.size()); |
38 | for (var entry : this.stores.entrySet()) { | 39 | for (var entry : this.stores.entrySet()) { |
39 | var symbol = entry.getKey(); | 40 | var symbol = entry.getKey(); |
@@ -45,8 +46,8 @@ public class ModelStoreImpl implements ModelStore { | |||
45 | } | 46 | } |
46 | 47 | ||
47 | @Override | 48 | @Override |
48 | public synchronized ModelImpl createModel(long state) { | 49 | public synchronized ModelImpl createModelForState(long state) { |
49 | var model = createEmptyModel(state); | 50 | var model = createModelWithoutInterpretations(state); |
50 | var interpretations = new HashMap<AnySymbol, VersionedInterpretation<?>>(stores.size()); | 51 | var interpretations = new HashMap<AnySymbol, VersionedInterpretation<?>>(stores.size()); |
51 | for (var entry : this.stores.entrySet()) { | 52 | for (var entry : this.stores.entrySet()) { |
52 | var symbol = entry.getKey(); | 53 | var symbol = entry.getKey(); |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java index 1bdb1cdf..6d82f5d7 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java +++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java | |||
@@ -77,6 +77,7 @@ public class VersionedInterpretation<T> implements Interpretation<T> { | |||
77 | @Override | 77 | @Override |
78 | public T put(Tuple key, T value) { | 78 | public T put(Tuple key, T value) { |
79 | checkKey(key); | 79 | checkKey(key); |
80 | model.markAsChanged(); | ||
80 | var oldValue = map.put(key, value); | 81 | var oldValue = map.put(key, value); |
81 | notifyListeners(key, oldValue, value, false); | 82 | notifyListeners(key, oldValue, value, false); |
82 | return oldValue; | 83 | return oldValue; |
@@ -88,6 +89,7 @@ public class VersionedInterpretation<T> implements Interpretation<T> { | |||
88 | map.putAll(cursor); | 89 | map.putAll(cursor); |
89 | return; | 90 | return; |
90 | } | 91 | } |
92 | model.markAsChanged(); | ||
91 | if (cursor.getDependingMaps().contains(map)) { | 93 | if (cursor.getDependingMaps().contains(map)) { |
92 | List<Tuple> keys = new ArrayList<>(); | 94 | List<Tuple> keys = new ArrayList<>(); |
93 | List<T> values = new ArrayList<>(); | 95 | List<T> values = new ArrayList<>(); |