leveldb源码分析2
leveldb源码分析2 本系列《leveldb源码分析》共有22篇文章,这是第二篇。 3.Int Coding 轻松一刻,前面约定中讲过Leveldb使用了很多VarInt型编码,典型的如后面将涉及到的各种key。其中的编码、解码函数分为VarInt和FixedInt两种。int32和int64操作都是类似的。 3.1 Decode 首先是FixedInt编码,直接上代码,很简单明了。 void EncodeFixed32(char* buf, uint32_t value) { if (port::kLittleEndian) { 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; } } 下面是VarInt编码,int32和int64格式,代码如下,有效位是7bit的,因此把uint32按7bit分割,对unsigned char赋值时,超出0xFF会自动截断,因此直接*(ptr++) = v|B即可,不需要再把(v|B)与0xFF作&操作。 char* EncodeVarint32(char* dst, uint32_t v) { 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); } // 对于uint64,直接循环 char* EncodeVarint64(char* dst, uint64_t v) { static const int B = 128; unsigned char* ptr =reinterpret_cast<unsigned char*>(dst); while (v >= B) { *(ptr++) = (v & (B-1)) |B; v >>= 7; } *(ptr++) =static_cast<unsigned char>(v); returnreinterpret_cast<char*>(ptr); } 3....