anchor.diff:  -module(nklib_throttle).
   -author('Carlos Gonzalez <carlosj.gf@gmail.com>').
   
  --export([get_time/1, incr/2, get_counters/2]).
  --export([test/0]).
  +-export([new/0, get_time_slots/1, get_time_slots/2, incr/2, incr/3]).
  +-export([get_last_counter/2, get_last_counter/3]).
  +-export([get_last_counters/2, get_last_counters/3]).
  +-export([wait_slot/1, test1/0, test2/0]).
   -export_type([time_key/0, counters/0]).
   
   
  
positive.code:     add_counters(Rest, Counters#{Key => List}).
  
  
  %% @private
  get_counters(TimeKeys, Counters) ->
      TimeList = get_time(TimeKeys),
      get_counters(TimeList, Counters, []).
  
  
  %% @private
  get_counters([], _Counters, Acc) ->
      Acc;
  
  get_counters([{Key, Time}|Rest], Counters, Acc) ->
      Count = case maps:get(Key, Counters, []) of
          [{Time, KCount}|Rest] ->
              KCount;
          _ ->
              0
      end,
      get_counters(Rest, Counters, Acc#{Key => Count}).
  
  
  
  
  
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).
  
  
  