<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -5,3 +5,5 @@ ebin
 session
 server.dot
 server.png
+graphs
+graphs/*</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,9 @@
 -define (TRACE(X, M),  io:format(user, &quot;TRACE ~p:~p ~p ~p~n&quot;,           [?MODULE, ?LINE, X, M])).
 -define (NTRACE(X, M), io:format(user, &quot;NTRACE ~p:~p ~p ~p ~p ~p ~p~n&quot;, [?MODULE, ?LINE, chordjerl_srv:registered_name(), node(), self(), X, M])).
 -define (RECONNECT_TIMEOUT, 10000).
--define (NBIT, 160). % number of bits in the hash function
+%-define (NBIT, 160). % number of bits in the hash function
+-define (NBIT, 7). % number of bits in the hash function
+-define (NBITMOD, round(math:pow(2, ?NBIT))).
 
 % may merge finger-like attributes into the srv state. Maybe
 % srv_state.finger_of_self?</diff>
      <filename>include/defines.hrl</filename>
    </modified>
    <modified>
      <diff>@@ -70,3 +70,6 @@ id_between_oo(Start, End, QueryId) when Start &lt; End  -&gt; % interval does not wrap
     Start &lt; QueryId andalso End &gt; QueryId;
 id_between_oo(Start, End, QueryId)                   -&gt; % interval wraps
     Start &lt; QueryId orelse  End &gt; QueryId.
+
+
+%Node#srv_state.sha rem math:pow(2, ?NBIT)</diff>
      <filename>src/ch_id_utils.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 -module(ch_utils).
--export([max/1, list_replace_n/3]).
+-export([max/1, list_replace_n/3, partition_integer/2]).
 
 % max from http://www.zorched.net/2008/05/28/erlang-example-min-and-max-element-of-a-list/
 max([H|T]) -&gt;
@@ -25,3 +25,12 @@ list_replace_n(N, NewElement, List) -&gt;
    {L1, L2} = lists:split(N - 1, List), 
    [_H|T] = L2,
    lists:append([L1, [NewElement], T]).
+
+
+partition_integer(N,P) -&gt;
+    partition_integer(lists:reverse(integer_to_list(N)),P,[]).
+
+partition_integer([A,B,C,D|T],P,Acc) -&gt;
+    partition_integer([D|T],P,[P,C,B,A|Acc]);
+partition_integer(L,_,Acc) -&gt;
+    lists:reverse(L) ++ Acc.</diff>
      <filename>src/ch_utils.erl</filename>
    </modified>
    <modified>
      <diff>@@ -61,18 +61,27 @@ markup_for_node(Node) -&gt;
             [Node#srv_state.sha, 
             gen_server:call(Node#srv_state.pid, {registered_name}), 
                             Node#srv_state.pid,
-                            Node#srv_state.sha rem ?NBIT]),
+                            Node#srv_state.sha]), 
     O1 = O  ++ [markup_for_connection(Node, Finger, Index) || {Finger, Index} &lt;- lists:zip(Node#srv_state.fingers, lists:seq(1, length(Node#srv_state.fingers)))],
-    O2 = O1 ++ markup_for_predecessor(Node, Node#srv_state.predecessor) ,
-    O2.
+    O2 = O1 ++ markup_for_predecessor(Node, Node#srv_state.predecessor),
+    O3 = O2 ++ markup_for_finger_table(Node),
+    O3.
 
 
 markup_for_connection(Node, Finger, Index) -&gt;
-    io_lib:format(&quot;~p -&gt; ~p [label=~p]~n&quot;, [Node#srv_state.sha, Finger#finger.sha, Index]).
-markup_for_connection(Node, Finger) -&gt;
-    io_lib:format(&quot;~p -&gt; ~p~n&quot;, [Node#srv_state.sha, Finger#finger.sha]).
+    case Index &gt; 1 andalso 
+         lists:nth(Index, Node#srv_state.fingers) =:= lists:nth(Index - 1, Node#srv_state.fingers) of
+        true -&gt; []; % skip it
+        false -&gt; io_lib:format(&quot;~p -&gt; ~p [label=~p]~n&quot;, [Node#srv_state.sha, Finger#finger.sha, Index])
+    end.
 
 markup_for_predecessor(_Node, undefined) -&gt;
     [];
 markup_for_predecessor(Node, Finger) -&gt;
     io_lib:format(&quot;~p -&gt; ~p [style=dashed,arrowhead=open]~n&quot;, [Node#srv_state.sha, Finger#finger.sha]).
+
+markup_for_finger_table(Node) -&gt;
+    Fingers = [io_lib:format(&quot;~p: ~p\\l&quot;, [Index, Finger#finger.sha]) || {Finger, Index} &lt;- lists:zip(Node#srv_state.fingers, lists:seq(1, length(Node#srv_state.fingers)))],
+    Name = gen_server:call(Node#srv_state.pid, {registered_name}),
+    O  = io_lib:format(&quot;~p_finger_table [label=\&quot;{~p fingers|~s}\&quot;, shape=record]~n&quot;, [Name, Name, Fingers]),
+    O.</diff>
      <filename>src/chordjerl_dot.erl</filename>
    </modified>
    <modified>
      <diff>@@ -187,6 +187,8 @@ handle_call({stabilize}, _From, State) -&gt;
     {reply, Reply, NewState};
 
 handle_call({claim_to_be_predecessor, Node}, _From, State) -&gt;
+    % io:format(user, &quot;rec'd a claim to be predecessor on ~p ~p from ~p ~p~n&quot;, 
+    %     [State#srv_state.sha, State#srv_state.pid, Node#finger.sha, Node#finger.pid]),
     {Reply, NewState} = handle_claim_to_be_predecessor(Node, State),
     {reply, Reply, NewState};
 
@@ -317,7 +319,7 @@ handle_closest_preceding_node(Id, State) -&gt;
     handle_closest_preceding_node(Id, State, FingersR).
 
 handle_closest_preceding_node(Id, State, [Finger|T]) -&gt;
-    case ch_id_utils:id_between_oo(State#srv_state.sha, Id, Finger#finger.sha) of 
+    case ch_id_utils:id_between_oo(State#srv_state.sha, Id, Finger#finger.sha) of % one book says _oc
         true  -&gt; 
            {{ok, Finger}, State};
         false -&gt; 
@@ -381,7 +383,12 @@ handle_return_predecessor(State) -&gt;
     end.
 
 handle_claim_to_be_predecessor(Node, State) when is_record(Node, finger) -&gt; 
-    Predecessor = handle_return_predecessor(State),
+    PredecessorResponse = handle_return_predecessor(State),
+    Predecessor = case PredecessorResponse of
+        {finger, Finger} -&gt; Finger;
+        _                -&gt; undefined
+    end,
+
     {Response, NewState} = if
         undefined =:= Predecessor -&gt; 
             handle_set_new_predecessor(Node, State);
@@ -427,20 +434,20 @@ handle_fix_fingers(State) -&gt;
 % this way we dont have to look for all the extras every single time
 % if it isn't set it as fingers[Next]
 handle_fix_fingers(State, Next) -&gt;
-    TargetId   = State#srv_state.sha + math:pow(2, (Next - 1)),
+    TargetId = ch_id_utils:successor_id(State#srv_state.sha, Next),
+    % ?NTRACE(&quot;fixing fingers finding successor&quot;, {next, Next, statesha, State#srv_state.sha, sha, TargetId}),
+
     {{ok, Successor}, _NewState} = handle_find_successor(TargetId, State),
     Fingers    = State#srv_state.fingers,
-    PrevFinger = finger_before(Next, Fingers),
 
-    case PrevFinger#finger.sha =:= Successor#finger.sha of
-        true -&gt;
-            NewNext = 1,
-            {ok, State#srv_state{next=NewNext}};
-        false -&gt;
-            NewFingers = ch_utils:list_replace_n(Next, Successor, Fingers),
-            {ok, State#srv_state{next=Next,fingers=NewFingers}}
-    end.
-            
+    NewFingers = case length(Fingers) &lt; Next of
+        true  -&gt; Fingers ++ [undefined];
+        false -&gt; Fingers
+    end,
+
+    ?NTRACE(&quot;replacing next with successor&quot;, {next, Next, successor, Successor#finger.sha}),
+    NewFingers2 = ch_utils:list_replace_n(Next, Successor, NewFingers),
+    {ok, State#srv_state{next=Next,fingers=NewFingers2}}.
 
 handle_check_predecessor(_State) -&gt;
     {todo}.
@@ -455,7 +462,9 @@ handle_return_finger_ref(State) -&gt;
 handle_set_immediate_successor(NewSuccessor, State) -&gt;
     % io:format(user, &quot;setting new successor for ~p ~p to ~p ~p~n&quot;, 
     %      [State#srv_state.sha, State#srv_state.pid, NewSuccessor#finger.sha, NewSuccessor#finger.pid]),
-    NewState = State#srv_state{fingers=[NewSuccessor|State#srv_state.fingers]},
+    % NewState = State#srv_state{fingers=[NewSuccessor|State#srv_state.fingers]},
+    NewFingers = ch_utils:list_replace_n(1, NewSuccessor, State#srv_state.fingers),
+    NewState = State#srv_state{fingers=NewFingers},
     {ok, NewState}.
 
 %%--------------------------------------------------------------------
@@ -503,8 +512,10 @@ make_sha([]) -&gt;
 
     IdString = atom_to_list(node()) ++ Scope,  % not sure about this
     Sha = sha1:hexstring(IdString), 
-    ch_id_utils:hex_to_int(Sha).               % for now, just store the finger as an int
+    Int = ch_id_utils:hex_to_int(Sha),               % for now, just store the finger as an int
+    Int rem ?NBITMOD.
 
+% return the finger previous to the index N
 finger_before(N, Fingers) -&gt;
     case (N - 1) &gt; 0 of
       true -&gt;</diff>
      <filename>src/chordjerl_srv.erl</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,9 @@
 
 -define(MOD, chordjerl_srv).
 
-setup() -&gt; % todo, figure out how to tear-down
+setup() -&gt; 
+     filelib:ensure_dir(&quot;./graphs/&quot;),
+
      % start three nodes
      chordjerl_srv:start_named(testnode1),
      chordjerl_srv:start_named(testnode2),
@@ -18,46 +20,50 @@ setup() -&gt; % todo, figure out how to tear-down
      ok     = gen_server:call(testnode3, {join, Node2}),
      Node3  = gen_server:call(testnode3, {return_finger_ref}),
      ok     = gen_server:call(testnode4, {join, Node3}), % what's happening is the node is being asked itself to find a node
+     Node4  = gen_server:call(testnode4, {return_finger_ref}),
+
+     % Shas = [{testnode1, Node1#finger.sha}, {testnode2, Node2#finger.sha}, {testnode3, Node3#finger.sha}, {testnode4, Node4#finger.sha}],
+     % io:format(user, &quot;~p~n&quot;, [lists:keysort(2, Shas)]),
+
      {ok}.
 
 generate_diagram_test_() -&gt;
   {
       setup, fun setup/0,
       fun () -&gt;
-         gen_server:call(testnode4, {stabilize}),
-         gen_server:call(testnode3, {stabilize}),
-         gen_server:call(testnode2, {stabilize}),
-         gen_server:call(testnode1, {stabilize}),
-
-         % stabilize here should set testnode3 as testnode1's successor because
-         % stabilize should be having testnode1 asking testnode2 'who is your predecessor?'
-         % testnode2 should respond &quot;testnode3&quot;. testnode1 should see that testnode3 is within the 
-         % right segment and therefore set testnode3 as its successor
-
-         % io:format(user, &quot;node1 ~p~n&quot;, [gen_server:call(testnode1, {return_state})]),
-         % io:format(user, &quot;node2 ~p~n&quot;, [gen_server:call(testnode2, {return_state})]),
-         % io:format(user, &quot;node3 ~p~n&quot;, [gen_server:call(testnode3, {return_state})]),
-
-         % gen_server:call(testnode1, {fix_fingers}),
-         % gen_server:call(testnode2, {fix_fingers}),
-         % gen_server:call(testnode3, {fix_fingers}),
-
-         % connections missing:
-         % * node3's predecessor should be node1
-         % * node1's successor   should be node3
-
-         Response = chordjerl_dot:generate_server_graph(testnode3),
-         {ok, FileId} = file:open(&quot;server.dot&quot;, [write]),
-         io:fwrite(FileId, &quot;~s~n&quot;, [Response]),
-         file:close(FileId),
+         write_diagram_to_file(testnode4, 0, 0),
+
+         Max = 4,
+         Iterations = 4,
+         [ [ (fun() -&gt;
+                     NodeName     = list_to_atom(&quot;testnode&quot; ++ integer_to_list(I)),
+                     gen_server:call(NodeName, {stabilize}),
+                     %gen_server:call(NodeName, {fix_fingers}),
+                     write_diagram_to_file(testnode4, I, J)
+              end)() || I &lt;- lists:seq(1, Max) ]
+         || J &lt;- lists:seq(1, Iterations) ],
+
+         write_diagram_to_file(testnode4, done, done),
+
          {ok}
       end
   }.
 
+write_diagram_to_file(Nodename, I, J) -&gt; 
+    Response = chordjerl_dot:generate_server_graph(Nodename),
+    FileName = io_lib:format(&quot;graphs/server_~p_~p.dot&quot;, [I, J]),
+    io:format(user, &quot;writing to ~s~n&quot;, [FileName]),
+    {ok, FileId} = file:open(FileName, [write]),
+    io:fwrite(FileId, &quot;~s~n&quot;, [Response]),
+    file:close(FileId).
+
+
+
 setup2() -&gt;
     {ok}.
 
 generate_dynamic_diagram_test_() -&gt;
+% generate_dynamic_diagram() -&gt;
   {
       setup, fun setup2/0,
       fun () -&gt;
@@ -79,18 +85,16 @@ generate_dynamic_diagram_test_() -&gt;
              || I &lt;- lists:seq(1, Max)
          ],
 
-         % stabilize each node Max times
+         % stabilize each node a few times
+         Iterations = 50,
          [ [ (fun() -&gt;
                      NodeName     = list_to_atom(&quot;testnode&quot; ++ integer_to_list(I)),
                      gen_server:call(NodeName, {stabilize})
               end)() || I &lt;- lists:seq(1, Max) ]
-         || J &lt;- lists:seq(1, Max) ],
+         || J &lt;- lists:seq(1, Iterations) ],
 
          LastNodeName = list_to_atom(&quot;testnode&quot; ++ integer_to_list(Max)),
-         Response = chordjerl_dot:generate_server_graph(LastNodeName),
-         {ok, FileId} = file:open(&quot;server3.dot&quot;, [write]),
-         io:fwrite(FileId, &quot;~s~n&quot;, [Response]),
-         file:close(FileId),
+         write_diagram_to_file(LastNodeName, large, done),
          {ok}
       end
   }.</diff>
      <filename>test/src/eunit_chordjerl_dot.erl</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8402b95747f1c8b7cc7151ed8dadcdfd09cd1ba3</id>
    </parent>
  </parents>
  <author>
    <name>Nate Murray</name>
    <email>nate@natemurray.com</email>
  </author>
  <url>http://github.com/jashmenn/chordjerl/commit/a7f02cff73c708e7d214f876c22e15274e951bc2</url>
  <id>a7f02cff73c708e7d214f876c22e15274e951bc2</id>
  <committed-date>2009-02-17T12:13:35-08:00</committed-date>
  <authored-date>2009-02-17T10:39:55-08:00</authored-date>
  <message>changed nbit for testing

tweaks to make sure process is correct:

added finger-tables to the dot graph

fixed predecessor claims to interpret response correctly

cleanup on some formatting</message>
  <tree>a1635114b86ad3297d892f225f278de00317ab51</tree>
  <committer>
    <name>Nate Murray</name>
    <email>nate@natemurray.com</email>
  </committer>
</commit>
