package edu.washington.escience.myria.operator.agg; import com.google.common.collect.ImmutableSet; import com.google.common.math.LongMath; import edu.washington.escience.myria.Type; import edu.washington.escience.myria.storage.AppendableTable; import edu.washington.escience.myria.storage.MutableTupleBuffer; import edu.washington.escience.myria.storage.ReadableColumn; import edu.washington.escience.myria.storage.ReplaceableColumn; import edu.washington.escience.myria.storage.TupleBatch; /** * Knows how to compute some aggregate over a set of IntFields. */ public final class IntegerAggregator extends PrimitiveAggregator { protected IntegerAggregator(final String inputName, final int column, final AggregationOp aggOp) { super(inputName, column, aggOp); } /** Required for Java serialization. */ private static final long serialVersionUID = 1L; @Override public void addRow( final TupleBatch from, final int fromRow, final MutableTupleBuffer to, final int toRow, final int offset) { ReadableColumn fromCol = from.asColumn(column); ReplaceableColumn toCol = to.getColumn(offset, toRow); final int inColumnRow = to.getInColumnIndex(toRow); switch (aggOp) { case COUNT: toCol.replaceLong(toCol.getLong(inColumnRow) + 1, inColumnRow); break; case MAX: toCol.replaceInt(Math.max(fromCol.getInt(fromRow), toCol.getInt(inColumnRow)), inColumnRow); break; case MIN: toCol.replaceInt(Math.min(fromCol.getInt(fromRow), toCol.getInt(inColumnRow)), inColumnRow); break; case SUM: toCol.replaceLong( LongMath.checkedAdd((long) fromCol.getInt(fromRow), toCol.getLong(inColumnRow)), inColumnRow); break; case SUM_SQUARED: toCol.replaceLong( LongMath.checkedAdd( LongMath.checkedMultiply((long) fromCol.getInt(fromRow), fromCol.getInt(fromRow)), toCol.getLong(inColumnRow)), inColumnRow); break; default: throw new IllegalArgumentException(aggOp + " is invalid"); } } @Override protected boolean isSupported(final AggregationOp aggOp) { return ImmutableSet.of( AggregationOp.COUNT, AggregationOp.MIN, AggregationOp.MAX, AggregationOp.SUM, AggregationOp.AVG, AggregationOp.STDEV, AggregationOp.SUM_SQUARED) .contains(aggOp); } @Override protected Type getOutputType() { switch (aggOp) { case COUNT: case SUM: return Type.LONG_TYPE; case MAX: case MIN: return Type.INT_TYPE; case AVG: case STDEV: return Type.DOUBLE_TYPE; default: throw new IllegalArgumentException("Type " + aggOp + " is invalid"); } }; @Override public void appendInitValue(AppendableTable data, final int column) { switch (aggOp) { case COUNT: case SUM: case SUM_SQUARED: data.putLong(column, 0); break; case MAX: data.putInt(column, Integer.MIN_VALUE); break; case MIN: data.putInt(column, Integer.MAX_VALUE); break; default: throw new IllegalArgumentException("Type " + aggOp + " is invalid"); } } }