anchor.diff:      InZone = filter_map_by_zone(shards_by_node(Shards, Nodes), Zone),
       SortedByCount = lists:sort(smallest_first(Moves), InZone),
       SourceCount = get_shard_count(Node, SortedByCount),
  +    GlobalShardCounts = shard_count_by_node(Moves),
  +    TotalSource = get_global_shard_count(Node, GlobalShardCounts),
       Fun = fun({CandidateNode, OwnShards}) ->
           HasRange = lists:keymember(Shard#shard.range, #shard.range, OwnShards),
           TargetCount = get_shard_count(CandidateNode, SortedByCount),
  -        NodeKey = couch_util:to_binary(CandidateNode),
  -        Total = couch_util:get_value(NodeKey, shard_count_by_node(Moves)),
  +        TotalTarget = get_global_shard_count(CandidateNode, GlobalShardCounts),
           if
               CandidateNode =:= Node ->
                   % Can't move a shard to ourselves
  
positive.code:     fun(A, B) -> sort_by_count(A, B, Global) =< 0 end.
  
  sort_by_count({NodeA, SA}, {NodeB, SB}, Global) when length(SA) =:= length(SB) ->
      CountA = couch_util:get_value(couch_util:to_binary(NodeA), Global, 0),
      CountB = couch_util:get_value(couch_util:to_binary(NodeB), Global, 0),
      cmp(CountA, CountB);
  sort_by_count({_, A}, {_, B}, _) ->
      cmp(length(A), length(B)).
  
negative.code:         lists:member(Node, TargetNodes)
      end, shard_count_by_node(LocalOps)),
      TotalCount = lists:foldl(fun({_, C}, Sum) -> Sum + C end, 0, CountByNode),
      TargetLevel = TotalCount div length(TargetNodes),
      FoldFun = fun
          (_, Acc) when length(Acc) >= Limit ->
              % We've already accumulated the max number of shard ops.
  