From 9d0df77b2950e76b5dec7c4a7865f95d2e2557c6 Mon Sep 17 00:00:00 2001 From: lsowen Date: Wed, 7 Nov 2012 14:06:27 -0500 Subject: [PATCH] Now using named ets tables. More closely mirrors the design of the mnesia backed version. --- src/ezic_db_ets.erl | 40 +++++++++++++++++----------------- src/ezic_db_ets_admin.erl | 45 ++++++++++++++++++++++++++++++++------- src/ezic_flatten.erl | 28 ++++++++++++------------ 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/ezic_db_ets.erl b/src/ezic_db_ets.erl index f3c570f..dd1d32c 100644 --- a/src/ezic_db_ets.erl +++ b/src/ezic_db_ets.erl @@ -80,17 +80,17 @@ init(_) -> %%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -handle_call({zones, Name}, _, Ets) -> - Matches= ets:select(Ets, [{#zone{name=Name, _='_'}, [], ['$_']}]), - {reply, Matches, Ets}; -handle_call({rules, Name}, _, Ets) -> - Matches= ets:select(Ets, [{#rule{name=Name, _='_'}, [], ['$_']}]), - {reply, Matches, Ets}; -handle_call({all, Table}, _, Ets) -> - Matches= ets:lookup(Ets, Table), - {reply, Matches, Ets}; -handle_call({flatzone, Date, Name}, _, Ets) -> - FlatZones= ets:select(Ets, ezic_flatten:ms(Date, Name)), +handle_call({zones, Name}, _, State) -> + Matches= ets:select(zone, [{#zone{name=Name, _='_'}, [], ['$_']}]), + {reply, Matches, State}; +handle_call({rules, Name}, _, State) -> + Matches= ets:select(rule, [{#rule{name=Name, _='_'}, [], ['$_']}]), + {reply, Matches, State}; +handle_call({all, Tab}, _, State) -> + Matches= ets:lookup(Tab, Tab), + {reply, Matches, State}; +handle_call({flatzone, Date, Name}, _, State) -> + FlatZones= ets:select(flatzone, ezic_flatten:ms(Date, Name)), Result= case length(FlatZones) of 1 -> hd(FlatZones); @@ -101,21 +101,21 @@ handle_call({flatzone, Date, Name}, _, Ets) -> _ -> erlang:error(should_not_happen, {FlatZones, Date, Name}) end, - {reply, Result, Ets}; + {reply, Result, State}; %handle_call({insert_all, Records}, _, Ets) -> % Result= ets:insert(Ets, Records), % {reply, Result, Ets}; %handle_call({wipe}, _, Ets) -> % Result= ets:delete(Ets), % {reply, Result, Ets}; -handle_call({wipe, Tab}, _, Ets) -> - Result= ets:delete(Ets, Tab), - {reply, Result, Ets}; -handle_call({flatten}, _, Ets) -> - Result= ezic_flatten:flatten(Ets), - {reply, Result, Ets}; -handle_call(_, _, Ets) -> - {noreply, Ets}. +handle_call({wipe, Tab}, _, State) -> + Result= ets:delete(Tab, Tab), + {reply, Result, State}; +handle_call({flatten}, _, State) -> + Result= ezic_flatten:flatten(), + {reply, Result, State}; +handle_call(_, _, State) -> + {noreply, State}. %%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/ezic_db_ets_admin.erl b/src/ezic_db_ets_admin.erl index aecda26..163ef2c 100644 --- a/src/ezic_db_ets_admin.erl +++ b/src/ezic_db_ets_admin.erl @@ -37,11 +37,11 @@ init() -> {ok, DbDir}= application:get_env(db_dir), Filename= filename:join(DbDir, ?DB_FILENAME), - Ets= case db_sane(Filename) of + case db_sane(Filename) of true -> load_tabfile(Filename); false -> create_tables(Filename) end, - {ok, Ets}. + {ok, []}. % erases all data @@ -84,21 +84,50 @@ db_sane(Filename) -> %% creates the dets table and populates it. create_tables(Filename) -> - Ets= ets:new(ezic_ets_db, [duplicate_bag]), - ets:insert(Ets, ezic_loader:load()), - ezic_flatten:flatten(Ets), + {ok, Zones, Rules, _, _} = ezic_record:separate(ezic_loader:load()), + + ets:new(zone, [duplicate_bag, named_table]), + ets:insert(zone, Zones), + + ets:new(rule, [duplicate_bag, named_table]), + ets:insert(rule, Rules), + + ets:new(flatzone, [duplicate_bag, named_table]), + ezic_flatten:flatten(), + + % combine into one ets + Ets= ets:new(ezic_db_ets, [duplicate_bag]), + ets:insert(Ets, ets:lookup(zone, zone)), + ets:insert(Ets, ets:lookup(rule, rule)), + ets:insert(Ets, ets:lookup(flatzone, flatzone)), % save to disk ets:tab2file(Ets, Filename), - Ets. + ets:delete(Ets), + + ok. %% loads or creates the dets table. load_tabfile(Filename) -> - {ok, Name}= ets:file2tab(Filename), - Name. + {ok, Ets}= ets:file2tab(Filename), + + Zones= ets:lookup(Ets, zone), + ets:new(zone, [duplicate_bag, named_table]), + ets:insert(zone, Zones), + + Rules= ets:lookup(Ets, rule), + ets:new(rule, [duplicate_bag, named_table]), + ets:insert(rule, Rules), + + FlatZones= ets:lookup(Ets, flatzone), + ets:new(flatzone, [duplicate_bag, named_table]), + ets:insert(flatzone, FlatZones), + + ets:delete(Ets), + ok. diff --git a/src/ezic_flatten.erl b/src/ezic_flatten.erl index 112c7e7..c94cb38 100644 --- a/src/ezic_flatten.erl +++ b/src/ezic_flatten.erl @@ -15,15 +15,15 @@ -export([ - flatten/1 + flatten/0 , contains_date/2 , ms/2 ]). -flatten(Ets) -> - AllZones= ets:lookup(Ets, zone), - flatten_all_zones(Ets, AllZones), +flatten() -> + AllZones= ets:lookup(zone, zone), + flatten_all_zones(AllZones), done. @@ -75,16 +75,16 @@ ms(Date, Name) -> % recursively processes sets of similar zones until they're all done, % passing zone sets to flatten_zone_set/1 -flatten_all_zones(Ets, []) -> +flatten_all_zones([]) -> done; -flatten_all_zones(Ets, [Z1|_]= AllZones) -> +flatten_all_zones([Z1|_]= AllZones) -> io:format("Flattening zones: ~s~n", [Z1#zone.name]), {CurrentZones, RestZones}= ezic_zone:split_by_name(Z1, AllZones), - Flats= flatten_zone_set(Ets, CurrentZones), - ets:insert(Ets, Flats), + Flats= flatten_zone_set(CurrentZones), + ets:insert(flatzone, Flats), - flatten_all_zones(Ets, RestZones). + flatten_all_zones(RestZones). @@ -109,8 +109,8 @@ contains_date2(FlatZone=#flatzone{wall_from=From, wall_to=To}, {Dt,#tztime{time= %% gathers relevant rules and creates flat periods of the same gmt %% offset (#flatzone). This is a recursive solution, eliminating Zones %% from the list until it's been exhausted -flatten_zone_set(Ets, Zones) -> - flatten_zone_set(Ets, ?MINFLAT, Zones, [], none). +flatten_zone_set(Zones) -> + flatten_zone_set(?MINFLAT, Zones, [], none). % flatten_zone_set(FromTime, Zones, Flats) -> [#flatzone{}] @@ -119,7 +119,7 @@ flatten_zone_set(Ets, Zones) -> % Flats= [#flatzone{}] % % assumes a new zone every time it is called -flatten_zone_set(Ets, FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset} +flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset} , Zones %[Z1=#zone{rule=RuleName, until=UntilTime, gmtoff=Offset} | _RestZones], , Flats , CurrentRule) -> @@ -141,7 +141,7 @@ flatten_zone_set(Ets, FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffs %% we gather all rules that _may_ apply - Rules= ets:select(Ets, [{#rule{name=RuleName, _='_'}, [], ['$_']}]), + Rules= ets:select(rule, [{#rule{name=RuleName, _='_'}, [], ['$_']}]), ?debugVal(FromTime), @@ -165,7 +165,7 @@ flatten_zone_set(Ets, FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffs ?debugMsg("maxyear reached from flatten_zone_set"), FinalFlats; false -> - flatten_zone_set(Ets, NextFlat, RestZones, FinalFlats, EndingRule) + flatten_zone_set(NextFlat, RestZones, FinalFlats, EndingRule) catch exit:Reason -> ?debugMsg("bad year for nextflat:"),