summaryrefslogtreecommitdiff
path: root/src/fabric_db_doc_count.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/fabric_db_doc_count.erl')
-rw-r--r--src/fabric_db_doc_count.erl42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/fabric_db_doc_count.erl b/src/fabric_db_doc_count.erl
new file mode 100644
index 00000000..4c3a72d5
--- /dev/null
+++ b/src/fabric_db_doc_count.erl
@@ -0,0 +1,42 @@
+-module(fabric_db_doc_count).
+
+-export([go/1]).
+
+-include("fabric.hrl").
+
+go(DbName) ->
+ Shards = partitions:all_parts(DbName),
+ Workers = fabric_util:submit_jobs(Shards, get_doc_count, []),
+ Acc0 = {length(Workers), [{Beg,nil} || #shard{range=[Beg,_]} <- Workers]},
+ fabric_util:recv(Workers, #shard.ref, fun handle_message/3, Acc0).
+
+handle_message({ok, Count}, #shard{range=[Beg,_]}, {N, Infos0}) ->
+ case couch_util:get_value(Beg, Infos0) of
+ nil ->
+ Infos = lists:keyreplace(Beg, 1, Infos0, {Beg, Count}),
+ case is_complete(Infos) of
+ true ->
+ {stop, lists:sum([C || {_, C} <- Infos])};
+ false ->
+ if N > 1 ->
+ {ok, {N-1, Infos}};
+ true ->
+ report_error(Infos),
+ {error, missing_shards}
+ end
+ end;
+ _ ->
+ {ok, {N-1, Infos0}}
+ end;
+handle_message(_, _, {1, Infos}) ->
+ report_error(Infos),
+ {error, missing_shards};
+handle_message(_Other, _, {N, Infos0}) ->
+ {ok, {N-1, Infos0}}.
+
+report_error(Infos) ->
+ MissingShards = [S || {S,nil} <- Infos],
+ ?LOG_ERROR("doc_count error, missing shards: ~p", [MissingShards]).
+
+is_complete(List) ->
+ not lists:keymember(nil, 2, List).