天天看點

leveldb學習筆記之七——util/coding.h

coding.h中主要是與編碼相關的内容,主要選取以下幾個函數進行分析:

  • EncodeFixed32
void EncodeFixed32(char* buf, uint32_t value) {
  if (port::kLittleEndian) {  //小端次序直接使用memcpy
    memcpy(buf, &value, sizeof(value));
  } else {            //大端次序則按位元組處理
    buf[0] = value & 0xff;
    buf[1] = (value >> 8) & 0xff;
    buf[2] = (value >> 16) & 0xff;
    buf[3] = (value >> 24) & 0xff;
  }
}      
  • PutFixed32
void PutFixed32(std::string* dst, uint32_t value) {
    char buf[sizeof(value)];
    EncodeFixed32(buf, value);
    dst->append(buf, sizeof(buf)); //對資料編碼後再将長度放入
}      
  • EncodeVarint32

    varint編碼是一種變長編碼,用來減少資料的存儲空間。在varint的每個位元組中,如果最高位bit為1,表示後續的位元組也是該數字的一部分,如果該位是0,則結束。其它的7個比特都用來表示資料。是以小于128的數字都可以用一個位元組來表示。

char* EncodeVarint32(char* dst, uint32_t v) {
    unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
    static const int B = 128;
    if (v < (1<<7)) {  //小于128的一個位元組就能搞定
      *(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);
}      
  • PutVarint32
//将編碼後的資料追加到dst中
void PutVarint32(std::string* dst, uint32_t v) {
    char buf[5];
    char* ptr = EncodeVarint32(buf, v);
    dst->append(buf, ptr - buf);
}      
  • PutLengthPrefixedSlice
void PutLengthPrefixedSlice(std::string* dst, const Slice& value) {
  PutVarint32(dst, value.size());
  dst->append(value.data(), value.size());  //将value編碼到dst中
}