### Question:
SemiJoinStatsCalculator { public static PlanNodeStatsEstimate computeSemiJoin(PlanNodeStatsEstimate sourceStats, PlanNodeStatsEstimate filteringSourceStats, Symbol sourceJoinSymbol, Symbol filteringSourceJoinSymbol) { return compute(sourceStats, filteringSourceStats, sourceJoinSymbol, filteringSourceJoinSymbol, (sourceJoinSymbolStats, filteringSourceJoinSymbolStats) -> min(filteringSourceJoinSymbolStats.getDistinctValuesCount(), sourceJoinSymbolStats.getDistinctValuesCount())); } private  SemiJoinStatsCalculator(); static PlanNodeStatsEstimate computeSemiJoin(PlanNodeStatsEstimate sourceStats, PlanNodeStatsEstimate filteringSourceStats, Symbol sourceJoinSymbol, Symbol filteringSourceJoinSymbol); static PlanNodeStatsEstimate computeAntiJoin(PlanNodeStatsEstimate sourceStats, PlanNodeStatsEstimate filteringSourceStats, Symbol sourceJoinSymbol, Symbol filteringSourceJoinSymbol);  }### Answer:
@Test public void testSemiJoin() { assertThat(computeSemiJoin(inputStatistics, inputStatistics, x, w)) .symbolStats(x, stats -> stats .lowValue(xStats.getLowValue()) .highValue(xStats.getHighValue()) .nullsFraction(0) .distinctValuesCount(wStats.getDistinctValuesCount())) .symbolStats(w, stats -> stats.isEqualTo(wStats)) .symbolStats(z, stats -> stats.isEqualTo(zStats)) .outputRowsCount(inputStatistics.getOutputRowCount() * xStats.getValuesFraction() * (wStats.getDistinctValuesCount() / xStats.getDistinctValuesCount())); assertThat(computeSemiJoin(inputStatistics, inputStatistics, x, u)) .symbolStats(x, stats -> stats .lowValue(xStats.getLowValue()) .highValue(xStats.getHighValue()) .nullsFraction(0) .distinctValuesCount(xStats.getDistinctValuesCount())) .symbolStats(u, stats -> stats.isEqualTo(uStats)) .symbolStats(z, stats -> stats.isEqualTo(zStats)) .outputRowsCount(inputStatistics.getOutputRowCount() * xStats.getValuesFraction()); assertThat(computeSemiJoin(inputStatistics, inputStatistics, unknown, u)) .symbolStats(unknown, stats -> stats .nullsFraction(0) .distinctValuesCountUnknown() .unknownRange()) .symbolStats(u, stats -> stats.isEqualTo(uStats)) .symbolStats(z, stats -> stats.isEqualTo(zStats)) .outputRowsCountUnknown(); assertThat(computeSemiJoin(inputStatistics, inputStatistics, x, unknown)) .symbolStats(x, stats -> stats .nullsFraction(0) .lowValue(xStats.getLowValue()) .highValue(xStats.getHighValue()) .distinctValuesCountUnknown()) .symbolStatsUnknown(unknown) .symbolStats(z, stats -> stats.isEqualTo(zStats)) .outputRowsCountUnknown(); assertThat(computeSemiJoin(inputStatistics, inputStatistics, emptyRange, emptyRange)) .outputRowsCount(0); assertThat(computeSemiJoin(inputStatistics, inputStatistics, fractionalNdv, fractionalNdv)) .outputRowsCount(1000) .symbolStats(fractionalNdv, stats -> stats .nullsFraction(0) .distinctValuesCount(0.1)); }