{
// apply new data to aggregates
int count = 0;
for (EventBean aNewData : newData)
{
MultiKeyUntyped mk = newDataMultiKey[count];
eventsPerStream[0] = aNewData;
aggregationService.applyEnter(eventsPerStream, mk, agentInstanceContext);
count++;
// keep the new event as a representative for the group
workCollection.put(mk, eventsPerStream);
eventGroupReps.put(mk, new EventBean[] {aNewData});
}
}
if (oldData != null)
{
// apply old data to aggregates
int count = 0;
for (EventBean anOldData : oldData)
{
eventsPerStream[0] = anOldData;
aggregationService.applyLeave(eventsPerStream, oldDataMultiKey[count], agentInstanceContext);
count++;
}
}
if (prototype.isSelectRStream())
{
generateOutputBatchedView(oldData, oldDataMultiKey, false, generateSynthetic, oldEvents, oldEventsSortKey);
}
generateOutputBatchedView(newData, newDataMultiKey, true, generateSynthetic, newEvents, newEventsSortKey);
}
// For any group representatives not in the work collection, generate a row
for (Map.Entry<MultiKeyUntyped, EventBean[]> entry : eventGroupReps.entrySet())
{
if (!workCollection.containsKey(entry.getKey()))
{
workCollectionTwo.put(entry.getKey(), entry.getValue());
generateOutputBatchedArr(workCollectionTwo, true, generateSynthetic, newEvents, newEventsSortKey);
workCollectionTwo.clear();
}
}
EventBean[] newEventsArr = (newEvents.isEmpty()) ? null : newEvents.toArray(new EventBean[newEvents.size()]);
EventBean[] oldEventsArr = null;
if (prototype.isSelectRStream())
{
oldEventsArr = (oldEvents.isEmpty()) ? null : oldEvents.toArray(new EventBean[oldEvents.size()]);
}
if (orderByProcessor != null)
{
MultiKeyUntyped[] sortKeysNew = (newEventsSortKey.isEmpty()) ? null : newEventsSortKey.toArray(new MultiKeyUntyped[newEventsSortKey.size()]);
newEventsArr = orderByProcessor.sort(newEventsArr, sortKeysNew, agentInstanceContext);
if (prototype.isSelectRStream())
{
MultiKeyUntyped[] sortKeysOld = (oldEventsSortKey.isEmpty()) ? null : oldEventsSortKey.toArray(new MultiKeyUntyped[oldEventsSortKey.size()]);
oldEventsArr = orderByProcessor.sort(oldEventsArr, sortKeysOld, agentInstanceContext);
}
}
if ((newEventsArr == null) && (oldEventsArr == null))
{
return null;
}
return new UniformPair<EventBean[]>(newEventsArr, oldEventsArr);
}
else if (outputLimitLimitType == OutputLimitLimitType.FIRST)
{
List<EventBean> resultNewEvents = new ArrayList<EventBean>();
List<MultiKeyUntyped> resultNewSortKeys = null;
List<EventBean> resultOldEvents = null;
List<MultiKeyUntyped> resultOldSortKeys = null;
if (orderByProcessor != null) {
resultNewSortKeys = new ArrayList<MultiKeyUntyped>();
}
if (prototype.isSelectRStream()) {
resultOldEvents = new ArrayList<EventBean>();
resultOldSortKeys = new ArrayList<MultiKeyUntyped>();
}
workCollection.clear();
if (prototype.getOptionalHavingNode() == null) {
for (UniformPair<EventBean[]> pair : viewEventsList)
{
EventBean[] newData = pair.getFirst();
EventBean[] oldData = pair.getSecond();
MultiKeyUntyped[] newDataMultiKey = generateGroupKeys(newData, true);
MultiKeyUntyped[] oldDataMultiKey = generateGroupKeys(oldData, false);
if (newData != null)
{
// apply new data to aggregates
for (int i = 0; i < newData.length; i++)
{
eventsPerStreamOneStream[0] = newData[i];
MultiKeyUntyped mk = newDataMultiKey[i];
OutputConditionPolled outputStateGroup = outputState.get(mk);
if (outputStateGroup == null) {
try {
outputStateGroup = OutputConditionPolledFactory.createCondition(prototype.getOutputLimitSpec(), agentInstanceContext);
}
catch (ExprValidationException e) {
log.error("Error starting output limit for group for statement '" + agentInstanceContext.getStatementContext().getStatementName() + "'");
}
outputState.put(newDataMultiKey[i], outputStateGroup);
}
boolean pass = outputStateGroup.updateOutputCondition(1, 0);
if (pass) {
workCollection.put(mk, new EventBean[]{newData[i]});
}
aggregationService.applyEnter(eventsPerStreamOneStream, mk, agentInstanceContext);
}
}
if (oldData != null)
{
// apply new data to aggregates
for (int i = 0; i < oldData.length; i++)
{
eventsPerStreamOneStream[0] = oldData[i];
MultiKeyUntyped mk = oldDataMultiKey[i];
OutputConditionPolled outputStateGroup = outputState.get(mk);
if (outputStateGroup == null) {
try {
outputStateGroup = OutputConditionPolledFactory.createCondition(prototype.getOutputLimitSpec(), agentInstanceContext);
}
catch (ExprValidationException e) {
log.error("Error starting output limit for group for statement '" + agentInstanceContext.getStatementContext().getStatementName() + "'");
}
outputState.put(oldDataMultiKey[i], outputStateGroup);
}
boolean pass = outputStateGroup.updateOutputCondition(0, 1);
if (pass) {
workCollection.put(mk, new EventBean[]{oldData[i]});
}
aggregationService.applyLeave(eventsPerStreamOneStream, mk, agentInstanceContext);
}
}
if (false) // there is no remove stream currently for output first
{
generateOutputBatchedArr(workCollection, false, generateSynthetic, resultOldEvents, resultOldSortKeys);
}
generateOutputBatchedArr(workCollection, false, generateSynthetic, resultNewEvents, resultNewSortKeys);
}
}
else { // has a having-clause
for (UniformPair<EventBean[]> pair : viewEventsList)
{
EventBean[] newData = pair.getFirst();
EventBean[] oldData = pair.getSecond();
MultiKeyUntyped[] newDataMultiKey = generateGroupKeys(newData, true);
MultiKeyUntyped[] oldDataMultiKey = generateGroupKeys(oldData, false);
if (newData != null)
{
// apply new data to aggregates
for (int i = 0; i < newData.length; i++)
{
eventsPerStreamOneStream[0] = newData[i];
MultiKeyUntyped mk = newDataMultiKey[i];
aggregationService.applyEnter(eventsPerStreamOneStream, mk, agentInstanceContext);
}
}
if (oldData != null)
{
for (int i = 0; i < oldData.length; i++)
{
eventsPerStreamOneStream[0] = oldData[i];
MultiKeyUntyped mk = oldDataMultiKey[i];
aggregationService.applyLeave(eventsPerStreamOneStream, mk, agentInstanceContext);
}
}
if (newData != null)
{
// check having clause and first-condition
for (int i = 0; i < newData.length; i++)
{
eventsPerStreamOneStream[0] = newData[i];
MultiKeyUntyped mk = newDataMultiKey[i];
aggregationService.setCurrentAccess(mk, agentInstanceContext.getAgentInstanceIds());
// Filter the having clause
Boolean result = (Boolean) prototype.getOptionalHavingNode().evaluate(eventsPerStreamOneStream, true, agentInstanceContext);
if ((result == null) || (!result))
{
continue;
}
OutputConditionPolled outputStateGroup = outputState.get(mk);
if (outputStateGroup == null) {
try {
outputStateGroup = OutputConditionPolledFactory.createCondition(prototype.getOutputLimitSpec(), agentInstanceContext);
}
catch (ExprValidationException e) {
log.error("Error starting output limit for group for statement '" + agentInstanceContext.getStatementContext().getStatementName() + "'");
}
outputState.put(mk, outputStateGroup);
}
boolean pass = outputStateGroup.updateOutputCondition(1, 0);
if (pass) {
workCollection.put(mk, new EventBean[]{newData[i]});
}
}
}
if (oldData != null)
{
// apply new data to aggregates
for (int i = 0; i < oldData.length; i++)
{
eventsPerStreamOneStream[0] = oldData[i];
MultiKeyUntyped mk = oldDataMultiKey[i];
aggregationService.setCurrentAccess(mk, agentInstanceContext.getAgentInstanceIds());
// Filter the having clause
Boolean result = (Boolean) prototype.getOptionalHavingNode().evaluate(eventsPerStreamOneStream, true, agentInstanceContext);
if ((result == null) || (!result))
{
continue;
}
OutputConditionPolled outputStateGroup = outputState.get(mk);
if (outputStateGroup == null) {
try {
outputStateGroup = OutputConditionPolledFactory.createCondition(prototype.getOutputLimitSpec(), agentInstanceContext);
}
catch (ExprValidationException e) {
log.error("Error starting output limit for group for statement '" + agentInstanceContext.getStatementContext().getStatementName() + "'");
}
outputState.put(oldDataMultiKey[i], outputStateGroup);
}
boolean pass = outputStateGroup.updateOutputCondition(0, 1);
if (pass) {
workCollection.put(mk, new EventBean[]{oldData[i]});
}
}
}
if (false) // there is no remove stream currently for output first
{
generateOutputBatchedArr(workCollection, false, generateSynthetic, resultOldEvents, resultOldSortKeys);
}
generateOutputBatchedArr(workCollection, false, generateSynthetic, resultNewEvents, resultNewSortKeys);
}
}
EventBean[] newEventsArr = null;
EventBean[] oldEventsArr = null;
if (!resultNewEvents.isEmpty()) {
newEventsArr = resultNewEvents.toArray(new EventBean[resultNewEvents.size()]);
}
if ((resultOldEvents != null) && (!resultOldEvents.isEmpty())) {
oldEventsArr = resultOldEvents.toArray(new EventBean[resultOldEvents.size()]);
}
if (orderByProcessor != null)
{
MultiKeyUntyped[] sortKeysNew = (resultNewSortKeys.isEmpty()) ? null : resultNewSortKeys.toArray(new MultiKeyUntyped[resultNewSortKeys.size()]);
newEventsArr = orderByProcessor.sort(newEventsArr, sortKeysNew, agentInstanceContext);
if (prototype.isSelectRStream())
{
MultiKeyUntyped[] sortKeysOld = (resultOldSortKeys.isEmpty()) ? null : resultOldSortKeys.toArray(new MultiKeyUntyped[resultOldSortKeys.size()]);
oldEventsArr = orderByProcessor.sort(oldEventsArr, sortKeysOld, agentInstanceContext);
}
}
if ((newEventsArr == null) && (oldEventsArr == null))
{
return null;
}
return new UniformPair<EventBean[]>(newEventsArr, oldEventsArr);
}
else // (outputLimitLimitType == OutputLimitLimitType.LAST) Compute last per group
{
Map<MultiKeyUntyped, EventBean> lastPerGroupNew = new LinkedHashMap<MultiKeyUntyped, EventBean>();
Map<MultiKeyUntyped, EventBean> lastPerGroupOld = null;
if (prototype.isSelectRStream())
{
lastPerGroupOld = new LinkedHashMap<MultiKeyUntyped, EventBean>();
}
Map<MultiKeyUntyped, MultiKeyUntyped> newEventsSortKey = null; // group key to sort key
Map<MultiKeyUntyped, MultiKeyUntyped> oldEventsSortKey = null;
if (orderByProcessor != null)
{
newEventsSortKey = new LinkedHashMap<MultiKeyUntyped, MultiKeyUntyped>();
if (prototype.isSelectRStream())
{
oldEventsSortKey = new LinkedHashMap<MultiKeyUntyped, MultiKeyUntyped>();
}
}
for (UniformPair<EventBean[]> pair : viewEventsList)
{
EventBean[] newData = pair.getFirst();
EventBean[] oldData = pair.getSecond();
MultiKeyUntyped[] newDataMultiKey = generateGroupKeys(newData, true);
MultiKeyUntyped[] oldDataMultiKey = generateGroupKeys(oldData, false);
if (newData != null)
{
// apply new data to aggregates
int count = 0;
for (EventBean aNewData : newData)
{
MultiKeyUntyped mk = newDataMultiKey[count];
eventsPerStreamOneStream[0] = aNewData;
aggregationService.applyEnter(eventsPerStreamOneStream, mk, agentInstanceContext);
count++;
}
}