in accord-core/src/main/java/accord/local/cfk/Utils.java [161:260]
static void addToMissingArrays(TxnInfo[] byId, TxnInfo[] committedByExecuteAt, TxnInfo newInfo, TxnId insertTxnId, @Nonnull TxnId[] doNotInsert)
{
TxnId[] oneMissing = null;
int startIndex = SortedArrays.binarySearch(committedByExecuteAt, 0, committedByExecuteAt.length, insertTxnId, (id, info) -> id.compareTo(info.executeAt), FAST);
if (startIndex < 0) startIndex = -1 - startIndex;
else ++startIndex;
int minByIdSearchIndex = Arrays.binarySearch(byId, insertTxnId) + 1;
for (int i = 0 ; i < minByIdSearchIndex ; ++i)
{
TxnInfo txn = byId[i];
if (txn == newInfo) continue;
if (txn.mayExecute()) continue;
if (!txn.hasDeps()) continue;
if (txn.executeAt == txn) continue;
if (!txn.witnesses(insertTxnId)) continue;
if (txn.depsKnownBefore().compareTo(newInfo) < 0) continue;
TxnId[] missing = txn.missing();
if (missing == NO_TXNIDS) missing = oneMissing = ensureOneMissing(insertTxnId, oneMissing);
else missing = SortedArrays.insert(missing, insertTxnId, TxnId[]::new);
byId[i] = txn.withMissing(missing);
}
int minDoNotInsertSearchIndex = 0;
for (int i = startIndex ; i < committedByExecuteAt.length ; ++i)
{
int newMinSearchIndex;
{
TxnInfo txn = committedByExecuteAt[i];
if (txn == newInfo) continue;
if (!txn.witnesses(insertTxnId)) continue;
if (doNotInsert != NO_TXNIDS)
{
if (txn.executeAt == txn)
{
int j = SortedArrays.exponentialSearch(doNotInsert, 0, doNotInsert.length, txn);
if (j >= 0)
{
minDoNotInsertSearchIndex = j;
continue;
}
minDoNotInsertSearchIndex = -1 -j;
}
else
{
if (Arrays.binarySearch(doNotInsert, txn) >= 0)
continue;
}
}
TxnId[] missing = txn.missing();
if (missing == NO_TXNIDS) missing = oneMissing = ensureOneMissing(insertTxnId, oneMissing);
else missing = SortedArrays.insert(missing, insertTxnId, TxnId[]::new);
newMinSearchIndex = updateInfoArraysByExecuteAt(i, txn, txn.withMissing(missing), minByIdSearchIndex, byId, committedByExecuteAt);
}
for (; minByIdSearchIndex < newMinSearchIndex ; ++minByIdSearchIndex)
{
TxnInfo txn = byId[minByIdSearchIndex];
if (txn == newInfo) continue;
if (!txn.hasDeps()) continue;
if (!txn.witnesses(insertTxnId)) continue;
if (txn.compareTo(ACCEPTED) > 0 && txn.mayExecute()) continue;
if (minDoNotInsertSearchIndex < doNotInsert.length && doNotInsert[minDoNotInsertSearchIndex].equals(txn))
{
++minDoNotInsertSearchIndex;
continue;
}
TxnId[] missing = txn.missing();
if (missing == NO_TXNIDS) missing = oneMissing = ensureOneMissing(insertTxnId, oneMissing);
else missing = SortedArrays.insert(missing, insertTxnId, TxnId[]::new);
byId[minByIdSearchIndex] = txn.withMissing(missing);
}
}
for (; minByIdSearchIndex < byId.length ; ++minByIdSearchIndex)
{
TxnInfo txn = byId[minByIdSearchIndex];
if (txn == newInfo) continue;
// TODO (expected): optimise this with flag bits
if (!txn.hasDeps()) continue;
if (!txn.witnesses(insertTxnId)) continue;
if (txn.compareTo(ACCEPTED) > 0 && txn.mayExecute()) continue;
if (minDoNotInsertSearchIndex < doNotInsert.length && doNotInsert[minDoNotInsertSearchIndex].equals(txn))
{
++minDoNotInsertSearchIndex;
continue;
}
TxnId[] missing = txn.missing();
if (missing == NO_TXNIDS) missing = oneMissing = ensureOneMissing(insertTxnId, oneMissing);
else missing = SortedArrays.insert(missing, insertTxnId, TxnId[]::new);
byId[minByIdSearchIndex] = txn.withMissing(missing);
}
}