List<Message> selectedMessages = new ArrayList<Message>();
Map<State, Bounds> bounds = new HashMap<State, Bounds>();
// count currentState, if no currentState, count as in initialState
for (ParticipantId liveParticipantId : liveParticipants.keySet()) {
State state = initialState;
if (currentStates.containsKey(liveParticipantId)) {
state = currentStates.get(liveParticipantId);
}
if (!bounds.containsKey(state)) {
bounds.put(state, new Bounds(0, 0));
}
bounds.get(state).increaseLowerBound();
bounds.get(state).increaseUpperBound();
}
// count pendingStates
for (ParticipantId participantId : pendingStates.keySet()) {
State state = pendingStates.get(participantId);
if (!bounds.containsKey(state)) {
bounds.put(state, new Bounds(0, 0));
}
// TODO: add lower bound, need to refactor pendingState to include fromState also
bounds.get(state).increaseUpperBound();
}
// group messages based on state transition priority
Map<Integer, List<Message>> messagesGroupByStateTransitPriority =
new TreeMap<Integer, List<Message>>();
for (Message message : messages) {
State fromState = message.getTypedFromState();
State toState = message.getTypedToState();
String transition = fromState.toString() + "-" + toState.toString();
int priority = Integer.MAX_VALUE;
if (stateTransitionPriorities.containsKey(transition)) {
priority = stateTransitionPriorities.get(transition);
}
if (!messagesGroupByStateTransitPriority.containsKey(priority)) {
messagesGroupByStateTransitPriority.put(priority, new ArrayList<Message>());
}
messagesGroupByStateTransitPriority.get(priority).add(message);
}
// select messages
for (List<Message> messageList : messagesGroupByStateTransitPriority.values()) {
for (Message message : messageList) {
State fromState = message.getTypedFromState();
State toState = message.getTypedToState();
if (!bounds.containsKey(fromState)) {
LOG.error("Message's fromState is not in currentState. message: " + message);
continue;
}