Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: basho/riak_core
base: cet-bg-mgr-proto
...
head fork: basho/riak_core
compare: bos-bucket-type
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 6 files changed
  • 0 commit comments
  • 2 contributors
Commits on Aug 14, 2013
@jrwest jrwest Teach riak_core Bucket Types
Like buckets, we must teach core this because a few subsystems
use them. Bucket Types provide a method for grouping buckets
logically (see basho/riak#362).
b74d7d5
Commits on Aug 27, 2013
@Vagabond Vagabond Isolate app.config from non-default bucket type properties, implement…
… reset

Non-default bucket-types are unaffected by changes to app.config and
bucket types can have their properties reset to the hardcoded defaults.
81024be
View
2  ebin/riak_core.app
@@ -20,6 +20,8 @@
riak_core_apl,
riak_core_app,
riak_core_bucket,
+ riak_core_bucket_type,
+ riak_core_bucket_props,
riak_core_cinfo_core,
riak_core_claimant,
riak_core_claim,
View
8 src/riak_core_app.erl
@@ -64,13 +64,7 @@ start(_StartType, _StartArgs) ->
%% add these defaults now to supplement the set that may have been
%% configured in app.config
- riak_core_bucket:append_bucket_defaults(
- [{n_val,3},
- {allow_mult,false},
- {last_write_wins,false},
- {precommit, []},
- {postcommit, []},
- {chash_keyfun, {riak_core_util, chash_std_keyfun}}]),
+ riak_core_bucket:append_bucket_defaults(riak_core_bucket_type:defaults()),
%% Spin up the supervisor; prune ring files as necessary
case riak_core_sup:start_link() of
View
139 src/riak_core_bucket.erl
@@ -41,6 +41,8 @@
-include_lib("eunit/include/eunit.hrl").
-endif.
+-define(METADATA_PREFIX, {core, buckets}).
+
%% @doc Add a list of defaults to global list of defaults for new
%% buckets. If any item is in Items is already set in the
%% current defaults list, the new setting is omitted, and the old
@@ -48,47 +50,52 @@
%% behavior, to allow settings from app.config to override any
%% hard-coded values.
append_bucket_defaults(Items) when is_list(Items) ->
- OldDefaults = app_helper:get_env(riak_core, default_bucket_props, []),
- NewDefaults = merge_props(OldDefaults, Items),
- FixedDefaults = case riak_core:bucket_fixups() of
- [] -> NewDefaults;
- Fixups ->
- riak_core_ring_manager:run_fixups(Fixups, default, NewDefaults)
- end,
- application:set_env(riak_core, default_bucket_props, FixedDefaults),
- %% do a noop transform on the ring, to make the fixups re-run
- catch(riak_core_ring_manager:ring_trans(fun(Ring, _) ->
- {new_ring, Ring} end, undefined)).
-
+ riak_core_bucket_props:append_defaults(Items).
%% @spec set_bucket(riak_object:bucket(), BucketProps::riak_core_bucketprops()) -> ok
%% @doc Set the given BucketProps in Bucket.
+set_bucket({<<"default">>, Name}, BucketProps) ->
+ set_bucket(Name, BucketProps);
+set_bucket({Type, _Name}=Bucket, BucketProps0) ->
+ case riak_core_bucket_type:get(Type) of
+ undefined -> {error, no_type};
+ _ -> set_bucket(fun set_bucket_in_metadata/2, Bucket, BucketProps0)
+ end;
set_bucket(Name, BucketProps0) ->
- case validate_props(BucketProps0, riak_core:bucket_validators(), []) of
+ set_bucket(fun set_bucket_in_ring/2, Name, BucketProps0).
+
+set_bucket(StoreFun, Bucket, BucketProps0) ->
+ case riak_core_bucket_props:validate(BucketProps0) of
{ok, BucketProps} ->
- F = fun(Ring, _Args) ->
- OldBucket = get_bucket(Name),
- NewBucket = merge_props(BucketProps, OldBucket),
- {new_ring, riak_core_ring:update_meta({bucket,Name},
- NewBucket,
- Ring)}
- end,
- {ok, _NewRing} = riak_core_ring_manager:ring_trans(F, undefined),
- ok;
+ OldBucket = get_bucket(Bucket),
+ NewBucket = merge_props(BucketProps, OldBucket),
+ StoreFun(Bucket, NewBucket);
{error, Details} ->
- lager:error("Bucket validation failed ~p~n", [Details]),
+ lager:error("Bucket properties validation failed ~p~n", [Details]),
{error, Details}
end.
+set_bucket_in_metadata(Bucket, BucketMeta) ->
+ riak_core_metadata:put(?METADATA_PREFIX, bucket_key(Bucket), BucketMeta).
+
+set_bucket_in_ring(Bucket, BucketMeta) ->
+ F = fun(Ring, _Args) ->
+ {new_ring, riak_core_ring:update_meta(bucket_key(Bucket),
+ BucketMeta,
+ Ring)}
+ end,
+ {ok, _NewRing} = riak_core_ring_manager:ring_trans(F, undefined),
+ ok.
+
+
%% @spec merge_props(list(), list()) -> list()
%% @doc Merge two sets of bucket props. If duplicates exist, the
%% entries in Overriding are chosen before those in Other.
merge_props(Overriding, Other) ->
- lists:ukeymerge(1, lists:ukeysort(1, Overriding),
- lists:ukeysort(1, Other)).
+ riak_core_bucket_props:merge(Overriding, Other).
%% @spec get_bucket(riak_object:bucket()) ->
-%% {ok, BucketProps :: riak_core_bucketprops()}
+%% {ok, BucketProps :: riak_core_bucketprops()} | {error, no_type}
%% @doc Return the complete current list of properties for Bucket.
%% Properties include but are not limited to:
%% <pre>
@@ -97,6 +104,16 @@ merge_props(Overriding, Other) ->
%% linkfun: a function returning a m/r FunTerm for link extraction
%% </pre>
%%
+get_bucket({<<"default">>, Name}) ->
+ get_bucket(Name);
+get_bucket({Type, _Name}=Bucket) ->
+ TypeMeta = riak_core_bucket_type:get(Type),
+ BucketMeta = riak_core_metadata:get(?METADATA_PREFIX, bucket_key(Bucket),
+ [{resolver, fun riak_core_bucket_props:resolve/2}]),
+ case merge_type_props(TypeMeta, BucketMeta) of
+ {error, _}=Error -> Error;
+ Props -> [{name, Bucket} | Props]
+ end;
get_bucket(Name) ->
Meta = riak_core_ring_manager:get_bucket_meta(Name),
get_bucket_props(Name, Meta).
@@ -104,34 +121,55 @@ get_bucket(Name) ->
%% @spec get_bucket(Name, Ring::riak_core_ring:riak_core_ring()) ->
%% BucketProps :: riak_core_bucketprops()
%% @private
+get_bucket({<<"default">>, Name}, Ring) ->
+ get_bucket(Name, Ring);
+get_bucket({_Type, _Name}=Bucket, _Ring) ->
+ %% non-default type buckets are not stored in the ring, so just ignore it
+ get_bucket(Bucket);
get_bucket(Name, Ring) ->
- Meta = riak_core_ring:get_meta({bucket, Name}, Ring),
+ Meta = riak_core_ring:get_meta(bucket_key(Name), Ring),
get_bucket_props(Name, Meta).
-get_bucket_props(Name, Meta) ->
- case Meta of
- undefined ->
- [{name, Name}
- |app_helper:get_env(riak_core, default_bucket_props)];
- {ok, Bucket} -> Bucket
- end.
+get_bucket_props(Name, undefined) ->
+ [{name, Name} | riak_core_bucket_props:defaults()];
+get_bucket_props(_Name, {ok, Bucket}) ->
+ Bucket.
+
+merge_type_props(undefined, _) ->
+ {error, no_type};
+merge_type_props(TypeMeta, undefined) when is_list(TypeMeta) ->
+ TypeMeta;
+merge_type_props(TypeMeta, BucketMeta) when is_list(TypeMeta) andalso
+ is_list(BucketMeta) ->
+ merge_props(BucketMeta, TypeMeta).
%% @spec reset_bucket(binary()) -> ok
-%% @doc Reset the bucket properties for Bucket to the default settings
+%% @doc Reset the bucket properties for Bucket to the settings
+%% inherited from its Bucket Type
+reset_bucket({<<"default">>, Name}) ->
+ reset_bucket(Name);
+reset_bucket({_Type, _Name}=Bucket) ->
+ riak_core_metadata:delete(?METADATA_PREFIX, bucket_key(Bucket));
reset_bucket(Bucket) ->
F = fun(Ring, _Args) ->
- {new_ring, riak_core_ring:remove_meta({bucket, Bucket}, Ring)}
+ {new_ring, riak_core_ring:remove_meta(bucket_key(Bucket), Ring)}
end,
{ok, _NewRing} = riak_core_ring_manager:ring_trans(F, undefined),
ok.
%% @doc Get bucket properties `Props' for all the buckets in the given
-%% `Ring'
+%% `Ring' and stored in metadata
-spec get_buckets(riak_core_ring:riak_core_ring()) ->
Props::list().
get_buckets(Ring) ->
- Names = riak_core_ring:get_buckets(Ring),
- [get_bucket(Name, Ring) || Name <- Names].
+ RingNames = riak_core_ring:get_buckets(Ring),
+ RingBuckets = [get_bucket(Name, Ring) || Name <- RingNames],
+ MetadataBuckets = riak_core_metadata:fold(fun({_Key, Props}, Acc) ->
+ [Props | Acc]
+ end,
+ [], ?METADATA_PREFIX,
+ [{resolver, fun riak_core_bucket_props:resolve/2}]),
+ RingBuckets ++ MetadataBuckets.
%% @doc returns a proplist containing all buckets and their respective N values
-spec bucket_nval_map(riak_core_ring:riak_core_ring()) -> [{binary(),integer()}].
@@ -142,21 +180,7 @@ bucket_nval_map(Ring) ->
%% @doc returns the default n value for buckets that have not explicitly set the property
-spec default_object_nval() -> integer().
default_object_nval() ->
- riak_core_bucket:n_val(riak_core_config:default_bucket_props()).
-
-%% @private
--spec validate_props(BucketProps::list({PropName::atom(), Value::any()}),
- Validators::list(module()),
- Errors::list({PropName::atom(), Error::atom()})) ->
- {ok, BucketProps::list({PropName::atom(), Value::any()})} |
- {error, Errors::list({PropName::atom(), Error::atom()})}.
-validate_props(BucketProps, [], []) ->
- {ok, BucketProps};
-validate_props(_, [], Errors) ->
- {error, Errors};
-validate_props(BucketProps0, [{_App, Validator}|T], Errors0) ->
- {BucketProps, Errors} = Validator:validate(BucketProps0),
- validate_props(BucketProps, T, lists:flatten([Errors|Errors0])).
+ riak_core_bucket:n_val(riak_core_bucket_props:defaults()).
name(BProps) ->
proplists:get_value(name, BProps).
@@ -164,6 +188,13 @@ name(BProps) ->
n_val(BProps) ->
proplists:get_value(n_val, BProps).
+bucket_key({<<"default">>, Name}) ->
+ bucket_key(Name);
+bucket_key({_Type, _Name}=Bucket) ->
+ Bucket;
+bucket_key(Name) ->
+ {bucket, Name}.
+
%% ===================================================================
%% EUnit tests
%% ===================================================================
View
232 src/riak_core_bucket_props.erl
@@ -0,0 +1,232 @@
+%% -------------------------------------------------------------------
+%%
+%% Copyright (c) 2013 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+%% -------------------------------------------------------------------
+-module(riak_core_bucket_props).
+
+-export([merge/2,
+ validate/1,
+ resolve/2,
+ defaults/0,
+ append_defaults/1]).
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+-endif.
+
+-spec merge([{atom(), any()}], [{atom(), any()}]) -> [{atom(), any()}].
+merge(Overriding, Other) ->
+ lists:ukeymerge(1, lists:ukeysort(1, Overriding),
+ lists:ukeysort(1, Other)).
+
+
+-spec validate([{atom(), any()}]) -> {ok, [{atom(), any()}]} |
+ {error, [{atom(), atom()}]}.
+validate(BucketProps) ->
+ validate(BucketProps, riak_core:bucket_validators(), []).
+
+validate(BucketProps, [], []) ->
+ {ok, BucketProps};
+validate(_, [], Errors) ->
+ {error, Errors};
+validate(BucketProps0, [{_App, Validator}|T], Errors0) ->
+ {BucketProps, Errors} = Validator:validate(BucketProps0),
+ validate(BucketProps, T, lists:flatten([Errors|Errors0])).
+
+
+-spec defaults() -> [{atom(), any()}].
+defaults() ->
+ app_helper:get_env(riak_core, default_bucket_props).
+
+-spec append_defaults([{atom(), any()}]) -> ok.
+append_defaults(Items) when is_list(Items) ->
+ OldDefaults = app_helper:get_env(riak_core, default_bucket_props, []),
+ NewDefaults = merge(OldDefaults, Items),
+ FixedDefaults = case riak_core:bucket_fixups() of
+ [] -> NewDefaults;
+ Fixups ->
+ riak_core_ring_manager:run_fixups(Fixups, default, NewDefaults)
+ end,
+ application:set_env(riak_core, default_bucket_props, FixedDefaults),
+ %% do a noop transform on the ring, to make the fixups re-run
+ catch(riak_core_ring_manager:ring_trans(fun(Ring, _) ->
+ {new_ring, Ring}
+ end, undefined)),
+ ok.
+
+-spec resolve([{atom(), any()}], [{atom(), any()}]) -> [{atom(), any()}].
+resolve(PropsA, PropsB) when is_list(PropsA) andalso
+ is_list(PropsB) ->
+ PropsASorted = lists:ukeysort(1, PropsA),
+ PropsBSorted = lists:ukeysort(1, PropsB),
+ {_, Resolved} = lists:foldl(fun({KeyA, _}=PropA, {[{KeyA, _}=PropB | RestB], Acc}) ->
+ {RestB, [{KeyA, resolve(PropA, PropB)} | Acc]};
+ (PropA, {RestB, Acc}) ->
+ {RestB, [PropA | Acc]}
+ end,
+ {PropsBSorted, []},
+ PropsASorted),
+ Resolved;
+resolve({allow_mult, Mult1}, {allow_mult, Mult2}) ->
+ Mult1 orelse Mult2; %% assumes allow_mult=true is default
+resolve({basic_quorum, Basic1}, {basic_quorum, Basic2}) ->
+ Basic1 andalso Basic2;
+resolve({big_vclock, Big1}, {big_vclock, Big2}) ->
+ case Big1 > Big2 of
+ true -> Big1;
+ false -> Big2
+ end;
+resolve({chash_keyfun, KeyFun1}, {chash_keyfun, _KeyFun2}) ->
+ KeyFun1; %% arbitrary choice
+resolve({dw, DW1}, {dw, DW2}) ->
+ %% 'quorum' wins over set numbers
+ case DW1 > DW2 of
+ true -> DW1;
+ false -> DW2
+ end;
+resolve({last_write_wins, LWW1}, {last_write_wins, LWW2}) ->
+ LWW1 andalso LWW2;
+resolve({linkfun, LinkFun1}, {linkfun, _LinkFun2}) ->
+ LinkFun1; %% arbitrary choice
+resolve({n_val, N1}, {n_val, N2}) ->
+ case N1 > N2 of
+ true -> N1;
+ false -> N2
+ end;
+resolve({notfound_ok, NF1}, {notfound_ok, NF2}) ->
+ NF1 orelse NF2;
+resolve({old_vclock, Old1}, {old_vclock, Old2}) ->
+ case Old1 > Old2 of
+ true -> Old1;
+ false -> Old2
+ end;
+resolve({postcommit, PC1}, {postcommit, PC2}) ->
+ resolve_hooks(PC1, PC2);
+resolve({pr, PR1}, {pr, PR2}) ->
+ case PR1 > PR2 of
+ true -> PR1;
+ false -> PR2
+ end;
+resolve({precommit, PC1}, {precommit, PC2}) ->
+ resolve_hooks(PC1, PC2);
+resolve({pw, PW1}, {pw, PW2}) ->
+ case PW1 > PW2 of
+ true -> PW1;
+ false -> PW2
+ end;
+resolve({r, R1}, {r, R2}) ->
+ case R1 > R2 of
+ true -> R1;
+ false -> R2
+ end;
+resolve({rw, RW1}, {rw, RW2}) ->
+ case RW1 > RW2 of
+ true -> RW1;
+ false -> RW2
+ end;
+resolve({small_vclock, Small1}, {small_vclock, Small2}) ->
+ case Small1 > Small2 of
+ true -> Small1;
+ false -> Small2
+ end;
+resolve({w, W1}, {w, W2}) ->
+ case W1 > W2 of
+ true -> W1;
+ false -> W2
+ end;
+resolve({young_vclock, Young1}, {young_vclock, Young2}) ->
+ case Young1 > Young2 of
+ true -> Young1;
+ false -> Young2
+ end;
+resolve({_, V1}, {_, _V2}) ->
+ V1.
+
+resolve_hooks(Hooks1, Hooks2) ->
+ lists:usort(Hooks1 ++ Hooks2).
+
+%% ===================================================================
+%% EUnit tests
+%% ===================================================================
+
+-ifdef(TEST).
+
+simple_resolve_test() ->
+ Props1 = [{name,<<"test">>},
+ {allow_mult,false},
+ {basic_quorum,false},
+ {big_vclock,50},
+ {chash_keyfun,{riak_core_util,chash_std_keyfun}},
+ {dw,quorum},
+ {last_write_wins,false},
+ {linkfun,{modfun,riak_kv_wm_link_walker,mapreduce_linkfun}},
+ {n_val,3},
+ {notfound_ok,true},
+ {old_vclock,86400},
+ {postcommit,[]},
+ {pr,0},
+ {precommit,[{a, b}]},
+ {pw,0},
+ {r,quorum},
+ {rw,quorum},
+ {small_vclock,50},
+ {w,quorum},
+ {young_vclock,20}],
+ Props2 = [{name,<<"test">>},
+ {allow_mult, true},
+ {basic_quorum, true},
+ {big_vclock,60},
+ {chash_keyfun,{riak_core_util,chash_std_keyfun}},
+ {dw,3},
+ {last_write_wins,true},
+ {linkfun,{modfun,riak_kv_wm_link_walker,mapreduce_linkfun}},
+ {n_val,5},
+ {notfound_ok,false},
+ {old_vclock,86401},
+ {postcommit,[{a, b}]},
+ {pr,1},
+ {precommit,[{c, d}]},
+ {pw,3},
+ {r,3},
+ {rw,3},
+ {w,1},
+ {young_vclock,30}],
+ Expected = [{name,<<"test">>},
+ {allow_mult,true},
+ {basic_quorum,false},
+ {big_vclock,60},
+ {chash_keyfun,{riak_core_util,chash_std_keyfun}},
+ {dw,quorum},
+ {last_write_wins,false},
+ {linkfun,{modfun,riak_kv_wm_link_walker,mapreduce_linkfun}},
+ {n_val,5},
+ {notfound_ok,true},
+ {old_vclock,86401},
+ {postcommit,[{a, b}]},
+ {pr,1},
+ {precommit,[{a, b}, {c, d}]},
+ {pw,3},
+ {r,quorum},
+ {rw,quorum},
+ {small_vclock,50},
+ {w,quorum},
+ {young_vclock,30}],
+ ?assertEqual(lists:ukeysort(1, Expected), lists:ukeysort(1, resolve(Props1, Props2))).
+
+-endif.
+
View
124 src/riak_core_bucket_type.erl
@@ -0,0 +1,124 @@
+%% -------------------------------------------------------------------
+%%
+%% Copyright (c) 2013 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+%% -------------------------------------------------------------------
+-module(riak_core_bucket_type).
+
+-export([defaults/0,
+ create/2,
+ update/2,
+ get/1,
+ reset/1,
+ iterator/0,
+ itr_next/1,
+ itr_done/1,
+ itr_value/1]).
+
+-type bucket_type() :: binary().
+-type bucket_type_props() :: [{term(), term()}].
+
+-define(KEY_PREFIX, {core, bucket_types}).
+-define(DEFAULT_TYPE, <<"default">>).
+
+%% @doc The hardcoded defaults for all bucket types.
+-spec defaults() -> bucket_type_props().
+defaults() ->
+ [{n_val,3},
+ {allow_mult,false},
+ {last_write_wins,false},
+ {precommit, []},
+ {postcommit, []},
+ {chash_keyfun, {riak_core_util, chash_std_keyfun}}].
+
+%% @doc Create a new bucket type. Properties provided will be merged with default
+%% bucket properties set in config. "Creation" as implemented is subject to concurrent
+%% write issues, so for now this is more of a semantic name. This will be addressed
+%% when proper support is added to cluster metadata
+-spec create(bucket_type(), bucket_type_props()) -> ok | {error, term()}.
+create(?DEFAULT_TYPE, _Props) ->
+ {error, already_exists};
+create(BucketType, Props) when is_binary(BucketType) ->
+ %% TODO: this doesn't actually give us much guaruntees
+ case ?MODULE:get(BucketType) of
+ undefined -> update(BucketType, Props);
+ _ -> {error, already_exists}
+ end.
+
+%% @doc Update an existing bucket type. See comments in create/1 for caveats.
+-spec update(bucket_type(), bucket_type_props()) -> ok | {error, term()}.
+update(?DEFAULT_TYPE, _Props) ->
+ {error, no_default_update}; %% default props are in the app.config
+update(BucketType, Props0) when is_binary(BucketType)->
+ case riak_core_bucket_props:validate(Props0) of
+ {ok, Props} ->
+ OldProps = get(BucketType, defaults()),
+ NewProps = riak_core_bucket_props:merge(Props, OldProps),
+ %% TODO: but what if DNE? not much "update" guarantee
+ riak_core_metadata:put(?KEY_PREFIX, BucketType, NewProps);
+ {error, Details} ->
+ lager:error("Bucket Type properties validation failed ~p~n", [Details]),
+ {error, Details}
+ end.
+
+%% @doc Return the properties associated with the given bucket type
+-spec get(bucket_type()) -> undefined | bucket_type_props().
+get(BucketType) when is_binary(BucketType) ->
+ get(BucketType, undefined).
+
+%% @private
+get(BucketType, Default) ->
+ riak_core_metadata:get(?KEY_PREFIX,
+ BucketType,
+ [{default, Default}, {resolver, fun riak_core_bucket_props:resolve/2}]).
+
+
+reset(BucketType) ->
+ case ?MODULE:get(BucketType) of
+ undefined ->
+ {error, no_type};
+ _ ->
+ riak_core_metadata:put(?KEY_PREFIX, BucketType, defaults()),
+ ok
+ end.
+
+%% @doc Return an iterator that can be used to walk iterate through all existing bucket types
+-spec iterator() -> riak_core_metadata:iterator().
+iterator() ->
+ %% we don't allow deletion (yet) so we should never need the default but we provide one anyway
+ riak_core_metadata:iterator(?KEY_PREFIX, [{default, undefined},
+ {resolver, fun riak_core_bucket_props:resolve/2}]).
+
+%% @doc Advance the iterator to the next bucket type. itr_done/1 should always be called
+%% before this function
+-spec itr_next(riak_core_metadata:iterator()) ->
+ riak_core_metadata:iterator().
+itr_next(It) ->
+ riak_core_metadata:itr_next(It).
+
+%% @doc Returns true if there are no more bucket types to iterate over
+-spec itr_done(riak_core_metadata:iterator()) -> boolean().
+itr_done(It) ->
+ riak_core_metadata:itr_done(It).
+
+%% @doc Returns the type and properties that the iterator points too. Any siblings,
+%% are resolved at this time. itr_done/1 should be checked before calling this function.
+-spec itr_value(riak_core_metadata:iterator()) ->
+ {bucket_type(), bucket_type_props()}.
+itr_value(It) ->
+ {BucketType, Props} = riak_core_metadata:itr_key_values(It),
+ {BucketType, Props}.
View
10 src/riak_core_ring_manager.erl
@@ -174,7 +174,15 @@ get_ring_id() ->
{0,0}
end.
-%% @doc Return metadata for the given bucket
+%% @doc Return metadata for the given bucket. If a bucket
+%% for the non-default type is provided {error, no_type}
+%% is returned when the type does not exist
+get_bucket_meta({<<"default">>, Name}) ->
+ get_bucket_meta(Name);
+get_bucket_meta({_Type, _Name}=Bucket) ->
+ %% reads from cluster metadata ets table
+ %% these aren't stored in ring manager ever
+ riak_core_bucket:get_bucket(Bucket);
get_bucket_meta(Bucket) ->
case ets:lookup(?ETS, {bucket, Bucket}) of
[] ->

No commit comments for this range

Something went wrong with that request. Please try again.