leveldb注释7–key与value

2023-11-08

作为一个kv的系统,key的存储至关重要。在leveldb中,主要涉及到如下几个key,user_key、InternalKey与LookupKey(memtable_key)。 
其关系构成如下图。user_key就是用户输入的key,而InternalKey在user_key的基础上封装了sequence_num+type。sequence_num是一个全局递增的序列号,每一次Put操作都会递增。这样,不同时间的写入操作会得到不一样的sequence_num。前面章节中提到的sstable单条record中的key,其内部其实就是一个InternalKey。sequence_num主要跟snapshot机制与version机制相关,对压缩会产生一定影响。这些我们在后续章节分析。根据type字段,可以获知本次写入操作是写还是删除(也就是说删除是一种特殊的写)。而LookupKey/memtable_key用于在memtable中,多了一个长度字段。代码主要在dbformat.cc/.h中。 

leveldb lookup key

leveldb lookup key


static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {
  assert(seq <= kMaxSequenceNumber);
  assert(t <= kValueTypeForSeek);
  return (seq <<  \8) | t;
}

skiplist中的单个节点不仅存储了Key,也存储了value。格式如下图。尽管单个节点的开头部分是一个LookupKey,但其内部比较时,还是使用的InternalKey。也就是说,比较时,先使用InternalKey内部的user_key进行比较,再比较sequence_num。这样不管是memtable还是sstable文件,其内部都是按InternalKey有序的。 

leveldb skiplist node

leveldb skiplist node


int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
  // Order by:
  //    increasing user key (according to user-supplied comparator)
  //    decreasing sequence number
  //    decreasing type (though sequence# should be enough to disambiguate)
  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
  if (r == 0) {
    const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);
    const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);
    if (anum > bnum) {
      r = -1;
    } else if (anum < bnum) {
      r = +1;
    }
  }
  return r;
}

在进行Get操作时,leveldb会使用用户传入的user_key与当前db最大的sequence_num进行合并,以得到LookupKey(实际还会受snapshot机制影响)。但在内部查找时还是使用的InternalKey。

Put操作会稍微复杂点。leveldb的3种写入操作最终都会封装成WriteBatch。这3种写入操作分别是Put(写入单条key 
/value)、Delete(删除单条key)、Write(批量进行Put与Delete操作)。WriteBath的内部格式如下图。WriteBatch所表示的多条记录最终会按SkipList所要求的格式1条条地顺序插入到memtable中。 

leveldb writebatch

leveldb writebatch


Status WriteBatchInternal::InsertInto(const WriteBatch* b,
                                      MemTable* memtable) {
  MemTableInserter inserter;
  // memtable 的初始sequence为WriteBatchInternal中的seq
  inserter.sequence_ = WriteBatchInternal::Sequence(b);
  inserter.mem_ = memtable;
  return b->Iterate(&inserter);
}

Status WriteBatch::Iterate(Handler* handler) const {
  Slice input(rep_);
  if (input.size() < kHeader) {
    return Status::Corruption("malformed WriteBatch (too small)");
  }
  // kHeader=12 = seq(8字节) + count(4字节)
  input.remove_prefix(kHeader);
  Slice key, value;
  int found = 0;
  while (!input.empty()) {
    found++;
    char tag = input[0];
    // type:1字节
    input.remove_prefix(1);
    switch (tag) {
      case kTypeValue:
        if (GetLengthPrefixedSlice(&input, &key) &&
            GetLengthPrefixedSlice(&input, &value)) {
          handler->Put(key, value);
        } else {
          return Status::Corruption("bad WriteBatch Put");
        }
        break;
      case kTypeDeletion:
        if (GetLengthPrefixedSlice(&input, &key)) {
          handler->Delete(key);
        } else {
          return Status::Corruption("bad WriteBatch Delete");
        }
        break;
      default:
        return Status::Corruption("unknown WriteBatch tag");
    }
  }
  if (found != WriteBatchInternal::Count(this)) {
    return Status::Corruption("WriteBatch has wrong count");
  } else {
    return Status::OK();
  }
}

关于读写压缩等对key/value的具体操作,我们在后续章节进行分析,这里只需要了解大概。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

leveldb注释7–key与value 的相关文章

  • 有没有办法将平面索引数组中的所有键更改为同一字符串(“名称”)? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 有没有办法将所有数字键更改为 Name 而不循环遍历数组 本机 PHP 函数 0 gt blabla 1 gt blabla 2 gt bl
  • 在渲染对象数组的数组时,不断收到“警告:列表中的每个子项都应该有一个唯一的“key”道具。”

    我有一个包含数组数组的对象 我能够让它按照我想要的方式呈现 然而 React 键给我带来了麻烦 抛出此 警告 列表中的每个子项都应该有一个唯一的 key 道具 我尝试在原始数组对象中为每个数组中的每个元素提供唯一的 id 属性 但没有帮助
  • 在 R 中向多直方图添加关键图例

    如何在下面的图中添加关键图例 我希望在右上角的某个地方有一个关键图例 其中有两个短水平颜色条 红色的应该说 整形手术出了问题 蓝色的应该说 德国 我使用以下代码来生成该图 bar2 lt read table div ana mut bar
  • WPF:如何使文本块触发按键事件?

    TextBlock 有 KeyDown 和 KeyUp 事件 但它从未被触发 有办法让它发生吗 我只需要检测是否按下了任何键 首先 您需要设置Focusable http msdn microsoft com en us library s
  • Delphi7,按向上键时进行形状​​跳跃

    我想在玩家按下UP键时进行形状 跳跃 所以我能想到的最好的就是这个 但我使用的方法很糟糕并且有问题 形状坐标 shape1 top 432 procedure TForm1 FormKeyDown Sender TObject var Ke
  • Python 字典键中的空格

    我知道 Python 字典键中可以有空格 但这被认为是糟糕的编程吗 我在 PEP 中找不到任何与此相关的内容 编辑以澄清 在我正在做的一个项目中 我正在研究解析 Apache 的记分板输出的东西mod status 请参阅下面的示例输出 我
  • const 键和非 const 键有什么区别?

    下面两行有什么区别 map
  • 在 Emacs 中如何重新映射键?

    我正在寻找一种方法 可以在 emacs 窗口中切换控制键和大写锁定键 但是当我转到任何其他程序 例如 Firefox 时 我希望能够在新窗口中使用普通控制按钮 选项卡等 附加信息 我正在使用 Ubuntu 但所有系统的答案都很好 因为其他人
  • EntityType 未定义键

    我正在创建一个应用程序 用户通过 Facebook oAuth 登录 然后设置歌曲列表 我收到以下错误消息 BandFinderCsharp Models IdentityUserLogin EntityType IdentityUserL
  • 如何根据 Mongodb 中的键删除重复项?

    我在 MongoDB 中有一个集合 其中大约有 约 300 万条记录 我的样本记录看起来像 id ObjectId 50731xxxxxxxxxxxxxxxxxxxx source references id ObjectId 5045xx
  • 如何让 PreOrder、InOrder、PostOrder 正常工作?

    如何让 PreOrder InOrder PostOrder 正常工作 这是我当前的代码和实现 请参阅 InOrder PreOrder PostOrder 我有来自 Geek4Geek 的参考 https www geeksforgeek
  • Python - 查找字典中最长(最多单词)的键

    有没有一种方法可以快速查询字典对象以找到单词最多的键 所有键都是字符串类型 即 如果具有最大键的项目有五个单词 这是最大的键 3 我如何快速查询字典并返回 int 5 最好的 乔治娜 这将为您提供密钥 max d key lambda x
  • 检查字典是否有多个键

    如何检查字典 实际上是类似字典的对象 是否具有给定集合的所有内容keys 复数 到目前为止 我已经使用过 d a 1 b 2 c 3 keys a b def has keys d keys for key in keys if not k
  • 如何从python字典中的给定名称获取键

    我有一个变量叫做 anime dict which contains a dictionary of lists of objects as shown below JI2212 Inu Yasha year 1992 rating 3 E
  • Python 元组作为键慢吗?

    我正在尝试实现字典中排序元组的快速查找 回答 元组 3 8 是否有关联值 如果有 它是什么 的问题 令元组中的整数从下方以 0 为界 从上方以 max int 为界 我继续使用 Python 的 dict 但发现速度相当慢 解决此问题的另一
  • 如何在vim中将菜单键(“应用程序键”)映射到Escape键?

    我认为使用菜单键退出 vim 的插入模式将是一件很棒的事情 使用 Super 键也很好 但我不确定是否可能 因为 Super 键是一个修饰符 无论如何 我找不到任何与此相关的内容 寻求您的帮助并提前致谢 我认为没有任何方法可以配置 Vim
  • Scala SBT 和 JNI 库

    我正在编写一个简单的应用程序Scala通过以下方式使用 leveldb 数据库leveldbjni图书馆 我的build sbt文件看起来像这样 name Whatever version 1 0 scalaVersion 2 10 2 l
  • 如何在 JavaScript 中访问“关联”数组的第一个键?

    我有一个 js 关联 数组 其中 array serial number value serial number 和 value 是字符串 例如array 20910930923 20101102 我按价值排序 效果很好 假设我取回了 已排
  • Facebook-API 中的会话密钥和访问令牌

    有人可以向我解释一下什么是会话密钥和访问令牌吗 怎样才能抓住那两个人呢 为什么以及何时需要使用它们 什么时候是 一次性 什么时候不是 另外 他们之间有什么区别 请用Java 来做 我是一位刚接触 facebook API 的 Java 开发
  • 如何在 C++ 上检查某个键是否被按下

    我怎样才能检查 Windows 上是否按下了某个键 正如其他人提到的 没有跨平台的方法可以做到这一点 但在 Windows 上你可以这样做 下面的代码检查 A 键是否按下 if GetKeyState A 0x8000 Check if h

随机推荐

  • 何利用streamlit快速搭建一个web应用并部署到heroku服务器上

    如何利用streamlit快速搭建一个web应用并部署到heroku服务器上 streamlit入门 所有的都一样安装包 尝试包的示例 如何快速搭建你的webApp 1 首先在本地创建一个 py文件 例如我的app py 2设置题目 3设置
  • AJAX请求后页面数据未刷新问题

    这段时间因为做毕设 涉及到AJAX的问题比较多 今天的问题就是一个 中所周知 ajax最大的特点就是局部刷新 可以在不更新整个页面的情况下刷新局部数据 但是 有时候这种优点也会成为一种优点 多说无益 直接上图 首先来看未操作之前的页面 之后
  • Python-WingIde各种调试方法

    一 本地从IDE启动文件调试 主要步骤 设置断点 F5开始调试 二 本地从IDE外启动文件调试 1 从WingIDE的安装目录 默认C Program Files x86 Wing IDE 6 0 复制wingdbstub py到被调试代码
  • 【jQuery】4、jquery设置css属性

    css name pro val fn 访问匹配元素的样式属性 p style color rgb 255 0 0 jquery p 获取color样式 p css color rgb 255 0 0 设置css样式 p css color
  • 毕业设计-基于MATLAB的含噪语音信号降噪处理方法的研究与实现

    目录 前言 课题背景和意义 实现技术思路 一 设计思路 二 数字滤波器的设计原理 三 语音信号的采集 含噪语音信号的分析处理 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边
  • 域名与DNS域名系统

    文章目录 导读 域名 域名的结构 域名再深入 顶级域名 二级域名 三级域名 四级域名 DNS域名系统 导读 全球的公网ip约有40多亿个 在没有域名的概念时 如果你要打开百度的网站请记住 39 156 66 14 是的 百度好用 360也不
  • MMC、SD、TF、SDIO、SDMMC简介

    MMC 概念 MMC的全称是 MultiMediaCard 所以也通常被叫做 多媒体卡 是一种小巧大容量的快闪存储卡 特别应用于移动电话和数字影像及其他移动终端中 外形及接口定义 如上图所示 MMC存贮卡只有7pin 可以支持MMC和SPI
  • 如何将ChatGPT培养成「私人助理」

    让她先懂你 然后再AI你 人类的爱建立在相互理解的基础上 而人工智能也是如此 因此 使用ChatGPT并不仅仅是一种训练 而更是一种相互理解的过程 与许多介绍如何使用ChatGPT进行编程 翻译 信息查找或闲聊的文章不同 本文旨在介绍如何在
  • (附源码)计算机毕业设计ssm大学生网络安全题库系统

    项目运行 环境配置 Jdk1 8 Tomcat7 0 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 SSM mybatis Ma
  • 武汉腾讯前端一面

    腾讯文档前端开发工程师 1 自我介绍 2 项目难点及解决方案 3 Vue双向数据绑定原理 4 diff算法 5 递归实现方式 6 深浅拷贝 object assign 7 跨域原因及解决方式 你公司项目是怎么解决的 8 webpack 9
  • JSON与String字符串相互转换的方法

    首先创建一个简单的类 package com wei demo pojo Author wei Date 2022 6 2 9 24 Version 1 0 public class Teacher private int id priva
  • ASP精华[转]

  • Linux命令:ps

    ps命令 查看系统中的进程状态 ps命令的参数以及作用 参数 作用 a 显示所有进程 包括其他用户的进程 u 用户及其他详细信息 x 显示没有控制终端的进程 Linux系统中时刻运行许多进程 如果能够合理的管理它们 则可以优化系统性能 si
  • js中使用DES加解密解决方案总结

    js中使用DES加解密解决方案总结 1 需求背景 最近开发vue项目中 对于用户手机号码需要进行DES加解密操作 简介 DES加密 是一种比较传统的加密方式 其加密运算 解密运算使用的是同样的密钥 信息的发送者和信息的接收者在进行信息的传输
  • 【MLOps】第 1 章 : 为什么选择它以及现在面临的挑战

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 常用数组方法总结

    添加 删除元素 push items 从结尾添加元素 pop 从结尾弹出 提取元素 unshift items 从开头添加元素 shift 从开头提取元素 splice pos deleteCount items 从index开始 删除de
  • win10 安装 python报错-已安装这个产品的另一版本

    尝试清理干净电脑上关于之前安装的Python3 在 输入win R 输入cmd 回车 输入 python 回车 却看到 C Users 86136 gt python python 不是内部或外部命令 也不是可运行的程序 或批处理文件 但是
  • Python pd.merge()函数介绍(全)

    目录 1 前言 2 参数介绍 参数如下 3 基础案例 3 1on关键字演示 3 2left on 和 right on 关键字 3 3left index 和 right index 关键字 3 4数据连接的类型 3 4 1 1 前言 在数
  • 4.3 Verilog练习(2)

    目录 练习五 用always块实现较复杂的组合逻辑电路 练习六 在Verilog HDL中使用函数 练习七 在Verilog HDL中使用任务 task 练习八 利用有限状态机进行复杂时序逻辑的设计 练习五 用always块实现较复杂的组合
  • leveldb注释7–key与value

    作为一个kv的系统 key的存储至关重要 在leveldb中 主要涉及到如下几个key user key InternalKey与LookupKey memtable key 其关系构成如下图 user key就是用户输入的key 而Int