private void doTest( TestData.TupleGeneratorIterator buildInput, TestData.TupleGeneratorIterator probeInput, TupleGenerator bgen, TupleGenerator pgen) throws Exception { // collect expected data final Map<Integer, Collection<TupleMatch>> expectedFirstMatchesMap = NonReusingHashJoinIteratorITCase.joinTuples( NonReusingHashJoinIteratorITCase.collectTupleData(buildInput), NonReusingHashJoinIteratorITCase.collectTupleData(probeInput)); final List<Map<Integer, Collection<TupleMatch>>> expectedNMatchesMapList = new ArrayList<>(NUM_PROBES); final FlatJoinFunction[] nMatcher = new TupleMatchRemovingJoin[NUM_PROBES]; for (int i = 0; i < NUM_PROBES; i++) { Map<Integer, Collection<TupleMatch>> tmp; expectedNMatchesMapList.add(tmp = deepCopy(expectedFirstMatchesMap)); nMatcher[i] = new TupleMatchRemovingJoin(tmp); } final FlatJoinFunction firstMatcher = new TupleMatchRemovingJoin(expectedFirstMatchesMap); final Collector<Tuple2<Integer, String>> collector = new DiscardingOutputCollector<>(); // reset the generators bgen.reset(); pgen.reset(); buildInput.reset(); probeInput.reset(); // compare with iterator values NonReusingBuildFirstReOpenableHashJoinIterator< Tuple2<Integer, String>, Tuple2<Integer, String>, Tuple2<Integer, String>> iterator = new NonReusingBuildFirstReOpenableHashJoinIterator<>( buildInput, probeInput, this.recordSerializer, this.record1Comparator, this.recordSerializer, this.record2Comparator, this.recordPairComparator, this.memoryManager, ioManager, this.parentTask, 1.0, false, false, true); iterator.open(); // do first join with both inputs while (iterator.callWithNextKey(firstMatcher, collector)) ; // assert that each expected match was seen for the first input for (Entry<Integer, Collection<TupleMatch>> entry : expectedFirstMatchesMap.entrySet()) { if (!entry.getValue().isEmpty()) { Assert.fail("Collection for key " + entry.getKey() + " is not empty"); } } for (int i = 0; i < NUM_PROBES; i++) { pgen.reset(); probeInput.reset(); // prepare .. iterator.reopenProbe(probeInput); // .. and do second join while (iterator.callWithNextKey(nMatcher[i], collector)) ; // assert that each expected match was seen for the second input for (Entry<Integer, Collection<TupleMatch>> entry : expectedNMatchesMapList.get(i).entrySet()) { if (!entry.getValue().isEmpty()) { Assert.fail("Collection for key " + entry.getKey() + " is not empty"); } } } iterator.close(); }