Skip to content

Instantly share code, notes, and snippets.

@sevaa
Last active July 7, 2020 17:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sevaa/ad99e9af26eb0850a776cb47242ab87e to your computer and use it in GitHub Desktop.
Save sevaa/ad99e9af26eb0850a776cb47242ab87e to your computer and use it in GitHub Desktop.
MurMurHash64B in MySQL dialect of SQL
drop function if exists MurmurHash64B;
delimiter $$
create function MurmurHash64B(s longblob, seed int unsigned)
returns bigint unsigned
deterministic no sql
begin
declare m int unsigned default 0x5bd1e995;
declare r int default 24;
declare len int default length(s);
declare i int default 1;
declare h1 int unsigned default len ^ seed;
declare h2 int unsigned default 0;
declare k1, k2 int unsigned;
declare h bigint unsigned;
while len >= 8 do
set k1 = cast(conv(hex(reverse(mid(s, i, 4))), 16, 10) as unsigned integer);
set k1 = (k1 * m) & 0xffffffff;
set k1 = k1 ^ (k1 >> r);
set k1 = (k1 * m) & 0xffffffff;
set h1 = (h1 * m) & 0xffffffff;
set h1 = h1 ^ k1;
set k2 = cast(conv(hex(reverse(mid(s, i + 4, 4))), 16, 10) as unsigned integer);
set k2 = (k2 * m) & 0xffffffff;
set k2 = k2 ^ (k2 >> r);
set k2 = (k2 * m) & 0xffffffff;
set h2 = (h2 * m) & 0xffffffff;
set h2 = h2 ^ k2;
set len = len - 8;
set i = i + 8;
end while;
if len >= 4 then
set k1 = cast(conv(hex(reverse(mid(s, i, 4))), 16, 10) as unsigned integer);
set k1 = (k1 * m) & 0xffffffff;
set k1 = k1 ^ (k1 >> r);
set k1 = (k1 * m) & 0xffffffff;
set h1 = (h1 * m) & 0xffffffff;
set h1 = h1 ^ k1;
set len = len - 4;
set i = i + 4;
end if;
if len >= 1 then
if len >= 2 then
if len >= 3 then
set h2 = h2 ^ (ord(mid(s, i + 2, 1)) << 16);
end if;
set h2 = h2 ^ (ord(mid(s, i + 1)) << 8);
end if;
set h2 = h2 ^ ord(mid(s, i, 1));
set h2 = (h2 * m) & 0xffffffff;
end if;
set h1 = ((h1 ^ (h2 >> 18)) * m) & 0xffffffff;
set h2 = ((h2 ^ (h1 >> 22)) * m) & 0xffffffff;
set h1 = ((h1 ^ (h2 >> 17)) * m) & 0xffffffff;
set h2 = ((h2 ^ (h1 >> 19)) * m) & 0xffffffff;
set h = h1;
set h = (h << 32) | h2;
return h;
end$$
delimiter ;
@sevaa
Copy link
Author

sevaa commented Feb 29, 2020

An implementation of MurMurHash64B in MySQL's dialect of SQL. Similar, but not identical to Transact-SQL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment