All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datatorrent.lib.math.SumKeyVal Maven / Gradle / Ivy

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 at
 *
 *   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 com.datatorrent.lib.math;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.mutable.MutableDouble;

import com.datatorrent.api.DefaultInputPort;
import com.datatorrent.api.DefaultOutputPort;
import com.datatorrent.api.StreamCodec;
import com.datatorrent.api.annotation.OutputPortFieldAnnotation;
import com.datatorrent.lib.util.BaseNumberKeyValueOperator;
import com.datatorrent.lib.util.KeyValPair;

/**
 * Emits the sum of values for each key at the end of window.
 * 

* This is an end window operator. Default unifier works as this operator follows sticky partition.

Ports:
* data: expects KeyValPair<K,V extends Number>
sum: emits KeyValPair<K,V extends Number>

Properties:
inverse: If set to true the key in the * filter will block tuple
filterBy: List of keys to filter on
* cumulative: boolean flag, if set the sum is not cleared at the end of window,
* hence generating cumulative sum * across streaming windows. Default is false.
*
* @displayName Sum Key Value * @category Math * @tags numeric, sum, key value * @since 0.3.2 */ public class SumKeyVal extends BaseNumberKeyValueOperator { protected static class SumEntry { public MutableDouble sum; public boolean changed = true; SumEntry() { } SumEntry(MutableDouble sum, boolean changed) { this.sum = sum; this.changed = changed; } } /** * Sums key map. */ protected HashMap sums = new HashMap(); /** * Cumulative sum flag. */ protected boolean cumulative = false; /** * Input port that takes key value pairs and adds the values for each key. */ public final transient DefaultInputPort> data = new DefaultInputPort>() { /** * For each tuple (a key value pair) Adds the values for each key. */ @Override public void process(KeyValPair tuple) { K key = tuple.getKey(); if (!doprocessKey(key)) { return; } SumEntry val = sums.get(key); if (val == null) { val = new SumEntry(new MutableDouble(tuple.getValue().doubleValue()), true); } else { val.sum.add(tuple.getValue().doubleValue()); val.changed = true; } sums.put(cloneKey(key), val); } /** * Stream codec used for partitioning. */ @Override public StreamCodec> getStreamCodec() { return getKeyValPairStreamCodec(); } }; /** * Output sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sum = new DefaultOutputPort>(); /** * Output double sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sumDouble = new DefaultOutputPort>(); /** * Output integer sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sumInteger = new DefaultOutputPort>(); /** * Output long sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sumLong = new DefaultOutputPort>(); /** * Output short sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sumShort = new DefaultOutputPort>(); /** * Output float sum port. */ @OutputPortFieldAnnotation(optional = true) public final transient DefaultOutputPort> sumFloat = new DefaultOutputPort>(); /** * Get cumulative flag. * @return cumulative flag. */ public boolean isCumulative() { return cumulative; } /** * * @param cumulative */ public void setCumulative(boolean cumulative) { this.cumulative = cumulative; } /** * Emits on all ports that are connected. Data is precomputed during process on input port and endWindow just emits it for each key. Clears the internal data. */ @Override public void endWindow() { for (Map.Entry e: sums.entrySet()) { K key = e.getKey(); SumEntry val = e.getValue(); if (val.changed) { sum.emit(new KeyValPair(key, getValue(val.sum.doubleValue()))); sumDouble.emit(new KeyValPair(key, val.sum.doubleValue())); sumInteger.emit(new KeyValPair(key, val.sum.intValue())); sumFloat.emit(new KeyValPair(key, val.sum.floatValue())); sumShort.emit(new KeyValPair(key, val.sum.shortValue())); sumLong.emit(new KeyValPair(key, val.sum.longValue())); } } clearCache(); } /** * Clears the cache making this operator stateless on window boundary */ public void clearCache() { if (cumulative) { for (Map.Entry e : sums.entrySet()) { SumEntry val = e.getValue(); val.changed = false; } } else { sums.clear(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy