aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java
diff options
context:
space:
mode:
Diffstat (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java')
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java136
1 files changed, 96 insertions, 40 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java
index 5c911bb4..8d7cda14 100644
--- a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java
@@ -4,6 +4,7 @@ import java.util.List;
4import java.util.stream.Collectors; 4import java.util.stream.Collectors;
5import java.util.stream.Stream; 5import java.util.stream.Stream;
6 6
7import org.eclipse.viatra.solver.data.map.ContinousHashProvider;
7import org.eclipse.viatra.solver.data.map.Cursor; 8import org.eclipse.viatra.solver.data.map.Cursor;
8import org.eclipse.viatra.solver.data.map.DiffCursor; 9import org.eclipse.viatra.solver.data.map.DiffCursor;
9import org.eclipse.viatra.solver.data.map.VersionedMap; 10import org.eclipse.viatra.solver.data.map.VersionedMap;
@@ -17,43 +18,52 @@ public class MapDiffCursor<KEY,VALUE> implements DiffCursor<KEY, VALUE>, Cursor<
17 /** 18 /**
18 * Default value representing missing elements. 19 * Default value representing missing elements.
19 */ 20 */
20 VALUE defaultValue; 21 private VALUE defaultValue;
21 MapCursor<KEY,VALUE> cursor1; 22 private MapCursor<KEY,VALUE> cursor1;
22 MapCursor<KEY,VALUE> cursor2; 23 private MapCursor<KEY,VALUE> cursor2;
24 private ContinousHashProvider<? super KEY> hashProvider;
23 25
24 // Values 26 // Values
25 KEY key; 27 private KEY key;
26 VALUE value1; 28 private VALUE fromValue;
27 VALUE value2; 29 private VALUE toValue;
28 30
29 // State 31 // State
30 /** 32 /**
31 * Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position. 33 * Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position.
32 */ 34 */
33 int cursorRelation; 35 private int cursorRelation;
36 /**
37 * Denotes a state when two cursors are in the same position, but they contain different keys.
38 * Possible values:
39 * <ul>
40 * <li>0: not stuck</li>
41 * <li>1: hashClash, next it should return the key of cursor 1.</li>
42 * <li>2: hashClash, next it should return the key of cursor 2.</li>
43 * </ul>
44 */
45 private int hashClash=0;
34 46
35 public MapDiffCursor(VALUE defaultValue, Cursor<KEY, VALUE> cursor1, Cursor<KEY, VALUE> cursor2) { 47 public MapDiffCursor(ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, Cursor<KEY, VALUE> cursor1, Cursor<KEY, VALUE> cursor2) {
36 super(); 48 super();
49 this.hashProvider = hashProvider;
37 this.defaultValue = defaultValue; 50 this.defaultValue = defaultValue;
38 this.cursor1 = (MapCursor<KEY, VALUE>) cursor1; 51 this.cursor1 = (MapCursor<KEY, VALUE>) cursor1;
39 this.cursor2 = (MapCursor<KEY, VALUE>) cursor2; 52 this.cursor2 = (MapCursor<KEY, VALUE>) cursor2;
40
41 this.updateState();
42 this.moveToConsistentState();
43 } 53 }
44 54
45 public KEY getKey() { 55 public KEY getKey() {
46 return key; 56 return key;
47 } 57 }
48 public VALUE getValue1() { 58 public VALUE getFromValue() {
49 return value1; 59 return fromValue;
50 } 60 }
51 public VALUE getValue2() { 61 public VALUE getToValue() {
52 return value2; 62 return toValue;
53 } 63 }
54 @Override 64 @Override
55 public VALUE getValue() { 65 public VALUE getValue() {
56 return this.value2; 66 return getToValue();
57 } 67 }
58 public boolean isTerminated() { 68 public boolean isTerminated() {
59 return cursor1.isTerminated() && cursor2.isTerminated(); 69 return cursor1.isTerminated() && cursor2.isTerminated();
@@ -71,33 +81,72 @@ public class MapDiffCursor<KEY,VALUE> implements DiffCursor<KEY, VALUE>, Cursor<
71 } 81 }
72 82
73 protected void updateState() { 83 protected void updateState() {
74 this.cursorRelation = MapCursor.compare(cursor1, cursor2); 84 if(!isTerminated()) {
75 if(cursorRelation > 0 || cursor2.isTerminated()) { 85 this.cursorRelation = MapCursor.compare(cursor1, cursor2);
76 this.key = cursor1.getKey(); 86 if(cursorRelation > 0 || cursor2.isTerminated()) {
77 this.value1 = cursor1.getValue(); 87 this.key = cursor1.getKey();
78 this.value2 = defaultValue; 88 this.fromValue = cursor1.getValue();
79 } else if(cursorRelation < 0|| cursor1.isTerminated()){ 89 this.toValue = defaultValue;
80 this.key = cursor2.getKey(); 90 } else if(cursorRelation < 0 || cursor1.isTerminated()){
81 this.value1 = defaultValue; 91 this.key = cursor2.getKey();
82 this.value2 = cursor1.getValue(); 92 this.fromValue = defaultValue;
83 } else { 93 this.toValue = cursor1.getValue();
84 // cursor1 = cursor2 94 } else {
85 if(!cursor1.getKey().equals(cursor2.getKey())) { 95 // cursor1 = cursor2
86 throw new IllegalStateException( 96 if(cursor1.getKey().equals(cursor2.getKey())) {
87 "Cursor comarison tells that they are in the same state, but keys are different. " + cursor1.getKey() + " - " + cursor2.getKey()); 97 this.key = cursor1.getKey();
98 this.fromValue = cursor1.getValue();
99 this.toValue = defaultValue;
100 } else {
101 resolveHashClash1();
102 }
88 } 103 }
89 this.key = cursor1.getKey();
90 this.value1 = cursor1.getValue();
91 this.value2 = defaultValue;
92 } 104 }
93 } 105 }
106 protected void resolveHashClash1() {
107 int compareResult = this.hashProvider.compare(cursor1.key, cursor2.key);
108 if(compareResult<0) {
109 this.hashClash = 2;
110 this.cursorRelation = 0;
111 this.key = cursor1.key;
112 this.fromValue = cursor1.value;
113 this.toValue = defaultValue;
114 } else if(compareResult>0) {
115 this.hashClash = 1;
116 this.cursorRelation = 0;
117 this.key = cursor2.key;
118 this.fromValue = defaultValue;
119 this.toValue = cursor2.value;
120 } else {
121 throw new IllegalArgumentException("Inconsistent compare result for diffcursor");
122 }
123 }
124 protected boolean isInHashClash() {
125 return this.hashClash != 0;
126 }
127 protected void resolveHashClash2() {
128 if(hashClash == 1) {
129 this.hashClash = 0;
130 this.cursorRelation = 0;
131 this.key = cursor1.key;
132 this.fromValue = cursor1.value;
133 this.toValue = defaultValue;
134 } else if(hashClash == 2) {
135 this.hashClash = 0;
136 this.cursorRelation = 0;
137 this.key = cursor2.key;
138 this.fromValue = defaultValue;
139 this.toValue = cursor2.value;
140 } else throw new IllegalArgumentException("Inconsistent compare result for diffcursor");
141 }
142
94 143
95 protected boolean differentValues() { 144 protected boolean sameValues() {
96 return this.value1 != this.value2; 145 return this.fromValue == this.toValue;
97 } 146 }
98 protected boolean moveOne() { 147 protected boolean moveOne() {
99 if(isTerminated()) { 148 if(isTerminated()) {
100 throw new IllegalStateException("DiffCursor tries to move when terminated!"); 149 return false;
101 } 150 }
102 if(this.cursorRelation > 0 || cursor2.isTerminated()) { 151 if(this.cursorRelation > 0 || cursor2.isTerminated()) {
103 return cursor1.move(); 152 return cursor1.move();
@@ -129,10 +178,11 @@ public class MapDiffCursor<KEY,VALUE> implements DiffCursor<KEY, VALUE>, Cursor<
129 lastResult = skipNode(); 178 lastResult = skipNode();
130 changed = true; 179 changed = true;
131 } 180 }
132 if(differentValues()) { 181 if(sameValues()) {
133 lastResult = moveOne(); 182 lastResult = moveOne();
134 changed = true; 183 changed = true;
135 } 184 }
185 updateState();
136 } while(changed && !isTerminated()); 186 } while(changed && !isTerminated());
137 return lastResult; 187 return lastResult;
138 } else { 188 } else {
@@ -142,11 +192,17 @@ public class MapDiffCursor<KEY,VALUE> implements DiffCursor<KEY, VALUE>, Cursor<
142 192
143 public boolean move() { 193 public boolean move() {
144 if(!isTerminated()) { 194 if(!isTerminated()) {
145 if(moveOne()) { 195 if(isInHashClash()) {
146 return moveToConsistentState(); 196 this.resolveHashClash2();
197 return true;
147 } else { 198 } else {
148 return false; 199 if(moveOne()) {
200 return moveToConsistentState();
201 } else {
202 return false;
203 }
149 } 204 }
205
150 } else return false; 206 } else return false;
151 } 207 }
152} 208}