/*
 * Copyright 2009-2010 by The Regents of the University of California
 * Licensed 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 from
 * 
 *     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 edu.uci.ics.hyracks.dataflow.std.aggregators;

import java.io.DataOutput;
import java.io.IOException;

import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;

/**
 * SUM aggregator factory (for integer only; another SUM aggregator for floats
 * is available at {@link FloatSumAggregatorFactory})
 */
public class SumAggregatorFactory implements IFieldValueResultingAggregatorFactory {

    private int sumField;

    public SumAggregatorFactory(int field) {
        sumField = field;
    }

    /**
	 * 
	 */
    private static final long serialVersionUID = 1L;

    /*
     * (non-Javadoc)
     * 
     * @see edu.uci.ics.hyracks.dataflow.std.aggregators.
     * IFieldValueResultingAggregatorFactory
     * #createFieldValueResultingAggregator()
     */
    @Override
    public IFieldValueResultingAggregator createFieldValueResultingAggregator() {
        return new IFieldValueResultingAggregator() {
            private int sum;

            @Override
            public void output(DataOutput resultAcceptor) throws HyracksDataException {
                try {
                    resultAcceptor.writeInt(sum);
                } catch (IOException e) {
                    throw new HyracksDataException(e);
                }
            }

            @Override
            public void init(IFrameTupleAccessor accessor, int tIndex) throws HyracksDataException {
                sum = 0;
            }

            @Override
            public void accumulate(IFrameTupleAccessor accessor, int tIndex) throws HyracksDataException {
                int tupleOffset = accessor.getTupleStartOffset(tIndex);
                int fieldCount = accessor.getFieldCount();
                int fieldStart = accessor.getFieldStartOffset(tIndex, sumField);
                sum += IntegerSerializerDeserializer.getInt(accessor.getBuffer().array(), tupleOffset + 2 * fieldCount
                        + fieldStart);
            }
        };
    }

    /*
     * (non-Javadoc)
     * 
     * @see edu.uci.ics.hyracks.dataflow.std.aggregators.spillable.
     * ISpillableFieldValueResultingAggregatorFactory
     * #createFieldValueResultingAggregator()
     */
    @Override
    public ISpillableFieldValueResultingAggregator createSpillableFieldValueResultingAggregator() {
        return new ISpillableFieldValueResultingAggregator() {

            private int sum;

            @Override
            public void output(DataOutput resultAcceptor) throws HyracksDataException {
                try {
                    resultAcceptor.writeInt(sum);
                } catch (IOException ex) {
                    throw new HyracksDataException(ex);
                }
            }

            @Override
            public void initFromPartial(IFrameTupleAccessor accessor, int tIndex, int fIndex)
                    throws HyracksDataException {
                sum = IntegerSerializerDeserializer.getInt(
                        accessor.getBuffer().array(),
                        accessor.getTupleStartOffset(tIndex) + accessor.getFieldCount() * 4
                                + accessor.getFieldStartOffset(tIndex, fIndex));
            }

            @Override
            public void init(IFrameTupleAccessor accessor, int tIndex) throws HyracksDataException {
                sum = 0;
            }

            @Override
            public void accumulatePartialResult(IFrameTupleAccessor accessor, int tIndex, int fIndex)
                    throws HyracksDataException {
                sum += IntegerSerializerDeserializer.getInt(
                        accessor.getBuffer().array(),
                        accessor.getTupleStartOffset(tIndex) + accessor.getFieldCount() * 4
                                + accessor.getFieldStartOffset(tIndex, fIndex));
            }

            @Override
            public void accumulate(IFrameTupleAccessor accessor, int tIndex) throws HyracksDataException {
                int tupleOffset = accessor.getTupleStartOffset(tIndex);
                int fieldCount = accessor.getFieldCount();
                int fieldStart = accessor.getFieldStartOffset(tIndex, sumField);
                sum += IntegerSerializerDeserializer.getInt(accessor.getBuffer().array(), tupleOffset + 2 * fieldCount
                        + fieldStart);
            }
        };
    }

}

@@ -1138,16 +1138,24 @@
 plements
+%0A       
  IFieldV
@@ -1809,32 +1809,52 @@
  resultAcceptor)
+%0A                   
  throws HyracksD
@@ -2154,32 +2154,52 @@
 sor, int tIndex)
+%0A                   
  throws HyracksD
@@ -2343,32 +2343,52 @@
 sor, int tIndex)
+%0A                   
  throws HyracksD
@@ -2478,67 +2478,8 @@
 x);%0A
-                int fieldCount = accessor.getFieldCount();%0A
     
@@ -2627,59 +2627,132 @@
 ssor
-.getBuffer().array(), tupleOffset + 2 * fieldCount%0A
+%0A                        .getBuffer().array(),%0A                        tupleOffset + accessor.getFieldSlotsLength()%0A        
     
@@ -3317,16 +3317,36 @@
 cceptor)
+%0A                   
  throws 
@@ -3655,32 +3655,52 @@
 cessor accessor,
+%0A                   
  int tIndex, int
@@ -3707,36 +3707,16 @@
  fIndex)
-%0A                   
  throws 
@@ -3904,32 +3904,64 @@
 rtOffset(tIndex)
+%0A                               
  + accessor.getF
@@ -3960,35 +3960,37 @@
 sor.getField
-Count() * 4
+SlotsLength()
 %0A           
@@ -4158,32 +4158,52 @@
 sor, int tIndex)
+%0A                   
  throws HyracksD
@@ -4348,32 +4348,52 @@
 cessor accessor,
+%0A                   
  int tIndex, int
@@ -4400,36 +4400,16 @@
  fIndex)
-%0A                   
  throws 
@@ -4606,16 +4606,48 @@
 (tIndex)
+%0A                               
  + acces
@@ -4662,19 +4662,21 @@
 ield
-Count() * 4
+SlotsLength()
 %0A   
@@ -4862,24 +4862,44 @@
  int tIndex)
+%0A                   
  throws Hyra
@@ -4993,67 +4993,8 @@
 x);%0A
-                int fieldCount = accessor.getFieldCount();%0A
     
@@ -5142,59 +5142,132 @@
 ssor
-.getBuffer().array(), tupleOffset + 2 * fieldCount%0A
+%0A                        .getBuffer().array(),%0A                        tupleOffset + accessor.getFieldSlotsLength()%0A        
     

Update legacy tuple slot length computation code, regarding to issue #51