@Override public <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> bindCombiningValueWithContext( StateTag<CombiningState<InputT, AccumT, OutputT>> address, Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) { return bindCombiningValue(address, accumCoder, CombineFnUtil.bindContext(combineFn, c)); } };
@Test public void testToFnWithContextIdempotent() throws Exception { CombineFnWithContext<Integer, int[], Integer> fnWithContext = CombineFnUtil.toFnWithContext(Sum.ofIntegers()); assertTrue(fnWithContext == CombineFnUtil.toFnWithContext(fnWithContext)); }
@Test public void testToFnWithContext() throws Exception { CombineFnWithContext<Integer, int[], Integer> fnWithContext = CombineFnUtil.toFnWithContext(Sum.ofIntegers()); List<Integer> inputs = ImmutableList.of(1, 2, 3, 4); Context nullContext = CombineContextFactory.nullContext(); int[] accum = fnWithContext.createAccumulator(nullContext); for (Integer i : inputs) { accum = fnWithContext.addInput(accum, i, nullContext); } assertEquals(10, fnWithContext.extractOutput(accum, nullContext).intValue()); } }
@Override public <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> bindCombiningValueWithContext( StateTag<CombiningState<InputT, AccumT, OutputT>> address, Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) { return bindCombiningValue(address, accumCoder, CombineFnUtil.bindContext(combineFn, c)); } };
/** * Returns a {@link ComposedCombineFnWithContext} with an additional {@link * CombineFnWithContext}. */ public <InputT, OutputT> ComposedCombineFnWithContext<DataT> with( SimpleFunction<DataT, InputT> extractInputFn, CombineFnWithContext<InputT, ?, OutputT> combineFn, TupleTag<OutputT> outputTag) { checkUniqueness(outputTags, outputTag); List<CombineFnWithContext<Object, Object, Object>> fnsWithContext = Lists.newArrayList(); for (CombineFn<Object, Object, Object> fn : combineFns) { fnsWithContext.add(CombineFnUtil.toFnWithContext(fn)); } return new ComposedCombineFnWithContext<>( ImmutableList.<SerializableFunction<DataT, ?>>builder() .addAll(extractInputFns) .add(extractInputFn) .build(), ImmutableList.<Optional<Coder>>builder() .addAll(combineInputCoders) .add(Optional.absent()) .build(), ImmutableList.<CombineFnWithContext<?, ?, ?>>builder() .addAll(fnsWithContext) .add(combineFn) .build(), ImmutableList.<TupleTag<?>>builder().addAll(outputTags).add(outputTag).build()); }
@Override public <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> bindCombiningValueWithContext( StateTag<CombiningState<InputT, AccumT, OutputT>> address, Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) { return bindCombiningValue(address, accumCoder, CombineFnUtil.bindContext(combineFn, c)); } };
StateTags.combiningValueWithContext("foo", accum1, CombineFnUtil.toFnWithContext(maxFn)); StateTag<?> fooCoder1Max2 = StateTags.combiningValueWithContext("foo", accum1, CombineFnUtil.toFnWithContext(maxFn)); StateTag<?> fooCoder1Min = StateTags.combiningValueWithContext("foo", accum1, CombineFnUtil.toFnWithContext(minFn)); StateTags.combiningValueWithContext("foo", accum2, CombineFnUtil.toFnWithContext(maxFn)); StateTag<?> barCoder1Max = StateTags.combiningValueWithContext("bar", accum1, CombineFnUtil.toFnWithContext(maxFn));
@Override public <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> bindCombiningValueWithContext( StateTag<CombiningState<InputT, AccumT, OutputT>> address, Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) { return bindCombiningValue(address, accumCoder, CombineFnUtil.bindContext(combineFn, c)); } };
/** * Returns a {@link ComposedCombineFnWithContext} with an additional {@link GlobalCombineFn}. */ public <InputT, OutputT> ComposedCombineFnWithContext<DataT> with( SimpleFunction<DataT, InputT> extractInputFn, Coder<InputT> combineInputCoder, GlobalCombineFn<InputT, ?, OutputT> globalCombineFn, TupleTag<OutputT> outputTag) { checkUniqueness(outputTags, outputTag); return new ComposedCombineFnWithContext<>( ImmutableList.<SerializableFunction<DataT, ?>>builder() .addAll(extractInputFns) .add(extractInputFn) .build(), ImmutableList.<Optional<Coder>>builder() .addAll(combineInputCoders) .add(Optional.of(combineInputCoder)) .build(), ImmutableList.<CombineFnWithContext<?, ?, ?>>builder() .addAll(combineFnWithContexts) .add(CombineFnUtil.toFnWithContext(globalCombineFn)) .build(), ImmutableList.<TupleTag<?>>builder().addAll(outputTags).add(outputTag).build()); }
@Override public <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> bindCombiningValueWithContext( StateTag<CombiningState<InputT, AccumT, OutputT>> address, Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) { return bindCombiningValue(address, accumCoder, CombineFnUtil.bindContext(combineFn, c)); } }
/** * Returns a {@link ComposedCombineFnWithContext} with an additional {@link GlobalCombineFn}. */ public <InputT, OutputT> ComposedCombineFnWithContext<DataT> with( SimpleFunction<DataT, InputT> extractInputFn, GlobalCombineFn<InputT, ?, OutputT> globalCombineFn, TupleTag<OutputT> outputTag) { checkUniqueness(outputTags, outputTag); return new ComposedCombineFnWithContext<>( ImmutableList.<SerializableFunction<DataT, ?>>builder() .addAll(extractInputFns) .add(extractInputFn) .build(), ImmutableList.<Optional<Coder>>builder() .addAll(combineInputCoders) .add(Optional.absent()) .build(), ImmutableList.<CombineFnWithContext<?, ?, ?>>builder() .addAll(combineFnWithContexts) .add(CombineFnUtil.toFnWithContext(globalCombineFn)) .build(), ImmutableList.<TupleTag<?>>builder().addAll(outputTags).add(outputTag).build()); }
@Test public void testNonSerializable() throws Exception { expectedException.expect(NotSerializableException.class); expectedException.expectMessage( "Cannot serialize the CombineFn resulting from CombineFnUtil.bindContext."); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(buffer); oos.writeObject(CombineFnUtil.bindContext(mockCombineFn, StateContexts.nullContext())); }