postgresql xxhash64 哈希函数实现

由于业务需求,只支持 int8 -> int8,如果需要改类型,可以让 AI 改下

sql 复制代码
CREATE OR REPLACE FUNCTION public.xxhash64(p_input bigint)
RETURNS bigint
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $xxh$
DECLARE
    -- xxHash64 的 5 个 64 位素数(超出 int8 有符号范围,用 numeric 无损保存)
    c_p1 numeric := 11400714785074694791;
    c_p2 numeric := 14029467366897019727;
    c_p3 numeric := 1609587929392839161;
    c_p4 numeric := 9650029242287828579;
    c_p5 numeric := 2870177450012600261;
    c_mod numeric := 18446744073709551616;   -- 2^64,无符号回绕模数
    c_half numeric := 9223372036854775808;   -- 2^63,无符号<->有符号转换分界
    c_len numeric := 8;                      -- 输入字节数(int8 固定 8 字节)
    c_byte_mask bigint := 255;               -- 提取单字节用掩码(& 要求整型)
    c_shift_33 numeric := 8589934592;        -- 2^33,avalanche 逻辑右移量
    c_shift_29 numeric := 536870912;         -- 2^29
    c_shift_32 numeric := 4294967296;        -- 2^32
    v_le numeric;      -- 无符号 64 位输入值(小端展开)
    v_h numeric;       -- 无符号 64 位哈希累加器
    v_acc numeric;     -- round 中间累积值
    v_bits bit(64);    -- 供 按位(XOR/循环左移) 运算中转
    v_byte numeric;
    v_shift integer;
BEGIN
    -- 将 int8 输入按小端展开为无符号 64 位数(符号位视为 2^63)
    v_le := 0;
    FOR v_shift IN 0..7 LOOP
        -- power 必须显式 numeric,否则 PG 会解析为 double 导致 2^56 以上丢失精度
        v_byte := (p_input >> (8 * v_shift)) & c_byte_mask;
        v_le := v_le + v_byte * power(256::numeric, v_shift);
    END LOOP;

    -- xxHash64(seed=0),输入固定 8 字节,走 len<32 短路径
    v_h := mod(c_p5, c_mod);
    v_h := mod(v_h + c_len, c_mod);

    -- finalize 中处理第一个 8 字节组:k1 = XXH64_round(0, le64)
    v_acc := mod(v_le * c_p2, c_mod);
    -- rotl64(v_acc, 31):无符号值转 bit(64) 后做循环左移再转回无符号
    v_bits := (CASE WHEN v_acc >= c_half THEN v_acc - c_mod ELSE v_acc END)::bigint::bit(64);
    v_bits := (v_bits << 31) | (v_bits >> 33);
    v_acc := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                  ELSE (v_bits::bigint)::numeric END;
    v_acc := mod(v_acc * c_p1, c_mod);
    -- h ^= k1
    v_bits := (CASE WHEN v_h >= c_half THEN v_h - c_mod ELSE v_h END)::bigint::bit(64)
              # (CASE WHEN v_acc >= c_half THEN v_acc - c_mod ELSE v_acc END)::bigint::bit(64);
    v_h := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                ELSE (v_bits::bigint)::numeric END;
    -- rotl64(v_h, 27),再 h = h*P1 + P4
    v_bits := (CASE WHEN v_h >= c_half THEN v_h - c_mod ELSE v_h END)::bigint::bit(64);
    v_bits := (v_bits << 27) | (v_bits >> 37);
    v_h := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                ELSE (v_bits::bigint)::numeric END;
    v_h := mod(mod(v_h * c_p1, c_mod) + c_p4, c_mod);

    -- 8 字节已耗尽,无 4 字节/单字节尾部

    -- avalanche 归约:逻辑右移用 floor(v/2^n) 在无符号 numeric 域等价
    -- h ^= h >> 33
    v_bits := (CASE WHEN v_h >= c_half THEN v_h - c_mod ELSE v_h END)::bigint::bit(64)
              # (floor(v_h / c_shift_33))::bigint::bit(64);
    v_h := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                ELSE (v_bits::bigint)::numeric END;
    v_h := mod(v_h * c_p2, c_mod);
    -- h ^= h >> 29
    v_bits := (CASE WHEN v_h >= c_half THEN v_h - c_mod ELSE v_h END)::bigint::bit(64)
              # (floor(v_h / c_shift_29))::bigint::bit(64);
    v_h := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                ELSE (v_bits::bigint)::numeric END;
    v_h := mod(v_h * c_p3, c_mod);
    -- h ^= h >> 32
    v_bits := (CASE WHEN v_h >= c_half THEN v_h - c_mod ELSE v_h END)::bigint::bit(64)
              # (floor(v_h / c_shift_32))::bigint::bit(64);
    v_h := CASE WHEN (v_bits::bigint)::numeric < 0 THEN (v_bits::bigint)::numeric + c_mod
                ELSE (v_bits::bigint)::numeric END;

    -- 无符号值转有符号 int8 返回
    IF v_h >= c_half THEN
        v_h := v_h - c_mod;
    END IF;
    RETURN v_h::bigint;
END;
$xxh$;
相关推荐
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
geovindu3 天前
sql: Transaction & Concurrency Patterns using postgresql 18
postgresql·数据库开发·数据库架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
于平安3 天前
MySQL-触发器
数据库·mysql
白远山3 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析