Java Code Examples for org.apache.flink.api.common.functions.FlatJoinFunction#join()
The following examples show how to use
org.apache.flink.api.common.functions.FlatJoinFunction#join() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AbstractMergeIterator.java From flink with Apache License 2.0 | 6 votes |
/** * Crosses a single value from the second side with N values, all sharing a common key. * Effectively realizes a <i>N:1</i> join. * * @param val1 The value form the <i>1</i> side. * @param firstValN The first of the values from the <i>N</i> side. * @param valsN Iterator over remaining <i>N</i> side values. * @throws Exception Forwards all exceptions thrown by the stub. */ private void crossSecond1withNValues(T2 val1, T1 firstValN, Iterator<T1> valsN, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { T2 copy2 = createCopy(serializer2, val1, this.copy2); joinFunction.join(firstValN, copy2, collector); // set copy and join first element boolean more = true; do { final T1 nRec = valsN.next(); if (valsN.hasNext()) { copy2 = createCopy(serializer2, val1, this.copy2); joinFunction.join(nRec, copy2, collector); } else { joinFunction.join(nRec, val1, collector); more = false; } } while (more); }
Example 2
Source File: AbstractMergeIterator.java From flink with Apache License 2.0 | 6 votes |
/** * Crosses a single value from the first input with N values, all sharing a common key. * Effectively realizes a <i>1:N</i> join. * * @param val1 The value form the <i>1</i> side. * @param firstValN The first of the values from the <i>N</i> side. * @param valsN Iterator over remaining <i>N</i> side values. * @throws Exception Forwards all exceptions thrown by the stub. */ private void crossFirst1withNValues(final T1 val1, final T2 firstValN, final Iterator<T2> valsN, final FlatJoinFunction<T1, T2, O> joinFunction, final Collector<O> collector) throws Exception { T1 copy1 = createCopy(serializer1, val1, this.copy1); joinFunction.join(copy1, firstValN, collector); // set copy and join first element boolean more = true; do { final T2 nRec = valsN.next(); if (valsN.hasNext()) { copy1 = createCopy(serializer1, val1, this.copy1); joinFunction.join(copy1, nRec, collector); } else { joinFunction.join(val1, nRec, collector); more = false; } } while (more); }
Example 3
Source File: AbstractMergeIterator.java From Flink-CEPplus with Apache License 2.0 | 6 votes |
/** * Crosses a single value from the first input with N values, all sharing a common key. * Effectively realizes a <i>1:N</i> join. * * @param val1 The value form the <i>1</i> side. * @param firstValN The first of the values from the <i>N</i> side. * @param valsN Iterator over remaining <i>N</i> side values. * @throws Exception Forwards all exceptions thrown by the stub. */ private void crossFirst1withNValues(final T1 val1, final T2 firstValN, final Iterator<T2> valsN, final FlatJoinFunction<T1, T2, O> joinFunction, final Collector<O> collector) throws Exception { T1 copy1 = createCopy(serializer1, val1, this.copy1); joinFunction.join(copy1, firstValN, collector); // set copy and join first element boolean more = true; do { final T2 nRec = valsN.next(); if (valsN.hasNext()) { copy1 = createCopy(serializer1, val1, this.copy1); joinFunction.join(copy1, nRec, collector); } else { joinFunction.join(val1, nRec, collector); more = false; } } while (more); }
Example 4
Source File: AbstractMergeIterator.java From Flink-CEPplus with Apache License 2.0 | 6 votes |
/** * Crosses a single value from the second side with N values, all sharing a common key. * Effectively realizes a <i>N:1</i> join. * * @param val1 The value form the <i>1</i> side. * @param firstValN The first of the values from the <i>N</i> side. * @param valsN Iterator over remaining <i>N</i> side values. * @throws Exception Forwards all exceptions thrown by the stub. */ private void crossSecond1withNValues(T2 val1, T1 firstValN, Iterator<T1> valsN, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { T2 copy2 = createCopy(serializer2, val1, this.copy2); joinFunction.join(firstValN, copy2, collector); // set copy and join first element boolean more = true; do { final T1 nRec = valsN.next(); if (valsN.hasNext()) { copy2 = createCopy(serializer2, val1, this.copy2); joinFunction.join(nRec, copy2, collector); } else { joinFunction.join(nRec, val1, collector); more = false; } } while (more); }
Example 5
Source File: OuterJoinOperatorBase.java From flink with Apache License 2.0 | 5 votes |
@Override protected List<OUT> executeOnCollections(List<IN1> leftInput, List<IN2> rightInput, RuntimeContext runtimeContext, ExecutionConfig executionConfig) throws Exception { TypeInformation<IN1> leftInformation = getOperatorInfo().getFirstInputType(); TypeInformation<IN2> rightInformation = getOperatorInfo().getSecondInputType(); TypeInformation<OUT> outInformation = getOperatorInfo().getOutputType(); TypeComparator<IN1> leftComparator = buildComparatorFor(0, executionConfig, leftInformation); TypeComparator<IN2> rightComparator = buildComparatorFor(1, executionConfig, rightInformation); TypeSerializer<IN1> leftSerializer = leftInformation.createSerializer(executionConfig); TypeSerializer<IN2> rightSerializer = rightInformation.createSerializer(executionConfig); OuterJoinListIterator<IN1, IN2> outerJoinIterator = new OuterJoinListIterator<>(leftInput, leftSerializer, leftComparator, rightInput, rightSerializer, rightComparator, outerJoinType); // -------------------------------------------------------------------- // Run UDF // -------------------------------------------------------------------- FlatJoinFunction<IN1, IN2, OUT> function = userFunction.getUserCodeObject(); FunctionUtils.setFunctionRuntimeContext(function, runtimeContext); FunctionUtils.openFunction(function, this.parameters); List<OUT> result = new ArrayList<>(); Collector<OUT> collector = new CopyingListCollector<>(result, outInformation.createSerializer(executionConfig)); while (outerJoinIterator.next()) { IN1 left = outerJoinIterator.getLeft(); IN2 right = outerJoinIterator.getRight(); function.join(left == null ? null : leftSerializer.copy(left), right == null ? null : rightSerializer.copy(right), collector); } FunctionUtils.closeFunction(function); return result; }
Example 6
Source File: AbstractMergeIterator.java From flink with Apache License 2.0 | 5 votes |
protected void crossMatchingGroup(Iterator<T1> values1, Iterator<T2> values2, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { final T1 firstV1 = values1.next(); final T2 firstV2 = values2.next(); final boolean v1HasNext = values1.hasNext(); final boolean v2HasNext = values2.hasNext(); // check if one side is already empty // this check could be omitted if we put this in MatchTask. // then we can derive the local strategy (with build side). if (v1HasNext) { if (v2HasNext) { // both sides contain more than one value // TODO: Decide which side to spill and which to block! crossMwithNValues(firstV1, values1, firstV2, values2, joinFunction, collector); } else { crossSecond1withNValues(firstV2, firstV1, values1, joinFunction, collector); } } else { if (v2HasNext) { crossFirst1withNValues(firstV1, firstV2, values2, joinFunction, collector); } else { // both sides contain only one value joinFunction.join(firstV1, firstV2, collector); } } }
Example 7
Source File: AbstractMergeOuterJoinIterator.java From flink with Apache License 2.0 | 5 votes |
private void joinRightKeyValuesWithNull(Iterator<T2> values, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { while (values.hasNext()) { T2 next = values.next(); this.copy2 = createCopy(serializer2, next, copy2); joinFunction.join(null, copy2, collector); } }
Example 8
Source File: AbstractMergeOuterJoinIterator.java From flink with Apache License 2.0 | 5 votes |
private void joinLeftKeyValuesWithNull(Iterator<T1> values, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { while (values.hasNext()) { T1 next = values.next(); this.copy1 = createCopy(serializer1, next, copy1); joinFunction.join(copy1, null, collector); } }
Example 9
Source File: ReusingBuildSecondHashJoinIterator.java From flink with Apache License 2.0 | 5 votes |
@Override public boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V2> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V1 probeRecord = this.hashJoin.getCurrentProbeRecord(); V2 nextBuildSideRecord = buildSideIterator.next(this.nextBuildSideObject); if (probeRecord != null && nextBuildSideRecord != null) { matchFunction.join(probeRecord, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(probeRecord, nextBuildSideRecord, collector); } } else { if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(probeRecord, null, collector); } if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(null, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(null, nextBuildSideRecord, collector); } } } return true; } else { return false; } }
Example 10
Source File: OuterJoinOperatorBase.java From Flink-CEPplus with Apache License 2.0 | 5 votes |
@Override protected List<OUT> executeOnCollections(List<IN1> leftInput, List<IN2> rightInput, RuntimeContext runtimeContext, ExecutionConfig executionConfig) throws Exception { TypeInformation<IN1> leftInformation = getOperatorInfo().getFirstInputType(); TypeInformation<IN2> rightInformation = getOperatorInfo().getSecondInputType(); TypeInformation<OUT> outInformation = getOperatorInfo().getOutputType(); TypeComparator<IN1> leftComparator = buildComparatorFor(0, executionConfig, leftInformation); TypeComparator<IN2> rightComparator = buildComparatorFor(1, executionConfig, rightInformation); TypeSerializer<IN1> leftSerializer = leftInformation.createSerializer(executionConfig); TypeSerializer<IN2> rightSerializer = rightInformation.createSerializer(executionConfig); OuterJoinListIterator<IN1, IN2> outerJoinIterator = new OuterJoinListIterator<>(leftInput, leftSerializer, leftComparator, rightInput, rightSerializer, rightComparator, outerJoinType); // -------------------------------------------------------------------- // Run UDF // -------------------------------------------------------------------- FlatJoinFunction<IN1, IN2, OUT> function = userFunction.getUserCodeObject(); FunctionUtils.setFunctionRuntimeContext(function, runtimeContext); FunctionUtils.openFunction(function, this.parameters); List<OUT> result = new ArrayList<>(); Collector<OUT> collector = new CopyingListCollector<>(result, outInformation.createSerializer(executionConfig)); while (outerJoinIterator.next()) { IN1 left = outerJoinIterator.getLeft(); IN2 right = outerJoinIterator.getRight(); function.join(left == null ? null : leftSerializer.copy(left), right == null ? null : rightSerializer.copy(right), collector); } FunctionUtils.closeFunction(function); return result; }
Example 11
Source File: AbstractMergeIterator.java From Flink-CEPplus with Apache License 2.0 | 5 votes |
protected void crossMatchingGroup(Iterator<T1> values1, Iterator<T2> values2, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { final T1 firstV1 = values1.next(); final T2 firstV2 = values2.next(); final boolean v1HasNext = values1.hasNext(); final boolean v2HasNext = values2.hasNext(); // check if one side is already empty // this check could be omitted if we put this in MatchTask. // then we can derive the local strategy (with build side). if (v1HasNext) { if (v2HasNext) { // both sides contain more than one value // TODO: Decide which side to spill and which to block! crossMwithNValues(firstV1, values1, firstV2, values2, joinFunction, collector); } else { crossSecond1withNValues(firstV2, firstV1, values1, joinFunction, collector); } } else { if (v2HasNext) { crossFirst1withNValues(firstV1, firstV2, values2, joinFunction, collector); } else { // both sides contain only one value joinFunction.join(firstV1, firstV2, collector); } } }
Example 12
Source File: AbstractMergeOuterJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 5 votes |
private void joinRightKeyValuesWithNull(Iterator<T2> values, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { while (values.hasNext()) { T2 next = values.next(); this.copy2 = createCopy(serializer2, next, copy2); joinFunction.join(null, copy2, collector); } }
Example 13
Source File: AbstractMergeOuterJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 5 votes |
private void joinLeftKeyValuesWithNull(Iterator<T1> values, FlatJoinFunction<T1, T2, O> joinFunction, Collector<O> collector) throws Exception { while (values.hasNext()) { T1 next = values.next(); this.copy1 = createCopy(serializer1, next, copy1); joinFunction.join(copy1, null, collector); } }
Example 14
Source File: ReusingBuildSecondHashJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 5 votes |
@Override public boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V2> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V1 probeRecord = this.hashJoin.getCurrentProbeRecord(); V2 nextBuildSideRecord = buildSideIterator.next(this.nextBuildSideObject); if (probeRecord != null && nextBuildSideRecord != null) { matchFunction.join(probeRecord, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(probeRecord, nextBuildSideRecord, collector); } } else { if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(probeRecord, null, collector); } if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(null, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(null, nextBuildSideRecord, collector); } } } return true; } else { return false; } }
Example 15
Source File: NonReusingBuildSecondHashJoinIterator.java From flink with Apache License 2.0 | 4 votes |
@Override public boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V2> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V1 probeRecord = this.hashJoin.getCurrentProbeRecord(); V2 nextBuildSideRecord = buildSideIterator.next(); if (probeRecord != null && nextBuildSideRecord != null) { V2 tmpRec; // check if there is another build-side value if ((tmpRec = buildSideIterator.next()) != null) { // more than one build-side value --> copy the probe side V1 probeCopy; probeCopy = this.probeSideSerializer.copy(probeRecord); // call match on the first pair matchFunction.join(probeCopy, nextBuildSideRecord, collector); // call match on the second pair probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(probeCopy, tmpRec, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { // call match on the next pair // make sure we restore the value of the probe side record probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(probeCopy, nextBuildSideRecord, collector); } } else { // only single pair matches matchFunction.join(probeRecord, nextBuildSideRecord, collector); } } else { // while probe side outer join, join current probe record with null. if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(probeRecord, null, collector); } // while build side outer join, iterate all build records which have not been probed before, // and join with null. if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(null, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { matchFunction.join(null, nextBuildSideRecord, collector); } } } return true; } else { return false; } }
Example 16
Source File: NonReusingBuildFirstHashJoinIterator.java From flink with Apache License 2.0 | 4 votes |
@Override public final boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V1> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V2 probeRecord = this.hashJoin.getCurrentProbeRecord(); V1 nextBuildSideRecord = buildSideIterator.next(); // get the first build side value if (probeRecord != null && nextBuildSideRecord != null) { V1 tmpRec; // check if there is another build-side value if ((tmpRec = buildSideIterator.next()) != null) { // more than one build-side value --> copy the probe side V2 probeCopy; probeCopy = this.probeSideSerializer.copy(probeRecord); // call match on the first pair matchFunction.join(nextBuildSideRecord, probeCopy, collector); // call match on the second pair probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(tmpRec, probeCopy, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { // call match on the next pair // make sure we restore the value of the probe side record probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(nextBuildSideRecord, probeCopy, collector); } } else { // only single pair matches matchFunction.join(nextBuildSideRecord, probeRecord, collector); } } else { // while probe side outer join, join current probe record with null. if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(null, probeRecord, collector); } // while build side outer join, iterate all build records which have not been probed before, // and join with null. if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(nextBuildSideRecord, null, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { matchFunction.join(nextBuildSideRecord, null, collector); } } } return true; } else { return false; } }
Example 17
Source File: ReusingBuildFirstHashJoinIterator.java From flink with Apache License 2.0 | 4 votes |
@Override public final boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V1> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V2 probeRecord = this.hashJoin.getCurrentProbeRecord(); V1 nextBuildSideRecord = buildSideIterator.next(this.nextBuildSideObject); if (probeRecord != null && nextBuildSideRecord != null) { matchFunction.join(nextBuildSideRecord, probeRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(nextBuildSideRecord, probeRecord, collector); } } else { if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(null, probeRecord, collector); } if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { // call match on the first pair matchFunction.join(nextBuildSideRecord, null, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { // call match on the next pair // make sure we restore the value of the probe side record matchFunction.join(nextBuildSideRecord, null, collector); } } } return true; } else { return false; } }
Example 18
Source File: ReusingBuildFirstHashJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 4 votes |
@Override public final boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V1> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V2 probeRecord = this.hashJoin.getCurrentProbeRecord(); V1 nextBuildSideRecord = buildSideIterator.next(this.nextBuildSideObject); if (probeRecord != null && nextBuildSideRecord != null) { matchFunction.join(nextBuildSideRecord, probeRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { matchFunction.join(nextBuildSideRecord, probeRecord, collector); } } else { if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(null, probeRecord, collector); } if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { // call match on the first pair matchFunction.join(nextBuildSideRecord, null, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next(nextBuildSideRecord)) != null)) { // call match on the next pair // make sure we restore the value of the probe side record matchFunction.join(nextBuildSideRecord, null, collector); } } } return true; } else { return false; } }
Example 19
Source File: NonReusingBuildFirstHashJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 4 votes |
@Override public final boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V1> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V2 probeRecord = this.hashJoin.getCurrentProbeRecord(); V1 nextBuildSideRecord = buildSideIterator.next(); // get the first build side value if (probeRecord != null && nextBuildSideRecord != null) { V1 tmpRec; // check if there is another build-side value if ((tmpRec = buildSideIterator.next()) != null) { // more than one build-side value --> copy the probe side V2 probeCopy; probeCopy = this.probeSideSerializer.copy(probeRecord); // call match on the first pair matchFunction.join(nextBuildSideRecord, probeCopy, collector); // call match on the second pair probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(tmpRec, probeCopy, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { // call match on the next pair // make sure we restore the value of the probe side record probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(nextBuildSideRecord, probeCopy, collector); } } else { // only single pair matches matchFunction.join(nextBuildSideRecord, probeRecord, collector); } } else { // while probe side outer join, join current probe record with null. if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(null, probeRecord, collector); } // while build side outer join, iterate all build records which have not been probed before, // and join with null. if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(nextBuildSideRecord, null, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { matchFunction.join(nextBuildSideRecord, null, collector); } } } return true; } else { return false; } }
Example 20
Source File: NonReusingBuildSecondHashJoinIterator.java From Flink-CEPplus with Apache License 2.0 | 4 votes |
@Override public boolean callWithNextKey(FlatJoinFunction<V1, V2, O> matchFunction, Collector<O> collector) throws Exception { if (this.hashJoin.nextRecord()) { // we have a next record, get the iterators to the probe and build side values final MutableObjectIterator<V2> buildSideIterator = this.hashJoin.getBuildSideIterator(); final V1 probeRecord = this.hashJoin.getCurrentProbeRecord(); V2 nextBuildSideRecord = buildSideIterator.next(); if (probeRecord != null && nextBuildSideRecord != null) { V2 tmpRec; // check if there is another build-side value if ((tmpRec = buildSideIterator.next()) != null) { // more than one build-side value --> copy the probe side V1 probeCopy; probeCopy = this.probeSideSerializer.copy(probeRecord); // call match on the first pair matchFunction.join(probeCopy, nextBuildSideRecord, collector); // call match on the second pair probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(probeCopy, tmpRec, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { // call match on the next pair // make sure we restore the value of the probe side record probeCopy = this.probeSideSerializer.copy(probeRecord); matchFunction.join(probeCopy, nextBuildSideRecord, collector); } } else { // only single pair matches matchFunction.join(probeRecord, nextBuildSideRecord, collector); } } else { // while probe side outer join, join current probe record with null. if (probeSideOuterJoin && probeRecord != null && nextBuildSideRecord == null) { matchFunction.join(probeRecord, null, collector); } // while build side outer join, iterate all build records which have not been probed before, // and join with null. if (buildSideOuterJoin && probeRecord == null && nextBuildSideRecord != null) { matchFunction.join(null, nextBuildSideRecord, collector); while (this.running && ((nextBuildSideRecord = buildSideIterator.next()) != null)) { matchFunction.join(null, nextBuildSideRecord, collector); } } } return true; } else { return false; } }