Change both implementations to use numbers instead of dateTimes

pull/392/head
Connor Rigby 2017-12-22 18:13:13 -08:00 committed by Connor Rigby
parent 1b14b8415d
commit 3370e84761
2 changed files with 37 additions and 54 deletions

View File

@ -5,77 +5,56 @@
#include <erl_nif.h>
#define MAX_GENERATED 1000
static ERL_NIF_TERM do_build_calendar(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
long int nowSeconds;
long int startTimeSeconds;
long int endTimeSeconds;
// Arguments
long int nowSeconds, startTimeSeconds, endTimeSeconds, frequencySeconds;
int repeat;
long int frequencySeconds;
// Fetch arguments.
enif_get_long(env, argv[0], &nowSeconds);
enif_get_long(env, argv[1], &startTimeSeconds);
enif_get_long(env, argv[2], &endTimeSeconds);
enif_get_int(env, argv[3], &repeat);
enif_get_long(env, argv[4], &frequencySeconds);
// Data used to build the calendar.
long int gracePeriodSeconds;
gracePeriodSeconds = nowSeconds - 60;
gracePeriodSeconds = nowSeconds - MAX_GENERATED;
long int step = frequencySeconds * repeat;
printf("now: %li\r\ngrace: %li\r\nstart: %li\r\nend: %li\r\n\r\n", nowSeconds, gracePeriodSeconds, startTimeSeconds, endTimeSeconds);
// iterators
long int i;
long int j;
// printf("now: %li\r\ngrace: %li\r\nstart: %li\r\nend: %li\r\n\r\n", nowSeconds, gracePeriodSeconds, startTimeSeconds, endTimeSeconds);
// iterators for loops
long int i, j;
// build our events array, fill it with zeroes.
long int events[60];
for(i = 0; i < 60; i++) {events[i] = 0;}
long int events[MAX_GENERATED];
for(i = 0; i < MAX_GENERATED; i++)
events[i] = 0;
// put up to 60 events into the array
for(j = 0, i = startTimeSeconds; (i < endTimeSeconds) && (j < 60); i += step) {
// put up to MAX_GENERATED events into the array
for(j = 0, i = startTimeSeconds; (i < endTimeSeconds) && (j < MAX_GENERATED); i += step) {
// if this event (i) is after the grace period, add it to the array.
if(i > gracePeriodSeconds) {
events[j] = i;
events[j] -= (events[j] % 60);
events[j] -= (events[j] % MAX_GENERATED);
j++;
}
}
// Count up our total generated events
int count = 0;
for(j=0; j<60; j++) { if(events[j] > 0) { count++; } }
for(i = 0, j=0; j<MAX_GENERATED; j++) { if(events[j] > 0) { i++; } }
// Build the array to be returned.
ERL_NIF_TERM arr[count];
// size_t stringSize = 21;
// char buffer[stringSize];
// ErlNifBinary outputData;
// enif_alloc_binary(stringSize, &outputData);
for(j=0; j<count; j++) {
// // Build a timeinfo struct.
// struct tm * timeinfo;
// timeinfo = localtime(&events[j]);
//
// // Format the timeinfo struct as a iso datetime.
// strftime(buffer, stringSize, "%FT%TZ", timeinfo);
//
// printf("%s\r\n", buffer);
// memcpy(outputData.data, buffer, strlen(buffer));
//
// // Add the binary to the array.
// // arr[j] = enif_make_binary(env, &outputData);
arr[j] = enif_make_long(env, events[j]);
}
// Release the binary
// enif_release_binary(&outputData);
ERL_NIF_TERM retArr [i];
for(j=0; j <i ; j++)
retArr[j] = enif_make_long(env, events[j]);
// we survived.
return enif_make_list_from_array(env, arr, count);
return enif_make_list_from_array(env, retArr, i);
}
static ErlNifFunc nif_funcs[] =

View File

@ -52,16 +52,14 @@ defmodule Farmbot.Repo.FarmEvent do
def bench do
begin = :os.system_time(:seconds)
res = Farmbot.HTTP.get!("/api/farm_events").body
|> fn(stuff) -> IO.puts("http: #{:os.system_time(:seconds) - begin}"); stuff end.()
|> Poison.decode!(as: [%__MODULE__{}])
|> fn(stuff) -> IO.puts("json decode: #{:os.system_time(:seconds) - begin}"); stuff end.()
|> Enum.map(&build_calendar(&1))
|> fn(stuff) -> IO.puts("build calendar: #{:os.system_time(:seconds) - begin}"); stuff end.()
IO.puts "total: #{:os.system_time(:seconds) - begin}"
res
end
@compile {:inline, [build_calendar: 1]}
def build_calendar(%__MODULE__{calendar: nil} = fe), do: fe
def build_calendar(%__MODULE__{calendar: calendar} = fe) when is_list(calendar) do
current_time_seconds = :os.system_time(:second)
@ -70,7 +68,14 @@ defmodule Farmbot.Repo.FarmEvent do
repeat = fe.repeat
repeat_frequency_seconds = time_unit_to_seconds(repeat, fe.time_unit)
new_calendar = do_build_calendar(current_time_seconds, start_time_seconds, end_time_seconds, repeat, repeat_frequency_seconds)
new_calendar =
do_build_calendar(current_time_seconds,
start_time_seconds,
end_time_seconds,
repeat,
repeat_frequency_seconds)
|> Enum.map(&DateTime.from_unix!(&1))
|> Enum.map(&DateTime.to_iso8601(&1))
%{fe | calendar: new_calendar}
end
@ -78,15 +83,14 @@ defmodule Farmbot.Repo.FarmEvent do
def do_build_calendar(now_seconds, start_time_seconds, end_time_seconds, repeat, repeat_frequency_seconds) do
Logger.error 1, "Using (very) slow calendar builder!"
grace_period_cutoff_seconds = now_seconds - 1
Range.new(start_time_seconds, end_time_seconds)
|> Enum.take_every(repeat * repeat_frequency_seconds)
|> Enum.filter(&Kernel.>(&1, grace_period_cutoff_seconds))
|> Enum.take(60)
|> Enum.map(&DateTime.from_unix!(&1))
|> Enum.map(&(Timex.shift(&1, seconds: -(&1.second), microseconds: -(&1.microsecond |> elem(0)))))
|> Enum.map(&DateTime.to_iso8601(&1))
Range.new(start_time_seconds, end_time_seconds)
|> Enum.take_every(repeat * repeat_frequency_seconds)
|> Enum.filter(&Kernel.>(&1, grace_period_cutoff_seconds))
|> Enum.take(60)
|> Enum.map(&Kernel.-(&1, div(&1, 60)))
end
@compile {:inline, [time_unit_to_seconds: 2]}
defp time_unit_to_seconds(_, "never"), do: 0
defp time_unit_to_seconds(repeat, "minutely"), do: 60 * repeat
defp time_unit_to_seconds(repeat, "hourly"), do: 60 * 60 * repeat