/*
* StreamCruncher: Copyright (c) 2006-2008, Ashwin Jayaprakash. All Rights Reserved.
* Contact: ashwin {dot} jayaprakash {at} gmail {dot} com
* Web: http://www.StreamCruncher.com
*
* This file is part of StreamCruncher.
*
* StreamCruncher is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* StreamCruncher is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with StreamCruncher. If not, see <http://www.gnu.org/licenses/>.
*/
package streamcruncher.api.aggregator;
import java.util.LinkedHashMap;
import java.util.List;
/*
* Author: Ashwin Jayaprakash Date: Sep 21, 2006 Time: 10:59:37 PM
*/
/**
* <p>
* Custom Aggregator functions can be plugged into the Kernel before the Query
* is registered. The APIs provide a means to register and unregister these
* custom functions. Such custom Aggregators must extend this Class. The
* Sub-classes must have a <b>no argument constructor</b>.
* </p>
* <p>
* When the Kernel creates a Window in a Partition that uses the function name
* against which this Aggregate is registered, an instance of the registered
* Class is created and used. When the Window expires, the corresponding
* Aggregator instance is also discarded.
* </p>
*/
public abstract class AbstractAggregator {
private String[] params;
private LinkedHashMap<String, String> columnNamesAndTypes;
private AggregationStage aggregationStage;
/**
* <b>Note:</b> This class' method must be invoked even if it is
* over-ridden (i.e <code>super.init(...)</code>).
*
* @param params
* Parameters that were supplied to the function in the "Running
* Query". Ex: A definition such as
* <code>with custom(test_fn, order_id, J) as test_fn_val</code>
* will produce <code>String[]{"order_id", "J"}</code>
* @param columnNamesAndTypes
* The same order in which the columns are placed in Lists in
* {@link #aggregate(List, List)}.
* @param aggregationStage
*/
public void init(String[] params, LinkedHashMap<String, String> columnNamesAndTypes,
AggregationStage aggregationStage) {
this.params = params;
this.columnNamesAndTypes = columnNamesAndTypes;
this.aggregationStage = aggregationStage;
}
public LinkedHashMap<String, String> getColumnNamesAndTypes() {
return columnNamesAndTypes;
}
public String[] getParams() {
return params;
}
public AggregationStage getAggregationStage() {
return aggregationStage;
}
// -------------
/**
* <p>
* At the end of each Query execution, this method will be called to
* aggregate the Events in the Window over which this Aggregate is created.
* </p>
* <p>
* One of the parameters (added/removed) can be <code>null</code>. But,
* never both.
* </p>
*
* @param removedValues
* List of rows that were removed in the current cycle. Each
* array in the list is a group of columns in that Row.
* @param addedValues
* List of rows added in the current cycle. Each array in the
* list is a group of columns in that Row.
* @return The aggregated value or <code>null</code> for some cases (Ex:
* In-built functions return a <code>null</code> if the aggregate
* calculation yields a NaN).
* @see #columnNamesAndTypes for the names and types of the data/columns.
*/
public abstract Object aggregate(List<Object[]> removedValues, List<Object[]> addedValues);
// -------------
/**
* <p>
* This feature is to provide a choice for the User to decide whether an
* Event's entrance into a Window only or both entrance and exit should
* affect the aggregate.
* </p>
* <p>
* The default is {@link AggregationStage#BOTH}.
* </p>
*
* @since 1.03 Beta
*/
public static enum AggregationStage {
ENTRANCE, BOTH;
}
}