package org.araqne.logdb.query.aggregator; import java.util.List; import org.araqne.logdb.Row; import org.araqne.logdb.query.aggregator.Variance.VarianceMapper; import org.araqne.logdb.query.aggregator.Variance.VarianceReducer; import org.araqne.logdb.query.expr.Expression; public class StdDev extends AbstractAggregationFunction { Variance var; public StdDev(List<Expression> exprs) { super(exprs); } @Override public String getName() { return "stddev"; } @Override public void apply(Row map) { Expression expr = exprs.get(0); Object obj = expr.eval(map); if (obj == null || !(obj instanceof Number)) return; if (var == null) var = new Variance(exprs); var.apply(map); } @Override public Object eval() { if (var == null) return null; else return Math.sqrt(((Number) var.eval()).doubleValue()); } @Override public void clean() { var = null; } @Override public AggregationFunction clone() { StdDev f = new StdDev(exprs); if (var != null) f.var = (Variance) var.clone(); return f; } @Override public Object[] serialize() { if (var == null) var = new Variance(exprs); return var.serialize(); } @Override public void deserialize(Object[] values) { if (var == null) var = new Variance(exprs); var.deserialize(values); } @Override public void merge(AggregationFunction func) { // d should not be null here (do not allow null merge set) StdDev other = (StdDev) func; if (this.var == null) { this.var = other.var; } else { this.var.merge(other.var); } } @Override public String toString() { return "stddev(" + exprs.get(0) + ")"; } public boolean canBeDistributed() { return true; } public AggregationFunction mapper(List<Expression> exprs) { return new VarianceMapper(exprs); } public AggregationFunction reducer(List<Expression> exprs) { return new StdDevReducer(exprs); } public static class StdDevReducer extends AbstractAggregationFunction { VarianceReducer varReducer; public StdDevReducer(List<Expression> exprs) { super(exprs); varReducer = new VarianceReducer(exprs); } public StdDevReducer(List<Expression> exprs, VarianceReducer varReducer) { super(exprs); this.varReducer = varReducer; } @Override public Object eval() { Object var = varReducer.eval(); if (var == null) return null; else return Math.sqrt(((Number) var).doubleValue()); } @Override public String getName() { return "stddevReducer"; } @Override public String toString() { return "stddevReducer(" + exprs.get(0) + ")"; } @Override public void apply(Row map) { varReducer.apply(map); } @Override public void merge(AggregationFunction func) { varReducer.merge(func); } @Override public Object[] serialize() { return varReducer.serialize(); } @Override public void deserialize(Object[] values) { varReducer.deserialize(values); } @Override public void clean() { varReducer.clean(); } @Override public AggregationFunction clone() { StdDevReducer result = new StdDevReducer(exprs, (VarianceReducer) varReducer.clone()); return result; } } }