anchor.diff:  -module(stats_archiver).
   
   -include_lib("eunit/include/eunit.hrl").
  --include_lib("stdlib/include/qlc.hrl").
   
   -include("ns_common.hrl").
   -include("ns_stats.hrl").
  
positive.code:       end, archives()).
  
  
  %% @doc Return the last N records starting with the given key from Tab.
  fetch_latest(Bucket, Period, N) ->
      case lists:keyfind(Period, 1, archives()) of
          false ->
              {error, bad_period, Period};
          {_, Interval, _} ->
              Seconds = N * Interval,
              Tab = table(Bucket, Period),
              case mnesia:dirty_last(Tab) of
                  '$end_of_table' ->
                      {ok, []};
                  Key ->
                      Oldest = Key - Seconds * 1000 + 500,
                      Handle = qlc:q([Sample || #stat_entry{timestamp=TS} = Sample
                                                    <- mnesia:table(Tab), TS > Oldest]),
                      case mnesia:activity(async_dirty, fun qlc:eval/1, [Handle]) of
                          {error, _, _} = Error ->
                              Error;
                          Results ->
                              {ok, Results}
                      end
              end
      end.
  
  
  last_chunk(Tab, Step) ->
      case mnesia:last(Tab) of
          '$end_of_table' ->
  
negative.code: %% @doc Truncate a timestamp to the nearest multiple of N seconds.
  trunc_ts(TS, N) ->
      TS - (TS rem (N*1000)).
  
  
  %% @doc Return the last N records starting with the given key from Tab.
  walk(Tab, N) ->
      {atomic, Results} = mnesia:transaction(
                            fun () -> walk(Tab, mnesia:last(Tab), N, []) end,
                            ?RETRIES),
      Results.
  
  
  walk(_Tab, Key, N, Records) when N == 0; Key == '$end_of_table' ->
      Records;
  walk(Tab, Key, N, Records) ->
      [Record] = mnesia:read(Tab, Key),
      NextKey = mnesia:prev(Tab, Key),
      walk(Tab, NextKey, N - 1, [Record | Records]).
  