@Override public PCollection<KV<K, Iterable<V>>> expand(PCollection<KV<K, V>> input) { applicableTo(input); // Verify that the input Coder<KV<K, V>> is a KvCoder<K, V>, and that // the key coder is deterministic. Coder<K> keyCoder = getKeyCoder(input.getCoder()); try { keyCoder.verifyDeterministic(); } catch (NonDeterministicException e) { throw new IllegalStateException("the keyCoder of a GroupByKey must be deterministic", e); } // This primitive operation groups by the combination of key and window, // merging windows as needed, using the windows assigned to the // key/value input elements and the window merge operation of the // window function associated with the input PCollection. return PCollection.createPrimitiveOutputInternal( input.getPipeline(), updateWindowingStrategy(input.getWindowingStrategy()), input.isBounded(), getOutputKvCoder(input.getCoder())); }
@Override public PCollection<KV<K, Iterable<V>>> expand(PCollection<KV<K, V>> input) { WindowingStrategy<?, ?> windowingStrategy = input.getWindowingStrategy(); return input // Group by just the key. // Combiner lifting will not happen regardless of the disallowCombinerLifting value. // There will be no combiners right after the GroupByKeyOnly because of the two ParDos // introduced in here. .apply(new GroupByKeyOnly<>()) // Sort each key's values by timestamp. GroupAlsoByWindow requires // its input to be sorted by timestamp. .apply(new SortValuesByTimestamp<>()) // Group each key's values by window, merging windows as needed. .apply(new GroupAlsoByWindow<>(windowingStrategy)) // And update the windowing strategy as appropriate. .setWindowingStrategyInternal(gbkTransform.updateWindowingStrategy(windowingStrategy)); }