hadoop中compare函数

在看hadoop  的二次排序的时候,改写了下, 加了第三个参数,  本来以为是在

   public int compareTo(IntPair o) {
      System.out.println("-----------compareTo");
      if (first != o.first) {
        return first < o.first ? -1 : 1;
      } else if (second != o.second) {
        return second < o.second ? -1 : 1;
      }else if (third != o.third) {
    	        return third < o.third ? -1 : 1;}

        return 0;
      }

本来以为排序在这里面进行, 后来发现不是,把比较第3个字段的代码去掉, 发现还是有序的。

后来通过打印得知在compare函数中,稍微改写了下

      public int compare(byte[] b1, int s1, int l1,
                         byte[] b2, int s2, int l2) {
       // 二进制数组读取
       int intvalue = readInt(b1, s1);
       System.out.println("s1 = " +  b1.length);
           // 验证b1中存储的数据
       int third = 0;
       for(int i =s1 + 9; i<= s1+ 12; i++){
           third += (b1[i]&0xff) << (24-8*i);
        }
           System.out.println("third = " + third);

        return compareBytes(b1, s1, l1, b2, s2, l2);
      }
    }

有3个整形值, s1为开始位置, l1为长度12, 这样我们就可以读出我们的值

return compareBytes(b1, s1, l1, b2, s2, l2);调用 return FastByteComparisons.compareTo(b1, s1, l1, b2, s2, l2);

    public int compareTo(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2)
      {
        if ((buffer1 == buffer2) && (offset1 == offset2) && (length1 == length2))
        {
          return 0;
        }

        int end1 = offset1 + length1;
        int end2 = offset2 + length2;
        int i = offset1; for (int j = offset2; (i < end1) && (j < end2); ++j) {
          int a = buffer1[i] & 0xFF;
          int b = buffer2[j] & 0xFF;
          if (a != b)
            return (a - b);
          ++i;
        }

        return (length1 - length2);
      }
    }
  }

从代码中就知道了,通过字节数组比较三个值, 这样就出来的结果就是有序的了

结论, 理论上N个字段这样出来的结果的都是有序的,只是比较的长度有所变化

测试又加了一个字段, 输出结果都是有序的。

测试代码

  public static class IntPair
                      implements WritableComparable<IntPair> {
    private int first = 0;
    private int second = 0;
    private int third = 0;
    private int fourth = 0;

    /**
     * Set the left and right values.
     */
    public void set(int left, int right, int third, int fourth) {
      first = left;
      second = right;
      this.third = third;
      this.fourth = fourth;
    }

    public int getFirst() {
      return first;
    }

    public int getSecond() {
      return second;
    }

    public int getThird() {
        return third;
      }

    public int getFourth() {
        return fourth;
      }

    @Override
	public String toString() {
    	System.out.println("third = " + third);
    	return first + "\t" + second + "\t" + third + "\t" + fourth;
	}

	/**
     * Read the two integers.
     * Encoded as: MIN_VALUE -> 0, 0 -> -MIN_VALUE, MAX_VALUE-> -1
     */
    @Override
    public void readFields(DataInput in) throws IOException {
      first = in.readInt();// + Integer.MIN_VALUE;
      second = in.readInt();// + Integer.MIN_VALUE;
      third = in.readInt();// + Integer.MIN_VALUE;
      fourth = in.readInt();
    }
    @Override
    public void write(DataOutput out) throws IOException {
     /*
      out.writeInt(first - Integer.MIN_VALUE);
      out.writeInt(second - Integer.MIN_VALUE);
      out.writeInt(third - Integer.MIN_VALUE);
      */
        out.writeInt(first );
        out.writeInt(second );
        out.writeInt(third );
        out.writeInt(fourth);
    }
    @Override
    public int hashCode() {
      return first * 157 + second*10 + third;
    }

    @Override
    public boolean equals(Object right) {
      if (right instanceof IntPair) {
        IntPair r = (IntPair) right;
        return r.first == first && r.second == second && r.third == third && r.fourth == fourth;
      } else {
        return false;
      }
    }

    /** A Comparator that compares serialized IntPair. */
    public static class Comparator extends WritableComparator {
      public Comparator() {
        super(IntPair.class);
      }

      // 排序比较器,数据全部存在byte数组
      public int compare(byte[] b1, int s1, int l1,
                         byte[] b2, int s2, int l2) {
       // 二进制数组读取
       int intvalue = readInt(b1, s1);
       System.out.println("s1 = " +  b1.length);

       int third = 0;
       for(int i =s1 + 9; i<= s1+ 12; i++){
    	   third += (b1[i]&0xff) << (24-8*i);
    	}
       	System.out.println("third = " + third);

        return compareBytes(b1, s1, l1, b2, s2, l2);
      }
    }

    static {   // register this comparator
      WritableComparator.define(IntPair.class, new Comparator());
    }

    // 好像没用上
    @Override
    public int compareTo(IntPair o) {
      System.out.println("-----------compareTo");
      if (first != o.first) {
        return first < o.first ? -1 : 1;
      } else if (second != o.second) {
        return second < o.second ? -1 : 1;
      }// else if (third != o.third) {
    	//        return third < o.third ? -1 : 1;}

        return 0;
      }
  }

hadoop中compare函数

时间: 2024-08-05 02:30:12

hadoop中compare函数的相关文章

C++中compare函数的使用

compare函数用来进行字符串以及其子串的比较,示例如下: #include <iostream> #include <string> #include <cctype> using std::cout; using std::endl; using std::cin; using std::string; int main(void){ string str1="hi,test,hello"; string str2="hi,test&

32、C++中compare函数的使用

compare函数用来进行字符串以及其子串的比较,示例如下: #include <iostream> #include <string> #include <cctype> using std::cout; using std::endl; using std::cin; using std::string; int main(void){ string str1="hi,test,hello"; string str2="hi,test&

java.lang.Comparable, java.util.Compartor区别以及Hadoop中关于自定义类型中的compare方法

public interface Comparable<T> { public int compareTo(T o); } 规定了对象内部比较的方法 public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); } 定义外部比较器的基本方法,其中equals是用来确定两个比较器是否相等. 关于对象内部比较和外部比较这两个接口的区别和使用场景如下: 个人总结: Compara

Oracle 中 decode 函数用法

Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN RETURN(翻译值2) ......ELSIF 条件=值n THEN RETURN(翻译值n)ELSE RETURN(缺省值)END IFdecode(字段或字段的运算,值1,值2,值3) 这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值

hadoop中setup,cleanup,run和context讲解

hadoop 执行中的setup run cleanup context的作用1.简介1) setup(),此方法被MapReduce框架仅且执行一次,在执行Map任务前,进行相关变量或者资源的集中初始化工作.若是将资源初始化工作放在方法map()中,导致Mapper任务在解析每一行输入时都会进行资源初始化工作,导致重复,程序运行效率不高!2) Mapper或Reducer运行3) cleanup(),此方法被MapReduce框架仅且执行一次,在执行完毕Map任务后,进行相关变量或资源的释放工

深度分析如何在Hadoop中控制Map的数量

深度分析如何在Hadoop中控制Map的数量 [email protected] 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定.在默认情况下,最终input 占据了多少block,就应该启动多少个Mapper.如果输入的文件数量巨大,但是每个文件的size都小于HDFS的blockSize,那么会造成 启动的Mapper等于文件的数量(即每个文件都占据了一个block),那么很可能造成启动的Mapper数量超出限制而导致崩溃.这些逻

Hadoop中的Speculative Task调度策略

一:背景 Speculative Task,又叫推测式任务,是指在分布式集群环境下,因为程序bug,负载不均衡或者资源分布不均,造成同一个job多个task运行速度不不一致,有的task运行速度明显要慢于其他task(比如:一个job的某个task进度只有10%,而其他所有task已经运行完毕),则这些task拖慢了了作业的整体执行进度,为了避免这种情况发生,Hadoop会为该task启动Speculative task,让该Speculative task与原始task同时运行,哪个先运行完,

浅谈swift中的函数类型和闭包

在讲swift的函数类型之前,我们先回忆一下我们以前学的定义一个swift的函数 func add(a: Int,b: Int) -> Int { return a + b } 好了, 我们开始我们函数类型的讲解 上面这个函数的类型是(Int ,Int)->Int 使用函数类型 我们都知道, 在swift中 , 函数类型就像其他数据类型一样,也就意味着我们可以给一个函数的常量或者是变量赋值 var f2: (Int,Int)-> Int = add f2(2,3) //结果为5 好了,接

Hadoop中两表JOIN的处理方法(转)

1. 概述 在传统数据库(如:MYSQL)中,JOIN操作是非常常见且非常耗时的.而在HADOOP中进行JOIN操作,同样常见且耗时,由于Hadoop的独特设计思想,当进行JOIN操作时,有一些特殊的技巧. 本文首先介绍了Hadoop上通常的JOIN实现方法,然后给出了几种针对不同输入数据集的优化方法. 2. 常见的join方法介绍 假设要进行join的数据分别来自File1和File2. 2.1 reduce side join reduce side join是一种最简单的join方式,其主