Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public sealed interface PropagationQueue<T>

void insert(T item);

/**
* Double updates of the same item count as a single update.
*
* @param item the item to be updated in the propagation queue
*/
void update(T item);

void retract(T item, TupleState state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@

/**
* The implementation records the tuples each object affects inside
* an internal {@link ai.timefold.solver.core.impl.bavet.NodeNetwork} and
* replays them on update.
* an internal {@link NodeNetwork} and replays them on update.
* Used by {@link AbstractPrecomputeNode} to precompute constraint streams.
*
* @param <Tuple_>
Expand All @@ -33,7 +32,6 @@ public final class RecordAndReplayPropagator<Tuple_ extends AbstractTuple>
implements Propagator {

private final Set<Object> retractQueue;
private final Set<Object> updateQueue;
private final Set<Object> insertQueue;

// Store entities and facts separately; we don't need to precompute
Expand All @@ -58,7 +56,6 @@ public RecordAndReplayPropagator(

// Guesstimate that updates are dominant.
this.retractQueue = CollectionUtils.newIdentityHashSet(size / 20);
this.updateQueue = CollectionUtils.newIdentityHashSet((size / 20) * 18);
this.insertQueue = CollectionUtils.newIdentityHashSet(size / 20);
this.objectClassToIsEntitySourceClass = new HashMap<>();
this.seenEntitySet = CollectionUtils.newIdentityHashSet(size);
Expand All @@ -80,7 +77,14 @@ public void insert(Object object) {
}

public void update(Object object) {
updateQueue.add(object);
// Updates happen very frequently, so we optimize by avoiding the update queue
// and going straight to the propagation queue.
// The propagation queue deduplicates updates internally.
var outTupleList = objectToOutputTuplesMap.get(object);
if (outTupleList == null) {
return;
}
outTupleList.forEach(propagationQueue::update);
}

public void retract(Object object) {
Expand Down Expand Up @@ -129,7 +133,6 @@ public void propagateRetracts() {
}
}

updateQueue.clear();
retractQueue.clear();
insertQueue.clear();

Expand All @@ -154,12 +157,6 @@ private static <A> List<BavetRootNode<A>> getRootNodes(Object object, NodeNetwor

@Override
public void propagateUpdates() {
Set<Tuple_> updatedTuples = CollectionUtils.newIdentityHashSet(2 * updateQueue.size());
for (var update : updateQueue) {
updatedTuples.addAll(objectToOutputTuplesMap.get(update));
}
updateQueue.clear();
updatedTuples.forEach(propagationQueue::update);
propagationQueue.propagateUpdates();
}

Expand Down
Loading