varint-levelDB源码解析

【什么是变长整型?】

大家知道,int整型一般是4个字节,那变长整型所需要的空间在1-5个字节之间,因为长度是不固定的,所以称之为变长整型。其特点就是只要数值小于2^21,那么就会节省空间。

【编码原理】


如图所示为300,编码后的字节图,只占了2个字节。这是怎么实现的呢?请看下面的详解:

300的二进制编码为00000000 00000000 00000001 00101100,从低位到高位,每次取7位,如果能取完,最高位补0,表示这个数字已经表示完整了,如果不是,最高位补1,表示这个数字还没表示完整。由于存储的每个字节的最高位用来标识有没有结束,所以实际上每个字节只用了7位来表示数字,这也是为什么最多需要5个字节来表示的原因,4*7 < 32, 5*7 > 32.

【代码实现】

编码:

  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;           //先给*ptr的内存赋值v,然后ptr指针向右移一位

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

  }


解码:

  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;

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值