用于比较TextPair字节表示的RawComparator

时间:2016-07-13 03:55:45

标签: hadoop io

Hadoop:The Definitive Guide:

一书中有一个类
public static class Comparator extends WritableComparator {
    private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();

    public Comparator() {
        super(TextPair.class);
    }

    @Override
    public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
        try {
            int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);
            int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);
            int cmp = TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);
            if (cmp != 0) {
                return cmp;
            }
            return TEXT_COMPARATOR.compare(b1, s1 + firstL1, l1 - firstL1,b2, s2 + firstL2, l2 - firstL2);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }
}

static {
    WritableComparator.define(TextPair.class, new Comparator());
}

我不理解的部分是:

int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);

如书中所述:

  

“此代码的细微部分是计算firstL1和firstL2,即   每个字节流中第一个Text字段的长度。每个都是组成的   可变长度整数的长度(由...返回)   decodeVIntSize()上的WritableUtils及其编码的值   (由readVInt()返回)。“

根据我的理解,表达式WritableUtils.decodeVIntSize(b1[s1])只是第一个文本字段的长度(字节数),表达式readVInt(b1, s1)是字段的内容,这是我感到困惑的地方。 谁可以给我解释一下这个?提前谢谢。

2 个答案:

答案 0 :(得分:0)

如下所示的简单测试将澄清:

public static void main(String[] args) throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    DataOutputStream outDat = new DataOutputStream(out);
    TextPair tp1 = new TextPair("Pig", "Li");
    Comparator cmp = new TextPair.Comparator();
    tp1.write(outDat);
    byte[] b1 = out.toByteArray();
    outDat.close();
    System.out.println(WritableUtils.decodeVIntSize(b1[0]));
    System.out.println(WritableComparator.readVInt(b1, 0)); }

输出结果为:

  

1

     

3

这是因为1代表可变长度头的长度(1个字节),因为只需要1个字节来包含数字“3”而3代表文本的长度,即3个字符,因此3个字节(所有三个字符都可以用一个字节表示)。

答案 1 :(得分:0)

请注意,它使用VInt而不是Int。并且VInt使用第一个字节来指示跟随多少字节。 decodeVIntSize(b1 [s1])获取VInt的字节数,而readVInt(b1,s1)读取String的实际字节数。