/**
* 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.window.group;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.huawei.streaming.event.IEvent;
import com.huawei.streaming.expression.IExpression;
import com.huawei.streaming.timeservice.TimeService;
import com.huawei.streaming.view.IDataCollection;
import com.huawei.streaming.view.IView;
import com.huawei.streaming.window.TimeSlideEventList;
/**
* <基于时间滑动的分组窗口>
* <对每个分组值对应的窗口进行处理>
*
*/
public class GroupTimeSlideWindow extends GroupTimeBasedWindow
{
/**
* 序列化id
*/
private static final long serialVersionUID = 4847878507453629670L;
/**
* 日志打印对象
*/
private static final Logger LOG = LoggerFactory.getLogger(GroupTimeSlideWindow.class);
/**
* 分组窗口中每个分组对应事件 集合
*/
private final HashMap<Object, Object> eventsPerKey = new HashMap<Object, Object>();
/**
* 事件
*/
private TimeSlideEventList events = null;
/**
* 时间与分组反向索引,根据时间得到分组中具有过期事件,然后中分组事件集合中查找。
*/
private final TreeMap<Long, HashSet<Object>> timegroups = new TreeMap<Long, HashSet<Object>>();
/**
* 具有过期事件的分组信息
*/
private HashSet<Object> timegroup = null;
/**
* <默认构造函数>
*@param exprs 分组表达式
*@param keepTime 窗口保持时间,单位:ms
*@param slideInterval 窗口滑动间隔,单位:ms
*/
public GroupTimeSlideWindow(IExpression[] exprs, long keepTime, long slideInterval)
{
super(exprs, keepTime);
TimeService timeservice = new TimeService(slideInterval, this);
setTimeservice(timeservice);
}
/** {@inheritDoc} */
@Override
protected void processGroupedEvent(long currentTime)
{
Iterator<Long> itr = timegroups.keySet().iterator();
Set<Object> groupKeys = new HashSet<Object>();
while (itr.hasNext())
{
long expirTime = itr.next();
if (expirTime >= currentTime)
{
break;
}
else
{
timegroup = timegroups.get(expirTime);
for (Object groupKey : timegroup)
{
groupKeys.add(groupKey);
}
itr.remove();
}
}
Object subViews = null;
IDataCollection subCollection = null;
for (Object obj : groupKeys)
{
subViews = getSubViewsPerKey().get(obj);
subCollection = getSubCollectionPerKey().get(obj);
events = (TimeSlideEventList)eventsPerKey.get(obj);
IEvent[] oldData = events.getOldData(currentTime);
if ((null != subViews) && (null != oldData))
{
if (subCollection != null)
{
subCollection.update(null, oldData);
}
if (subViews instanceof IView)
{
((IView)subViews).update(null, oldData);
LOG.debug("Send Slide Window Events For GroupID: {}.", obj);
}
}
}
}
/** {@inheritDoc} */
@Override
protected void processGroupedEvent(Object subViews, IDataCollection subCollection, Object groupKey, IEvent theEvent)
{
events = (TimeSlideEventList)eventsPerKey.get(groupKey);
if (null == events)
{
events = new TimeSlideEventList();
eventsPerKey.put(groupKey, events);
}
long timestamp = System.currentTimeMillis();
long expirtimestamp = timestamp + getKeepTime();
events.add(expirtimestamp, theEvent);
timegroup = timegroups.get(expirtimestamp);
if (null == timegroup)
{
timegroup = new HashSet<Object>();
}
timegroup.add(groupKey);
timegroups.put(expirtimestamp, timegroup);
if (subCollection != null)
{
subCollection.update(new IEvent[] {theEvent}, null);
}
if (subViews instanceof IView)
{
IEvent[] newData = new IEvent[] {theEvent};
((IView)subViews).update(newData, null);
LOG.debug("Send Batch Window Events For GroupID: {}.", groupKey);
}
}
}