use of org.apache.flink.cep.pattern.FollowedByPattern in project flink by apache.
the class NFACompiler method compileFactory.
/**
* Compiles the given pattern into a {@link NFAFactory}. The NFA factory can be used to create
* multiple NFAs.
*
* @param pattern Definition of sequence pattern
* @param inputTypeSerializer Serializer for the input type
* @param timeoutHandling True if the NFA shall return timed out event patterns
* @param <T> Type of the input events
* @return Factory for NFAs corresponding to the given pattern
*/
@SuppressWarnings("unchecked")
public static <T> NFAFactory<T> compileFactory(Pattern<T, ?> pattern, TypeSerializer<T> inputTypeSerializer, boolean timeoutHandling) {
if (pattern == null) {
// return a factory for empty NFAs
return new NFAFactoryImpl<T>(inputTypeSerializer, 0, Collections.<State<T>>emptyList(), timeoutHandling);
} else {
// set of all generated states
Map<String, State<T>> states = new HashMap<>();
long windowTime;
// this is used to enforse pattern name uniqueness.
Set<String> patternNames = new HashSet<>();
Pattern<T, ?> succeedingPattern;
State<T> succeedingState;
Pattern<T, ?> currentPattern = pattern;
// we're traversing the pattern from the end to the beginning --> the first state is the final state
State<T> currentState = new State<>(currentPattern.getName(), State.StateType.Final);
patternNames.add(currentPattern.getName());
states.put(currentPattern.getName(), currentState);
windowTime = currentPattern.getWindowTime() != null ? currentPattern.getWindowTime().toMilliseconds() : 0L;
while (currentPattern.getPrevious() != null) {
succeedingPattern = currentPattern;
succeedingState = currentState;
currentPattern = currentPattern.getPrevious();
if (!patternNames.add(currentPattern.getName())) {
throw new MalformedPatternException("Duplicate pattern name: " + currentPattern.getName() + ". " + "Pattern names must be unique.");
}
Time currentWindowTime = currentPattern.getWindowTime();
if (currentWindowTime != null && currentWindowTime.toMilliseconds() < windowTime) {
// the window time is the global minimum of all window times of each state
windowTime = currentWindowTime.toMilliseconds();
}
if (states.containsKey(currentPattern.getName())) {
currentState = states.get(currentPattern.getName());
} else {
currentState = new State<>(currentPattern.getName(), State.StateType.Normal);
states.put(currentState.getName(), currentState);
}
currentState.addStateTransition(new StateTransition<T>(StateTransitionAction.TAKE, succeedingState, (FilterFunction<T>) succeedingPattern.getFilterFunction()));
if (succeedingPattern instanceof FollowedByPattern) {
// the followed by pattern entails a reflexive ignore transition
currentState.addStateTransition(new StateTransition<T>(StateTransitionAction.IGNORE, currentState, null));
}
}
// add the beginning state
final State<T> beginningState;
if (states.containsKey(BEGINNING_STATE_NAME)) {
beginningState = states.get(BEGINNING_STATE_NAME);
} else {
beginningState = new State<>(BEGINNING_STATE_NAME, State.StateType.Start);
states.put(BEGINNING_STATE_NAME, beginningState);
}
beginningState.addStateTransition(new StateTransition<T>(StateTransitionAction.TAKE, currentState, (FilterFunction<T>) currentPattern.getFilterFunction()));
return new NFAFactoryImpl<T>(inputTypeSerializer, windowTime, new HashSet<>(states.values()), timeoutHandling);
}
}
Aggregations