【PGCCC】Postgresql 动态哈希表实现

结构图

hash 表包含了多个 segment 切片,每个 segment 包含了相同数量的 bucket。里面的 bucket 使用链表存储着 hash 值相同的元素。
在这里插入图片描述
当查找指定的 key 时,首先计算出它的哈希值,然后根据后面的几位数,计算出对应的 bucket 位置。之后遍历 bucket 的元素链表,查看是否有 key 元素。

当增加元素时,同样先找到对应 bucket 位置,然后查看是否存在对应的链表中。如果不存在,直接添加到尾部。如果存在则可以覆盖或者报错。

当删除元素时,同样先找到对应 bucket 位置,然后查看是否存在对应的链表中。如果存在,则只需要将其从链表中删除即可。

扩容原理

postgresql 只会在负载率过高的情况下,发生扩容操作。并且它的一次扩容只会增加一个 bucket。我们来举个例子,查看下它的扩容过程。我们先初始化只有2个 bucket 的哈希表,
在这里插入图片描述
计算 key 对应的 bucket 位置,需要涉及到 hign_mask 和 low_mask。下面程序实现了

/* Convert a hash value to a bucket number */
static inline uint32 calc_bucket(HASHHDR *hctl, uint32 hash_val)
{
	uint32 bucket = hash_val & hctl->high_mask;
	if (bucket > hctl->max_bucket)
		bucket = bucket & hctl->low_mask;
	return bucket;
}

当发生扩容时,会计算新增bucket的元素和原先哪个bucket有关系,需要将旧有的bucket数据重新分开。并且还会更新相关属性

new_bucket = hctl->max_bucket + 1;
// 更新最大bucket索引
hctl->max_bucket+
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值