aboutsummaryrefslogtreecommitdiffstats
path: root/model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-07-29 19:01:25 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-07-29 19:01:25 +0200
commit7f6a2528bf83f93e3d35eff228f7180e0181f4eb (patch)
tree068dc3454cc9f968162e5ae03cc8733f9011de72 /model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java
parentRefactoring based on Sonar reports (diff)
downloadrefinery-7f6a2528bf83f93e3d35eff228f7180e0181f4eb.tar.gz
refinery-7f6a2528bf83f93e3d35eff228f7180e0181f4eb.tar.zst
refinery-7f6a2528bf83f93e3d35eff228f7180e0181f4eb.zip
Add new data structure for backend
Co-authored-by: Oszkár Semeráth <semerath@mit.bme.hu>
Diffstat (limited to 'model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java')
-rw-r--r--model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java131
1 files changed, 131 insertions, 0 deletions
diff --git a/model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java b/model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java
new file mode 100644
index 00000000..6c177611
--- /dev/null
+++ b/model-data/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapCursor.java
@@ -0,0 +1,131 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import java.util.ArrayDeque;
4import java.util.ConcurrentModificationException;
5import java.util.Iterator;
6import java.util.List;
7
8import org.eclipse.viatra.solver.data.map.Cursor;
9import org.eclipse.viatra.solver.data.map.VersionedMap;
10
11public class MapCursor<KEY,VALUE> implements Cursor<KEY,VALUE> {
12 // Constants
13 static int IndexStart = -1;
14 static int IndexFinish = -2;
15
16 // Tree stack
17 ArrayDeque<Node<KEY,VALUE>> nodeStack;
18 ArrayDeque<Integer> nodeIndexStack;
19 int dataIndex;
20
21 // Values
22 KEY key;
23 VALUE value;
24
25 // Hash code for checking concurrent modifications
26 final VersionedMap<KEY,VALUE> map;
27 final int creationHash;
28
29 public MapCursor(Node<KEY, VALUE> root, VersionedMap<KEY,VALUE> map) {
30 // Initializing tree stack
31 super();
32 this.nodeStack = new ArrayDeque<>();
33 this.nodeIndexStack = new ArrayDeque<>();
34 if(root != null) {
35 this.nodeStack.add(root);
36 this.nodeIndexStack.push(IndexStart);
37 }
38
39 this.dataIndex = IndexStart;
40
41 // Initializing cache
42 this.key = null;
43 this.value = null;
44
45 // Initializing state
46 this.map=map;
47 this.creationHash = map.hashCode();
48 }
49
50 public KEY getKey() {
51 return key;
52 }
53
54 public VALUE getValue() {
55 return value;
56 }
57
58 public boolean isTerminated() {
59 return this.nodeStack.isEmpty();
60 }
61
62 public boolean move() {
63 if(isDirty()) {
64 throw new ConcurrentModificationException();
65 }
66 if(!isTerminated()) {
67 boolean result = this.nodeStack.peek().moveToNext(this);
68 if(this.nodeIndexStack.size() != this.nodeStack.size()) {
69 throw new IllegalArgumentException("Node stack is corrupted by illegal moves!");
70 }
71 return result;
72 }
73 return false;
74 }
75 public boolean skipCurrentNode() {
76 nodeStack.pop();
77 nodeIndexStack.pop();
78 dataIndex = IndexFinish;
79 return move();
80 }
81 @Override
82 public boolean isDirty() {
83 return this.map.hashCode() != this.creationHash;
84 }
85 @Override
86 public List<VersionedMap<KEY, VALUE>> getDependingMaps() {
87 return List.of(this.map);
88 }
89
90 public static <KEY,VALUE> boolean sameSubnode(MapCursor<KEY,VALUE> cursor1, MapCursor<KEY,VALUE> cursor2) {
91 Node<KEY, VALUE> nodeOfCursor1 = cursor1.nodeStack.peek();
92 Node<KEY, VALUE> nodeOfCursor2 = cursor2.nodeStack.peek();
93 if(nodeOfCursor1 != null && nodeOfCursor2 != null) {
94 return nodeOfCursor1.equals(nodeOfCursor2);
95 } else {
96 return false;
97 }
98 }
99
100 /**
101 *
102 * @param <KEY>
103 * @param <VALUE>
104 * @param cursor1
105 * @param cursor2
106 * @returnv Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position.
107 */
108 public static <KEY,VALUE> int compare(MapCursor<KEY,VALUE> cursor1, MapCursor<KEY,VALUE> cursor2) {
109 // two cursors are equally deep
110 Iterator<Integer> stack1 = cursor1.nodeIndexStack.descendingIterator();
111 Iterator<Integer> stack2 = cursor2.nodeIndexStack.descendingIterator();
112 if(stack1.hasNext()) {
113 if(!stack2.hasNext()) {
114 // stack 2 has no more element, thus stack 1 is deeper
115 return 1;
116 }
117 int val1 = stack1.next();
118 int val2 = stack2.next();
119 if(val1 < val2) {
120 return -1;
121 } else if(val2 < val1) {
122 return 1;
123 }
124 }
125 if(stack2.hasNext()) {
126 // stack 2 has more element, thus stack 2 is deeper
127 return 1;
128 }
129 return Integer.compare(cursor1.dataIndex, cursor2.dataIndex);
130 }
131}