Skip to content

Commit 8bb7a1c

Browse files
committed
[#31] – Implement update_counter and update_element in shards_dist
1 parent 934cb59 commit 8bb7a1c

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

README.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ In your `mix.exs`:
4444

4545
```elixir
4646
def deps do
47-
[{:shards, "~> 0.4.0"}]
47+
[{:shards, "~> 0.4"}]
4848
end
4949
```
5050

@@ -231,23 +231,23 @@ If any microsecond matters to you, you can skip the call to the control ETS tabl
231231
`shards:new/2` by first time, or you can call `shards:state/1`, `shards_state:get/1` or
232232
`shards_state:new/0,1,2,3,4` at any time you want, and then it might be stored within
233233
the calling process, or wherever you want. E.g.:
234-
234+
235235
```erlang
236236
% take a look at the 2nd element of the returned tuple, that is the state
237237
> shards:new(mytab, [{n_shards, 4}]).
238238
mytab
239-
239+
240240
% remember you can get the state at any time you want
241241
> State = shards:state(mytab).
242242
{state,shards_local,4,#Fun<shards_local.pick.3>,
243243
#Fun<shards_local.pick.3>}
244-
244+
245245
% now you can call shards_local directly
246246
> shards_local:insert(mytab, {1, 1}, State).
247247
true
248248
> shards_local:lookup(mytab, 1, State).
249249
[{1,1}]
250-
250+
251251
% in this case, only the n_shards is different from default, so you
252252
% can do this:
253253
> shards_local:lookup(mytab, 1, shards_state:new(4)).
@@ -260,12 +260,12 @@ If any microsecond matters to you, you can skip the call to the control ETS tabl
260260
better, since in this case no additional calls are needed, not even to recover the `state`
261261
(like in the previous option), because a new `state` is created with default values.
262262
Therefore, the call is mapped directly to an **ETS** function. E.g.:
263-
263+
264264
```erlang
265265
% create a table without set n_shards, pick_shard_fun or pick_node_fun
266266
> shards:new(mytab, []).
267267
mytab
268-
268+
269269
% call shards_local without the state
270270
> shards_local:insert(mytab, {1, 1}).
271271
true
@@ -308,42 +308,42 @@ $ rebar3 shell --sname c@localhost
308308
There are two ways to achieve this:
309309

310310
1. Manually, create the table on each node and then from any of them, join the rest.
311-
311+
312312
Create the table on each node:
313-
313+
314314
```erlang
315315
% when a tables is created with {scope, g}, the module shards_dist is used
316316
% internally by shards
317317
> shards:new(mytab, [{scope, g}]).
318318
mytab
319319
```
320-
320+
321321
Join them. From node `a`, join `b` and `c` nodes:
322-
322+
323323
```erlang
324324
> shards:join(mytab, ['b@localhost', 'c@localhost']).
325325
[a@localhost,b@localhost,c@localhost]
326326
```
327-
327+
328328
Let's check that all nodes have the same nodes running next function on each node:
329-
329+
330330
```erlang
331331
> shards:get_nodes(mytab).
332332
[a@localhost,b@localhost,c@localhost]
333333
```
334-
334+
335335
2. The easier way, call `shards:new/3` but passing the option `{nodes, Nodes}`,
336336
where `Nodes` is the list of nodes you want to join.
337-
337+
338338
From Node `a`:
339-
339+
340340
```erlang
341341
> shards:new(mytab, [{scope, g}, {nodes, ['b@localhost', 'c@localhost']}]).
342342
mytab
343343
```
344-
344+
345345
Let's check again on all nodes:
346-
346+
347347
```erlang
348348
> shards:get_nodes(mytab).
349349
[a@localhost,b@localhost,c@localhost]
@@ -406,7 +406,7 @@ And again, let's check it out from any node:
406406
407407
## Examples and/or Projects using Shards
408408
409-
* [ExShards](https://github.com/cabol/exshards) is an **Elixir** wrapper for `shards`.
409+
* [ExShards](https://github.com/cabol/ex_shards) is an **Elixir** wrapper for `shards` – with extra and nicer functions.
410410
411411
* [KVX](https://github.com/cabol/kvx) – Simple/basic **Elixir** in-memory Key/Value Store using `shards` (default adapter).
412412

src/shards_dist.erl

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
select_count/3,
3131
select_delete/3,
3232
select_reverse/3,
33-
take/3
33+
take/3,
34+
update_counter/4,
35+
update_counter/5,
36+
update_element/4
3437
]).
3538

3639
%%%===================================================================
@@ -312,6 +315,41 @@ take(Tab, Key, State) ->
312315
Reduce = fun lists:append/2,
313316
mapred(Tab, Key, Map, Reduce, State, r).
314317

318+
-spec update_counter(Tab, Key, UpdateOp, State) -> Result when
319+
Tab :: atom(),
320+
Key :: term(),
321+
UpdateOp :: term(),
322+
State :: shards_state:state(),
323+
Result :: integer().
324+
update_counter(Tab, Key, UpdateOp, State) ->
325+
PickNodeFun = shards_state:pick_node_fun(State),
326+
Node = pick_node(PickNodeFun, Key, get_nodes(Tab), w),
327+
rpc:call(Node, ?SHARDS, update_counter, [Tab, Key, UpdateOp, State]).
328+
329+
-spec update_counter(Tab, Key, UpdateOp, Default, State) -> Result when
330+
Tab :: atom(),
331+
Key :: term(),
332+
UpdateOp :: term(),
333+
Default :: tuple(),
334+
State :: shards_state:state(),
335+
Result :: integer().
336+
update_counter(Tab, Key, UpdateOp, Default, State) ->
337+
PickNodeFun = shards_state:pick_node_fun(State),
338+
Node = pick_node(PickNodeFun, Key, get_nodes(Tab), w),
339+
rpc:call(Node, ?SHARDS, update_counter, [Tab, Key, UpdateOp, Default, State]).
340+
341+
-spec update_element(Tab, Key, ElementSpec, State) -> boolean() when
342+
Tab :: atom(),
343+
Key :: term(),
344+
Pos :: pos_integer(),
345+
Value :: term(),
346+
ElementSpec :: {Pos, Value} | [{Pos, Value}],
347+
State :: shards_state:state().
348+
update_element(Tab, Key, ElementSpec, State) ->
349+
PickNodeFun = shards_state:pick_node_fun(State),
350+
Node = pick_node(PickNodeFun, Key, get_nodes(Tab), w),
351+
rpc:call(Node, ?SHARDS, update_element, [Tab, Key, ElementSpec, State]).
352+
315353
%%%===================================================================
316354
%%% Internal functions
317355
%%%===================================================================

test/dist_SUITE.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
-include_lib("mixer/include/mixer.hrl").
1717
-mixin([
1818
{test_helper, [
19-
t_basic_ops/1
19+
t_basic_ops/1,
20+
t_update_ops/1
2021
]}
2122
]).
2223

@@ -44,6 +45,7 @@ groups() ->
4445
[{dist_test_group, [sequence], [
4546
t_join_leave_ops,
4647
t_basic_ops,
48+
t_update_ops,
4749
t_match_ops,
4850
t_select_ops,
4951
t_eject_node_on_failure,

0 commit comments

Comments
 (0)