Commits

Bob Ippolito  committed dd6e6bb

use some murmur2 tests based on Python results, remove a lot of code

  • Participants
  • Parent commits e82f2fc

Comments (0)

Files changed (1)

 %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 %% copies of the Software, and to permit persons to whom the Software is
 %% furnished to do so, subject to the following conditions:
-%% 
+%%
 %% The above copyright notice and this permission notice shall be included in
 %% all copies or substantial portions of the Software.
-%% 
+%%
 %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 -module(murmur2).
 -author('Jay Baird <jay@mochimedia.com>').
 -export([hash/1, hash/2]).
--export([test_hash/0]).
+-include_lib("eunit/include/eunit.hrl").
 
 hash(Key) ->
     hash(Key, 0).
     Mask = 16#ffffffff,
     R = 24,
     KeyLen = size(Key),
-    Remainder = KeyLen band 3,
     H = (Seed bxor KeyLen) band Mask,
-    Length = KeyLen - Remainder,
-    <<Chunk:Length/binary, Rest/binary>> = Key,
-    KArr = k_array(Chunk),
-    H1 = murmur2_hash(KArr, M, Mask, R, H),
-    case Remainder > 0 of
-        true ->
-            H2 = calc_remainder(Remainder, rem_array(Rest), H1, M, Mask);
-        false ->
-            H2 = H1
-    end,
+    H2 = murmur2_hash(Key, M, Mask, R, H),
     H3 = (H2 bxor (H2 bsr 13)),
     H4 = (H3 * M) band Mask,
     H5 = (H4 bxor (H4 bsr 15)),
     H5 band Mask.
 
-murmur2_hash([K|T], M, Mask, R, H) ->
+murmur2_hash(<<K:32/little, T/binary>>, M, Mask, R, H) ->
     K1 = (K * M) band Mask,
     K2 = (K1 bxor (K1 bsr R)),
     K3 = (K2 * M),
     H1 = (H * M),
     H2 = (H1 bxor K3) band Mask,
     murmur2_hash(T, M, Mask, R, H2);
-murmur2_hash([], _M, _Mask, _R, H) ->
-    H.
+murmur2_hash(<<>>, _M, _Mask, _R, H) ->
+    H;
+murmur2_hash(Remainder, M, Mask, _R, H) ->
+    N = size(Remainder) * 8,
+    <<K:N/little>> = Remainder,
+    ((H bxor K) * M) band Mask.
 
-calc_remainder(1, [D|_T], H, M, Mask) ->
-    H1 = (H bxor D),
-    (H1 * M) band Mask;
-calc_remainder(Remainder, [D|T], H, M, Mask) ->
-    case Remainder of
-        3 ->
-            H1 = (H bxor (D bsl 16)),
-            calc_remainder(Remainder-1, T, H1, M, Mask);
-        2 ->
-            H1 = (H bxor (D bsl 8)),
-            calc_remainder(Remainder-1, T, H1, M, Mask)
-    end.
-
-k_array(Data) when is_list(Data) ->
-    k_array(list_to_binary(Data));
-k_array(Data) when is_binary(Data) ->
-    k_array(Data, []).
-
-k_array(<<>>, Acc) ->
-    lists:reverse(Acc);
-k_array(Data, Acc) ->
-    <<Chunk:32/integer, Rest/binary>> = Data,
-    k_array(Rest, [Chunk] ++ Acc).
-    
-rem_array(Data) when is_list(Data) ->
-    rem_array(list_to_binary(Data));
-rem_array(Data) when is_binary(Data) ->
-    rem_array(Data, []).
-
-rem_array(<<>>, Acc) ->
-    Acc;
-rem_array(Data, Acc) ->
-    <<Chunk:8/integer, Rest/binary>> = Data,
-    rem_array(Rest, [Chunk] ++ Acc).
-
-test_hash() ->
-    3696606629 = hash(<<"this is a test of the murmur2 hash">>),
-    2294221586 = hash(term_to_binary([{foo, "bar"}, {raz, "matazz"}])).
+hash_test() ->
+    ?assertEqual(3680343784, hash(<<"lkasjdfklajslku2i1op3u49puid">>, 89012738)),
+    F1 = fun (N, Seed) ->
+                hash(list_to_binary(integer_to_list(N)), Seed)
+        end,
+    ?assertEqual(2187758613, lists:foldl(F1, 0, lists:seq(0, 99))),
+    F2 = fun (N, Seed) ->
+                hash(list_to_binary(integer_to_list(N * N)), Seed)
+        end,
+    ?assertEqual(384923386, lists:foldl(F2, 0, lists:seq(0, 99))).