    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
    003     *
    004     * Project and contact information: http://www.cascading.org/
    005     *
    006     * This file is part of the Cascading project.
    007     *
    008     * Licensed under the Apache License, Version 2.0 (the "License");
    009     * you may not use this file except in compliance with the License.
    010     * You may obtain a copy of the License at
    011     *
    012     *     http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing, software
    015     * distributed under the License is distributed on an "AS IS" BASIS,
    016     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017     * See the License for the specific language governing permissions and
    018     * limitations under the License.
    019     */
    020
    021    package cascading.operation.aggregator;
    022
    023    import java.beans.ConstructorProperties;
    024
    025    import cascading.flow.FlowProcess;
    026    import cascading.operation.Aggregator;
    027    import cascading.operation.AggregatorCall;
    028    import cascading.operation.BaseOperation;
    029    import cascading.operation.OperationCall;
    030    import cascading.tuple.Fields;
    031    import cascading.tuple.Tuple;
    032    import cascading.util.Pair;
    033
    034    /**
    035     * Class Count is an {@link Aggregator} that calculates the number of items in the current group.
    036     * </p>
    037     * Note the resulting value for count is always a long. So any comparisons should be against a long value.
    038     */
    039    public class Count extends BaseOperation<Pair<Long[], Tuple>> implements Aggregator<Pair<Long[], Tuple>>
    040      {
    041      /** Field COUNT */
    042      public static final String FIELD_NAME = "count";
    043
    044      /** Constructor Count creates a new Count instance using the default field declaration of name 'count'. */
    045      public Count()
    046        {
    047        super( new Fields( FIELD_NAME, Long.class ) );
    048        }
    049
    050      /**
    051       * Constructor Count creates a new Count instance and returns a field with the given fieldDeclaration name.
    052       *
    053       * @param fieldDeclaration of type Fields
    054       */
    055      @ConstructorProperties({"fieldDeclaration"})
    056      public Count( Fields fieldDeclaration )
    057        {
    058        super( fieldDeclaration ); // allow ANY number of arguments
    059        }
    060
    061      @Override
    062      public void prepare( FlowProcess flowProcess, OperationCall<Pair<Long[], Tuple>> operationCall )
    063        {
    064        operationCall.setContext( new Pair<Long[], Tuple>( new Long[]{0L}, Tuple.size( 1 ) ) );
    065        }
    066
    067      @Override
    068      public void start( FlowProcess flowProcess, AggregatorCall<Pair<Long[], Tuple>> aggregatorCall )
    069        {
    070        aggregatorCall.getContext().getLhs()[ 0 ] = 0L;
    071        }
    072
    073      @Override
    074      public void aggregate( FlowProcess flowProcess, AggregatorCall<Pair<Long[], Tuple>> aggregatorCall )
    075        {
    076        aggregatorCall.getContext().getLhs()[ 0 ] += 1L;
    077        }
    078
    079      @Override
    080      public void complete( FlowProcess flowProcess, AggregatorCall<Pair<Long[], Tuple>> aggregatorCall )
    081        {
    082        aggregatorCall.getOutputCollector().add( getResult( aggregatorCall ) );
    083        }
    084
    085      protected Tuple getResult( AggregatorCall<Pair<Long[], Tuple>> aggregatorCall )
    086        {
    087        aggregatorCall.getContext().getRhs().set( 0, aggregatorCall.getContext().getLhs()[ 0 ] );
    088
    089        return aggregatorCall.getContext().getRhs();
    090        }
    091      }