aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java')
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java104
1 files changed, 104 insertions, 0 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
new file mode 100644
index 00000000..14298bee
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
@@ -0,0 +1,104 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.statespace.internal;
7
8import org.eclipse.collections.api.factory.primitive.IntLists;
9import org.eclipse.collections.api.list.primitive.MutableIntList;
10
11public class ActivationStoreListEntry extends ActivationStoreEntry {
12 private final MutableIntList visitedActivations = IntLists.mutable.empty();
13
14 ActivationStoreListEntry(int numberOfActivations) {
15 super(numberOfActivations);
16 }
17
18 @Override
19 public int getNumberOfVisitedActivations() {
20 return visitedActivations.size();
21 }
22
23 @Override
24 public int getAndAddActivationAfter(int index) {
25 // If it is empty, just add it.
26 if(this.visitedActivations.isEmpty()) {
27 this.visitedActivations.add(index);
28 return index;
29 }
30 final int positionInSearch = getPosition(index);
31 int position = positionInSearch;
32
33 // if the position is after the last, we can insert it at the end of the list
34 if(position == this.visitedActivations.size()) {
35 this.visitedActivations.add(index);
36 return index;
37 } else if(this.visitedActivations.get(position) != index) {
38 // If the index is not in the position, one can insert it
39
40 this.visitedActivations.addAtIndex(position,index);
41 return index;
42 }
43
44 // Otherwise, get the next empty space between two elements
45 while(position + 1 < this.visitedActivations.size()) {
46 if(this.visitedActivations.get(position+1)-this.visitedActivations.get(position) > 1) {
47 int newElement = this.visitedActivations.get(position)+1;
48 this.visitedActivations.addAtIndex(position+1, newElement);
49 return newElement;
50 }
51 position++;
52 }
53
54 // Otherwise, try to add to the last space
55 int last = this.visitedActivations.get(this.visitedActivations.size()-1);
56 if(last<this.numberOfActivations-1) {
57 this.visitedActivations.add(last+1);
58 return last+1;
59 }
60
61 // Otherwise, try to put to the beginning
62 if(this.visitedActivations.get(0) > 0) {
63 this.visitedActivations.addAtIndex(0,0);
64 return 0;
65 }
66
67 // Otherwise, get the next empty space between two elements
68 position = 0;
69 while(position < positionInSearch) {
70 if(this.visitedActivations.get(position+1)-this.visitedActivations.get(position) > 1) {
71 int newElement = this.visitedActivations.get(position)+1;
72 this.visitedActivations.addAtIndex(position+1, newElement);
73 return newElement;
74 }
75 position++;
76 }
77
78 throw new IllegalArgumentException("There is are no unvisited activations!");
79 }
80
81 /**
82 * Returns the position of an index in the {@code visitedActivations}. If the collection contains the index, in
83 * returns its position, otherwise, it returns the position where the index need to be put.
84 *
85 * @param index Index of an activation.
86 * @return The position of the index.
87 */
88 private int getPosition(int index) {
89 int left = 0;
90 int right = this.visitedActivations.size() - 1;
91 while (left <= right) {
92 final int middle = (right - left) / 2 + left;
93 final int middleElement = visitedActivations.get(middle);
94 if(middleElement == index) {
95 return middle;
96 } else if(middleElement < index) {
97 left = middle +1;
98 } else{
99 right = middle-1;
100 }
101 }
102 return right+1;
103 }
104}