io.datakernel.stream.processor.StreamReducers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of async-streams Show documentation
Show all versions of async-streams Show documentation
Composable asynchronous/reactive streams with powerful data processing capabilities.
The newest version!
/*
* Copyright (C) 2015 SoftIndex LLC.
*
* 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 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 io.datakernel.stream.processor;
import io.datakernel.stream.StreamDataReceiver;
/**
* Static utility methods pertaining to {@link StreamReducers.Reducer}.
* Contains primary ready for use reducers.
*/
public class StreamReducers {
private StreamReducers() {
}
/**
* Returns reducer which streams only one element from group of same keys.
*
* @param type of key
* @param type of output
*/
public static Reducer mergeDeduplicateReducer() {
return new MergeDeduplicateReducer<>();
}
/**
* Returns reducer which streams all receives elements sorted by keys.
*
* @param type of key
* @param type of output
*/
public static Reducer mergeSortReducer() {
return new MergeSortReducer<>();
}
/**
* It is primary interface of Reducer.
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public interface Reducer {
/**
* Run when reducer received first element with key from argument.
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
* @return accumulator for further operations
*/
A onFirstItem(StreamDataReceiver stream, K key, I firstValue);
/**
* Run when reducer received each next element with key from argument
*
* @param stream stream where to send result
* @param key key of element
* @param nextValue received value
* @param accumulator accumulator which contains results of all previous operations
* @return accumulator for further operations
*/
A onNextItem(StreamDataReceiver stream, K key, I nextValue, A accumulator);
/**
* Run after receiving last element with key from argument
*
* @param stream stream where to send result
* @param key key of element
* @param accumulator accumulator which contains results of all previous operations
*/
void onComplete(StreamDataReceiver stream, K key, A accumulator);
}
/**
* Represents a helpful class which contains methods for simple casting types of input and
* output streams
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public abstract static class ReducerToResult {
/**
* Creates a new accumulator with key from argument
*
* @param key key for new accumulator
* @return new accumulator
*/
public abstract A createAccumulator(K key);
/**
* Processing value with accumulator
*
* @param accumulator accumulator with partials results
* @param value received value for accumulating
* @return changing accumulator
*/
public abstract A accumulate(A accumulator, I value);
/**
* Combines two accumulators from argument.
*
* @return new accumulator
*/
public A combine(A accumulator, A anotherAccumulator) {
throw new UnsupportedOperationException("can not combine two accumulators");
}
/**
* Calls after completing receiving results for some key. It processed
* obtained accumulator and returns stream of output type from generic
*
* @param accumulator obtained accumulator after end receiving
* @return stream of output type from generic
*/
public abstract O produceResult(A accumulator);
/**
* Creates a new reducer which receives items,accumulated it, produces after end of stream
* and streams result
*/
public final Reducer inputToOutput() {
return new InputToOutput<>(this);
}
/**
* Creates a new reducer which receives items,accumulated it and streams obtained accumulator
*/
public final Reducer inputToAccumulator() {
return new InputToAccumulator<>(this);
}
/**
* Creates a new reducer which receives accumulators,combines it, produces after end of stream
* and streams result
*/
public final Reducer accumulatorToOutput() {
return new AccumulatorToOutput<>(this);
}
/**
* Creates a new reducer which receives accumulators,combines it, and streams obtained accumulator
*/
public final Reducer accumulatorToAccumulator() {
return new AccumulatorToAccumulator<>(this);
}
/**
* Represents a reducer which contains ReducerToResult where identified methods for processing
* items . After searching accumulator performs some action with it with method produceResult
* from ReducerToResult.
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public static final class InputToOutput implements Reducer {
private ReducerToResult reducerToResult;
/**
* Creates a new instance of InputToOutput with ReducerToResult from arguments
*/
public InputToOutput(ReducerToResult reducerToResult) {
this.reducerToResult = reducerToResult;
}
/**
* Creates accumulator with ReducerToResult and accumulates with it first item
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
* @return accumulator with result
*/
@Override
public final A onFirstItem(StreamDataReceiver stream, K key, I firstValue) {
A accumulator = reducerToResult.createAccumulator(key);
return reducerToResult.accumulate(accumulator, firstValue);
}
/**
* Accumulates each next element.
*
* @param stream stream where to send result
* @param key key of element
* @param nextValue received value
* @param accumulator accumulator which contains results of all previous operations
* @return accumulator with result
*/
@Override
public final A onNextItem(StreamDataReceiver stream, K key, I nextValue, A accumulator) {
return reducerToResult.accumulate(accumulator, nextValue);
}
/**
* Produces result accumulator with ReducerToResult and streams it
*
* @param stream stream where to send result
* @param key key of element
* @param accumulator accumulator which contains results of all previous operations
*/
@Override
public final void onComplete(StreamDataReceiver stream, K key, A accumulator) {
stream.onData(reducerToResult.produceResult(accumulator));
}
}
/**
* Represents a reducer which contains ReducerToResult where identified methods for processing
* items . Streams obtained accumulator on complete.
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public static final class InputToAccumulator implements Reducer {
private ReducerToResult reducerToResult;
/**
* Creates a new instance of InputToAccumulator with ReducerToResult from argument
*/
public InputToAccumulator(ReducerToResult reducerToResult) {
this.reducerToResult = reducerToResult;
}
/**
* Creates accumulator with ReducerToResult and accumulates with it first item
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
* @return accumulator with result
*/
@Override
public A onFirstItem(StreamDataReceiver stream, K key, I firstValue) {
A accumulator = reducerToResult.createAccumulator(key);
return reducerToResult.accumulate(accumulator, firstValue);
}
/**
* Accumulates each next element.
*
* @param stream stream where to send result
* @param key key of element
* @param nextValue received value
* @param accumulator accumulator which contains results of all previous operations
* @return accumulator with result
*/
@Override
public A onNextItem(StreamDataReceiver stream, K key, I nextValue, A accumulator) {
return reducerToResult.accumulate(accumulator, nextValue);
}
/**
* Streams obtained accumulator
*
* @param stream stream where to send result
* @param key key of element
* @param accumulator accumulator which contains results of all previous operations
*/
@Override
public void onComplete(StreamDataReceiver stream, K key, A accumulator) {
stream.onData(accumulator);
}
}
/**
* Represents a reducer which contains ReducerToResult where identified methods for processing
* items . Each received item is accumulator and it combines with previous value. After
* searching accumulator performs some action with it with method produceResult from
* ReducerToResult.
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public static final class AccumulatorToOutput implements Reducer {
private ReducerToResult reducerToResult;
/**
* Creates a new instance of InputToAccumulator with ReducerToResult from argument
*/
public AccumulatorToOutput(ReducerToResult reducerToResult) {
this.reducerToResult = reducerToResult;
}
/**
* Creates accumulator which is first item
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
* @return accumulator with result
*/
@Override
public A onFirstItem(StreamDataReceiver stream, K key, A firstValue) {
return firstValue;
}
/**
* Combines previous accumulator and each next item
*
* @param stream stream where to send result
* @param key key of element
* @param nextValue received value
* @param accumulator accumulator which contains results of all previous combining
* @return accumulator with result
*/
@Override
public A onNextItem(StreamDataReceiver stream, K key, A nextValue, A accumulator) {
return reducerToResult.combine(accumulator, nextValue);
}
/**
* Produces result accumulator with ReducerToResult and streams it
*
* @param stream stream where to send result
* @param key key of element
* @param accumulator accumulator which contains results of all previous operations
*/
@Override
public void onComplete(StreamDataReceiver stream, K key, A accumulator) {
stream.onData(reducerToResult.produceResult(accumulator));
}
}
/**
* Represents a reducer which contains ReducerToResult where identified methods for processing
* items . Each received item is accumulator and it combines with previous value. Streams
* obtained accumulator on complete.
*
* @param type of keys
* @param type of input data
* @param type of output data
* @param type of accumulator
*/
public static final class AccumulatorToAccumulator implements Reducer {
private ReducerToResult reducerToResult;
public AccumulatorToAccumulator(ReducerToResult reducerToResult) {
this.reducerToResult = reducerToResult;
}
/**
* Creates accumulator which is first item
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
* @return accumulator with result
*/
@Override
public A onFirstItem(StreamDataReceiver stream, K key, A firstValue) {
return firstValue;
}
/**
* Combines previous accumulator and each next item
*
* @param stream stream where to send result
* @param key key of element
* @param nextValue received value
* @param accumulator accumulator which contains results of all previous combining
* @return accumulator with result
*/
@Override
public A onNextItem(StreamDataReceiver stream, K key, A nextValue, A accumulator) {
return reducerToResult.combine(accumulator, nextValue);
}
/**
* Streams obtained accumulator
*
* @param stream stream where to send result
* @param key key of element
* @param accumulator accumulator which contains results of all previous operations
*/
@Override
public void onComplete(StreamDataReceiver stream, K key, A accumulator) {
stream.onData(accumulator);
}
}
}
/**
* Represents a reducer which streams accumulator
*
* @param type of keys
* @param type of input data
* @param type of accumulator and type of output data
*/
public abstract static class ReducerToAccumulator extends ReducerToResult {
@Override
public final A produceResult(A accumulator) {
return accumulator;
}
}
/**
* Represents a reducer which deduplicates items with same keys. Streams only one item with
* each key
*
* @param type of keys
* @param type of input and output data
*/
public static class MergeDeduplicateReducer implements Reducer {
/**
* On first item with new key it streams it
*
* @param stream stream where to send result
* @param key key of element
* @param firstValue received value
*/
@Override
public Void onFirstItem(StreamDataReceiver stream, K key, T firstValue) {
stream.onData(firstValue);
return null;
}
@Override
public Void onNextItem(StreamDataReceiver stream, K key, T nextValue, Void accumulator) {
return null;
}
@Override
public void onComplete(StreamDataReceiver stream, K key, Void accumulator) {
}
}
/**
* Represent a reducer which streams received items sorted by keys
*
* @param type of keys
* @param type of input and output data
*/
public static class MergeSortReducer implements Reducer {
@Override
public Void onFirstItem(StreamDataReceiver stream, K key, T firstValue) {
stream.onData(firstValue);
return null;
}
@Override
public Void onNextItem(StreamDataReceiver stream, K key, T nextValue, Void accumulator) {
stream.onData(nextValue);
return null;
}
@Override
public void onComplete(StreamDataReceiver stream, K key, Void accumulator) {
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy