private CommandsForKeyUpdate update()

in accord-core/src/main/java/accord/local/cfk/CommandsForKey.java [1574:1638]


    private CommandsForKeyUpdate update(InternalStatus newStatus, Command updated, @Nullable LoadingPruned loading)
    {
        TxnId txnId = updated.txnId();
        Invariants.requireArgument(updated.participants().hasTouched(key) || !manages(txnId));

        if (txnId.compareTo(redundantBefore()) < 0)
            return this;

        boolean mayExecute = mayExecute(txnId, newStatus, updated);
        boolean isOutOfRange = !mayExecute && newStatus.compareTo(APPLIED) <= 0 && manages(txnId)
                               && !updated.participants().stillTouches(key);

        TxnId[] witnessedBy = loading != null ? loading.witnessedBy : NOT_LOADING_PRUNED;
        if (loading == null && isOutOfRange && newStatus.compareTo(COMMITTED) < 0)
            return this;

        int pos = Arrays.binarySearch(byId, txnId);
        CommandsForKeyUpdate result;
        if (pos < 0)
        {
            if (isOutOfRange && loading == null)
                return this; // if outOfRange we only need to maintain any existing records; if none, don't update

            pos = -1 - pos;
            if (isOutOfRange) result = insertOrUpdateOutOfRange(pos, txnId, null, newStatus, mayExecute, updated, witnessedBy);
            else if (newStatus.hasDeps()) result = insert(pos, txnId, newStatus, mayExecute, updated, witnessedBy);
            else result = insert(pos, txnId, TxnInfo.create(txnId, newStatus, mayExecute, updated), updated, witnessedBy);
        }
        else
        {
            // update
            TxnInfo cur = byId[pos];
            int c = cur.compareTo(newStatus);
            if (c > 0)
            {
                // newStatus moves us backwards; we only permit this for (Pre)?(Not)?Accepted states
                if (cur.compareTo(COMMITTED) >= 0 || newStatus.compareTo(PREACCEPTED) <= 0)
                    return this;

                // and only when the new ballot is strictly greater
                if (updated.acceptedOrCommitted().compareTo(cur.ballot()) <= 0)
                    return this;
            }
            else if (c == 0)
            {
                // we're updating to the same state; we only do this with a strictly greater ballot;
                // even so, if we have no executeAt or deps there's nothing to record
                if (updated.acceptedOrCommitted().compareTo(cur.ballot()) <= 0 || !newStatus.hasExecuteAtOrDeps())
                    return this;
            }
            else
            {
                // we're advancing to a higher status, but this is only permitted either if the new state is stable or the ballot is higher
                if (cur.compareTo(STABLE) < 0 && updated.acceptedOrCommitted().compareTo(cur.ballot()) < 0)
                    return this;
            }

            if (isOutOfRange) result = insertOrUpdateOutOfRange(pos, txnId, cur, newStatus, mayExecute, updated, witnessedBy);
            else if (cur.compareTo(STABLE) >= 0) result = update(pos, txnId, cur, cur.withEncodedStatus(TxnInfo.encode(txnId, newStatus, cur.mayExecute(), cur.statusOverrides())), updated, witnessedBy);
            else if (newStatus.hasDeps()) result = update(pos, txnId, cur, newStatus, mayExecute, updated, witnessedBy);
            else result = update(pos, txnId, cur, TxnInfo.create(txnId, newStatus, mayExecute, updated), updated, witnessedBy);
        }

        return result;
    }