private <K, V> OptimizableRepartitionNode<K, V> createRepartitionNode(final String repartitionTopicName,
                                                                          final Serde<K> keySerde,
                                                                          final Serde<V> valueSerde) {

        final OptimizableRepartitionNode.OptimizableRepartitionNodeBuilder<K, V> repartitionNodeBuilder =
            OptimizableRepartitionNode.optimizableRepartitionNodeBuilder();
        KStreamImpl.createRepartitionedSource(
                this,
                keySerde,
                valueSerde,
                repartitionTopicName,
                null,
                repartitionNodeBuilder
        );

        // ensures setting the repartition topic to the name of the
        // first repartition topic to get merged
        // this may be an auto-generated name or a user specified name
        repartitionNodeBuilder.withRepartitionTopic(repartitionTopicName);

        return repartitionNodeBuilder.build();

    }
The self-join rewriting can be applied if the StreamStreamJoinNode has a single parent.
If the join is a self-join, remove the node KStreamJoinWindow corresponding to the
right argument of the join (the "other"). The join node may have multiple siblings but for
this rewriting we only care about the ThisKStreamJoinWindow and the OtherKStreamJoinWindow.
We iterate over all the siblings to identify these two nodes so that we can remove the
latter.
streams/src/main/java/org/apache/kafka/streams/kstream/internals/InternalStreamsBuilder.java