Add function to determine shard membership locally 1843-feature-bigcouch
authorRobert Newson <rnewson@apache.org>
Wed, 7 May 2014 13:48:25 +0000 (14:48 +0100)
committerRobert Newson <rnewson@apache.org>
Wed, 7 May 2014 15:08:43 +0000 (16:08 +0100)
mem3:belongs/2 allows you to determine if a given doc id belongs to a
given shard (whether a #shard{} record or just the filename of a
shard) without looking up the shard map or making any remote
calls.

src/mem3.erl

index c9b4793d354f312647f40f7da8056e85e5e16678..36ff87b4f93e1c40efcb6a45baeec56a1fc8b6a8 100644 (file)
@@ -19,6 +19,7 @@
 -export([compare_nodelists/0, compare_shards/1]).
 -export([quorum/1, group_by_proximity/1]).
 -export([live_shards/2]).
+-export([belongs/2]).
 
 -include_lib("mem3/include/mem3.hrl").
 -include_lib("couch/include/couch_db.hrl").
@@ -192,6 +193,26 @@ dbname(DbName) when is_binary(DbName) ->
 dbname(_) ->
     erlang:error(badarg).
 
+%% @doc Determine if DocId belongs in shard (identified by record or filename)
+belongs(#shard{}=Shard, DocId) when is_binary(DocId) ->
+    [Begin, End] = range(Shard),
+    belongs(Begin, End, DocId);
+belongs(<<"shards/", _/binary>> = ShardName, DocId) when is_binary(DocId) ->
+    [Begin, End] = range(ShardName),
+    belongs(Begin, End, DocId);
+belongs(DbName, DocId) when is_binary(DbName), is_binary(DocId) ->
+    true.
+
+belongs(Begin, End, DocId) ->
+    HashKey = mem3_util:hash(DocId),
+    Begin =< HashKey andalso HashKey =< End.
+
+range(#shard{range = Range}) ->
+    Range;
+range(<<"shards/", Start:8/binary, "-", End:8/binary, "/", _/binary>>) ->
+    [httpd_util:hexlist_to_integer(binary_to_list(Start)),
+     httpd_util:hexlist_to_integer(binary_to_list(End))].
+
 nodes_in_zone(Nodes, Zone) ->
     [Node || Node <- Nodes, Zone == mem3:node_info(Node, <<"zone">>)].