public LinkedHashMap<NamedWindowConsumerView, NamedWindowDeltaData> getDeltaPerConsumer( Object perStmtObj, EPStatementAgentInstanceHandle handle) { List<NamedWindowConsumerDispatchUnit> list = (List<NamedWindowConsumerDispatchUnit>) perStmtObj; LinkedHashMap<NamedWindowConsumerView, NamedWindowDeltaData> deltaPerConsumer = new LinkedHashMap<NamedWindowConsumerView, NamedWindowDeltaData>(); for (NamedWindowConsumerDispatchUnit unit : list) // for each unit { for (NamedWindowConsumerView consumerView : unit.getDispatchTo().get(handle)) // each consumer { NamedWindowDeltaData deltaForConsumer = deltaPerConsumer.get(consumerView); if (deltaForConsumer == null) { deltaPerConsumer.put(consumerView, unit.getDeltaData()); } else { NamedWindowDeltaData aggregated = new NamedWindowDeltaData(deltaForConsumer, unit.getDeltaData()); deltaPerConsumer.put(consumerView, aggregated); } } } return deltaPerConsumer; }
private void processDispatches( ExprEvaluatorContext exprEvaluatorContext, NamedWindowConsumerDispatchUnit[] dispatches) { if (dispatches.length == 1) { NamedWindowConsumerDispatchUnit unit = dispatches[0]; EventBean[] newData = unit.getDeltaData().getNewData(); EventBean[] oldData = unit.getDeltaData().getOldData(); if (MetricReportingPath.isMetricsEnabled) { for (Map.Entry<EPStatementAgentInstanceHandle, List<NamedWindowConsumerView>> entry : unit.getDispatchTo().entrySet()) { EPStatementAgentInstanceHandle handle = entry.getKey(); if (handle.getStatementHandle().getMetricsHandle().isEnabled()) { long cpuTimeBefore = MetricUtil.getCPUCurrentThread(); long wallTimeBefore = MetricUtil.getWall(); processHandle(handle, entry.getValue(), newData, oldData, exprEvaluatorContext); long wallTimeAfter = MetricUtil.getWall(); long cpuTimeAfter = MetricUtil.getCPUCurrentThread(); long deltaCPU = cpuTimeAfter - cpuTimeBefore; long deltaWall = wallTimeAfter - wallTimeBefore; metricReportingService.accountTime( handle.getStatementHandle().getMetricsHandle(), deltaCPU, deltaWall, 1); } else { processHandle(handle, entry.getValue(), newData, oldData, exprEvaluatorContext); } if ((isPrioritized) && (handle.isPreemptive())) { break; } } } else { for (Map.Entry<EPStatementAgentInstanceHandle, List<NamedWindowConsumerView>> entry : unit.getDispatchTo().entrySet()) { EPStatementAgentInstanceHandle handle = entry.getKey(); processHandle(handle, entry.getValue(), newData, oldData, exprEvaluatorContext); if ((isPrioritized) && (handle.isPreemptive())) { break; } } } return; } // Multiple different-result dispatches to same or different statements are needed in two // situations: // a) an event comes in, triggers two insert-into statements inserting into the same named // window and the window produces 2 results // b) a time batch is grouped in the named window, and a timer fires for both groups at the same // time producing more then one result // c) two on-merge/update/delete statements fire for the same arriving event each updating the // named window // Most likely all dispatches go to different statements since most statements are not joins of // named windows that produce results at the same time. Therefore sort by statement handle. Map<EPStatementAgentInstanceHandle, Object> dispatchesPerStmt = dispatchesPerStmtTL.get(); for (NamedWindowConsumerDispatchUnit unit : dispatches) { for (Map.Entry<EPStatementAgentInstanceHandle, List<NamedWindowConsumerView>> entry : unit.getDispatchTo().entrySet()) { EPStatementAgentInstanceHandle handle = entry.getKey(); Object perStmtObj = dispatchesPerStmt.get(handle); if (perStmtObj == null) { dispatchesPerStmt.put(handle, unit); } else if (perStmtObj instanceof List) { List<NamedWindowConsumerDispatchUnit> list = (List<NamedWindowConsumerDispatchUnit>) perStmtObj; list.add(unit); } else // convert from object to list { NamedWindowConsumerDispatchUnit unitObj = (NamedWindowConsumerDispatchUnit) perStmtObj; List<NamedWindowConsumerDispatchUnit> list = new ArrayList<NamedWindowConsumerDispatchUnit>(); list.add(unitObj); list.add(unit); dispatchesPerStmt.put(handle, list); } } } // Dispatch - with or without metrics reporting if (MetricReportingPath.isMetricsEnabled) { for (Map.Entry<EPStatementAgentInstanceHandle, Object> entry : dispatchesPerStmt.entrySet()) { EPStatementAgentInstanceHandle handle = entry.getKey(); Object perStmtObj = entry.getValue(); // dispatch of a single result to the statement if (perStmtObj instanceof NamedWindowConsumerDispatchUnit) { NamedWindowConsumerDispatchUnit unit = (NamedWindowConsumerDispatchUnit) perStmtObj; EventBean[] newData = unit.getDeltaData().getNewData(); EventBean[] oldData = unit.getDeltaData().getOldData(); if (handle.getStatementHandle().getMetricsHandle().isEnabled()) { long cpuTimeBefore = MetricUtil.getCPUCurrentThread(); long wallTimeBefore = MetricUtil.getWall(); processHandle( handle, unit.getDispatchTo().get(handle), newData, oldData, exprEvaluatorContext); long wallTimeAfter = MetricUtil.getWall(); long cpuTimeAfter = MetricUtil.getCPUCurrentThread(); long deltaCPU = cpuTimeAfter - cpuTimeBefore; long deltaWall = wallTimeAfter - wallTimeBefore; metricReportingService.accountTime( handle.getStatementHandle().getMetricsHandle(), deltaCPU, deltaWall, 1); } else { Map<EPStatementAgentInstanceHandle, List<NamedWindowConsumerView>> entries = unit.getDispatchTo(); List<NamedWindowConsumerView> items = entries.get(handle); if (items != null) { processHandle(handle, items, newData, oldData, exprEvaluatorContext); } } if ((isPrioritized) && (handle.isPreemptive())) { break; } continue; } // dispatch of multiple results to a the same statement, need to aggregate per consumer view LinkedHashMap<NamedWindowConsumerView, NamedWindowDeltaData> deltaPerConsumer = getDeltaPerConsumer(perStmtObj, handle); if (handle.getStatementHandle().getMetricsHandle().isEnabled()) { long cpuTimeBefore = MetricUtil.getCPUCurrentThread(); long wallTimeBefore = MetricUtil.getWall(); processHandleMultiple(handle, deltaPerConsumer, exprEvaluatorContext); long wallTimeAfter = MetricUtil.getWall(); long cpuTimeAfter = MetricUtil.getCPUCurrentThread(); long deltaCPU = cpuTimeAfter - cpuTimeBefore; long deltaWall = wallTimeAfter - wallTimeBefore; metricReportingService.accountTime( handle.getStatementHandle().getMetricsHandle(), deltaCPU, deltaWall, 1); } else { processHandleMultiple(handle, deltaPerConsumer, exprEvaluatorContext); } if ((isPrioritized) && (handle.isPreemptive())) { break; } } } else { for (Map.Entry<EPStatementAgentInstanceHandle, Object> entry : dispatchesPerStmt.entrySet()) { EPStatementAgentInstanceHandle handle = entry.getKey(); Object perStmtObj = entry.getValue(); // dispatch of a single result to the statement if (perStmtObj instanceof NamedWindowConsumerDispatchUnit) { NamedWindowConsumerDispatchUnit unit = (NamedWindowConsumerDispatchUnit) perStmtObj; EventBean[] newData = unit.getDeltaData().getNewData(); EventBean[] oldData = unit.getDeltaData().getOldData(); processHandle( handle, unit.getDispatchTo().get(handle), newData, oldData, exprEvaluatorContext); if ((isPrioritized) && (handle.isPreemptive())) { break; } continue; } // dispatch of multiple results to a the same statement, need to aggregate per consumer view LinkedHashMap<NamedWindowConsumerView, NamedWindowDeltaData> deltaPerConsumer = getDeltaPerConsumer(perStmtObj, handle); processHandleMultiple(handle, deltaPerConsumer, exprEvaluatorContext); if ((isPrioritized) && (handle.isPreemptive())) { break; } } } dispatchesPerStmt.clear(); return; }