leveldb中记录user_key和user_value的相关结构使用“varint”编码记录其长度并置于首部,例如skiplist存储的项entry,以及Put时WriteBatch存储的批写入数据格式,对user_key和user_value的长度都采用变长编码。数据库
这样作的目的是节省存储空间,若是采用固定字节的长度记录,若是固定字节太大而大部分的key和value的长度只用一个或两个字节的整形就能够记录,那么就会形成不少浪费,反之若是固定字节过小则限制了数据库存储key和value的长度,因此采用变长编码的方式能够适合于各类状况。app
leveldb中关于变长编码和对应的解码函数在文件util/coding.h和util/coding.cc中。主要有定长编码/解码和变长编码/解码系列函数,关于leveldb中的编码策略,首先来看这个函数:函数
编码后的格式,每一个字节分为两部分:最高位和其他位,最高位用来指示下一个字节是否仍是编码存储字节,若是是则为1,不然为0,剩余的七位用来存储具体数据。ui
将一个32位数字v编码位可变长度,并存入以dst开头的地址中,返回结果为末尾存储位的下一位地址。数据由高位到低位存储。因为最高位不用来存储数据,因此一个uint32_t类型的数据最多会被编码为5个字节,固然,若是大部分数据编码后都小于4个字节,仍是很赚的。编码
这个函数还有一个64位版本,原理是一摸同样的,你们本身去分析。spa
固定编码很是简单,只须要判断系统是大端存储仍是小端存储,而后简单的copy一下就能够,此处略过。blog
对应的解码函数:ip
从p开始解码出数据并放入value中,首先判断最高位是否为1,若是是1意味着下一个字节中依然有数据存储,经过|操做得到底七位数据,循环继续。get
这两个函数属于底层函数,其之上有以下函数:input
put系列的函数将value编码而后append进dst中,get系列函数从input中读取数据解码放入value中,低层都是调用了上面介绍的函数。
总的来讲leveldb中的变长存储这部分很清晰,不须要过多介绍。