anchor.diff:      end,
       lists:foldl(FoldFun, LocalOps, CountByNode).
   
  -donate_fold(_Shard, {_, _, Moves, 0}) ->
  +donate_fold(_Shard, #gacc{limit = 0, moves = Moves}) ->
       throw({complete, Moves});
  -donate_fold(#shard{node = Node} = Shard, {Node, Nodes, Moves, DC}) ->
  +donate_fold(#shard{node = Node} = Shard, #gacc{node = Node} = Acc0) ->
  +     #gacc{
  +        targets = Nodes,
  +        moves = Moves,
  +        limit = DC,
  +        target_level = TargetLevel
  +    } = Acc0,
       Zone = mem3:node_info(Node, <<"zone">>),
       Shards = apply_shard_moves(mem3:shards(Shard#shard.dbname), Moves),
       InZone = filter_map_by_zone(shards_by_node(Shards, Nodes), Zone),
  
positive.code:             Acc;
          ({Node0, Count}, Acc) ->
              Node = list_to_existing_atom(binary_to_list(Node0)),
              % Compute the max number of shards to donate.
              DC0 = erlang:min(Count - TargetLevel, Limit - length(Acc)),
              InternalAcc0 = {Node, TargetNodes0, Acc, DC0},
              try mem3_shards:fold(fun donate_fold/2, InternalAcc0) of
                  {_, _, Moves, _} ->
                      Moves
              catch
                  {complete, Moves} ->
  
negative.code: ]).
  
  -include("mem3.hrl").
  
  -record (gacc, {
      node,
      targets,
      moves,
      limit,
      target_level
  }).
  
  %% @equiv expand(1000)
  -spec expand() -> [{atom(), #shard{}, node()}].
  