From 48c8fde34591f782be7af77575eaa02dab8659b3 Mon Sep 17 00:00:00 2001 From: Adam Kocoloski Date: Wed, 30 Jun 2010 16:23:38 -0400 Subject: standardize mem3 naming. app is horribly broken for now --- src/mem3_cache.erl | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/mem3_cache.erl (limited to 'src/mem3_cache.erl') diff --git a/src/mem3_cache.erl b/src/mem3_cache.erl new file mode 100644 index 00000000..8f5c372a --- /dev/null +++ b/src/mem3_cache.erl @@ -0,0 +1,91 @@ +-module(mem3_cache). +-behaviour(gen_server). +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, + code_change/3]). + +-export([start_link/0]). + +-include("mem3.hrl"). + +start_link() -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). + +init([]) -> + ets:new(partitions, [bag, protected, named_table, {keypos,#shard.dbname}]), + ets:new(memnodes, [bag, protected, named_table]), + cache_dbs(), + Self = self(), + couch_db_update_notifier:start_link(fun({updated, <<"dbs">>}) -> + Self ! rebuild_dbs_cache; + (_) -> ok end), + {ok, nil}. + +handle_call(_Msg, _From, State) -> + {reply, ok, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(rebuild_dbs_cache, State) -> + receive rebuild_dbs_cache -> + handle_info(rebuild_dbs_cache, State) + after 0 -> ok end, + T0 = now(), + ?LOG_INFO("rebuilding dbs DB cache", []), + ets:delete_all_objects(partitions), + ets:delete_all_objects(memnodes), + cache_dbs(), + ?LOG_INFO("rebuild of dbs DB cache complete in ~p ms", + [round(timer:now_diff(now(),T0)/1000)]), + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +cache_dbs() -> + try couch_db:open(<<"dbs">>, []) of + {ok, Db} -> + Bt = Db#db.id_tree, + FoldFun = fun(#full_doc_info{id=Id, deleted=false} = FullDocInfo, _, _) -> + {ok, Doc} = couch_db:open_doc_int(Db, FullDocInfo, []), + {Props} = couch_doc:to_json_obj(Doc, []), + cache_map(Id, Props), + cache_nodes(Id, Props), + {ok, true}; + (_, _, _) -> + {ok, nil} + end, + couch_btree:foldl(Bt, FoldFun, nil), + couch_db:close(Db) + catch exit:{noproc,{gen_server,call,[couch_server|_]}} -> + timer:sleep(1000), + exit(couch_server_is_dead) + end. + +cache_map(Id, Props) -> + Map = couch_util:get_value(<<"map">>, Props, []), + lists:foreach(fun({[{<<"node">>,Node},{<<"b">>,Beg},{<<"e">>,End}]}) -> + Part = #shard{ + name = partitions:shard_name(Beg, Id), + dbname = Id, + node = to_atom(Node), + range = [Beg,End] + }, + ets:insert(partitions, Part) + end, Map). + +cache_nodes(Id, Props) -> + Nodes = couch_util:get_value(<<"nodes">>, Props, []), + lists:foreach(fun({[{<<"order">>,Order},{<<"node">>, Node},{<<"options">>,Opts}]}) -> + ets:insert(memnodes, {Id, {Order, to_atom(Node), Opts}}) + end, Nodes). + +to_atom(Node) when is_binary(Node) -> + list_to_atom(binary_to_list(Node)); +to_atom(Node) when is_atom(Node) -> + Node. + +%{ok, ets:insert(dbs_cache, {Id, Props})}; -- cgit v1.2.3