Relax the mem3_sync_security fix constraint Instead of requiring that we only have an empty security object and a single non-empty version that out numbers empties, we relax the fixable constraint to be a single simple majority of (N/2)+1 objects of a single value.
BugzId: 11602 Project: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/commit/d358892c Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/tree/d358892c Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/diff/d358892c Branch: refs/heads/import Commit: d358892cc60c3f6b6d5bba8bdbb131d5304dea47 Parents: af18b14 Author: Paul J. Davis <paul.joseph.da...@gmail.com> Authored: Tue Sep 25 12:54:23 2012 -0500 Committer: Paul J. Davis <paul.joseph.da...@gmail.com> Committed: Tue Sep 25 22:24:58 2012 -0500 ---------------------------------------------------------------------- src/mem3_sync_security.erl | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/d358892c/src/mem3_sync_security.erl ---------------------------------------------------------------------- diff --git a/src/mem3_sync_security.erl b/src/mem3_sync_security.erl index 2419ebd..5a45dbb 100644 --- a/src/mem3_sync_security.erl +++ b/src/mem3_sync_security.erl @@ -24,9 +24,10 @@ go(DbName) when is_binary(DbName) -> handle_db(DbName). handle_db(DbName) -> + ShardCount = length(mem3:shards(DbName)), case get_all_security(DbName) of {ok, SecObjs} -> - case is_ok(SecObjs) of + case is_ok(SecObjs, ShardCount) of ok -> ok; {fixable, SecObj} -> @@ -56,21 +57,19 @@ get_all_security(DbName) -> Error end. -is_ok([_]) -> +is_ok([_], _) -> % One security object is the happy case ok; -is_ok([_, _] = SecObjs0) -> - % This is the strict heuristic where there is one version of - % the security object that out numbers empty security objects. - % If so, just overwrite the empty objects with the non-empty - % version. - case lists:keytake({[]}, 1, SecObjs0) of - {value, {_, EmptyCount}, [{SecObj, Count}]} when Count > EmptyCount -> - {fixable, SecObj}; - _ -> - broken +is_ok([_, _] = SecObjs0, ShardCount) -> + % Figure out if we have a simple majority of security objects + % and if so, use that as the correct value. Otherwise we abort + % and rely on human intervention. + {Count, SecObj} = lists:max([{C, O} || {O, C} <- SecObjs0]), + case Count >= ((ShardCount div 2) + 1) of + true -> {fixable, SecObj}; + false -> broken end; -is_ok(_) -> +is_ok(_, _) -> % Anything else requires human intervention broken.