in accord-core/src/main/java/accord/local/Commands.java [643:690]
protected static <P> void visitWaitingOn(SafeCommandStore safeStore, Ranges ranges, TxnId waitingId, Timestamp waitUntil, Deps deps, WaitingOnVisitor<P> visitor, P param)
{
boolean isAffectedByBootstrap = safeStore.commandStore().isAffectedByBootstrap(deps);
if (!isAffectedByBootstrap)
{
deps.forEachUniqueTxnId(ranges, dependencyId -> visitor.visit(safeStore, waitingId, waitUntil, dependencyId, param));
return;
}
BitSet bits = new BitSet(Math.max(deps.keyDeps.txnIdCount(), deps.rangeDeps.txnIdCount()));
if (!deps.keyDeps.isEmpty())
{
SortedArrays.SortedArrayList<TxnId> dependencyIds = deps.keyDeps.txnIds();
// process each interval of TxnId we have a different incomplete range for in a batch,
safeStore.commandStore().forEachBootstrapRange(dependencyIds, (kdeps, bootstrapId, rs, start, end) -> {
// We do not need to depend on the bootstrap transaction for writes, as we have a timestamp store
// (so any write we perform will persist past the bootstrap completing).
// For most reads we can rely on safeToRead, but this is not the case for reads that depend on
// writes that started before our ExclusiveSyncPoint but execute afterwards.
// We must retain a dependency on these transactions.
rs = ranges.slice(rs, Minimal);
kdeps.forEach(rs, (bs, txnId, i) -> {
if (i < end && i >= start)
bs.set(i);
}, bits);
}, deps.keyDeps);
int i = -1;
while ((i = bits.nextSetBit(i + 1)) >= 0)
visitor.visit(safeStore, waitingId, waitUntil, dependencyIds.get(i), param);
}
if (!deps.rangeDeps.isEmpty())
{
bits.clear();
SortedArrays.SortedArrayList<TxnId> dependencyIds = deps.rangeDeps.txnIds();
safeStore.commandStore().forEachBootstrapRange(dependencyIds, (rdeps, bootstrapId, rs, start, end) -> {
rs = ranges.slice(rs, Minimal);
rdeps.forEach(rs, (bs, i) -> {
if (i >= start && i < end)
bs.set(i);
}, bits);
}, deps.rangeDeps);
int i = -1;
while ((i = bits.nextSetBit(i + 1)) >= 0)
visitor.visit(safeStore, waitingId, waitUntil, dependencyIds.get(i), param);
}
}