leveldb源碼學(xué)習(xí)--Coding

VarInt

VarInt 是一種緊湊的表示數(shù)字的方法。它用一個(gè)或多個(gè)字節(jié)來表示一個(gè)數(shù)字憔儿,值越小的數(shù)字使用越少的字節(jié)數(shù)。這能減少用來表示數(shù)字的字節(jié)數(shù)。

VarInt 中的每個(gè) byte 的最高位 bit 有特殊的含義脑蠕,如果該位為 1,表示后續(xù)的 byte 也是該數(shù)字的一部分跪削,如果該位為 0谴仙,則結(jié)束。其他的 7 個(gè) bit 都用來表示數(shù)字碾盐。

字節(jié)序:小端

源碼分析

leveldb中的編碼晃跺、解碼函數(shù)分為VarInt和FixedInt兩種。int32和int64操作都是類似的毫玖。FixedInt的實(shí)現(xiàn)極為簡(jiǎn)單掀虎,這里就不說了,主要分析VarInt的解碼和編碼付枫,同樣32位和64位由于原理相似烹玉,也僅僅分析32位的實(shí)現(xiàn)

編碼

char* EncodeVarint32(char* dst, uint32_t v) {
  // Operate on characters as unsigneds
  unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
  static const int B = 128;
  if (v < (1<<7)) {
    *(ptr++) = v;
  } else if (v < (1<<14)) {
    *(ptr++) = v | B;
    *(ptr++) = v>>7;
  } else if (v < (1<<21)) {
    *(ptr++) = v | B;
    *(ptr++) = (v>>7) | B;
    *(ptr++) = v>>14;
  } else if (v < (1<<28)) {
    *(ptr++) = v | B;
    *(ptr++) = (v>>7) | B;
    *(ptr++) = (v>>14) | B;
    *(ptr++) = v>>21;
  } else {
    *(ptr++) = v | B;
    *(ptr++) = (v>>7) | B;
    *(ptr++) = (v>>14) | B;
    *(ptr++) = (v>>21) | B;
    *(ptr++) = v>>28;
  }
  return reinterpret_cast<char*>(ptr);
}

有效位是7bit的,因此把uint327bit分割阐滩,對(duì)unsigned char賦值時(shí)二打,超出0xFF會(huì)自動(dòng)截?cái)啵虼酥苯?code>*(ptr++) = v|B即可掂榔,不需要再把(v|B)0xFF&操作.

解碼

VarInt的解碼继效,很簡(jiǎn)單,依次讀取1byte装获,直到最高位為0byte瑞信,取低7bit,作(<<7)移位操作組合成int

inline const char* GetVarint32Ptr(const char* p,
                                  const char* limit,
                                  uint32_t* value) {
  if (p < limit) {
    uint32_t result = *(reinterpret_cast<const unsigned char*>(p));
    if ((result & 128) == 0) {
      *value = result;
      return p + 1;
    }
  }
  return GetVarint32PtrFallback(p, limit, value);
}
const char* GetVarint32PtrFallback(const char* p,
                                   const char* limit,
                                   uint32_t* value) {
  uint32_t result = 0;
  for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
    uint32_t byte = *(reinterpret_cast<const unsigned char*>(p));
    p++;
    if (byte & 128) {
      // More bytes are present
      result |= ((byte & 127) << shift);
    } else {
      result |= (byte << shift);
      *value = result;
      return reinterpret_cast<const char*>(p);
    }
  }
  return NULL;
}

其實(shí)我很好奇穴豫,在這為何不直接把兩個(gè)函數(shù)并為一個(gè)函數(shù)凡简,畢竟第二個(gè)能完成第一個(gè)任務(wù)。

編碼長(zhǎng)度

int VarintLength(uint64_t v) {
  int len = 1;
  while (v >= 128) {
    v >>= 7;
    len++;
  }
  return len;
}

非常簡(jiǎn)單的邏輯精肃,不用細(xì)說=潘鲫。=沒看明白的話,在理解下什么是varint

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肋杖,一起剝皮案震驚了整個(gè)濱河市溉仑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌状植,老刑警劉巖浊竟,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怨喘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡振定,警方通過查閱死者的電腦和手機(jī)必怜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來后频,“玉大人梳庆,你說我怎么就攤上這事”跋В” “怎么了膏执?”我有些...
    開封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)露久。 經(jīng)常有香客問我更米,道長(zhǎng),這世上最難降的妖魔是什么毫痕? 我笑而不...
    開封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任征峦,我火速辦了婚禮,結(jié)果婚禮上消请,老公的妹妹穿的比我還像新娘栏笆。我一直安慰自己,他們只是感情好臊泰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開白布蛉加。 她就那樣靜靜地躺著,像睡著了一般因宇。 火紅的嫁衣襯著肌膚如雪七婴。 梳的紋絲不亂的頭發(fā)上祟偷,一...
    開封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天察滑,我揣著相機(jī)與錄音,去河邊找鬼修肠。 笑死贺辰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嵌施。 我是一名探鬼主播饲化,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吗伤!你這毒婦竟也來了吃靠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤足淆,失蹤者是張志新(化名)和其女友劉穎巢块,沒想到半個(gè)月后礁阁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡族奢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年姥闭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片越走。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棚品,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出廊敌,到底是詐尸還是另有隱情铜跑,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布庭敦,位于F島的核電站疼进,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏秧廉。R本人自食惡果不足惜伞广,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疼电。 院中可真熱鬧嚼锄,春花似錦、人聲如沸蔽豺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)修陡。三九已至沧侥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間魄鸦,已是汗流浹背宴杀。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拾因,地道東北人旺罢。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绢记,于是被迫代替她去往敵國(guó)和親扁达。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容