@@ -8,6 +8,20 @@ EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
8
8
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9
9
See the Mulan PSL v2 for more details. */
10
10
11
+
12
+ // MemTable 将插入的 Key-Value 编码为如下的记录存储。
13
+ // ┌───────────┬──────────────┬───────┬──────────────┬──────────────────┐
14
+ // │ │ │ │ │ │
15
+ // │key_size(8)│ key(key_size)│ seq(8)│ value_size(8)│ value(value_size)│
16
+ // │ │ │ │ │ │
17
+ // └───────────┴──────────────┴───────┴──────────────┴──────────────────┘
18
+ // 其中,key_size 和 value_size 分别表示 key+seq 和 value 的长度,seq 表示记录的时间戳。括号中表示占用字节数。
19
+ // MemTable 的实现位于:src/oblsm/memtable/,在代码中,
20
+ // 我们将上图中的key 称为 user_key,
21
+ // 将 key + seq 称为 internal_key,
22
+ // 将key_size + key + seq 称为 lookup_key。
23
+
24
+
11
25
#include " oblsm/memtable/ob_memtable.h"
12
26
#include " common/lang/string.h"
13
27
#include " common/lang/memory.h"
@@ -16,8 +30,21 @@ See the Mulan PSL v2 for more details. */
16
30
17
31
namespace oceanbase {
18
32
33
+ // 将一个 (key, value) 以及版本号 seq 插入到内存表 MemTable 中。
34
+ // 示例:
35
+ // key = "apple" // 长度 = 5
36
+ // value = "red fruit" // 长度 = 9
37
+ // seq = 123456789ULL // 一个版本号
38
+ // [key_size (8 bytes)] [key (user_key)] [seq (8 bytes)] [value_size (8 bytes)] [value]
39
+ // [ 5 ] [apple ] [123456789 ] [9 ] [red fruit]
40
+ // 8字节 5字节 8字节 8字节 9字节
41
+ // 8+5 apple 123456789 9 red fruit
42
+ // 表示这些数据需要占据的长度
43
+ // encoded_len = sizeof(size_t) + 8+5 + sizeof(size_t) + 9;
44
+
19
45
void ObMemTable::put (uint64_t seq, const string_view &key, const string_view &value)
20
46
{
47
+ std::lock_guard<std::mutex> lock (table_mutex_); // 保护整个put操作
21
48
// TODO: add lookup_key, internal_key, user_key relationship and format in memtable/sstable/block
22
49
// TODO: unify the encode/decode logic in separate file.
23
50
// Format of an entry is concatenation of:
@@ -32,13 +59,13 @@ void ObMemTable::put(uint64_t seq, const string_view &key, const string_view &va
32
59
const size_t encoded_len = sizeof (size_t ) + internal_key_size + sizeof (size_t ) + val_size;
33
60
char * buf = reinterpret_cast <char *>(arena_.alloc (encoded_len));
34
61
char * p = buf;
35
- memcpy (p, &internal_key_size, sizeof (size_t ));
62
+ memcpy (p, &internal_key_size, sizeof (size_t )); // 8 字节
36
63
p += sizeof (size_t );
37
64
memcpy (p, key.data (), user_key_size);
38
65
p += user_key_size;
39
- memcpy (p, &seq, sizeof (uint64_t ));
66
+ memcpy (p, &seq, sizeof (uint64_t )); // 8 字节
40
67
p += sizeof (uint64_t );
41
- memcpy (p, &val_size, sizeof (size_t ));
68
+ memcpy (p, &val_size, sizeof (size_t )); // 8 字节
42
69
p += sizeof (size_t );
43
70
memcpy (p, value.data (), val_size);
44
71
table_.insert (buf);
@@ -68,4 +95,60 @@ void ObMemTableIterator::seek(const string_view &k)
68
95
iter_.seek (k.data ());
69
96
}
70
97
71
- } // namespace oceanbase
98
+ } // namespace oceanbase
99
+
100
+
101
+
102
+
103
+ // 📦 SSTable 的存储结构详解
104
+ // 我们来拆解你贴的结构图,帮助你理解 SSTable 是如何组织数据的:
105
+
106
+ // scss
107
+ // 复制代码
108
+ // ┌─────────────────┐
109
+ // │ block 1 │◄──┐
110
+ // ├─────────────────┤ │
111
+ // │ block 2 │ │
112
+ // ├─────────────────┤ │
113
+ // │ .. │ │
114
+ // ├─────────────────┤ │
115
+ // │ block n │◄┐ │
116
+ // ├─────────────────┤ │ │
117
+ // ┌─►│ meta size(n) │ │ │
118
+ // │ ├─────────────────┤ │ │
119
+ // │ │block meta 1 size│ │ │
120
+ // │ ├─────────────────┤ │ │
121
+ // │ │ block meta 1 ┼─┼─┘
122
+ // │ ├─────────────────┤ │
123
+ // │ │ .. │ │
124
+ // │ ├─────────────────┤ │
125
+ // │ │block meta n size│ │
126
+ // │ ├─────────────────┤ │
127
+ // │ │ block meta n ┼─┘
128
+ // │ ├─────────────────┤
129
+ // └──┼ │
130
+ // └─────────────────┘
131
+ // 我们从上到下看:
132
+
133
+ // 1. Block 区域(数据部分)
134
+ // │ block 1 │
135
+ // │ block 2 │
136
+ // │ ... │
137
+ // │ block n │
138
+ // 2. Meta 信息区域(索引/元信息)
139
+ // 紧跟在所有 block 后面,是描述这些 block 的元信息区域:
140
+ // │ meta size(n) │
141
+ // │ block meta 1 size │
142
+ // │ block meta 1 │
143
+ // │ block meta 2 size │
144
+ // │ block meta 2 │
145
+ // │ ... │
146
+ // │ block meta n size │
147
+ // │ block meta n │
148
+ // 这些是描述 block 的"目录",类似于书的目录页:
149
+ // meta size(n):说明一共有多少个 block。
150
+ // block meta i size:说明第 i 个 block 的元信息有多大。
151
+ // block meta i:包含该 block 的各种元数据,例如:
152
+ // block 在 SSTable 文件中的起始偏移(offset)
153
+ // block 的大小
154
+ // block 中 key 的范围(起始 key、结束 key)
0 commit comments