Go 1.24 起，`map` 的底层实现从传统的 `hmap` + `bmap` 哈希表，彻底切换到了 Swiss Table（瑞士表）

![Gemini_Generated_Image_jhqwi7jhqwi7jhqw](D:\zhangyuxin\code\lab\note\assets\golang-map[swiss table].png)



### Group内存布局图

你可以直接复制以下文本块到你的 Markdown 笔记中（使用 text 包裹）：

codeText



```
+-------------------------------------------------------------------------------+
|                               单 Group 内存布局                               |
+--------------------------+----------------------------+-----------------------+
|  1. Metadata 控制字节区   |      2. 连续 Key 存储区      |   3. 连续 Value 存储区  |
+--------------------------+----------------------------+-----------------------+
| [M0][M1][M2]...[M7]      | [K0][K1][K2]...[K7]        | [V0][V1][V2]...[V7]   |
+--------------------------+----------------------------+-----------------------+
| <-   固定 8 个字节     -> | <- 长度取决于 Key 类型 ->   | <- 长度取决于 Val ->  |
| <- 一次性载入寄存器对比 -> |                                                   |
```

**为什么这样设计？（设计优势）：**

1. 
2. **避免内存对齐填充（Padding）**：如果采用 [Meta][Key][Value] 交叉排列，由于不同类型的 Key/Value 字节大小不同，为了对齐，Go 必须在它们之间插入大量空白填充字节，浪费空间。分块连续存储消除了组内的对齐损耗。
3. **对 CPU 缓存友好**：8 字节的 Metadata 紧密相连，一次 Cache Line 填充就能把整组的控制信息全部读入，极大地提高了缓存命中率。

------



### 读取流程

以下为您整理的完整、正确的读取逻辑，您可以直接复制使用：

#### 1.哈希计算与分段 (Hash Splitting)

- 将 Key 传入哈希函数，计算出一个 **64 位的哈希值**。
- 该哈希值被拆分为两部分：**H1（高 57 位）**：用于定位哈希表中的初始 Group 索引。**H2（低 7 位）**：作为特征值（指纹），存储在 Group 的 Metadata 中，用于快速匹配。

#### 2.定位初始 Group (Locate Group)

- 计算初始 Group 索引：group_index = H1 & (Group数量 - 1)。

  > 可以理解与$2^B$进行取模运算，但是**位与运算**效率更高且等价。

#### 3.组内快速匹配 (Group-level SWAR Match)

- **一次性加载**：将目标 Group 的 8 字节 Metadata 一次性载入一个 64 位寄存器中。
- **并行对比（SWAR 技术）**：利用位运算，将 7 位的 H2 同时与这 8 个 Metadata 字节进行并行对比，输出一个 8 位的位掩码（Bitmask）。位掩码中为 1 的位，代表该位置的 H2 与目标 H2 匹配成功。这一步极快，完全避免了循环遍历。

#### 4.冲突解决与探测循环 (Verification & Probing Loop)

根据位掩码的匹配结果，执行以下逻辑：

1. 依次根据匹配成功的索引，去 **Key 存储区** 找到对应的真实 Key。
2. 进行完整的 Key 等值对比（如 if key == targetKey）：**若匹配成功**：直接去 **Value 存储区** 对应偏移量取出 Value 并返回。**若匹配失败**：说明发生了 **H2 哈希冲突**（即不同的 Key 产生了相同的 H2），继续对比下一个匹配的槽位。
3. 如果当前 Group 中所有匹配了 H2 的槽位都对比完了，仍未找到匹配的 Key，则**跳转至【情况 B】**。

此时需要检查当前 Group 的 Metadata 状态，决定是继续向后寻找还是停止：

- **若当前 Group 中存在“空位”（Empty，0xFF）**：

  说明探测链在此处断开，该 Key 在 Map 中**一定不存在**，直接返回 nil 或零值。

- **若当前 Group 中无空位，但存在“墓碑”（Tombstone，0x80）或已满**：

  虽然当前 Group 没找到，但可能因为历史删除操作（留下了墓碑）或哈希冲突，导致数据被存到了后续的 Group。不能停止！使用**二次探测算法（Quadratic Probing）**计算下一个 Group 的索引，跳转回 **【3.组内快速匹配】** 继续循环寻找。
