具体代码如下:
package com.lyz.storm.ewma;
import java.io.Serializable;
/**
* 实现指数移动平均值计算
* 实现中使用了流式风格的builder API
* @author liuyazhuang
*
*/
public class EWMA implements Serializable {
private static final long serialVersionUID = 2979391326784043002L;
//时间类型枚举
public static enum Time {
MILLISECONDS(1), SECONDS(1000), MINUTES(SECONDS.getTime() * 60), HOURS(MINUTES.getTime() * 60), DAYS(HOURS.getTime() * 24), WEEKS(DAYS.getTime() * 7);
private long millis;
private Time(long millis) {
this.millis = millis;
}
public long getTime() {
return this.millis;
}
}
//三个alpha常量,这些值和Unix系统计算负载时使用的标准alpha值相同
public static final double ONE_MINUTE_ALPHA = 1 - Math.exp(-5d / 60d / 1d);
public static final double FIVE_MINUTE_ALPHA = 1 - Math.exp(-5d / 60d / 5d);
public static final double FIFTEEN_MINUTE_ALPHA = 1 - Math.exp(-5d / 60d / 15d);
private long window;
private long alphaWindow;
private long last;
private double average;
private double alpha = -1D;
private boolean sliding = false;
public EWMA() {
}
public EWMA sliding(double count, Time time) {
return this.sliding((long) (time.getTime() * count));
}
public EWMA sliding(long window) {
this.sliding = true;
this.window = window;
return this;
}
public EWMA withAlpha(double alpha) {
if (!(alpha > 0.0D && alpha <= 1.0D)) {
throw new IllegalArgumentException("Alpha must be between 0.0 and 1.0");
}