Search in sources :

Example 6 with EventId

use of org.apache.flink.cep.nfa.sharedbuffer.EventId in project flink by apache.

the class NFA method computeNextStates.

/**
 * Computes the next computation states based on the given computation state, the current event,
 * its timestamp and the internal state machine. The algorithm is:
 *
 * <ol>
 *   <li>Decide on valid transitions and number of branching paths. See {@link OutgoingEdges}
 *   <li>Perform transitions:
 *       <ol>
 *         <li>IGNORE (links in {@link SharedBuffer} will still point to the previous event)
 *             <ul>
 *               <li>do not perform for Start State - special case
 *               <li>if stays in the same state increase the current stage for future use with
 *                   number of outgoing edges
 *               <li>if after PROCEED increase current stage and add new stage (as we change the
 *                   state)
 *               <li>lock the entry in {@link SharedBuffer} as it is needed in the created
 *                   branch
 *             </ul>
 *         <li>TAKE (links in {@link SharedBuffer} will point to the current event)
 *             <ul>
 *               <li>add entry to the shared buffer with version of the current computation
 *                   state
 *               <li>add stage and then increase with number of takes for the future computation
 *                   states
 *               <li>peek to the next state if it has PROCEED path to a Final State, if true
 *                   create Final ComputationState to emit results
 *             </ul>
 *       </ol>
 *   <li>Handle the Start State, as it always have to remain
 *   <li>Release the corresponding entries in {@link SharedBuffer}.
 * </ol>
 *
 * @param sharedBufferAccessor The accessor to shared buffer that we need to change
 * @param computationState Current computation state
 * @param event Current event which is processed
 * @param timerService timer service which provides access to time related features
 * @return Collection of computation states which result from the current one
 * @throws Exception Thrown if the system cannot access the state.
 */
private Collection<ComputationState> computeNextStates(final SharedBufferAccessor<T> sharedBufferAccessor, final ComputationState computationState, final EventWrapper event, final TimerService timerService) throws Exception {
    final ConditionContext context = new ConditionContext(sharedBufferAccessor, computationState, timerService, event.getTimestamp());
    final OutgoingEdges<T> outgoingEdges = createDecisionGraph(context, computationState, event.getEvent());
    // Create the computing version based on the previously computed edges
    // We need to defer the creation of computation states until we know how many edges start
    // at this computation state so that we can assign proper version
    final List<StateTransition<T>> edges = outgoingEdges.getEdges();
    int takeBranchesToVisit = Math.max(0, outgoingEdges.getTotalTakeBranches() - 1);
    int ignoreBranchesToVisit = outgoingEdges.getTotalIgnoreBranches();
    int totalTakeToSkip = Math.max(0, outgoingEdges.getTotalTakeBranches() - 1);
    final List<ComputationState> resultingComputationStates = new ArrayList<>();
    for (StateTransition<T> edge : edges) {
        switch(edge.getAction()) {
            case IGNORE:
                {
                    if (!isStartState(computationState)) {
                        final DeweyNumber version;
                        if (isEquivalentState(edge.getTargetState(), getState(computationState))) {
                            // Stay in the same state (it can be either looping one or
                            // singleton)
                            final int toIncrease = calculateIncreasingSelfState(outgoingEdges.getTotalIgnoreBranches(), outgoingEdges.getTotalTakeBranches());
                            version = computationState.getVersion().increase(toIncrease);
                        } else {
                            // IGNORE after PROCEED
                            version = computationState.getVersion().increase(totalTakeToSkip + ignoreBranchesToVisit).addStage();
                            ignoreBranchesToVisit--;
                        }
                        addComputationState(sharedBufferAccessor, resultingComputationStates, edge.getTargetState(), computationState.getPreviousBufferEntry(), version, computationState.getStartTimestamp(), computationState.getStartEventID());
                    }
                }
                break;
            case TAKE:
                final State<T> nextState = edge.getTargetState();
                final State<T> currentState = edge.getSourceState();
                final NodeId previousEntry = computationState.getPreviousBufferEntry();
                final DeweyNumber currentVersion = computationState.getVersion().increase(takeBranchesToVisit);
                final DeweyNumber nextVersion = new DeweyNumber(currentVersion).addStage();
                takeBranchesToVisit--;
                final NodeId newEntry = sharedBufferAccessor.put(currentState.getName(), event.getEventId(), previousEntry, currentVersion);
                final long startTimestamp;
                final EventId startEventId;
                if (isStartState(computationState)) {
                    startTimestamp = event.getTimestamp();
                    startEventId = event.getEventId();
                } else {
                    startTimestamp = computationState.getStartTimestamp();
                    startEventId = computationState.getStartEventID();
                }
                addComputationState(sharedBufferAccessor, resultingComputationStates, nextState, newEntry, nextVersion, startTimestamp, startEventId);
                // check if newly created state is optional (have a PROCEED path to Final state)
                final State<T> finalState = findFinalStateAfterProceed(context, nextState, event.getEvent());
                if (finalState != null) {
                    addComputationState(sharedBufferAccessor, resultingComputationStates, finalState, newEntry, nextVersion, startTimestamp, startEventId);
                }
                break;
        }
    }
    if (isStartState(computationState)) {
        int totalBranches = calculateIncreasingSelfState(outgoingEdges.getTotalIgnoreBranches(), outgoingEdges.getTotalTakeBranches());
        DeweyNumber startVersion = computationState.getVersion().increase(totalBranches);
        ComputationState startState = ComputationState.createStartState(computationState.getCurrentStateName(), startVersion);
        resultingComputationStates.add(startState);
    }
    if (computationState.getPreviousBufferEntry() != null) {
        // release the shared entry referenced by the current computation state.
        sharedBufferAccessor.releaseNode(computationState.getPreviousBufferEntry(), computationState.getVersion());
    }
    return resultingComputationStates;
}
Also used : ArrayList(java.util.ArrayList) NodeId(org.apache.flink.cep.nfa.sharedbuffer.NodeId) EventId(org.apache.flink.cep.nfa.sharedbuffer.EventId)

Aggregations

EventId (org.apache.flink.cep.nfa.sharedbuffer.EventId)6 NodeId (org.apache.flink.cep.nfa.sharedbuffer.NodeId)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)1 LongSerializer (org.apache.flink.api.common.typeutils.base.LongSerializer)1 StringSerializer (org.apache.flink.api.common.typeutils.base.StringSerializer)1 ComputationState (org.apache.flink.cep.nfa.ComputationState)1