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 的相关文章

  • WPF 中 DataTemplate 中的 x:Key、x:Name 和 x:UID 有什么区别?

    我正在尝试在 WPF 中创建动态选项卡 并且正在尝试编写一个仅适用于某些选项卡项目的内容模板 我希望能够为内容模板创建一个标识符 以便我可以在后面的代码中引用它 这样我就可以有选择地将它应用于单个 TabControl 中的某些选项卡 但是
  • 如何通过 RSA 生成唯一的公钥和私钥

    我正在构建一个自定义购物车 其中 CC 编号和到期日期将存储在数据库中直至处理 然后删除 我需要加密这些数据 显然 我想使用 RSACryptoServiceProvider 类 这是我创建密钥的代码 public static void
  • WPF:如何使文本块触发按键事件?

    TextBlock 有 KeyDown 和 KeyUp 事件 但它从未被触发 有办法让它发生吗 我只需要检测是否按下了任何键 首先 您需要设置Focusable http msdn microsoft com en us library s
  • 有效计算 JavaScript 中对象的键/属性的数量

    这个问题几乎与如何有效地计算 JavaScript 中对象的键 属性的数量 https stackoverflow com questions 126100 how to efficiently count the number of ke
  • g++ 找不到标头,但我确实包含了它们

    我开始使用 c 并且已经出错了 我正在尝试编译 levelDB 的一个小测试 include
  • const 键和非 const 键有什么区别?

    下面两行有什么区别 map
  • 如何按值(DESC)然后按键(ASC)对字典进行排序?

    就在发现了惊人的事情之后sorted 我又陷入困境了 问题是我有一本以下形式的字典string key integer value 我需要按整数值的降序对它进行排序 but如果两个元素具有相同的值 则按键的升序排列 一个更清楚的例子 d b
  • 将两个键与 std::map 一起使用的最佳方法是什么?

    我有一个std map我用来存储 x 和 y 坐标的值 我的数据非常稀疏 所以我不想使用数组或向量 这会导致内存的大量浪费 我的数据范围从 250000到250000 但我最多只有几千个点 目前我正在创建一个std string与两个坐标
  • 如何让 PreOrder、InOrder、PostOrder 正常工作?

    如何让 PreOrder InOrder PostOrder 正常工作 这是我当前的代码和实现 请参阅 InOrder PreOrder PostOrder 我有来自 Geek4Geek 的参考 https www geeksforgeek
  • 在java中注入击键

    我正在寻找一种将击键注入操作系统键盘输入缓冲区的方法 就像当您单击一个按钮时 程序会插入一个 或多个 键盘敲击 我想在java中执行此操作 因为我想在 win linux和osx 中运行它 我想我必须利用 JNI 有人有什么想法吗 感谢所有
  • Outlook 添加、文本框、删除\退格键不起作用

    我开发了一个 Outlook 插件 自定义任务窗格 在用户控件中带有 Web 浏览器 当我在网络浏览器的文本框中写入内容时 退格键或删除按钮旁边的所有功能都运行良好 但我无法使用这些键 我是否遗漏了什么 我迟到了几年 但我设法解决了这个问题
  • openssl-使用密钥和 IV 解密 Base64 字符串

    我正在尝试解密已在 openssl 中使用 aes256 加密的 base64 字符串 我获得了会话密钥和 IV 它们是用我的密钥加密的 我将它们转换为十六进制 以便可以使用以下 openssl 命令 openssl enc d aes25
  • 如何在C#中捕获键盘上的按键

    我有个问题 我需要写一个C 程序 输入 允许用户输入多行文本 按 Ctrl Enter 完成输入 输出 标准化 按照时间增加的正确顺序重新排列行 我尝试过 但我不知道如何从键盘捕获 Ctrl Enter 我期望输出像 例子 Created
  • 我可以定义一个具有与每个值的键对应的值约束的 Typescript 映射吗?

    In 这个游乐场 https www typescriptlang org play code KYDwDg9gTgLgBASwHY2FAZgQwMbDgQQCMBnGKHGfbGBCJOAbwCg44YBPMYALjlKmQBzANwtE
  • 如何在vim中将菜单键(“应用程序键”)映射到Escape键?

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

    Visual Studio 中的哪个选项可以让 Home 键转到行首 现在你必须做 Home Home or Home Ctrl Left Arrow 我希望 home 位于该行的开头 我以前见过 但现在找不到了 在 工具 自定义 键盘 中
  • 是否有一个看起来像“钥匙”图标的 Unicode 字形? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 Unicode 有一百万个类似图标的字形 但它们并不总是很容易搜索 因为我并不总是知道它们是什么样子 是否有一个看起来像 钥匙 的 Unicode 字
  • Facebook-API 中的会话密钥和访问令牌

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

    我想创建一个带有 QVariants 键的数据结构 它看起来像这样 QHash
  • 用java解密AES加密文件

    我有一个使用 AES 使用 java 应用程序加密的文件 我还有一个加密的密钥文件 但我不明白如何使用密钥来解密文件 大多数教程和示例都会在一个地方创建临时随机密钥 加密文件和解密 所以 问题是如何指定解密时必须使用的密钥 EDIT 我发现

随机推荐

  • 何利用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