/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.huawei.streaming.process.agg.resultmerge; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.huawei.streaming.common.MultiKey; import com.huawei.streaming.common.Pair; import com.huawei.streaming.event.IEvent; import com.huawei.streaming.output.OutputType; import com.huawei.streaming.process.GroupBySubProcess; import com.huawei.streaming.process.LimitProcess; import com.huawei.streaming.process.OrderBySubProcess; import com.huawei.streaming.process.SelectSubProcess; import com.huawei.streaming.process.agg.compute.IAggregationService; /** * <分组聚合操作的结果合并处理类,支持select中仅包含聚合操作,或者包含聚合操作以及group by对应的属性字段> * select sum(a) from stream.lengthbatchwindow(10) group by b; * select b, sum(a) from stream.lengthbatchwindow(10) group by b;> * */ public class AggResultSetMergeOnlyGrouped extends AggResultSetMergeGrouped { /** * 序列化ID */ private static final long serialVersionUID = 1996529928367579227L; /** * <默认构造函数> *@param aggregator 聚合操作 *@param selector 选择操作 *@param groupby 分组操作 *@param order 排序操作 *@param limit 限量操作 */ public AggResultSetMergeOnlyGrouped(IAggregationService aggregator, SelectSubProcess selector, GroupBySubProcess groupby, OrderBySubProcess order, LimitProcess limit) { super(aggregator, selector, groupby, order, limit); } /** * {@inheritDoc} */ public Pair<IEvent[], IEvent[]> processResult(IEvent[] newData, IEvent[] oldData, OutputType type) { IAggregationService aggregator = getAggregator(); if (getUnidirection()) { aggregator.clearResults(); } //对新旧事件计算分组键 Map<Object, IEvent> keysAndEvents = new HashMap<Object, IEvent>(); Object[] newDataMultiKey = generateGroupKeys(newData, keysAndEvents); Object[] oldDataMultiKey = generateGroupKeys(oldData, keysAndEvents); IEvent[] selectOldEvents = null; if (type != OutputType.I) { selectOldEvents = generateOutputEvents(keysAndEvents); } processAggregateData(newData, oldData, newDataMultiKey, oldDataMultiKey); //处理select 语句,完成聚合操作值获取,如果其中有过滤的话,需要过滤。 IEvent[] selectNewEvents = generateOutputEvents(keysAndEvents); //返回排序和限量后的结果集 return orderAndLimit(selectNewEvents, selectOldEvents, type); } /** * <产生分组健,并保存分组健和事件对应关系> */ protected Object[] generateGroupKeys(IEvent[] events, Map<Object, IEvent> keysAndEvents) { if (events == null) { return null; } IEvent eventsPerStream; Object keys[] = new Object[events.length]; //计算分组键并保存 for (int i = 0; i < events.length; i++) { eventsPerStream = events[i]; keys[i] = generateGroupKey(eventsPerStream); keysAndEvents.put(keys[i], events[i]); } return keys; } /** * <产生结果集> */ protected IEvent[] generateOutputEvents(Map<Object, IEvent> keysAndEvents) { IAggregationService aggregator = getAggregator(); SelectSubProcess selector = getSelector(); //每个分组键产生一条结果 int count = 0; IEvent[] events = new IEvent[keysAndEvents.size()]; IEvent theEvent; for (Map.Entry<Object, IEvent> entry : keysAndEvents.entrySet()) { //设置当前聚合操作对象 aggregator.setCurrentAggregator(entry.getKey()); //根据当前事件和聚合操作对象,得到结果 theEvent = entry.getValue(); events[count] = selector.processSingle(theEvent); count++; } return events; } /** * {@inheritDoc} */ @Override public Pair<IEvent[], IEvent[]> processJoinResult(Set<MultiKey> newEvents, Set<MultiKey> oldEvents, OutputType type) { IAggregationService aggregator = getAggregator(); if (getUnidirection()) { aggregator.clearResults(); } Map<Object, IEvent[]> keysAndEvents = new HashMap<Object, IEvent[]>(); Object[] newDataGroupByKeys = generateGroupKeys(newEvents, keysAndEvents); Object[] oldDataGroupByKeys = generateGroupKeys(oldEvents, keysAndEvents); IEvent[] selectOldEvents = null; if (type != OutputType.I) { selectOldEvents = generateOutputEventsJoin(keysAndEvents); } processJoinAggregateData(newEvents, oldEvents, newDataGroupByKeys, oldDataGroupByKeys); //处理select 语句,完成聚合操作值获取,如果其中有过滤的话,需要过滤。 IEvent[] selectNewEvents = generateOutputEventsJoin(keysAndEvents); //返回排序和限量后的结果集 return orderAndLimit(selectNewEvents, selectOldEvents, type); } /** * <根据JOIN事件产生结果> * <功能详细描述> */ protected IEvent[] generateOutputEventsJoin(Map<Object, IEvent[]> keysAndEvents) { IEvent[] events = new IEvent[keysAndEvents.size()]; IAggregationService aggregator = getAggregator(); SelectSubProcess selector = getSelector(); //每条JOIN事件产生结果 int count = 0; for (Map.Entry<Object, IEvent[]> entry : keysAndEvents.entrySet()) { //根据分组健,设置当前聚合操作对象 aggregator.setCurrentAggregator(entry.getKey()); IEvent[] eventsPerStream = entry.getValue(); //根据事件和当前聚合操作对象,得到结果 events[count] = (IEvent)selector.processSingle(eventsPerStream); count++; } return events; } /** * <产生分组健,并保存分组健和事件对应关系> */ protected Object[] generateGroupKeys(Set<MultiKey> eventSet, Map<Object, IEvent[]> keysAndEvents) { if (eventSet == null || eventSet.isEmpty()) { return null; } Object keys[] = new Object[eventSet.size()]; int count = 0; for (MultiKey composed : eventSet) { IEvent[] eventsPerStream = (IEvent[])composed.getKeys(); keys[count] = generateGroupKey(eventsPerStream); keysAndEvents.put(keys[count], eventsPerStream); count++; } return keys; } }