level(三) filterblock

filterblock用于确定某个key是否存在于某个datablock中,在插入一个key到datablock中时也会插入一个key到filterblock中,filterblock中会记录所有的key,并通过布隆过滤器来确定一个key是否存于这个datablock中。

下面来看下filterblock的代码:

class FilterBlockBuilder {public:explicit FilterBlockBuilder(const FilterPolicy*);FilterBlockBuilder(const FilterBlockBuilder&) = delete;FilterBlockBuilder& operator=(const FilterBlockBuilder&) = delete;void StartBlock(uint64_t block_offset);void AddKey(const Slice& key);Slice Finish();private:void GenerateFilter();const FilterPolicy* policy_;std::string keys_;             // Flattened key contentsstd::vector<size_t> start_;    // Starting index in keys_ of each keystd::string result_;           // Filter data computed so farstd::vector<Slice> tmp_keys_;  // policy_->CreateFilter() argumentstd::vector<uint32_t> filter_offsets_;
};class FilterBlockReader {public:// REQUIRES: "contents" and *policy must stay live while *this is live.FilterBlockReader(const FilterPolicy* policy, const Slice& contents);bool KeyMayMatch(uint64_t block_offset, const Slice& key);private:const FilterPolicy* policy_;const char* data_;    // Pointer to filter data (at block-start)const char* offset_;  // Pointer to beginning of offset array (at block-end)size_t num_;          // Number of entries in offset arraysize_t base_lg_;      // Encoding parameter (see kFilterBaseLg in .cc file)
};

FilterBlockBuilder类中,主要有四个方法,分别是StartBlock,AddKey,Finish和GenerateFilter,

AddKey

首先看AddKey,代码如下:

void FilterBlockBuilder::AddKey(const Slice& key) {Slice k = key;start_.push_back(keys_.size());keys_.append(k.data(), k.size());
}

每添加一个key value到databloc,就同步存一个key到filterblock,keys_保存每个key字符串,start_数组每次保存keys_字符串的长度,也就是每个key相对于起始keys_字符串的起始位置的偏移量。

GenerateFilter

可以生成一个filterblock的数据部分,其原理是,当存入datablock的数据已经达到指定大小时,生成一个filterblock的数据块,这个数据块存储的是所有key的hash值,因此可以通过这个filterblock块来确定一个key是否在这个block中。

void FilterBlockBuilder::GenerateFilter() {const size_t num_keys = start_.size();if (num_keys == 0) {// Fast path if there are no keys for this filter//GenerateFilter调用一次会将当前keys存储的所有key进行一次filter计算,并将结果存储到result_中,当连续调用第二次时,fiter_offsets_记录的偏移量还是一次result_的大小,并且不会再重新计算result_,//但是fiter_offsets_数组的元素个数与block_offset/2kb是一致的,即可以通过block_offset/2kb去查询这个block对应的filter的位置。filter_offsets_.push_back(result_.size());return;}// Make list of keys from flattened key structure//这次的push_back是为了便于计算,因为start_[i+1]在i=num_keys-1时会越界。start_.push_back(keys_.size());  // Simplify length computationtmp_keys_.resize(num_keys);//获取所有的keyfor (size_t i = 0; i < num_keys; i++) {const char* base = keys_.data() + start_[i];size_t length = start_[i + 1] - start_[i];tmp_keys_[i] = Slice(base, length);}// Generate filter for current set of keys and append to result_.//将上次生成的filter的大小存入result_,这就是生成的当前这个filter的起始偏移点。filter_offsets_.push_back(result_.size());policy_->CreateFilter(&tmp_keys_[0], static_cast<int>(num_keys), &result_);tmp_keys_.clear();keys_.clear();start_.clear();
}

StartBlock

根据datablock的大小,如果超过2kb的大小,就会生成一个filterblock,这个filterblock会存储当前这个block的所有key的hash值,然后block_offset/kFilterBase就是这个datablock在filterblock中的索引,只不过有可能出现几个filterblock索引指向的是相同的filterblock数据区。
所以查某个datablock中是否有一个key的流程大致是:
该datablock的大小/kFilterBase得到一个索引index,在filterblock中查找这个index所指向的filterblock的数据区,在filterblock的数据区中查找是否有这个key。
在这里插入图片描述

void FilterBlockBuilder::StartBlock(uint64_t block_offset) {uint64_t filter_index = (block_offset / kFilterBase);assert(filter_index >= filter_offsets_.size());while (filter_index > filter_offsets_.size()) {GenerateFilter();}
}

Finish

//filterblock生成完成,添加元数据到最后
Slice FilterBlockBuilder::Finish() {//将未生成filter的keys生成一次filterif (!start_.empty()) {GenerateFilter();}// Append array of per-filter offsetsconst uint32_t array_offset = result_.size();for (size_t i = 0; i < filter_offsets_.size(); i++) {PutFixed32(&result_, filter_offsets_[i]);}PutFixed32(&result_, array_offset);result_.push_back(kFilterBaseLg);  // Save encoding parameter in resultreturn Slice(result_);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2622.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优化 Vue项目中 app.js 文件过大,初始化加载过慢、带宽占用过大等问题

已亲测&#xff0c;绝对有效&#xff0c;底部有改善前后对比图证明。 1.服务器 nginx 增加配置 #开启gzip压缩 gzip on; #设置gzip压缩级别&#xff0c;2级是性价比最高的 gzip_comp_level 2; #设置动态gzip压缩的文件类型 gzip_types text/plain text/css text/javascript a…

浅谈云计算16 | 存储虚拟化技术

存储虚拟化技术 一、块级存储虚拟化基础2.1 LUN 解析2.1.1 LUN 概念阐释2.1.2 LUN 功能特性 2.2 Thick LUN与Thin LUN2.2.1 Thick LUN特性剖析2.2.2 Thin LUN特性剖析 三、块级存储虚拟化技术实现3.1 基于主机的实现方式3.1.1 原理阐述3.1.2 优缺点评估 3.2 基于存储设备的实现…

手摸手实战前端项目CI CD

由于图片和格式解析问题&#xff0c;为了更好阅读体验可前往 阅读原文 CI/CD 是 持续集成&#xff08;Continuous Integration&#xff09; 和 持续交付/部署&#xff08;Continuous Delivery/Continuous Deployment&#xff09; 的缩写&#xff0c;是现代软件开发中的一种自动…

【EI 会议征稿通知】第七届机器人与智能制造技术国际会议 (ISRIMT 2025)

第七届机器人与智能制造技术国际会议 (ISRIMT 2025) 2025 7th International Symposium on Robotics & Intelligent Manufacturing Technology 会议主要围绕“机器人”、“智能制造技术” 等研究领域展开讨论&#xff0c;旨在为机器人与智能制造技术等领域的专家学者、工…

【Linux】信号

目录 一、信号的概念二、信号的产生2.1 通过键盘进行信号的产生2.2 通过系统调用进行信号的产生2.2.1 kill函数2.2.2 raise函数2.2.3 abort函数 2.3 通过异常的方式进行信号的产生2.4 通过软件条件的方式进行信号的产生2.4.1 关闭管道读端2.4.2 alarm函数 2.5 Core Dump&#x…

基于go语言的驾考系统设计与实现

在Internet时代&#xff0c;Internet信息技术已广泛应用于各个领域。 对人们的生活以及学习产生了较大的影响。通过信息技术建立的驾照考试管理系统&#xff0c;利用系统对驾照考试进行统一的管理&#xff0c;能够提驾照考试管理的工作效率&#xff0c;具有重要的现实意义。 本…

鸿蒙打包发布

HarmonyOS应用/元服务发布&#xff08;打包发布&#xff09; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-publish-app-V13?catalogVersionV13 密钥&#xff1a;包含非对称加密中使用的公钥和私钥&#xff0c;存储在密钥库文件中&#xff0c;格式…

基于Linux系统指令使用详细解析

一 Linux系统常用操作命令编辑快捷 1.1终端快捷键&#xff1a; Ctrl a/Home 切换到命令行开始 Ctrl e/End 切换到命令行末尾 Ctrl l 清除屏幕内容&#xff0c;效果等同于 clear Ctrl u 清除剪切光标之前的内容 Ctrl k 剪切清除光标之后的内容 Ctrl y 粘贴刚才所删…

深度学习-87-大模型训练之预训练和微调所用的数据样式

文章目录 1 大模型训练的阶段1.1 预训练1.1.1 全量预训练1.1.2 二次预训练1.2 微调2 预训练需要的数据2.1 清洗成的文本文档2.2 如何从文本文档学习2.3 常见预训练中文语料库3 微调需要的数据3.1 微调例子一:电商客服场景3.2 微调例子二:行政咨询场景3.3 微调数据长什么样3.3…

基于 STM32 的多功能时间管理器项目

引言 在快节奏的生活中&#xff0c;时间管理显得尤为重要。本项目旨在通过 STM32 开发一个多功能时间管理器&#xff0c;功能包括计时器、闹钟和日历。用户可以方便地设置不同的提醒和计时任务&#xff0c;以更好地管理日常生活和工作。 项目名称 多功能时间管理器 环境准备 …

麦田物语学习笔记:代码链接UI实现时间日期对应转换

基本流程 时间系统UI如下 本篇文章将UI和TimeManager里的数据联系在一起, 1.代码思路 (1)新建TimeUI.cs挂载在GameTime物体上,然后获取它的子物体这些组件来改变里面的数值,所以需要获得Day & Night的子物体Image中的Rect Transform,用于旋转季节的图标;获得Clock每个子物…

HTML文章翻页功能

效果展示&#xff1a; 效果原理&#xff1a; 1、引入CDN 2、绘制文章翻页样式&#xff0c;以及自动分段 3、获取窗口宽高&#xff0c;计算出当前文章总分段&#xff0c;并实现分页 4、完整代码 <!DOCTYPE html> <html><head><meta charset"utf-8&qu…

深度学习电影推荐-CNN算法

文章目录 前言视频演示效果1.数据集环境配置安装教程与资源说明1.1 ML-1M 数据集概述1.1.1数据集内容1.1.2. 数据集规模1.1.3. 数据特点1.1.4. 文件格式1.1.5. 应用场景 2.模型架构3.推荐实现3.1 用户数据3.2 电影数据3.3 评分数据3.4 数据预处理3.5实现数据预处理3.6 加载数据…

代理模式实现

一、概念&#xff1a;代理模式属于结构型设计模式。客户端不能直接访问一个对象&#xff0c;可以通过代理的第三者来间接访问该对象&#xff0c;代理对象控制着对于原对象的访问&#xff0c;并允许在客户端访问对象的前后进行一些扩展和处理&#xff1b;这种设置模式称为代理模…

2024年11月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(一)

软考高级系统架构设计师考试包含三个科目&#xff1a;信息系统综合知识、系统架构设计案例分析和系统架构设计论文。考试形式为机考。本文主要回顾2024年下半年(2024-11-10)系统架构设计师考试上午综合知识科目的选择题&#xff0c;同时附带参考答案、解析和所涉知识点。 由于机…

【Kafka】Linux+KRaft集群部署指南

【Kafka】LinuxKRaft集群部署指南 摘要本地环境说明官网准备工作快速开始修改config/kraft/server.properties初始化数据存储目录 新节点加入集群启动停止测试创建topic创建生产者创建消费者 摘要 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在…

【GIS操作】使用ArcGIS Pro进行海图的地理配准(附:墨卡托投影对比解析)

文章目录 一、应用场景二、墨卡托投影1、知识点2、Arcgis中的坐标系选择 三、操作步骤1、数据转换2、数据加载3、栅格投影4、地理配准 一、应用场景 地理配准是数字化之前必须进行的一项工作。扫描得到的地图数据通常不包含空间参考信息&#xff0c;需要通过具有较高位置精度的…

计算机网络 (45)动态主机配置协议DHCP

前言 计算机网络中的动态主机配置协议&#xff08;DHCP&#xff0c;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;主要用于自动分配IP地址和其他网络配置参数给连接到网络的设备。 一、基本概念 定义&#xff1a;DHCP是一种网络协议&#xf…

自动驾驶3D目标检测综述(八)

在介绍完前九章的内容后&#xff0c;咱们已经基本完成了综述主题内容的解读。剩下只有第十章分析和展望以及第十一章总结的部分。本篇为自动驾驶3D目标检测综述的第八篇也将是最后一篇。 目录 1、研究趋势 1.1 数据选择的趋势 1.2 推理时间的趋势 1.3 基于激光雷达方法的趋…

Web3 时代,区块链与物联网的融合创新前景

随着Web3时代的到来&#xff0c;区块链技术和物联网&#xff08;IoT&#xff09;的融合成为科技领域的一个热点话题。Web3以去中心化为核心理念&#xff0c;而区块链正是这一理念的技术支撑。物联网则通过智能设备和传感器将现实世界的数据数字化&#xff0c;连接成一个庞大的网…