zoukankan      html  css  js  c++  java
  • Mapreduce中的字符串编码

    Mapreduce中的字符串编码

    $$$
    Shuffle的执行过程,需要经过多次比较排序。如果对每一个数据的比较都需要先反序列化,对性能影响极大。 RawComparator的作用就不言而喻,能够直接使用序列化后的字节流进行比较,不需要反序列化就能够完成排序功能。
    $$$

    hadoop使用的是jdk自带编码器和解码器(DataOutputStream和DataInputStream),它有一套规则把字符转化成字节。1个字符可能转化成1个,2个或者3个字节。

    字节流开始处用2个字节,写了字节流的有效长度,它的字节流最长是65535 (这个长度是编码后的字节流长度,不是传进行的字符串长度)

    在RawComparator读到的,是在这种规则下转换后的字节流,不能够直接使用它来做比较了。。。在 二次排序 里面我用了一种变通的方法解决这个问题。最好的方法是模仿Text的编码和比较器的实现,然后实现自定义key的比较器

    在这里主要是解析一下,Why???
    DataOutputStream.writeUTF()的源码不长,直接上

        /** 
        ** 把字符串编码为utf字节流,并写进out
        **/
        static int writeUTF(String str, DataOutput out) throws IOException {
    	int strlen = str.length();
    	int utflen = 0;
    	int c, count = 0;
    
    	/* 计算编码后的字节流长度 */
    	for (int i = 0; i < strlen; i++) {
    		c = str.charAt(i);
    		if ((c >= 0x0001) && (c <= 0x007F)) {	// ascii字符,1个字符->1个字节
    			utflen++;
    		} else if (c > 0x07FF) {							// 1个字符->3个字节
    			utflen += 3;
    		} else {
    			utflen += 2;									  // 1个字符->2个字节
    		}
    	}
    
    	// 编码后的字节流总长度不能超过65535
    	if (utflen > 65535)						
    		throw new UTFDataFormatException(
    			"encoded string too long: " + utflen + " bytes");
    
    	// 初始化用于编码的缓冲区
    	byte[] bytearr = null;
    	if (out instanceof DataOutputStream) {
    		DataOutputStream dos = (DataOutputStream)out;
    		if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
    			dos.bytearr = new byte[(utflen*2) + 2];
    		bytearr = dos.bytearr;
    	} else {
    		bytearr = new byte[utflen+2];
    	}
    
    	// 开头的2个字节,写字符串长度 utflen
    	bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
    	bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
    
    	// 先写入 [1到7E]的字符, 即ascii字符, 1个字符->1个字节
    	int i=0;
    	for (i=0; i<strlen; i++) {
    	   c = str.charAt(i);
    	   if (!((c >= 0x0001) && (c <= 0x007F))) break;
    	   bytearr[count++] = (byte) c;
    	}
    
    	for (;i < strlen; i++){
    		c = str.charAt(i);
    		if ((c >= 0x0001) && (c <= 0x007F)) {			// ascii字符
    			bytearr[count++] = (byte) c;
    
    		} else if (c > 0x07FF) {						// 非ascii字符,需要3个字节
    			bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
    			bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));
    			bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
    		} else {
    			bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));		// 其余的非ascii字符,需要2个字节
    			bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
    		}
    	}
    	out.write(bytearr, 0, utflen+2);
    	return utflen + 2;
    }
    
  • 相关阅读:
    百度mp3地址解密码
    VB 在EXE后附加信息
    截屏函数
    Base64和StrToByte
    The Android ION memory allocator, DMABUF is mentioned as well
    DDC EDID 介绍
    Memory management for graphic processors TTM的由来
    科普 写display driver的必看 How video card works [2D的四种主要操作]
    GEM vs TTM
    DMABUF 背景介绍文章 Sharing buffers between devices
  • 原文地址:https://www.cnblogs.com/ivanny/p/mapreduce_encode.html
Copyright © 2011-2022 走看看