目录
Reduce.run()
首先来到的是 Reduce.run(),先初始化 context,然后进入循环,进入判断条件 context.nextKey()。
/** Reduces a set of intermediate values which share a key to a smaller set ofvalues. **/
public void run(Context context) throws IOException, InterruptedException {
setup(context);
try {
while (context.nextKey()) {
reduce(context.getCurrentKey(), context.getValues(), context); //这里就是调用我们重写的reduce方法
// If a back up store is used, reset it
Iterator<VALUEIN> iter = context.getValues().iterator();
if(iter instanceof ReduceContext.ValueIterator) {
((ReduceContext.ValueIterator<VALUEIN>)iter).resetBackupStore();
}
}
} finally {
cleanup(context);
}
}
public boolean nextKey() throws IOException, InterruptedException {
return reduceContext.nextKey();
}
ReduceContextImpl.nextKey()
进入上面的 nextKey() 就会来到下面的 ReduceContextImpl.nextKey()。
由于 nextKeyIsSame 初始值是 false,所以一开始不会进入while循环。while循环的作用是如果下一个key和当前的key相同,就跳过当前ReduceContextImpl对象的key和value,nextKeyValue() 更新key和value。如果 hasMore==true,进入if,先增加value数,再进入 nextKeyValue()。
当执行完一次reduce方法再来这个地方时,该处的 nextKeyValue() 提前将旧的key和value更新为下一个key和value。
/** Start processing next unique key. */
public boolean nextKey() throws IOException,InterruptedException {
while (hasMore && nextKeyIsSame) {
nextKeyValue();
}
if (hasMore) {
if (inputKeyCounter != null) {
inputKeyCounter.increment(1);
}
return nextKeyValue();
} else {
return false;
}
}
hasMore 是是否还有下一个KV对,它在 ReduceContextImpl 对象创建时初始化,hasMore = input.next();。
input 是 RawKeyValueIterator 的对象,它是一个迭代器,用于遍历全部的KV对,reduce方法迭代会使用这个迭代器。
nextKeyIsSame 是标记当前key是否与下一个key相同,初始化为 false。
public class ReduceContextImpl<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
extends TaskInputOutputContextImpl<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
implements ReduceContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
private RawKeyValueIterator input; //用于遍历全部的KV对
private Counter inputValueCounter; //记录value数
private Counter inputKeyCounter; //记录key数
private RawComparator<KEYIN> comparator;
private KEYIN key; //当前key,在nextKeyValue()中更新
private VALUEIN value; //当前value,在nextKeyValue()中更新
private boolean firstValue = false; //同一个key中的第一个值,nextKeyValue()迭代时会用到
private boolean nextKeyIsSame = false; //当前key是否与下一个key相同
private boolean hasMore; //是否还有下一对KV对
protected Progressable reporter;
pr