aboutsummaryrefslogtreecommitdiffstats
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
parentfeat: track ModelQuery pending changes (diff)
downloadrefinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.gz
refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.tar.zst
refinery-f062947f68e79dc866fc0d8d1f9b8874fd00b51e.zip
feat: track uncommitted Model changes
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java28
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java2
-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
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java31
8 files changed, 82 insertions, 33 deletions
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
index ba0abca0..6a37b54a 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
@@ -38,7 +38,7 @@ class QueryTest {
38 .queries(predicate) 38 .queries(predicate)
39 .build(); 39 .build();
40 40
41 var model = store.createModel(); 41 var model = store.createEmptyModel();
42 var personInterpretation = model.getInterpretation(person); 42 var personInterpretation = model.getInterpretation(person);
43 var assetInterpretation = model.getInterpretation(asset); 43 var assetInterpretation = model.getInterpretation(asset);
44 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 44 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -79,7 +79,7 @@ class QueryTest {
79 .queries(predicate) 79 .queries(predicate)
80 .build(); 80 .build();
81 81
82 var model = store.createModel(); 82 var model = store.createEmptyModel();
83 var personInterpretation = model.getInterpretation(person); 83 var personInterpretation = model.getInterpretation(person);
84 var friendInterpretation = model.getInterpretation(friend); 84 var friendInterpretation = model.getInterpretation(friend);
85 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 85 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -127,7 +127,7 @@ class QueryTest {
127 .queries(predicate) 127 .queries(predicate)
128 .build(); 128 .build();
129 129
130 var model = store.createModel(); 130 var model = store.createEmptyModel();
131 var personInterpretation = model.getInterpretation(person); 131 var personInterpretation = model.getInterpretation(person);
132 var friendInterpretation = model.getInterpretation(friend); 132 var friendInterpretation = model.getInterpretation(friend);
133 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 133 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -181,7 +181,7 @@ class QueryTest {
181 .queries(predicate) 181 .queries(predicate)
182 .build(); 182 .build();
183 183
184 var model = store.createModel(); 184 var model = store.createEmptyModel();
185 var personInterpretation = model.getInterpretation(person); 185 var personInterpretation = model.getInterpretation(person);
186 var friendInterpretation = model.getInterpretation(friend); 186 var friendInterpretation = model.getInterpretation(friend);
187 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 187 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -233,7 +233,7 @@ class QueryTest {
233 .queries(predicate) 233 .queries(predicate)
234 .build(); 234 .build();
235 235
236 var model = store.createModel(); 236 var model = store.createEmptyModel();
237 var personInterpretation = model.getInterpretation(person); 237 var personInterpretation = model.getInterpretation(person);
238 var animalInterpretation = model.getInterpretation(animal); 238 var animalInterpretation = model.getInterpretation(animal);
239 var friendInterpretation = model.getInterpretation(friend); 239 var friendInterpretation = model.getInterpretation(friend);
@@ -278,7 +278,7 @@ class QueryTest {
278 .queries(predicate) 278 .queries(predicate)
279 .build(); 279 .build();
280 280
281 var model = store.createModel(); 281 var model = store.createEmptyModel();
282 var personInterpretation = model.getInterpretation(person); 282 var personInterpretation = model.getInterpretation(person);
283 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 283 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
284 var predicateResultSet = queryEngine.getResultSet(predicate); 284 var predicateResultSet = queryEngine.getResultSet(predicate);
@@ -319,7 +319,7 @@ class QueryTest {
319 .queries(predicate) 319 .queries(predicate)
320 .build(); 320 .build();
321 321
322 var model = store.createModel(); 322 var model = store.createEmptyModel();
323 var personInterpretation = model.getInterpretation(person); 323 var personInterpretation = model.getInterpretation(person);
324 var friendInterpretation = model.getInterpretation(friend); 324 var friendInterpretation = model.getInterpretation(friend);
325 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 325 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -372,7 +372,7 @@ class QueryTest {
372 .queries(predicate) 372 .queries(predicate)
373 .build(); 373 .build();
374 374
375 var model = store.createModel(); 375 var model = store.createEmptyModel();
376 var personInterpretation = model.getInterpretation(person); 376 var personInterpretation = model.getInterpretation(person);
377 var friendInterpretation = model.getInterpretation(friend); 377 var friendInterpretation = model.getInterpretation(friend);
378 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 378 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -414,7 +414,7 @@ class QueryTest {
414 .queries(predicate) 414 .queries(predicate)
415 .build(); 415 .build();
416 416
417 var model = store.createModel(); 417 var model = store.createEmptyModel();
418 var personInterpretation = model.getInterpretation(person); 418 var personInterpretation = model.getInterpretation(person);
419 var friendInterpretation = model.getInterpretation(friend); 419 var friendInterpretation = model.getInterpretation(friend);
420 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 420 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -467,7 +467,7 @@ class QueryTest {
467 .queries(predicate) 467 .queries(predicate)
468 .build(); 468 .build();
469 469
470 var model = store.createModel(); 470 var model = store.createEmptyModel();
471 var personInterpretation = model.getInterpretation(person); 471 var personInterpretation = model.getInterpretation(person);
472 var friendInterpretation = model.getInterpretation(friend); 472 var friendInterpretation = model.getInterpretation(friend);
473 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 473 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -509,7 +509,7 @@ class QueryTest {
509 .queries(predicate) 509 .queries(predicate)
510 .build(); 510 .build();
511 511
512 var model = store.createModel(); 512 var model = store.createEmptyModel();
513 var personInterpretation = model.getInterpretation(person); 513 var personInterpretation = model.getInterpretation(person);
514 var friendInterpretation = model.getInterpretation(friend); 514 var friendInterpretation = model.getInterpretation(friend);
515 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 515 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -559,7 +559,7 @@ class QueryTest {
559 .queries(predicate) 559 .queries(predicate)
560 .build(); 560 .build();
561 561
562 var model = store.createModel(); 562 var model = store.createEmptyModel();
563 var personInterpretation = model.getInterpretation(person); 563 var personInterpretation = model.getInterpretation(person);
564 var friendInterpretation = model.getInterpretation(friend); 564 var friendInterpretation = model.getInterpretation(friend);
565 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 565 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -600,7 +600,7 @@ class QueryTest {
600 .queries(predicate) 600 .queries(predicate)
601 .build(); 601 .build();
602 602
603 var model = store.createModel(); 603 var model = store.createEmptyModel();
604 var personInterpretation = model.getInterpretation(person); 604 var personInterpretation = model.getInterpretation(person);
605 var friendInterpretation = model.getInterpretation(friend); 605 var friendInterpretation = model.getInterpretation(friend);
606 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 606 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
@@ -652,7 +652,7 @@ class QueryTest {
652 .queries(predicate) 652 .queries(predicate)
653 .build(); 653 .build();
654 654
655 var model = store.createModel(); 655 var model = store.createEmptyModel();
656 var personInterpretation = model.getInterpretation(person); 656 var personInterpretation = model.getInterpretation(person);
657 var friendInterpretation = model.getInterpretation(friend); 657 var friendInterpretation = model.getInterpretation(friend);
658 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 658 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java
index ec2e7647..98995339 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java
@@ -31,7 +31,7 @@ class QueryTransactionTest {
31 .queries(predicate) 31 .queries(predicate)
32 .build(); 32 .build();
33 33
34 var model = store.createModel(); 34 var model = store.createEmptyModel();
35 var personInterpretation = model.getInterpretation(person); 35 var personInterpretation = model.getInterpretation(person);
36 var assetInterpretation = model.getInterpretation(asset); 36 var assetInterpretation = model.getInterpretation(asset);
37 var queryEngine = model.getAdapter(ModelQuery.ADAPTER); 37 var queryEngine = model.getAdapter(ModelQuery.ADAPTER);
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<>();
diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
index e7bff1f9..371b5e47 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
@@ -1,6 +1,7 @@
1package tools.refinery.store.model.tests; 1package tools.refinery.store.model.tests;
2 2
3import org.junit.jupiter.api.Test; 3import org.junit.jupiter.api.Test;
4import tools.refinery.store.model.Model;
4import tools.refinery.store.model.ModelStore; 5import tools.refinery.store.model.ModelStore;
5import tools.refinery.store.representation.Symbol; 6import tools.refinery.store.representation.Symbol;
6import tools.refinery.store.tuple.Tuple; 7import tools.refinery.store.tuple.Tuple;
@@ -30,7 +31,7 @@ class ModelTest {
30 var friend = new Symbol<>("friend", 2, Boolean.class, false); 31 var friend = new Symbol<>("friend", 2, Boolean.class, false);
31 32
32 var store = ModelStore.builder().symbols(person, age, friend).build(); 33 var store = ModelStore.builder().symbols(person, age, friend).build();
33 var model = store.createModel(); 34 var model = store.createEmptyModel();
34 var personInterpretation = model.getInterpretation(person); 35 var personInterpretation = model.getInterpretation(person);
35 var ageInterpretation = model.getInterpretation(age); 36 var ageInterpretation = model.getInterpretation(age);
36 var friendInterpretation = model.getInterpretation(friend); 37 var friendInterpretation = model.getInterpretation(friend);
@@ -59,7 +60,7 @@ class ModelTest {
59 var person = new Symbol<>("Person", 1, Boolean.class, false); 60 var person = new Symbol<>("Person", 1, Boolean.class, false);
60 61
61 var store = ModelStore.builder().symbols(person).build(); 62 var store = ModelStore.builder().symbols(person).build();
62 var model = store.createModel(); 63 var model = store.createEmptyModel();
63 var personInterpretation = model.getInterpretation(person); 64 var personInterpretation = model.getInterpretation(person);
64 65
65 final Tuple tuple3 = Tuple.of(1, 1, 1); 66 final Tuple tuple3 = Tuple.of(1, 1, 1);
@@ -72,7 +73,7 @@ class ModelTest {
72 var age = new Symbol<>("age", 1, Integer.class, null); 73 var age = new Symbol<>("age", 1, Integer.class, null);
73 74
74 var store = ModelStore.builder().symbols(age).build(); 75 var store = ModelStore.builder().symbols(age).build();
75 var model = store.createModel(); 76 var model = store.createEmptyModel();
76 var ageInterpretation = model.getInterpretation(age); 77 var ageInterpretation = model.getInterpretation(age);
77 78
78 ageInterpretation.put(Tuple.of(1), null); // valid 79 ageInterpretation.put(Tuple.of(1), null); // valid
@@ -88,7 +89,7 @@ class ModelTest {
88 var friend = new Symbol<>("friend", 2, Boolean.class, false); 89 var friend = new Symbol<>("friend", 2, Boolean.class, false);
89 90
90 var store = ModelStore.builder().symbols(person, age, friend).build(); 91 var store = ModelStore.builder().symbols(person, age, friend).build();
91 var model = store.createModel(); 92 var model = store.createEmptyModel();
92 var personInterpretation = model.getInterpretation(person); 93 var personInterpretation = model.getInterpretation(person);
93 var ageInterpretation = model.getInterpretation(age); 94 var ageInterpretation = model.getInterpretation(age);
94 var friendInterpretation = model.getInterpretation(friend); 95 var friendInterpretation = model.getInterpretation(friend);
@@ -116,7 +117,7 @@ class ModelTest {
116 var friend = new Symbol<>("friend", 2, Boolean.class, false); 117 var friend = new Symbol<>("friend", 2, Boolean.class, false);
117 118
118 var store = ModelStore.builder().symbols(person, friend).build(); 119 var store = ModelStore.builder().symbols(person, friend).build();
119 var model = store.createModel(); 120 var model = store.createEmptyModel();
120 var personInterpretation = model.getInterpretation(person); 121 var personInterpretation = model.getInterpretation(person);
121 var friendInterpretation = model.getInterpretation(friend); 122 var friendInterpretation = model.getInterpretation(friend);
122 123
@@ -124,25 +125,45 @@ class ModelTest {
124 personInterpretation.put(Tuple.of(1), true); 125 personInterpretation.put(Tuple.of(1), true);
125 friendInterpretation.put(Tuple.of(0, 1), true); 126 friendInterpretation.put(Tuple.of(0, 1), true);
126 friendInterpretation.put(Tuple.of(1, 0), true); 127 friendInterpretation.put(Tuple.of(1, 0), true);
128
129 assertTrue(model.hasUncommittedChanges());
130 assertEquals(Model.NO_STATE_ID, model.getState());
131
127 long state1 = model.commit(); 132 long state1 = model.commit();
128 133
134 assertFalse(model.hasUncommittedChanges());
135 assertEquals(state1, model.getState());
136
129 assertFalse(personInterpretation.get(Tuple.of(2))); 137 assertFalse(personInterpretation.get(Tuple.of(2)));
130 assertFalse(friendInterpretation.get(Tuple.of(0, 2))); 138 assertFalse(friendInterpretation.get(Tuple.of(0, 2)));
131 139
132 personInterpretation.put(Tuple.of(2), true); 140 personInterpretation.put(Tuple.of(2), true);
133 friendInterpretation.put(Tuple.of(0, 2), true); 141 friendInterpretation.put(Tuple.of(0, 2), true);
142
143 assertTrue(model.hasUncommittedChanges());
144 assertEquals(state1, model.getState());
145
134 long state2 = model.commit(); 146 long state2 = model.commit();
135 147
148 assertFalse(model.hasUncommittedChanges());
149 assertEquals(state2, model.getState());
150
136 assertTrue(personInterpretation.get(Tuple.of(2))); 151 assertTrue(personInterpretation.get(Tuple.of(2)));
137 assertTrue(friendInterpretation.get(Tuple.of(0, 2))); 152 assertTrue(friendInterpretation.get(Tuple.of(0, 2)));
138 153
139 model.restore(state1); 154 model.restore(state1);
140 155
156 assertFalse(model.hasUncommittedChanges());
157 assertEquals(state1, model.getState());
158
141 assertFalse(personInterpretation.get(Tuple.of(2))); 159 assertFalse(personInterpretation.get(Tuple.of(2)));
142 assertFalse(friendInterpretation.get(Tuple.of(0, 2))); 160 assertFalse(friendInterpretation.get(Tuple.of(0, 2)));
143 161
144 model.restore(state2); 162 model.restore(state2);
145 163
164 assertFalse(model.hasUncommittedChanges());
165 assertEquals(state2, model.getState());
166
146 assertTrue(personInterpretation.get(Tuple.of(2))); 167 assertTrue(personInterpretation.get(Tuple.of(2)));
147 assertTrue(friendInterpretation.get(Tuple.of(0, 2))); 168 assertTrue(friendInterpretation.get(Tuple.of(0, 2)));
148 } 169 }