From d48d32ddbbe24accd4a87c9c9efc61bcde5d64e6 Mon Sep 17 00:00:00 2001 From: aj Date: Thu, 4 Nov 2010 01:30:46 -0700 Subject: [PATCH] hit a speedbump. maximum and minimum are max & min absolutely! Projecting flattened dates out to both infinities is prohibitively wacky. Do I pick arbitrary maximum and minimum dates? Should I forgo premature projection, in lieu of on-demand processing? a combination of both? Those are my leading choices atm. --- .gitignore | 2 +- src/ezic_compile.erl | 65 ++++++++++++++++++++++++-------------------- src/ezic_date.erl | 13 +++++++++ src/ezic_rule.erl | 7 +++++ 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 447f283..497ba18 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ ebin/ tmp/ commit_msg tzdata/ - +\#* diff --git a/src/ezic_compile.erl b/src/ezic_compile.erl index 2849c8b..7b5902d 100644 --- a/src/ezic_compile.erl +++ b/src/ezic_compile.erl @@ -25,19 +25,23 @@ separate(Records) -> % args: Zones, Rules % % take the first zone, get all zones with the same name -% sort them by descending date (newest first) +% sort them by ascending date (oldest first) % foreach zone: -% find all rules between start & end(if exists) of zone +% find all rules between start (if exists) & end (if exists) of zone % foreach rule: % create a #flatzone % flatten the rest of the zones %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% note: recursive -flatten([], Rules) -> - done; flatten(Zones, Rules) -> +% ?debug("Rules: ~p", [Rules]), + flatten(Zones, Rules, []). + +% note: recursive +flatten([], Rules, Flats) -> + Flats; +flatten(Zones, Rules, Flats) -> [Zone | _] = Zones, % ?debug("Zone: ~p", [Zone]), ?debug("Flattening: ~p", [Zone#zone.name]), @@ -46,31 +50,23 @@ flatten(Zones, Rules) -> % ?debug("ZoneSet: ~p", [ZoneSet]), - NeededRules= lists:takewhile(make_rule_zone_filter(Zone), Rules), + NeededRules= lists:filter(make_rule_zone_filter(ZoneSet), Rules), % ?debug("NeededRules: ~p", [NeededRules]), SortedZoneSet= lists:sort(fun zone_sorter/2, ZoneSet), - flatten_set(SortedZoneSet, NeededRules), + NewFlats= lists:append(flatten_set(SortedZoneSet, NeededRules), Flats), % ?debug("Sorted Zones: ~p", [SortedZoneSet]), - flatten(RestZones, Rules). + flatten(RestZones, Rules, NewFlats). -zone_sorter(Z1=#zone{until=U1},#zone{until=U2}) -> +zone_sorter(Z1=#zone{until=U1}, #zone{until=U2}) -> ezic_date:compare_datetimes(U1, U2). - %% case (D1 =< D2) of - %% true -> - %% true; - %% false -> - %% ezic_record:compare_time(T1, T2) - %% end. - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % INTERNAL @@ -82,8 +78,12 @@ make_zone_filter(#zone{name=Name}) -> fun(#zone{name=N}) when Name=:=N-> true; (_)->false end. -make_rule_zone_filter(#zone{rule=Rule}) -> - fun(#rule{name=Rule})-> true; (_)->false end. +make_rule_zone_filter(ZoneSet) -> + ZS= sets:from_list([Z#zone.rule || Z<-ZoneSet]), +% ?debug("~n\t ZoneSetRules: ~p", [sets:to_list(ZS)]), + fun(#rule{name=R})-> + sets:is_element(R, ZS) + end. % accepts a rule, and returns true if it exists between the two years given @@ -94,27 +94,32 @@ make_rule_time_filter(D1, D2) -> -% note: recursive -flatten_set([], Rules) -> - done; flatten_set(ZoneSet, Rules) -> + flatten_set(ZoneSet, Rules, none, []). + +% note: recursive +flatten_set([], _, _, Flats) -> + Flats; +flatten_set(ZoneSet, Rules, Prev, Flats) -> [Zone|Rest] = ZoneSet, - NextZone= next_zone(Rest), - flatten_one(Zone, NextZone, Rules), - flatten_set(Rest, Rules). + NewFlats= lists:append(flatten_one(Zone, Prev, Rules), Flats), + flatten_set(Rest, Rules, Zone, NewFlats). flatten_one(Zone=#zone{until=Until}, none, Rules) -> - NeededRules= lists:takewhile(make_rule_time_filter({0,0,0}, Until), Rules), - lists:foreach(fun(R)-> flatten_each(Zone, R) end, Rules); + NeededRules= lists:filter(make_rule_time_filter(minimum, Until), Rules), + lists:map(fun(R)-> flatten_each(Zone, R, minimum) end, Rules); flatten_one(Zone=#zone{until=UTo}, NextZone=#zone{until=UFrom}, Rules) -> - NeededRules= lists:takewhile(make_rule_time_filter(UFrom, UTo), Rules), - lists:foreach(fun(R)-> flatten_each(Zone, R) end, Rules). + NeededRules= lists:filter(make_rule_time_filter(UFrom, UTo), Rules), + lists:map(fun(R)-> flatten_each(Zone, R, UFrom) end, Rules). -flatten_each(Zone, Rule) -> +flatten_each(Zone, Rule, From) -> +% ?debug("flatten_each: ~n\tZone: ~p~n\tRule: ~p~n\tFrom: ~p", [Zone, Rule, From]), +% erlang:error(dbg), + years not_done. diff --git a/src/ezic_date.erl b/src/ezic_date.erl index 94142a4..60ef192 100644 --- a/src/ezic_date.erl +++ b/src/ezic_date.erl @@ -107,6 +107,11 @@ compare_datetimes(DT1, DT2) -> compare_datetimes_normal(NDT1, NDT2). +compare_datetimes_normal(minimum, _) -> true; +compare_datetimes_normal(_, maximum) -> true; + + +compare_datetimes_normal(current, current) -> true; compare_datetimes_normal(current, _) -> false; compare_datetimes_normal(_,current) -> true; @@ -136,6 +141,8 @@ time_equalize(T1, T2) -> normalize(current) -> current; normalize(only) -> only; +normalize(maximum) -> maximum; +normalize(minimum) -> minimum; normalize(Y) when is_integer(Y) -> {{Y,1,1}, #tztime{}}; @@ -174,6 +181,12 @@ dates_overlap_normal({D1s,D1e}, {D2s,D2e}) -> orelse date_between_normal(D1e, {D2s,D2e}). +date_between_normal(minimum, {minimum,_}) -> true; +date_between_normal(minimum, {_,_}) -> false; + +date_between_normal(maximum, {_, maximum}) -> true; +date_between_normal(maximum, {_,_}) -> false; + date_between_normal(only, _) -> false; date_between_normal(current, {_, current}) -> true; date_between_normal(current, {_, End}) when End =/= current -> false; diff --git a/src/ezic_rule.erl b/src/ezic_rule.erl index b541508..0a03de9 100644 --- a/src/ezic_rule.erl +++ b/src/ezic_rule.erl @@ -11,3 +11,10 @@ project(Rule=#rule{from=F, to=only}) -> not_done; project(Rule=#rule{from=F, to=T}) -> Dates= lists:map(fun(Y)-> ezic_date:for(Rule, Y) end, lists:seq(F, T)). + + +% returns all the years inbetween +years(_, Rule=#rule{from=F, to=only}) -> + [F]; +years(Max, Rule=#rule{from=F, to=maximum}) -> + fudge.