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.
This commit is contained in:
aj
2010-11-04 01:30:46 -07:00
parent 2f727dd8bb
commit d48d32ddbb
4 changed files with 56 additions and 31 deletions

2
.gitignore vendored
View File

@@ -4,5 +4,5 @@ ebin/
tmp/
commit_msg
tzdata/
\#*

View File

@@ -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) ->
[Zone|Rest] = ZoneSet,
NextZone= next_zone(Rest),
flatten_set(ZoneSet, Rules, none, []).
flatten_one(Zone, NextZone, Rules),
flatten_set(Rest, Rules).
% note: recursive
flatten_set([], _, _, Flats) ->
Flats;
flatten_set(ZoneSet, Rules, Prev, Flats) ->
[Zone|Rest] = ZoneSet,
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.

View File

@@ -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;

View File

@@ -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.