// private helper method for custom partitioning private <K> DataStream<T> partitionCustom(Partitioner<K> partitioner, Keys<T> keys) { KeySelector<T, K> keySelector = KeySelectorUtil.getSelectorForOneKey(keys, partitioner, getType(), getExecutionConfig()); return setConnectionType( new CustomPartitionerWrapper<>(clean(partitioner), clean(keySelector))); }
/** * Partitions the operator state of a {@link DataStream} by the given key positions. * * @param fields The position of the fields on which the {@link DataStream} will be grouped. * @return The {@link DataStream} with partitioned state (i.e. KeyedStream) */ public KeyedStream<T, Tuple> keyBy(int... fields) { if (getType() instanceof BasicArrayTypeInfo || getType() instanceof PrimitiveArrayTypeInfo) { return keyBy(KeySelectorUtil.getSelectorForArray(fields, getType())); } else { return keyBy(new Keys.ExpressionKeys<>(fields, getType())); } }
private KeyedStream<T, Tuple> keyBy(Keys<T> keys) { return new KeyedStream<>( this, clean(KeySelectorUtil.getSelectorForKeys(keys, getType(), getExecutionConfig()))); }
public class TumblingGroupedPreReducerTest { TypeInformation<Tuple2<Integer, Integer>> type = TypeExtractor.getForObject(new Tuple2<Integer, Integer>(1, 1)); TypeSerializer<Tuple2<Integer, Integer>> serializer = type.createSerializer(null); KeySelector<Tuple2<Integer, Integer>, ?> key = KeySelectorUtil.getSelectorForKeys( new Keys.ExpressionKeys<Tuple2<Integer, Integer>>(new int[] {0}, type), type, null); Reducer reducer = new Reducer(); @SuppressWarnings("unchecked") @Test public void testEmitWindow() throws Exception { List<Tuple2<Integer, Integer>> inputs = new ArrayList<Tuple2<Integer, Integer>>(); inputs.add(new Tuple2<Integer, Integer>(1, 1)); inputs.add(new Tuple2<Integer, Integer>(0, 0)); inputs.add(new Tuple2<Integer, Integer>(1, -1)); inputs.add(new Tuple2<Integer, Integer>(1, -2)); TestCollector<StreamWindow<Tuple2<Integer, Integer>>> collector = new TestCollector<StreamWindow<Tuple2<Integer, Integer>>>(); List<StreamWindow<Tuple2<Integer, Integer>>> collected = collector.getCollected(); WindowBuffer<Tuple2<Integer, Integer>> wb = new TumblingGroupedPreReducer<Tuple2<Integer, Integer>>(reducer, key, serializer); wb.store(serializer.copy(inputs.get(0))); wb.store(serializer.copy(inputs.get(1))); wb.emitWindow(collector); wb.evict(2); assertEquals(1, collected.size()); assertSetEquals( StreamWindow.fromElements( new Tuple2<Integer, Integer>(1, 1), new Tuple2<Integer, Integer>(0, 0)), collected.get(0)); wb.store(serializer.copy(inputs.get(0))); wb.store(serializer.copy(inputs.get(1))); wb.store(serializer.copy(inputs.get(2))); wb.store(serializer.copy(inputs.get(3))); wb.emitWindow(collector); wb.evict(4); assertEquals(2, collected.size()); assertSetEquals( StreamWindow.fromElements( new Tuple2<Integer, Integer>(3, -2), new Tuple2<Integer, Integer>(0, 0)), collected.get(1)); // Test whether function is mutating inputs or not assertEquals(2, reducer.allInputs.size()); assertEquals(reducer.allInputs.get(0), inputs.get(2)); assertEquals(reducer.allInputs.get(1), inputs.get(3)); } @SuppressWarnings("unchecked") @Test public void testEmitWindow2() throws Exception { List<Tuple2<Integer, Integer>> inputs = new ArrayList<Tuple2<Integer, Integer>>(); inputs.add(new Tuple2<Integer, Integer>(1, 1)); inputs.add(new Tuple2<Integer, Integer>(0, 0)); inputs.add(new Tuple2<Integer, Integer>(1, -1)); inputs.add(new Tuple2<Integer, Integer>(1, -2)); TestCollector<StreamWindow<Tuple2<Integer, Integer>>> collector = new TestCollector<StreamWindow<Tuple2<Integer, Integer>>>(); List<StreamWindow<Tuple2<Integer, Integer>>> collected = collector.getCollected(); WindowBuffer<Tuple2<Integer, Integer>> wb = new TumblingGroupedPreReducer<Tuple2<Integer, Integer>>(reducer, key, serializer) .sequentialID(); wb.store(serializer.copy(inputs.get(0))); wb.store(serializer.copy(inputs.get(1))); wb.emitWindow(collector); wb.evict(2); assertSetEquals(StreamWindow.fromElements(inputs.get(0), inputs.get(1)), collected.get(0)); wb.store(serializer.copy(inputs.get(0))); wb.store(serializer.copy(inputs.get(1))); wb.store(serializer.copy(inputs.get(2))); wb.emitWindow(collector); wb.evict(3); assertSetEquals( StreamWindow.fromElements(new Tuple2<Integer, Integer>(2, 0), inputs.get(1)), collected.get(1)); } private static <T> void assertSetEquals(Collection<T> first, Collection<T> second) { assertEquals(new HashSet<T>(first), new HashSet<T>(second)); } @SuppressWarnings("serial") private class Reducer implements ReduceFunction<Tuple2<Integer, Integer>> { public List<Tuple2<Integer, Integer>> allInputs = new ArrayList<Tuple2<Integer, Integer>>(); @Override public Tuple2<Integer, Integer> reduce( Tuple2<Integer, Integer> value1, Tuple2<Integer, Integer> value2) throws Exception { allInputs.add(value2); value1.f0 = value1.f0 + value2.f0; value1.f1 = value1.f1 + value2.f1; return value1; } } }