anchor.diff:      add_counters(Rest, Counters#{Key => List}).
   
   
  -%% @private
  -get_counters(TimeKeys, Counters) ->
  -    TimeList = get_time(TimeKeys),
  -    get_counters(TimeList, Counters, []).
  -
  -
  -%% @private
  -get_counters([], _Counters, Acc) ->
  +%% @doc Get the current counter for a series of time slots
  +-spec get_last_counter([time_key()], counters()) ->
  +    #{time_key() => integer()}.
  +
  +get_last_counter(TimeKeys, Counters) ->
  +    get_last_counter(TimeKeys, Counters, timestamp()).
  +
  +
  +%% @doc Get the current counter for a series of time slots
  +-spec get_last_counter([time_key()], counters(), time()) ->
  +    #{time_key() => integer()}.
  +
  +get_last_counter(TimeKeys, Counters, Now) ->
  +    KeySlots = get_time_slots(TimeKeys, Now),
  +    %lager:error("NKLOG SLOTS ~p", [KeySlots]),
  +    do_get_counter(KeySlots, Counters, #{}).
  +
  +
  +%% @private
  +do_get_counter([], _Counters, Acc) ->
       Acc;
   
  -get_counters([{Key, Time}|Rest], Counters, Acc) ->
  -    Count = case maps:get(Key, Counters, []) of
  -        [{Time, KCount}|Rest] ->
  -            KCount;
  +do_get_counter([{Key, Slot}|Rest], Counters, Acc) ->
  +    KeyCount = case maps:get(Key, Counters, []) of
  +        [{Slot, Count}|_] ->
  +            Count;
           _ ->
               0
       end,
  -    get_counters(Rest, Counters, Acc#{Key => Count}).
  -
  +    do_get_counter(Rest, Counters, Acc#{Key => KeyCount}).
  +
  +
  +%% @doc Get the current counter for a series of time slots
  +-spec get_last_counters([time_key()], counters()) ->
  +    #{time_key() => [integer()]}.
  +
  +get_last_counters(TimeKeys, Counters) ->
  +    get_last_counters(TimeKeys, Counters, timestamp()).
  +
  +
  +%% @doc Get the current counter for a series of time slots
  +-spec get_last_counters([time_key()], counters(), time()) ->
  +    #{time_key() => [integer()]}.
  +
  +get_last_counters(TimeKeys, Counters, Now) ->
  +    KeySlots = get_time_slots(TimeKeys, Now),
  +    %lager:error("NKLOG SLOTS2 ~p", [KeySlots]),
  +    do_get_counters(KeySlots, Counters, #{}).
  +
  +
  +%% @private
  +do_get_counters([], _Counters, Acc) ->
  +    Acc;
  +
  +do_get_counters([{Key, Slot}|Rest], Counters, Acc) ->
  +    List = maps:get(Key, Counters, []),
  +    KeyCount = do_get_counters2(Slot, List, 5, []),
  +    do_get_counters(Rest, Counters, Acc#{Key => KeyCount}).
  +
  +
  +do_get_counters2(_Slot, _List, 0, Acc) ->
  +    lists:reverse(Acc);
  +
  +do_get_counters2(Slot, List, Len, Acc) ->
  +   Count = case lists:keyfind(Slot, 1, List) of
  +       {Slot, Counter} ->
  +           Counter;
  +       false ->
  +           0
  +    end,
  +    do_get_counters2(Slot-1, List, Len-1, [Count|Acc]).
   
   
   
  
positive.code:     Acc;
  
  get_time([Key|Rest], Now, Acc) ->
      get_time(Rest, Now, [{Key, round(Key, Now)}|Acc]).
  
  
  %% @private
  round(Key, Now) ->
      Time = time(Key),
      (Now div Time).
  
  
  %% @private
  time(secs) -> 1000;
  time(secs5) -> 5 * 1000;
  time(mins) -> 60 * 1000;
  time(mins5) -> 5 * 60 * 1000;
  time(hours) -> 60 * 60 * 1000;
  time(days) -> 24 * 60 * 60 * 1000;
  time(months) -> 30 * 24 * 60 * 60 * 1000;
  time(years) -> 365 * 24 * 60 * 60 * 1000.
  
  
  %% @private
  timestamp() ->
      nklib_util:m_timestamp() - 1510326450792.
  
  
  %% @private
  test() ->
      Now = timestamp(),
      Wait = 5000 - (Now rem 5000),
      io:format("\n\nWaiting for a 5-secs slot (~p msecs)\n\n", [Wait]),
      timer:sleep(Wait+1),
      Counters1 = #{},
  
      % We are starting at the beginning of a 5-secs slot
  
      Counters2 = incr([secs, secs5], Counters1),
      io:format("Sending now...\ncounters: ~p\n\n", [Counters2]),
      #{secs := [{TS1, 1}], secs5 := [{T51, 1}]} = Counters2,
      io:format("Waiting 500 msecs\n"),
      timer:sleep(500),
      Counters3 = incr([secs, secs5], Counters2),
      io:format("Sending now...\ncounters: ~p\n\n", [Counters3]),
      #{secs := [{TS1, 2}], secs5 := [{T51, 2}]} = Counters3,
  
      io:format("Waiting 600 msecs (total 1.1secs)\n"),   % 1100 from start
      timer:sleep(600),
      Counters4 = incr([secs, secs5], Counters3),
      io:format("Sending now...\ncounters: ~p\n\n", [Counters4]),
      #{secs := [{TS2, 1}, {TS1, 2}], secs5 := [{T51, 3}]} = Counters4,
      TS2 = TS1+1,
  
      io:format("Waiting 2000 msecs (total 4.2secs)\n"),  % 4200 from start
      timer:sleep(2000),
      Counters5 = incr([secs, secs5], Counters4),
      #{secs := [{TS3, 1}, {TS2, 1}, {TS1, 2}], secs5 := [{T51, 4}]} = Counters5,
      io:format("Sending now...\ncounters: ~p\n\n", [Counters5]),
      TS3 = TS2+2,
  
      io:format("Waiting 1910 msecs (total 5.1secs)\n"),  % 5010 from start
      timer:sleep(1910),
      Counters6 = incr([secs, secs5], Counters5),
      #{secs := [{TS4, 1}, {TS3, 1}, {TS2, 1}, {TS1, 2}], secs5 := [{T52, 1}, {T51, 4}]} = Counters6,
      io:format("Sending now...\ncounters: ~p\n\n", [Counters6]),
      TS4 = TS3+2,
      T52 = T51+1,
  
      io:format("Waiting 1000 msecs (total 6.1secs)\n"),  % 6010 from start
      timer:sleep(1000),
      Counters7 = incr([secs, secs5], Counters6),
      #{secs := [{TS5, 1}, {TS4, 1}, {TS3, 1}, {TS2, 1}, {TS1, 2}], secs5 := [{T52, 2}, {T51, 4}]} = Counters7,
      io:format("Sending now...\ncounters: ~p\n\n", [Counters7]),
      TS5 = TS4+1,
  
      io:format("Waiting 1000 msecs (total 7.1secs)\n"),  % 7010 from start
      timer:sleep(1000),
      Counters8 = incr([secs, secs5], Counters7),
      #{secs := [{TS6, 1}, {TS5, 1}, {TS4, 1}, {TS3, 1}, {TS2, 1}], secs5 := [{T52, 3}, {T51, 4}]} = Counters8,
      io:format("Sending now...\ncounters: ~p\n\n", [Counters8]),
      TS6 = TS5+1,
      ok.
  
  
  
  
  
negative.code: %% Types
  %% ===================================================================
  
  -type time_key() ::
      {msecs, integer()}  |
      {secs, integer()}  |
      {mins, integer()} |
      {hours, integer()} |
      {days, integer()} |
      {months, integer()} |
      {years, integer()}.
  
  -type time() :: nklib_util:m_timestamp().
  
  -type time_slot() :: integer().
  
  -type counters() :: #{time_key() => [{time_slot(), Counter::integer()}]}.
  
  
  %% ===================================================================
  %% Public
  %% ===================================================================
  
  %% @doc Create a new counter
  -spec new() ->
      counters().
  
  new() ->
      #{}.
  
  
  %% @doc Get a time series (number of units of the time_key() from unixtime 0)
  -spec get_time_slots([time_key()]) ->
      [{time_key(), time_slot()}].
  
  get_time_slots(TimeKeys) ->
      get_time_slots(TimeKeys, timestamp()).
  
  
  %% @doc Get a time series (number of units of the time_key() from unixtime 0)
  -spec get_time_slots([time_key()], time()) ->
      [{time_key(), time_slot()}].
  
  get_time_slots(TimeKeys, Now) ->
      get_time(TimeKeys, Now, []).
  
  
  %% @doc Increment counters for a series of time slots
  -spec incr([time_key()], counters()) ->
      counters().
  
  incr(TimeKeys, Counters) ->
      incr(TimeKeys, Counters, timestamp()).
  
  
  %% @doc
  -spec incr([time_key()], counters(), time()) ->
      counters().
  
  incr(TimeKeys, Counters, Now) ->
      TimeList = get_time_slots(TimeKeys, Now),
      add_counters(TimeList, Counters).
  
  
  