您的位置:首页 > 其它

Leveldb源码分析--2

2013-02-06 11:32 337 查看

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);

}

char* EncodeVarint64(char* dst, uint64_t v) {//
对于uint64,直接循环

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.2 Decode

Fixed Int的Decode,操作,代码:

inline uint32_t DecodeFixed32(const char* ptr)

{

if (port::kLittleEndian) {

uint32_t result;

memcpy(&result, ptr,sizeof(result)); // gcc optimizes this to a plain load

return result;

} else {

return((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))

|(static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) <<8)

| (static_cast<uint32_t>(static_cast<unsignedchar>(ptr[2])) << 16)

|(static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) <<24));

}

}

再来看看VarInt的解码,很简单,依次读取1byte,直到最高位为0的byte结束,取低7bit,作(<<7)移位操作组合成Int。看代码:

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;

returnreinterpret_cast<const char*>(p);

}

}

return NULL;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: