PDB 序列化哈希表格式

简介

PDB 格式的设计目标之一是提供对调试信息的加速访问,因此在某些情况下,哈希表会被序列化并直接嵌入到文件中,而不是要求使用者读取值列表并在运行时重建哈希表。

序列化格式支持任意大小和容量的哈希表,以及值类型和哈希函数。唯一支持的键值类型是 uint32。唯一的限制是生产者和消费者必须就哈希函数达成一致。因此,本文档中不再进一步讨论哈希函数,假设对于 PDB 文件哈希表的特定实例,正在使用适当的哈希函数。

磁盘格式

.--------------------.-- +0
|        Size        |
.--------------------.-- +4
|      Capacity      |
.--------------------.-- +8
| Present Bit Vector |
.--------------------.-- +N
| Deleted Bit Vector |
.--------------------.-- +M                  ─╮
|        Key         |                        │
.--------------------.-- +M+4                 │
|       Value        |                        │
.--------------------.-- +M+4+sizeof(Value)   │
         ...                                  ├─ |Capacity| Bucket entries
.--------------------.                        │
|        Key         |                        │
.--------------------.                        │
|       Value        |                        │
.--------------------.                       ─╯
  • 大小 - 哈希表中包含的值的数量。

  • 容量 - 哈希表中桶的数量。生产者应将负载因子保持在不超过 2/3*Capacity+1

  • 存在位向量 - 一个序列化的位向量,其中包含有关哪些桶具有有效值的信息。如果桶具有值,则相应的位将被设置,如果桶没有值(因为桶为空或因为值是墓碑值),则位将被清除。

  • 已删除位向量 - 一个序列化的位向量,其中包含有关哪些桶具有墓碑值的信息。如果此桶中的条目已删除,则该位将被设置,否则将被清除。

  • 键和值 - 一个包含 Capacity 个哈希桶的列表,其中第一个条目是键(始终为 uint32),第二个条目是值。可以通过检查存在和已删除位向量来确定每个桶的状态(有效、空、已删除)。

存在和已删除位向量

指示每个桶状态的位向量按如下方式序列化

.--------------------.-- +0
|     Word Count     |
.--------------------.-- +4
|        Word_0      |        ─╮
.--------------------.-- +8    │
|        Word_1      |         │
.--------------------.-- +12   ├─ |Word Count| values
         ...                   │
.--------------------.         │
|       Word_N       |         │
.--------------------.        ─╯

当将这些字视为一个连续的字节块时,它们表示一个具有以下布局的位向量

  .------------.         .------------.------------.
  |   Word_N   |   ...   |   Word_1   |   Word_0   |
  .------------.         .------------.------------.
  |            |         |            |            |
+N*32      +(N-1)*32    +64          +32          +0

其中此位向量的第 k 位表示哈希表中第 k 个桶的状态。