# 69.2.实施
散列索引中有四种页面:元页面(第0页),其中包含静态分配的控制信息;主存储桶页面;溢出页面;和位图页面,它们跟踪已释放并可重复使用的溢出页面。出于寻址目的,位图页被视为溢出页的子集。
扫描索引和插入元组都需要定位给定元组应该位于的bucket。要做到这一点,我们需要元页面中的桶计数、高掩码和低掩码;然而,出于性能原因,必须为每一个这样的操作锁定和锁定图元页是不可取的。相反,我们在每个后端的relcache条目中保留一个元页面的缓存副本。只要目标存储桶自上次缓存刷新后未被拆分,这将生成正确的存储桶映射。
主存储桶页面和溢出页面是独立分配的,因为任何给定的索引可能需要相对于其存储桶数量更多或更少的溢出页面。散列代码使用一组有趣的寻址规则来支持可变数量的溢出页,而不必在创建主存储桶页后移动它们。
索引表中的每一行都由散列索引中的一个索引元组表示。散列索引元组存储在bucket页中,如果存在,则存储在溢出页中。我们通过将任何一个索引页中的索引项按哈希代码排序来加快搜索速度,从而允许在索引页中使用二进制搜索。但是请注意,有*不*假设一个bucket的不同索引页上的散列码的相对顺序。
扩展散列索引的桶分割算法过于复杂,不值得在这里提及,尽管在中有更详细的描述src/backend/access/hash/README
。拆分算法是安全的,如果未能成功完成,可以重新启动。