diff --git a/src/couch_db.erl b/src/couch_db.erl index 5d4619a5..f8c00262 100644 --- a/src/couch_db.erl +++ b/src/couch_db.erl @@ -617,12 +617,43 @@ load_validation_funs(#db{main_pid=Pid}=Db) -> Doc end, DDocs = lists:map(OpenDocs, DDocInfos), - Funs = lists:flatmap(fun(DDoc) -> + Funs0 = lists:flatmap(fun(DDoc) -> case couch_doc:get_validate_doc_fun(DDoc) of nil -> []; Fun -> [Fun] end end, DDocs), + ShardDB = ?l2b(config:get("mem3", "shard_db", "dbs")), + Funs = case Db#db.name of + ShardDB -> + ValidateShardDbUpdate = fun(_ShardDBDoc, nil, _JsonCtx, _SecObj) -> + ok; + (NewShardMapDoc0, OldShardMapDoc0, _JsonCtx, _SecObj) -> + OldShardMapDoc = couch_doc:with_ejson_body(OldShardMapDoc0), + NewShardMapDoc = couch_doc:with_ejson_body(NewShardMapDoc0), + #doc{body=OldShardMapBody, deleted=OldDeleted} = OldShardMapDoc, + #doc{body=NewShardMapBody, deleted=NewDeleted} = NewShardMapDoc, + if OldDeleted =:= NewDeleted -> + HashAlgo = couch_util:get_value( + <<"hash_algorithm">>, NewShardMapBody), + OldHashAlgo = couch_util:get_value( + <<"hash_algorithm">>, OldShardMapBody), + if HashAlgo =/= OldHashAlgo -> + throw({ + bad_request, + <<"You can't change the hash algorithm.">> + }); + true -> + ok + end; + true -> + ok + end + end, + [ValidateShardDbUpdate|Funs0]; + _ -> + Funs0 + end, gen_server:cast(Pid, {load_validation_funs, Funs}), Funs. diff --git a/src/couch_db_updater.erl b/src/couch_db_updater.erl index 93ee6e90..236aeeda 100644 --- a/src/couch_db_updater.erl +++ b/src/couch_db_updater.erl @@ -625,7 +625,23 @@ refresh_validate_doc_funs(Db0) -> Fun -> [Fun] end end, DesignDocs), - Db#db{validate_doc_funs=ProcessDocFuns}. + + DbName = Db0#db.name, + couch_log:error("Refreshing validate doc funs", []), + ProcessDocFuns1 = case config:get("mem3", "shard_db", "dbs") of + DbName -> + [fun validate_shard_db_update/4|ProcessDocFuns]; + _ -> + ProcessDocFuns + end, + + Db#db{validate_doc_funs=ProcessDocFuns1}. + +validate_shard_db_update(Doc, DiskDoc, JsonCtx, SecObj) -> + couch_log:error("Doc: ~p", [Doc]), + couch_log:error("DiskDoc: ~p", [DiskDoc]), + ok. + % rev tree functions diff --git a/src/couch_secondary_sup.erl b/src/couch_secondary_sup.erl index 09e77b7c..e1a9ae77 100644 --- a/src/couch_secondary_sup.erl +++ b/src/couch_secondary_sup.erl @@ -26,7 +26,7 @@ init([]) -> worker, dynamic} ], - Children = SecondarySupervisors ++ [ + Children0 = SecondarySupervisors ++ [ begin {ok, {Module, Fun, Args}} = couch_util:parse_term(SpecStr), @@ -39,4 +39,32 @@ init([]) -> end || {Name, SpecStr} <- config:get("daemons"), SpecStr /= ""], + Children = [{ + hash_fun_lru, + {ets_lru, start_link, [hash_fun_lru, lru_opts()]}, + permanent, + 5000, + worker, + [ets_lru] + }|Children0], {ok, {{one_for_one, 50, 3600}, Children}}. + +lru_opts() -> + case application:get_env(couch, hash_fun_lru_max_objects) of + {ok, MxObjs} when is_integer(MxObjs), MxObjs > 0 -> + [{max_objects, MxObjs}]; + _ -> + [] + end ++ + case application:get_env(couch, hash_fun_lru_max_size) of + {ok, MxSize} when is_integer(MxSize), MxSize > 0 -> + [{max_size, MxSize}]; + _ -> + [] + end ++ + case application:get_env(couch, hash_fun_lru_max_lifetime) of + {ok, MxLT} when is_integer(MxLT), MxLT > 0 -> + [{max_lifetime, MxLT}]; + _ -> + [] + end.