anchor.diff:                                  "{int(), int()}");
               _ -> false
           end.
  +
  +
  +
  +%% @doc Generate a random key from the pdf as defined in (Nagao, Shudo, 2011)
  +% TODO unit test that the generator doesn't generate keys from outside ?MINUS_INFINITY
  +% to ?PLUS_INFINITY
  +%% TODO
  +%I floor the key for now; the key generator should return ints, but returns
  +%float. It is currently unclear if this is a bug in the original paper by Nagao and
  +%Shudo. Using erlang:trunc/1 should be enough for flooring, as X >= 0
  +% TODO using the remainder might destroy the CDF. why can X > 2^128?
  +-spec get_random_key_from_generator(SourceNodeId :: key(),
  +                                    PredId :: key(),
  +                                    SuccId :: key()
  +                                   ) -> key().
  +get_random_key_from_generator(SourceNodeId, PredId, SuccId) ->
  +    Rand = random:uniform(),
  +    X = SourceNodeId + get_range(SourceNodeId, SuccId) *
  +        math:pow(get_range(SourceNodeId, PredId) /
  +                    get_range(SourceNodeId, SuccId),
  +                    Rand
  +                ),
  +    erlang:trunc(X) rem 16#100000000000000000000000000000000
  +    .
   
   %% userdevguide-begin rt_frtchord:handle_custom_message
   %% @doc Handle custom messages. The following messages can occur:
  
positive.code:     .
  
  % @doc Delete an entry from the routing table
  % TODO stale fingers, delete pointers
  -spec entry_delete(EntryKey :: key(), RT :: rt()) -> RefinedRT :: rt().
  entry_delete(EntryKey, RT) ->
      Tree = gb_trees:delete(EntryKey, get_rt_tree(RT)),
  
negative.code: %% @doc Creates an "empty" routing table.
  -spec empty(nodelist:neighborhood()) -> rt().
  empty(Neighbors) ->
      EmptyRT = add_source_entry(nodelist:node(Neighbors), #rt_t{}),
      remove_and_ping_entries(Neighbors, EmptyRT)
      .
  %% userdevguide-end rt_frtchord:empty
  
  