aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java')
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java131
1 files changed, 131 insertions, 0 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
new file mode 100644
index 00000000..1229ec15
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
@@ -0,0 +1,131 @@
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.block.procedure.Procedure;
9import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
10import tools.refinery.store.dse.transition.statespace.ActivationStore;
11
12import java.util.*;
13
14public class ActivationStoreImpl implements ActivationStore {
15 final int numberOfTransformations;
16 final Procedure<VersionWithObjectiveValue> actionWhenAllActivationVisited;
17 final Map<VersionWithObjectiveValue, List<ActivationStoreEntry>> versionToActivations;
18
19 public ActivationStoreImpl(final int numberOfTransformations,
20 Procedure<VersionWithObjectiveValue> actionWhenAllActivationVisited) {
21 this.numberOfTransformations = numberOfTransformations;
22 this.actionWhenAllActivationVisited = actionWhenAllActivationVisited;
23 versionToActivations = new HashMap<>();
24 }
25
26 public synchronized VisitResult markNewAsVisited(VersionWithObjectiveValue to, int[] emptyEntrySizes) {
27 boolean[] successful = new boolean[]{false};
28 var entries = versionToActivations.computeIfAbsent(to, x -> {
29 successful[0] = true;
30 List<ActivationStoreEntry> result = new ArrayList<>(emptyEntrySizes.length);
31 for(int emptyEntrySize : emptyEntrySizes) {
32 result.add(ActivationStoreListEntry.create(emptyEntrySize));
33 }
34 return result;
35 });
36 boolean hasMore = false;
37 for (var entry : entries) {
38 if (entry.getNumberOfUnvisitedActivations() > 0) {
39 hasMore = true;
40 break;
41 }
42 }
43 if(!hasMore) {
44 actionWhenAllActivationVisited.accept(to);
45 }
46 return new VisitResult(successful[0], hasMore, -1, -1);
47 }
48
49 public synchronized VisitResult visitActivation(VersionWithObjectiveValue from, int transformationIndex, int activationIndex) {
50 var entries = versionToActivations.get(from);
51 var entry = entries.get(transformationIndex);
52 final int unvisited = entry.getNumberOfUnvisitedActivations();
53
54 final boolean successfulVisit = unvisited > 0;
55 final boolean hasMoreInActivation = unvisited > 1;
56 final boolean hasMore;
57 final int transformation;
58 final int activation;
59
60 if (successfulVisit) {
61 transformation = transformationIndex;
62 activation = entry.getAndAddActivationAfter(activationIndex);
63
64 } else {
65 transformation = -1;
66 activation = -1;
67 }
68
69 if(hasMoreInActivation) {
70 boolean hasMoreInOtherTransformation = false;
71 for (var e : entries) {
72 if (e != entry && e.getNumberOfVisitedActivations() > 0) {
73 hasMoreInOtherTransformation = true;
74 break;
75 }
76 }
77 hasMore = hasMoreInOtherTransformation;
78 } else {
79 hasMore = true;
80 }
81
82 if(!hasMore) {
83 actionWhenAllActivationVisited.accept(from);
84 }
85
86 return new VisitResult(false, hasMore, transformation, activation);
87 }
88
89 @Override
90 public synchronized boolean hasUnmarkedActivation(VersionWithObjectiveValue version) {
91 var entries = versionToActivations.get(version);
92 boolean hasMore = false;
93 for (var entry : entries) {
94 if (entry.getNumberOfUnvisitedActivations() > 0) {
95 hasMore = true;
96 break;
97 }
98 }
99 return hasMore;
100 }
101
102 @Override
103 public synchronized VisitResult getRandomAndMarkAsVisited(VersionWithObjectiveValue version, Random random) {
104 var entries = versionToActivations.get(version);
105
106 int sum1 = 0;
107 for (var entry : entries) {
108 sum1 += entry.getNumberOfUnvisitedActivations();
109 }
110
111 int selected = random.nextInt(sum1);
112 int sum2 = 0;
113 int transformation = 0;
114 int activation = -1;
115 for (; transformation < entries.size(); transformation++) {
116 var entry = entries.get(transformation);
117 int unvisited = entry.getNumberOfUnvisitedActivations();
118 if (selected < sum2 + unvisited) {
119 activation = sum2 + unvisited - selected;
120 break;
121 } else {
122 sum2 += unvisited;
123 }
124 }
125 if (activation == -1) {
126 throw new IllegalArgumentException("no unvisited");
127 }
128
129 return this.visitActivation(version, transformation, activation);
130 }
131}