in accord-core/src/main/java/accord/messages/PreAccept.java [270:322]
public static boolean rejectExecuteAt(TxnId txnId, Topologies topologies)
{
// for each superseding shard, mark any nodes removed in a long bitmap; once the number of removals
// is greater than the minimum maxFailures for any shard, we reject the executeAt.
// Note, this over-estimates the number of removals by counting removals from _any_ superseding shard
// (rather than counting each superseding shard separately)
int originalIndex = topologies.indexForEpoch(txnId.epoch());
if (originalIndex == 0)
return false;
List<Shard> originalShards = topologies.get(originalIndex).shards();
if (originalShards.stream().anyMatch(s -> s.sortedNodes.size() > 64))
return true;
long[] removals = new long[originalShards.size()];
int minMaxFailures = originalShards.stream().mapToInt(s -> s.maxFailures).min().getAsInt();
for (int i = originalIndex - 1 ; i >= 0 ; --i)
{
List<Shard> newShards = topologies.get(i).shards();
minMaxFailures = Math.min(minMaxFailures, newShards.stream().mapToInt(s -> s.maxFailures).min().getAsInt());
int n = 0, o = 0;
while (n < newShards.size() && o < originalShards.size())
{
Shard nv = newShards.get(n);
Shard ov = originalShards.get(o);
{
int c = nv.range.compareIntersecting(ov.range);
if (c < 0) { ++n; continue; }
else if (c > 0) { ++o; continue; }
}
int nvi = 0, ovi = 0;
while (nvi < nv.sortedNodes.size() && ovi < ov.sortedNodes.size())
{
int c = nv.sortedNodes.get(nvi).compareTo(ov.sortedNodes.get(ovi));
if (c < 0) ++nvi;
else if (c == 0) { ++nvi; ++ovi; }
// TODO (required): consider if this needs to be >=
// consider case where one (or more) of the original nodes is bootstrapping from other original nodes
else if (Long.bitCount(removals[o] |= 1L << ovi++) > minMaxFailures)
return true;
}
while (ovi < ov.sortedNodes.size())
{
if (Long.bitCount(removals[o] |= 1L << ovi++) > minMaxFailures)
return true;
}
int c = nv.range.end().compareTo(ov.range.end());
if (c <= 0) ++n;
if (c >= 0) ++o;
}
}
return false;
}