tanodb is a distributed in memory key value store built on top of riak_core.
It is used as the example code for the Little Riak Core Book.
(kudos to @cv for the original version)
I found the following piece of code in a gist, but when I tried to execute it under taminodb, it returned an empty array.
(tanodb3@127.0.0.1)7> Preflist = fun(Bucket,Key) ->
(tanodb3@127.0.0.1)7> BKey = {Bucket,Key},
(tanodb3@127.0.0.1)7> {ok, Ring} = riak_core_ring_manager:get_my_ring(),
(tanodb3@127.0.0.1)7> DocIdx = riak_core_util:chash_key(BKey),
(tanodb3@127.0.0.1)7> BucketProps = riak_core_bucket:get_bucket(Bucket, Ring),
(tanodb3@127.0.0.1)7> [NValue] = [Y || {X1, Y} <- BucketProps, n_val == X1],
(tanodb3@127.0.0.1)7> UpNodes = riak_core_node_watcher:nodes(riak_kv),
(tanodb3@127.0.0.1)7> Preflist2 = riak_core_apl:get_apl_ann(DocIdx, NValue, Ring, UpNodes),
(tanodb3@127.0.0.1)7> [IndexNode || {IndexNode, _Type} <- Preflist2]
(tanodb3@127.0.0.1)7> end.
#Fun<erl_eval.12.54118792>
(tanodb3@127.0.0.1)8> Preflist(<<"foo">>,<<"bar">>).
[]
Let's take a look at the implementation, and the debugging and steps required for it to execute correctly on a running Tanodb instance.
(tanodb3@127.0.0.1)16> f().
ok
(tanodb3@127.0.0.1)17> Bucket = <<"foo">>.
<<"foo">>
(tanodb3@127.0.0.1)18> Key = <<"bar">>.
<<"bar">>
(tanodb3@127.0.0.1)19> BKey = {Bucket,Key}.
{<<"foo">>,<<"bar">>}
(tanodb3@127.0.0.1)20> {ok, Ring} = riak_core_ring_manager:get_my_ring().
{ok,{chstate_v2,'tanodb3@127.0.0.1',
[{'tanodb3@127.0.0.1',{18,63615060109}},
{'tanodb1@127.0.0.1',{110,63615060109}},
{'tanodb2@127.0.0.1',{10,63615060107}}],
{64,
[{0,'tanodb1@127.0.0.1'},
{22835963083295358096932575511191922182123945984,
'tanodb2@127.0.0.1'},
{45671926166590716193865151022383844364247891968,
'tanodb2@127.0.0.1'},
{68507889249886074290797726533575766546371837952,
'tanodb3@127.0.0.1'},
{91343852333181432387730302044767688728495783936,
'tanodb1@127.0.0.1'},
{114179815416476790484662877555959610910619729920,
'tanodb2@127.0.0.1'},
{137015778499772148581595453067151533092743675904,
'tanodb2@127.0.0.1'},
{159851741583067506678528028578343455274867621888,
[.......]
(tanodb3@127.0.0.1)21> DocIdx = riak_core_util:chash_key(BKey).
<<73,212,27,234,104,13,150,207,0,82,86,183,125,225,172,
154,135,46,6,112>>
(tanodb3@127.0.0.1)22> BucketProps = riak_core_bucket:get_bucket(Bucket, Ring).
[{name,<<"foo">>},
{allow_mult,true},
{basic_quorum,false},
{big_vclock,50},
{chash_keyfun,{riak_core_util,chash_std_keyfun}},
{dvv_enabled,true},
{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,[]},
{pw,0},
{r,quorum},
{rw,quorum},
{small_vclock,50},
{w,quorum},
{young_vclock,20}]
(tanodb3@127.0.0.1)23>
(tanodb3@127.0.0.1)23> [NValue] = [Y || {X1, Y} <- BucketProps, n_val == X1].
[3]
(tanodb3@127.0.0.1)24> UpNodes = riak_core_node_watcher:nodes(riak_kv).
[]So it looks like we aren't running any nodes which are using Riak KV. In retrospect that's pretty obvious, we are running Taminodb, after all.
(tanodb3@127.0.0.1)25> riak_core_node_watcher:services().
[tanodb]
(tanodb3@127.0.0.1)28> f(UpNodes).
okLets try again to generate the preflist, this time when trying to retrieve the running nodes, lets use tanodb as the service name.
(tanodb3@127.0.0.1)29> UpNodes = riak_core_node_watcher:nodes(tanodb).
['tanodb1@127.0.0.1','tanodb2@127.0.0.1',
'tanodb3@127.0.0.1']Success! Lets generate the preflist!
(tanodb3@127.0.0.1)31> Preflist2 = riak_core_apl:get_apl_ann(DocIdx, NValue, Ring, UpNodes).
[{{433883298582611803841718934712646521460354973696,
'tanodb3@127.0.0.1'},
primary},
{{456719261665907161938651510223838443642478919680,
'tanodb1@127.0.0.1'},
primary},
{{479555224749202520035584085735030365824602865664,
'tanodb2@127.0.0.1'},
primary}]So, finally, the finished version:
% Example : Preflist({<<"bucket">>,<<"key">>}}.
%
Preflist = fun(Bucket,Key) ->
BKey = {Bucket,Key},
{ok, Ring} = riak_core_ring_manager:get_my_ring(),
DocIdx = riak_core_util:chash_key(BKey),
BucketProps = riak_core_bucket:get_bucket(Bucket, Ring),
[NValue] = [Y || {X1, Y} <- BucketProps, n_val == X1],
UpNodes = riak_core_node_watcher:nodes(tanodb),
Preflist2 = riak_core_apl:get_apl_ann(DocIdx, NValue, Ring, UpNodes),
[IndexNode || {IndexNode, _Type} <- Preflist2]
end.