Search code examples
network-programmingfunctional-programmingerlangp2psctp

Erlang Hash Tree


I'm working on a p2p app that uses hash trees.

I am writing the hash tree construction functions (publ/4 and publ_top/4) but I can't see how to fix publ_top/4.

I try to build a tree with publ/1:

nivd:publ("file.txt").

prints hashes...

** exception error: no match of right hand side value [67324168]
     in function  nivd:publ_top/4
     in call from nivd:publ/1

The code in question is here:

http://github.com/AndreasBWagner/nivoa/blob/886c624c116c33cc821b15d371d1090d3658f961/nivd.erl

Where do you think the problem is?

Thank You, Andreas


Solution

  • Looking at your code I can see one issue that would generate that particular exception error

    publ_top(_,[],Accumulated,Level) ->
        %% Go through the accumulated list of hashes from the prior level
        publ_top(string:len(Accumulated),Accumulated,[],Level+1);
    
    publ_top(FullLevelLen,RestofLevel,Accumulated,Level) ->
      case FullLevelLen =:= 1 of
        false -> [F,S|T]=RestofLevel,
          io:format("~w---~w~n",[F,S]),
          publ_top(FullLevelLen,T,lists:append(Accumulated,[erlang:phash2(string:concat([F],[S]))]),Level);
        true -> done
      end.
    

    In the first function declaration you match against the empty list. In the second declaration you match against a list of length (at least) 2 ([F,S|T]). What happens when FullLevelLen is different from 1 and RestOfLevel is a list of length 1? (Hint: You'll get the above error).

    The error would be easier to spot if you would pattern match on the function arguments, perhaps something like:

    publ_top(_,[],Accumulated,Level) ->
        %% Go through the accumulated list of hashes from the prior level
        publ_top(string:len(Accumulated),Accumulated,[],Level+1);
    
    publ_top(1, _, _, _) ->
        done;
    
    publ_top(_, [F,S|T], Accumulated, Level) ->
        io:format("~w---~w~n",[F,S]),
        publ_top(FullLevelLen,T,lists:append(Accumulated,[erlang:phash2(string:concat([F],[S]))]),Level);
    
    %% Missing case:
    % publ_top(_, [H], Accumulated, Level) ->
    %     ...