diff options
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.java | 104 |
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 | */ | ||
6 | package tools.refinery.store.dse.transition.statespace.internal; | ||
7 | |||
8 | import org.eclipse.collections.api.factory.primitive.IntLists; | ||
9 | import org.eclipse.collections.api.list.primitive.MutableIntList; | ||
10 | |||
11 | public 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 | } | ||