- 博客(31)
- 收藏
- 关注
原创 大白话解析LevelDB:TableCache
`TableCache`在`LevelDB`中的作用是管理和缓存`SST`(Sorted String Tables)的读取。为了提高读取效率,`TableCache`会缓存已打开的`SST`。这样,对同一`SST`的多次读取操作就不需要每次都打开文件。
2024-02-29 21:44:30 950
原创 大白话解析LevelDB:ShardedLRUCache
`ShardedLRUCache`只是一个`LRUCache`的封装,包含多个`LRUCache` shard。插入、查找、删除等操作都是基于`LRUCache`的操作,只是在操作之前,需要先计算出`key`的`hash`值,然后根据`hash`值选择一个`shard`,再在该`shard`的`LRUCache`中进行操作。
2024-02-29 21:38:04 2194
原创 大白话解析LevelDB:LRUCache
`LRUCache`是一个基于LRU(Least Recently Used)算法实现的`Cache`。当`Cache`满了之后,再插入新的缓存项时,会将`Cache`中访问时间最早的缓存项移除,为新的缓存项腾出空间。
2024-02-29 21:19:40 992
原创 大白话解析LevelDB: Table
`Table`就是`SST(Sorted Strings Table)`。当我们要对一个`SST`进行读取操作时,比如查找一个`Key`,或者遍历这个`SST`,就需要通过`Table`提供的接口来完成。`Table`将`SST`文件的读取细节封装了起来,让上层不需要去关心`SST`文件的格式和读取细节。
2024-02-21 22:34:26 926 2
原创 大白话解析LevelDB: TwoLevelIterator
`TwoLevelIterator`其实就是用于遍历`SST`里所有`Key-Value`的`Iterator`。那为什么要叫做`TwoLevelIterator`而不叫`SSTIterator`呢?`TwoLevel`指的是哪两个`Level`呢?`TwoLevel`不是指同时遍历两层`Level`,而是指`SST`里的`Index Block`和`Data Block`两层。
2024-02-21 22:24:12 1144
原创 大白话解析LevelDB 4: 查找一个 Key
LevelDB 中查询一个`Key`的接口为`Status DBImpl::Get(const ReadOptions& options, const Slice& key, std::string* value);`,其实现如下。
2024-01-29 22:43:50 650
原创 大白话解析LevelDB 3: SST Compaction
LevelDB中有两种`Compaction`,一种是`Compact MemTable`,另一种是`Compact SST`。`Compact MemTable`是将`MemTable`落盘为SST文件,`Compact SST`是将多个SST文件合并为一个SST文件。本章讲述的是`Compact SST`的过程。
2024-01-23 21:35:25 1191 2
原创 大白话解析LevelDB 0: 食用顺序
- [大白话解析LevelDB 1:把Key-Value写入MemTable](https://blog.csdn.net/sinat_38293503/article/details/134740029)- [大白话解析LevelDB 2: MemTable 落盘为 SST 文件](https://blog.csdn.net/sinat_38293503/article/details/135662037)
2024-01-17 22:44:45 539
原创 大白话解析LevelDB 2: MemTable 落盘为 SST 文件
LevelDB中有两种`Compaction`,一种是`Compact MemTable`,另一种是`Compact SST`。`Compact MemTable`是将`MemTable`落盘为SST文件,`Compact SST`是将多个SST文件合并为一个SST文件。LevelDB在将`Key-Value`写入`MemTable`的过程中,会先检查当前`MemTable`的大小是否有达到阈值。如果达到阈值,则创建一个新的`MemTable`,并且在后台线程中将旧的`MemTable`写入磁盘。这个
2024-01-17 22:38:24 1067
原创 大白话解析LevelDB: VersionSet
在 LevelDB 中,`VersionSet` 类是一个关键的内部组件,负责管理数据库的不同版本。这个类跟踪了所有的 SSTables(排序字符串表)和它们在数据库中的布局。每次对数据库进行修改时(如添加、删除数据),LevelDB 会创建一个新的 `Version` 对象,这个对象由 `VersionSet` 管理。`VersionSet` 通过维护这些 `Version` 对象,可以快速地切换到数据库的不同历史状态,从而支持 LevelDB 的快照和压缩操作。简而言之,`VersionSet` 在 L
2024-01-17 22:33:37 2067
原创 大白话解析LevelDB: VersionEdit
LevelDB 在进行 Compaction 的过程中,会增加一些 SST 并且删除一些 SST,这些操作都会引起数据库状态的变化。每个数据库状态都对应一个 Version 版本,Version 里对应的数据库状态,也就是每层 level 里都有哪些 SST 文件。VersionEdit 就是用来记录两个 Version 版本之间的变化的。`Version N + VersionEdit = Version N+1`。
2024-01-17 22:17:10 523
原创 大白话解析LevelDB: FilterBlockBuilder
与 BlockBuilder 类似,FilterBlockBuilder 是 FilterBlock 的构建器。在构造 SST 的过程中,每当一个 Data Block 构建完成,就会通过`StartBlock(uint64_t block_offset)`方法在 Filter Block 里构建与下一个 Data Block 对应的 Filte。通过`Add(const Slice& key)`方法,我们可以将需
2024-01-17 21:34:24 934 2
原创 大白话解析LevelDB: FilterPolicy
FilterPolicy 是一个接口类,定义了两个方法:- `CreateFilter(const Slice* keys, int n, std::string* dst)`:为 keys 中的所有 key 创建一个 filter,将 filter 编码后压入 dst 里。- `KeyMayMatch(const Slice& key, const Slice& filter)`:判断 key 是否在 filter 中。
2024-01-17 21:30:39 532
原创 大白话解析LeveDB: LevelDB 中各种文件的作用
LevelDB 中有 SST文件、WAL文件、MANIFEST文件、CURRENT文件、LOCK文件和LOG文件。SST文件存储实际的Key-Value数据,WAL文件记录最近的写操作以便在系统崩溃后恢复数据,MANIFEST文件记录数据库的当前状态,CURRENT文件指向当前使用的MANIFEST文件,LOCK文件防止多个进程同时访问数据库,LOG文件记录数据库的运行状态和重要事件。
2024-01-01 18:09:44 1266
原创 大白话解析LevelDB: Env
Env 类在 LevelDB 中是一个抽象基类,它定义了一组虚拟方法,这些方法封装了所有与操作系统环境交互的操作。这包括文件操作(如打开、读取、写入、关闭文件),线程创建和同步操作(如互斥锁和条件变量),以及获取系统相关信息(如当前时间,或者某个文件的大小)等。这种设计使得 LevelDB 可以在不同的操作系统和平台上运行,只需要提供一个特定平台的 Env 实现。例如,LevelDB 提供了一个针对 POSIX 系统的 Env 实现。
2023-12-31 17:21:48 1053
原创 大白话解析LevelDB: Version
在 LevelDB 中,Version 扮演着核心的角色,负责管理和维护数据库的不同版本。LevelDB 是一种基于 LSM-tree(Log-Structured Merge-tree)的键值存储,它通过创建数据的不同“版本”来优化读写操作。
2023-12-26 11:22:51 1161 1
原创 大白话解析LevelDB: WritableFile 接口
由于文件写入在不同平台(比如posix && win)需要使用不同的接口,所以LevelDB将文件写入相关的操作抽象出了一个接口`WritableFile`。本文只关注`PosixWritableFile`的实现,嘿嘿。
2023-12-20 22:10:27 2218 1
原创 大白话解析LevelDB: TableBuilder
LevelDB将`MemTable`生成`SST`的相关操作封装成了`TableBuilder`类
2023-12-17 11:52:42 1232 1
原创 大白话解析LevelDB: BlockBuilder
BlockBuilder 是一个 Block 的构建器,它会将 Block 的 Key-Value 以及重启点信息编码到一个`char* buffer`里。
2023-12-14 15:49:48 914 1
原创 大白话解析LevelDB:Comparator
LevelDB 中 将 Key 之间的比较抽象为 Comparator,方便用户根据不同的业务场景实现不同的比较策略。
2023-12-12 10:10:20 806
原创 大白话解析LevelDB:Pimpl模式
在 LevelDB 中,Rep 通常是一种编程惯用法,用于实现类的 Pimpl(Pointer to Implementation)模式。Rep 是 “Representation” 的缩写,意味着这个结构体或类包含了另一个类的实际表示或实现细节。
2023-12-06 14:32:59 484 1
原创 大白话解析LevelDB 1:把Key-Value写入MemTable
10分钟讲明白LevelDB是如何将Key-Value写入MemTable的
2023-12-01 17:26:36 988 3
原创 大白话解析LevelDB:数据格式
本文讲解LevelDB中定义的各种数据格式,如UserKey、InternalKey、WriteBatch
2023-12-01 17:19:11 1267 3
原创 大白话解析LevelDB:整数序列化
`FixedInt`的编解码速度快,但是会浪费空间,属于空间换时间的做法。`Varint`的编解码速度慢,但是节省空间,属于时间换空间的做法。- 被频繁调用,并且出现值较大数的概率偏大时,选择`FixedInt`。- 当数据量较大,且经常出现较小数值时,选择`Varint`可以节省存储空间,但不会损失多少性能。
2023-12-01 15:44:30 1003 3
原创 大话C++之:类型转换
5分钟彻底讲清楚C++里4种不同的类型转换。- `static_cast` 是最常用的类型转换,适用于**基本类型**之间的转换。- `dynamic_cast` 主要用于**基类指针或引用**与**派生类指针或引用**之间的转换 。- `const_cast` 用于修改或移除对象的**const**或**volatile**属性。- `reinterpret_cast` 等效于C语言里强制类型转换。
2023-11-30 14:37:46 172 1
原创 大话C++之:volatile关键字
5分钟彻底讲明白volatile的使用场景,volatile等效于没有std::atomic的memory_order_seq_cst。
2023-11-30 14:27:21 167 1
原创 大白话解析LevelDB:Arena内存分配器
大多数C++相关的开源项目都会实现自己的内存管理,而不直接使用标准库的malloc。现在流行的malloc实现有jemalloctcmallocptmalloc等,它们都能高效的管理内存,减少内存碎片,提高多线程下内存分配的性能。但这都是对应于general的应用场景,每个应用都有不同的场景,有的分配大内存为主,有的分配小内存为主。为了更进一步的提高内存分配效率与减少内存碎片,LevelDB使用自己的内存管理机制,Arena。相比于直接使用malloc:LevelDB经常需要分配小块内存。
2023-11-29 20:32:32 1365 3
原创 大白话解析LevelDB:SkipList(跳表)
LevelDB使用SkipList作为有序集合的实现。相比于红黑树、B+Tree,SkipList的实现简单,写入操作高效,唯一的缺点是最坏情况下其读写的时间复杂度是O(N)。
2023-11-27 14:05:10 1437 2
原创 大白话C++之:一文搞懂C++多线程内存模型(Memory Order)
本文深入探讨了多线程编程中的两大核心概念:数据竞争与内存顺序。通过具体的 C++ 示例,我们首先了解了数据竞争的本质及其对程序正确性的影响,随后展示了如何利用 C++11 引入的 std::atomic 来有效解决这一问题。接着,文章转向讨论内存顺序,阐释了在并发环境下,如何处理由于编译器和处理器优化带来的指令重排现象。文章最后通过示例代码清晰地说明了内存顺序在保证多线程程序正确性中的重要性。
2023-11-25 23:13:58 3999 9
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人