leveldb源码分析--Key结构
【注】本文参考了sparkliang的专栏的Leveldb源码分析--3并进行了一定的重组和排版
经过上一篇文章的分析我们队leveldb的插入流程有了一定的认识,而该文设计最多的又是Batch的概念。这篇文章本来应该顺理成章的介绍Batch相关流程和结构了,但是Batch涉及到了一些编码和Key相关的概念,所以我觉得应该先理清这方面的概念有助于大家更容易理解后面的内容。
在dbformat.h/cc文件中我们首先看到的是
typedef uint64_t SequenceNumber;
struct ParsedInternalKey {
Slice user_key;
SequenceNumber sequence;
ValueType type;
...
};
而InternalKey只包含了一个string类型的对象,但是我们可以从其构造函数可以得出其主要由ParsedInternalKey的三个字段编码而来
user_key (string) | sequence ( byte) | value_type ( byte)
由此可sequence number大小是7 byte,sequence number是所有基于op log系统的关键数据,它唯一指定了不同操作的时间顺序。
把user key放到前面的原因是,这样对同一个user key的操作就可以按照sequence number顺序连续存放了,这样在后继的Compaction过程中就可以容易的对相同Key的操作进行合并了。另外用户可以为user key定制比较函数,系统默认是字节序的。
另外在Memtable的查询时又涉及到了LookupKey,它也是由User Key和Sequence Number组合而成的,从其构造函数:LookupKey(const Slice& user_key, SequenceNumber s)中分析出LookupKey的格式为:
Size (int32变长)| User key (string) | sequence number ( byte) | value type ( byte)
而LookupKey又有几个函数
// Return a key suitable for lookup in a MemTable.
Slice memtable_key() const { return Slice(start_, end_ - start_); }
// Return an internal key (suitable for passing to an internal iterator)
Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }
// Return the user key
Slice user_key() const { return Slice(kstart_, end_ - kstart_ - ); }
memtable_key是在查找过程中传递给SkipList的Comparator进行查找比较的时候用的,前面提到过目前默认的Comparator实现是会将其中的User key抽取出来按照字节序进行比较。
在这些key的组成和编码过程中我们又接触到了一些leveldb 的内部编码方式,比如Varint32(int32变长)、Fixed32等,具体编码方式在coding.cc中,这些编码方式都是根据Google的protobuffer的来的。这个协议在Google内部的数据传输中得到了广泛的使用,另外在一些电信和移动通信领域也得到了一些借鉴和发展。如果对其具体的实现细节感兴趣,可以参见https://developers.google.com/protocol-buffers/docs/overview
leveldb源码分析--Key结构的更多相关文章
- leveldb源码分析--SSTable之block
在SSTable中主要存储数据的地方是data block,block_builder就是这个专门进行block的组织的地方,我们来详细看看其中的内容,其主要有Add,Finish和CurrentSi ...
- leveldb源码分析--WriteBatch
从[leveldb源码分析--插入删除流程]和WriteBatch其名我们就很轻易的知道,这个是leveldb内部的一个批量写的结构,在leveldb为了提高插入和删除的效率,在其插入过程中都采用了批 ...
- Leveldb源码分析--1
coming from http://blog.csdn.net/sparkliang/article/details/8567602 [前言:看了一点oceanbase,没有意志力继续坚持下去了,暂 ...
- LevelDB源码分析--Cache及Get查找流程
本打算接下来分析version相关的概念,但是在准备的过程中看到了VersionSet的table_cache_这个变量才想起还有这样一个模块尚未分析,经过权衡觉得leveldb的version相对C ...
- leveldb源码分析--日志
我们知道在一个数据库系统中为了保证数据的可靠性,我们都会记录对系统的操作日志.日志的功能就是用来在系统down掉的时候对数据进行恢复,所以日志系统对一个要求可靠性的存储系统是极其重要的.接下来我们分析 ...
- leveldb源码分析之Slice
转自:http://luodw.cc/2015/10/15/leveldb-02/ leveldb和redis这样的优秀开源框架都没有使用C++自带的字符串string,redis自己写了个sds,l ...
- leveldb源码分析--SSTable之TableBuilder
上一篇文章讲述了SSTable的格式以后,本文结合源码解析SSTable是如何生成的. void TableBuilder::Add(const Slice& key, const Slice ...
- leveldb源码分析--Comparator
既然leveldb是一个按Key序组织的LSM-Tree实现,那么对于Key的比较就是非常之重要了,这个Key的比较在leveldb中是Comparator的形式出现的.我们首先来看看Comparat ...
- leveldb源码分析之内存池Arena
转自:http://luodw.cc/2015/10/15/leveldb-04/ 这篇博客主要讲解下leveldb内存池,内存池很多地方都有用到,像linux内核也有个内存池.内存池的存在主要就是减 ...
随机推荐
- spring boot的拦截器简单使用
1.spring boot拦截器默认有: HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationIntercept ...
- 【字符串】Reverse Words in a String(两个栈)
题目: Given an input string, reverse the string word by word. For example,Given s = "the sky is b ...
- 关于Spring的一点东西
Spring IoC 容器 容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁.Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件.这些对象被称为 Spr ...
- HUE配置文件hue.ini 的hdfs_clusters模块详解(图文详解)(分HA集群和非HA集群)
不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...
- 二叉查找树 Java实现
定义: 一棵二叉查找树是一棵二叉树,每个节点都含有一个Comparable的键(以及对应的值). 每个节点的键都大于左子树中任意节点的键而小于右子树中任意节点的键. 树的术语: Name Functi ...
- Oracle数据库中的分页--rownum
1. 介绍 当我们在做查询时,经常会遇到如查询限定行数或分页查询的需求,MySQL中可以使用LIMIT子句完成,在MSSQL中可以使用TOP子句完成,那么在Oracle中,我们如何实现呢? Oracl ...
- 软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比
本文出自 “抚琴煮酒” 博客,出处http://andrewyu.blog.51cto.com/1604432/697466 现在网站发展的趋势对网络负载均衡的使用是随着网站规模的提升根据不同的阶 ...
- Cmake编写JNI
调用两个库 CMakeLists.txt //把那种大段的注释去掉了 cmake_minimum_required(VERSION ) add_library( # Sets the name of ...
- PHP 类与对象 全解析( 二)
目录 PHP 类与对象 全解析( 一) PHP 类与对象 全解析( 二) PHP 类与对象 全解析(三 ) 7.Static关键字 声明类成员或方法为static,就可以不实例化类而直接访问.不能通过 ...
- 线程5--GCD简介
/******************************************************/ 同步函数 (1)并发队列:不会开线程 (2)串行队列:不会开线程 异步函数 ...