com.datatorrent.lib.multiwindow.SimpleMovingAverage Maven / Gradle / Ivy
/**
* 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.datatorrent.lib.multiwindow;
import java.util.ArrayList;
import com.datatorrent.api.DefaultOutputPort;
import com.datatorrent.api.annotation.OperatorAnnotation;
import com.datatorrent.api.annotation.OutputPortFieldAnnotation;
import com.datatorrent.lib.util.KeyValPair;
/**
* Calculates simple moving average (SMA) of last N window.
*
* StateFull : Yes, operator store values for n-1 th windows.
* Partitions : No, sum is not unified on output ports.
*
* Ports:
* data: Expects KeyValPair where K is Object and V is Number.
* doubleSMA: Emits simple moving average of N window as Double.
* floatSMA: Emits simple moving average of N window as Float.
* longSMA: Emits simple moving average of N window as Long.
* integerSMA: Emits simple moving average of N window as Integer.
*
* Properties:
* windowSize: Number of windows to keep state on
*
* @displayName Simple Moving Average
* @category Stats and Aggregations
* @tags key value, numeric, average
* @since 0.3.3
*/
@OperatorAnnotation(partitionable = false)
public class SimpleMovingAverage extends
AbstractSlidingWindowKeyVal
{
/**
* Output port to emit simple moving average (SMA) of last N window as Double.
*/
@OutputPortFieldAnnotation(optional = true)
public final transient DefaultOutputPort> doubleSMA = new DefaultOutputPort>();
/**
* Output port to emit simple moving average (SMA) of last N window as Float.
*/
@OutputPortFieldAnnotation(optional = true)
public final transient DefaultOutputPort> floatSMA = new DefaultOutputPort>();
/**
* Output port to emit simple moving average (SMA) of last N window as Long.
*/
@OutputPortFieldAnnotation(optional = true)
public final transient DefaultOutputPort> longSMA = new DefaultOutputPort>();
/**
* Output port to emit simple moving average (SMA) of last N window as
* Integer.
*/
@OutputPortFieldAnnotation(optional = true)
public final transient DefaultOutputPort> integerSMA = new DefaultOutputPort>();
/**
* Create the list if key doesn't exist. Add value to buffer and increment
* counter.
*
* @param tuple
*/
@Override
public void processDataTuple(KeyValPair tuple)
{
K key = tuple.getKey();
double val = tuple.getValue().doubleValue();
ArrayList dataList = buffer.get(key);
if (dataList == null) {
dataList = new ArrayList(windowSize);
for (int i = 0; i < windowSize; ++i) {
dataList.add(new SimpleMovingAverageObject());
}
}
dataList.get(currentstate).add(val); // add to previous value
buffer.put(key, dataList);
}
/**
* Calculate average and emit in appropriate port.
*
* @param key
* @param obj
*/
@Override
public void emitTuple(K key, ArrayList obj)
{
double sum = 0;
int count = 0;
for (int i = 0; i < windowSize; i++) {
SimpleMovingAverageObject d = obj.get(i);
sum += d.getSum();
count += d.getCount();
}
if (count == 0) { // Nothing to emit.
return;
}
if (doubleSMA.isConnected()) {
doubleSMA.emit(new KeyValPair(key, (sum / count)));
}
if (floatSMA.isConnected()) {
floatSMA.emit(new KeyValPair(key, (float)(sum / count)));
}
if (longSMA.isConnected()) {
longSMA.emit(new KeyValPair(key, (long)(sum / count)));
}
if (integerSMA.isConnected()) {
integerSMA.emit(new KeyValPair(key, (int)(sum / count)));
}
}
}