|
1 | 1 | package ai.timefold.solver.core.impl.domain.variable.declarative; |
2 | 2 |
|
3 | | -import java.util.BitSet; |
| 3 | +import ai.timefold.solver.core.impl.util.DynamicIntArray; |
4 | 4 |
|
5 | 5 | import org.jspecify.annotations.NullMarked; |
6 | 6 |
|
7 | 7 | @NullMarked |
8 | 8 | public final class LoopedTracker { |
9 | 9 |
|
10 | | - // Simple LoopedStatus[] array would have occupied too much memory with large node counts. |
11 | | - // Furthermore, allocating and/or clearing these large arrays is expensive as well. |
12 | | - private final BitSet present; |
13 | | - private final BitSet looped; |
| 10 | + // For some reason, the array was getting re-created on every values() call. |
| 11 | + // So, we cache a single instance. |
| 12 | + private static final LoopedStatus[] VALUES = LoopedStatus.values(); |
| 13 | + |
| 14 | + private final DynamicIntArray looped; |
14 | 15 |
|
15 | 16 | public LoopedTracker(int nodeCount) { |
16 | | - this.present = new BitSet(nodeCount); |
17 | | - this.looped = new BitSet(nodeCount); |
| 17 | + this.looped = new DynamicIntArray(nodeCount); |
18 | 18 | } |
19 | 19 |
|
20 | 20 | public void mark(int node, LoopedStatus status) { |
21 | | - if (status == LoopedStatus.UNKNOWN) { |
22 | | - present.clear(node); |
23 | | - looped.clear(node); |
24 | | - } else { |
25 | | - present.set(node); |
26 | | - looped.set(node, status == LoopedStatus.LOOPED); |
27 | | - } |
| 21 | + looped.set(node, status.ordinal()); |
28 | 22 | } |
29 | 23 |
|
30 | 24 | public LoopedStatus status(int node) { |
31 | | - if (present.isEmpty() || !present.get(node)) { |
32 | | - return LoopedStatus.UNKNOWN; |
33 | | - } |
34 | | - return looped.get(node) ? LoopedStatus.LOOPED : LoopedStatus.NOT_LOOPED; |
| 25 | + // When in the unallocated part of the dynamic array, the value returned is zero. |
| 26 | + // Therefore it is imperative that LoopedStatus.UNKNOWN be the first element in the enum. |
| 27 | + return VALUES[looped.get(node)]; |
35 | 28 | } |
36 | 29 |
|
37 | 30 | public void clear() { |
38 | | - present.clear(); |
39 | 31 | looped.clear(); |
40 | 32 | } |
41 | 33 |
|
|
0 commit comments