aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/main
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-02 17:20:35 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-02 17:20:35 +0100
commitf062947f68e79dc866fc0d8d1f9b8874fd00b51e (patch)
tree9719e020fd3a9c0fa5a3fe7877937a81dad45b35 /subprojects/store/src/main
parentfeat: track ModelQuery pending changes (diff)
downloadrefinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.gz
refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.zst
refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.zip
feat: track uncommitted Model changes
Diffstat (limited to 'subprojects/store/src/main')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/Model.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java33
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelStoreImpl.java11
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/VersionedInterpretation.java2
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;
9import java.util.Optional; 9import java.util.Optional;
10 10
11public interface Model extends Versioned { 11public 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;
12public interface ModelStore { 12public 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;
6import tools.refinery.store.adapter.ModelStoreAdapter; 6import tools.refinery.store.adapter.ModelStoreAdapter;
7import tools.refinery.store.map.DiffCursor; 7import tools.refinery.store.map.DiffCursor;
8import tools.refinery.store.map.VersionedMapStore; 8import tools.refinery.store.map.VersionedMapStore;
9import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelDiffCursor; 10import tools.refinery.store.model.ModelDiffCursor;
10import tools.refinery.store.model.ModelStore; 11import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.representation.AnySymbol; 12import 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<>();