package org.googlecode.perftrace.stat; import java.math.BigDecimal; /** * DIFF = sample-old_ttl * * smoothed_rtt = old_ttl + a*diff * * dev = old_dev + b*(|diff|-old_dev) * * timeout = smoothed_rtt + c*dev * * dev 是平均(mean deviation)偏差的估计,a的取值范围(0-1), 用于控制加权平均值影响的快慢程度; * b(0-1),用于控制新样本对平均方差影响的快慢程度; * * c是控制方差对往返超时时限影响程度的因子; * * * @author zhongfeng * */ class ComplexTimeoutCalculator { public final static BigDecimal DEFAULT_RTTL = new BigDecimal(10); public final static BigDecimal DEFAULT_DEV = new BigDecimal(5); /** * a 取值1/8 */ private final static BigDecimal a = new BigDecimal(1.00) .divide(new BigDecimal(8.00)); /** * b 取值1/8 */ private final static BigDecimal b = new BigDecimal(1.00) .divide(new BigDecimal(4.00)); /** * c 取值3 */ private final static BigDecimal c = new BigDecimal(3.00); private BigDecimal currentRttl = DEFAULT_RTTL; private BigDecimal currentDev = DEFAULT_DEV; private BigDecimal timeout = currentRttl.add(c.multiply(currentDev)); ComplexTimeoutCalculator calculate(int sample) { BigDecimal diff = new BigDecimal(sample).subtract(currentRttl); currentRttl = currentRttl.add(a.multiply(diff)); currentDev = currentDev .add(b.multiply(diff.abs().subtract(currentDev))); timeout = currentRttl.add(c.multiply(currentDev)); return this; } public BigDecimal getCurrentRttl() { return currentRttl; } public void setCurrentRttl(BigDecimal currentRttl) { this.currentRttl = currentRttl; } public BigDecimal getCurrentDev() { return currentDev; } public void setCurrentDev(BigDecimal currentDev) { this.currentDev = currentDev; } public BigDecimal getTimeout() { return timeout; } public void setTimeout(BigDecimal timeout) { this.timeout = timeout; } @Override public String toString() { return "ComplexTimeoutCalculator [currentDev=" + currentDev + ", currentRttl=" + currentRttl + ", timeout=" + timeout + "]"; } public static void main(String[] args) { ComplexTimeoutCalculator cal = new ComplexTimeoutCalculator(); System.out.println(cal.calculate(10).calculate(1).calculate(1)); } }