成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Hadoop的一個變長long編碼剖析

大數據 Hadoop
Hadoop對于long、int (化成long進行編碼)的編碼設計了自己的一套編碼方式,這是一個zero-compressed encoded的變長編碼方式,有利于大大壓縮冗余數據。

Hadoop對于long、int (化成long進行編碼)的編碼設計了自己的一套編碼方式,這是一個zero-compressed encoded的變長編碼方式,有利于大大壓縮冗余數據。具體算法其實很簡單,具體來說有如下幾點:

Hadoop的一個變長long編碼剖析

1、對于-112 <= i <= 127的整數,只用1個字節byte來表示;如果超過上述范圍時,編碼***個字節則會用來表示i的總字節數,后面則跟著 i 的字節;

2、如果i大于0,則編碼的***個字節 b 范圍在-113和-120之間,則 i 會有 (-112 - b)個字節,所以可以表示有1-8個字節;

3、如果i小于0,則編碼***個字節 b 范圍在 -121 和 -128之間,則 i 會有 (-120 - b)個字節,同樣也可以表示有1-8個字節。(Hadoop的實現里,當i為負數被編碼的是 i 補碼)。

算法看上去比較容易理解,具體要點就是利用***個字節表示 i 的長度,以及 i 的符號,不過其實,如果深入源碼后,發現Hadoop的實現有點小巧妙的地方,我們先看代碼的實現:

首先是變長long的編碼:

public static void writeVLong(DataOutput stream, long i) throws IOException { if (i >= -112 && i <= 127) { stream.writeByte((byte)i); return; } int len = -112; if (i < 0) { i ^= -1L; // take one's complement' //關鍵部分! 替換做法是 i = -i; len = -120; } long tmp = i; while (tmp != 0) { tmp = tmp >> 8; len--; } stream.writeByte((byte)len); len = (len < -120) ? -(len + 120) : -(len + 112); for (int idx = len; idx != 0; idx--) { int shiftbits = (idx - 1) * 8; long mask = 0xFFL << shiftbits; stream.writeByte((byte)((i & mask) >> shiftbits)); } }

為了方便,我這里也貼上自己稍微簡化了Hadoop實現的解碼變長long的實現:

public static long readVLong(DataInputStream input) throws IOException { byte firstByte = input.readByte; int len = -112; boolean isNegative = false; if (firstByte >= -112 && firstByte <= 127) { return firstByte; } else if (firstByte <= -121) { len = -120; isNegative = true; } len = len - firstByte; long res = 0; for (int i = 0; i < len; ++i) { res <<= 8; byte b = input.readByte; res = (b & 0xFF) | res; } //如果編碼是i = -i; 則這里是return isNegative ? (-res) : res; return isNegative ? (res ^ -1L) : res; } 算法的具體實現部分,參照之前概括的描述很容易了解大致框架,但有一個很關鍵的部分,就是在添加了注釋的編碼和解碼的部分,對于算法第3個條件里,如果 i 為負數的時候,Hadoop的默認實現里會把 i 進行補碼運算,然后再繼續執行編碼,而因此,在解碼的時候,***部分也要重新取一個補碼操作。

算法思想分析

為什么要這樣呢?其實分析一下整個算法的原理。首先如果我們簡單的把***個字節表示 i 的字節數,不分為正、負兩個部分來額外表示符號的話,這樣會出現一個問題:那就是會沒辦法通過變長編碼簡單實現正負判斷,舉個簡單的例子,對于 i = 128和 i = -128,這兩個數的編碼對于1個字節來說,都是0x80!為什么會這樣呢?如果想到負數的二進制編碼是正數取反后加1(加1是為了避免直接取反對0進行 兩次編碼,這樣負數能夠多表示1個數),因此,對于給定的字節,負數總是會比正數多表示1個數,對于1個字節,能表示-128~127。因此對于 i = 128的時候,沒辦法分辨出正負,必須要靠***個字節添加符號信息。

當給***個字節多分8個數出來表示符號的時候,為了要計算 i 的位數,如果 i 為負數的時候,i 的高位則全為1, 因此必須要對 i 為負數的情況取反,然后再不斷循環計算 i 的長度,但事實上,我們同樣也可以對 i 取反后加1,也就是對 i = -i;轉為絕對值,而事實上,經過本人的測試,無論是取反或者是做絕對值操作,兩者均可以正常進行編碼解碼,但事實上,取反有一個好處,對于i = -256的時候,如果將 i 取反,則會編碼輸出的兩個字節為:-121,-1。如果將 i 取絕對值,則編碼輸出的兩個字節為:-122,1,0。可見,對于這種的時候,取反能夠比取絕對值少用1個字節。

 
責任編輯:王雪燕
相關推薦

2017-06-27 08:41:04

JVM設計缺陷GC

2024-09-29 15:15:46

2014-07-21 10:25:12

ENode開發論壇

2021-01-28 07:21:13

算法虛擬DOM前端

2011-06-02 10:37:02

Android 對話框

2012-05-10 16:32:01

Hadoop

2010-06-03 13:08:51

2010-11-29 15:35:36

云計算經濟學

2012-06-01 16:13:09

Hadoo大數據

2021-04-01 13:07:07

編碼開發代碼

2020-12-07 06:26:32

模式交付工作

2022-05-12 09:22:16

Memray內存剖析器開源

2010-03-05 15:02:09

Linux文件編碼

2020-03-27 09:24:39

程序員技能開發者

2016-09-26 17:26:20

2022-02-14 07:19:43

數據中臺業務中臺雙中臺

2024-04-15 00:00:00

LongBigDecimal運算

2017-06-07 12:49:21

2010-06-03 11:23:19

Hadoop

2014-10-14 15:50:19

UIAndroid
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品综合 | 精品久久久久久一区二区 | 亚洲视频免费在线观看 | 欧美在线一区二区三区 | 欧美日韩在线一区二区三区 | 国产乱码久久久久久 | 久久久123| 精品一区二区三区不卡 | 婷婷激情综合 | 国产精品九九视频 | 久久99精品久久久 | 狠狠草视频 | 国产精品久久久久一区二区三区 | 午夜影院 | 午夜网址 | 国产精品片aa在线观看 | 中文字幕电影在线观看 | 日韩一二区 | 欧美在线观看一区二区 | 亚洲天堂av网| 91免费在线看| 超碰97免费| 国产精品国产精品国产专区不片 | 亚洲精品久久久久久国产精华液 | 欧美综合久久久 | 涩涩视频在线观看免费 | 野狼在线社区2017入口 | 国产精品国产精品国产专区不卡 | 在线色网 | 亚洲国产精品区 | 日韩电影免费在线观看中文字幕 | 国产成人在线一区二区 | 男人天堂国产 | 欧美视频第三页 | 琪琪午夜伦伦电影福利片 | 亚洲 欧美 另类 综合 偷拍 | 日韩免费视频一区二区 | 香蕉大人久久国产成人av | 色妹子综合网 | 国产成人精品免高潮在线观看 | 欧美视频在线播放 |