in accord-core/src/main/java/accord/local/cfk/Updating.java [502:631]
static void insertOrUpdateWithAdditions(TxnInfo[] byId, int sourceInsertPos, int sourceUpdatePos, TxnId plainTxnId, TxnInfo newInfo, TxnId[] additions, int additionCount, TxnInfo[] newById, TxnInfo[] newCommittedByExecuteAt, @Nonnull TxnId[] witnessedBy, QuickBounds bounds)
{
int additionInsertPos = Arrays.binarySearch(additions, 0, additionCount, plainTxnId);
additionInsertPos = Invariants.requireArgument(-1 - additionInsertPos, additionInsertPos < 0);
int targetInsertPos = sourceInsertPos + additionInsertPos;
// we may need to insert or remove ourselves, depending on the new and prior status
boolean insertSelfMissing = sourceUpdatePos < 0 && newInfo.compareTo(COMMITTED) < 0;
boolean removeSelfMissing = newInfo.compareTo(COMMITTED) >= 0 && sourceUpdatePos >= 0 && byId[sourceUpdatePos].compareTo(COMMITTED) < 0;
boolean removeWitnessedMissing = newInfo.compareTo(COMMITTED) >= 0 && witnessedBy.length > 0;
// missingSource starts as additions, but if we insertSelfMissing at the relevant moment it becomes the merge of additions and plainTxnId
TxnId[] missingSource = additions;
// the most recently constructed pure insert missing array, so that it may be reused if possible
int i = 0, j = 0, missingCount = 0, missingLimit = additionCount, count = 0;
int minByExecuteAtSearchIndex = 0;
while (i < byId.length)
{
if (count == targetInsertPos)
{
newById[count] = newInfo;
if (i == sourceUpdatePos) ++i;
else if (insertSelfMissing) ++missingCount;
++count;
continue;
}
int c = j == additionCount ? -1 : byId[i].compareTo(additions[j]);
if (c < 0)
{
TxnInfo txn = byId[i];
if (i == sourceUpdatePos)
{
txn = newInfo;
}
else if (txn.hasDeps())
{
Timestamp depsKnownBefore = txn.depsKnownBefore();
if (insertSelfMissing && missingSource == additions && (missingCount != j || (depsKnownBefore != txn && depsKnownBefore.compareTo(plainTxnId) > 0)))
{
// add ourselves to the missing collection
missingSource = insertMissing(additions, additionCount, plainTxnId, additionInsertPos);
++missingLimit;
}
int to = missingTo(txn, depsKnownBefore, missingSource, missingCount, missingLimit);
if (to > 0 || removeSelfMissing || removeWitnessedMissing)
{
int witnessedByIndex = -1;
if (witnessedBy != NOT_LOADING_PRUNED && (to > 0 || !removeSelfMissing))
witnessedByIndex = Arrays.binarySearch(witnessedBy, txn);
TxnId[] curMissing = txn.missing();
TxnId[] newMissing = curMissing;
if (to > 0)
{
TxnId skipInsertMissing = null;
if (insertSelfMissing && witnessedByIndex >= 0)
skipInsertMissing = plainTxnId;
newMissing = mergeAndFilterMissing(txn, curMissing, missingSource, to, skipInsertMissing);
}
if (removeSelfMissing || (removeWitnessedMissing && witnessedByIndex >= 0))
newMissing = removeOneMissing(newMissing, plainTxnId);
if (newMissing != curMissing)
{
TxnInfo newTxn = txn.withMissing(newMissing);
if (txn.isCommittedAndExecutes())
{
// update newCommittedByExecuteAt
int ci;
if (txn.executeAt == txn)
{
ci = SortedArrays.exponentialSearch(newCommittedByExecuteAt, minByExecuteAtSearchIndex, newCommittedByExecuteAt.length, txn, TxnInfo::compareExecuteAt, FAST);
minByExecuteAtSearchIndex = 1 + ci;
}
else
{
ci = Arrays.binarySearch(newCommittedByExecuteAt, minByExecuteAtSearchIndex, newCommittedByExecuteAt.length, txn, TxnInfo::compareExecuteAt);
}
Invariants.require(newCommittedByExecuteAt[ci] == txn);
newCommittedByExecuteAt[ci] = newTxn;
}
txn = newTxn;
}
}
}
newById[count] = txn;
i++;
}
else if (c > 0)
{
TxnId txnId = additions[j++];
newById[count] = TxnInfo.createTransitive(txnId, bounds, plainTxnId);
++missingCount;
}
else
{
throw illegalState(byId[i] + " should be an insertion, but found match when merging with origin");
}
count++;
}
if (j < additionCount)
{
if (count <= targetInsertPos)
{
while (count < targetInsertPos)
{
TxnId txnId = additions[j++];
newById[count++] = TxnInfo.createTransitive(txnId, bounds, plainTxnId);
}
newById[targetInsertPos] = newInfo;
count = targetInsertPos + 1;
}
while (j < additionCount)
{
TxnId txnId = additions[j++];
newById[count++] = TxnInfo.createTransitive(txnId, bounds, plainTxnId);
}
}
else if (count == targetInsertPos)
{
newById[targetInsertPos] = newInfo;
}
}