[erlang-questions] update_counter on steroids

Ulf Wiger ulf@REDACTED
Sun May 11 13:52:10 CEST 2014


Hi Anthony,

That’s certainly a function that many erlangers have had to implement over and over. :)

And of course, having to write it in Erlang by combining several operation into a non-atomic function introduces some problems of its own.

BR,
Ulf W

On 11 May 2014, at 13:12, Anthony Ramine <n.oxyde@REDACTED> wrote:

> Hello Ulf,
> 
> Not what you asked for, but I implemented ets:update_counter/4 which takes a default value yesterday:
> 
> 	ets:new(counters, [set,named_table]),
> 	1 = ets:update_counter(counters, c1, 1, {c1,1}),
> 	3 = ets:update_counter(counters, c1, 2, {c1,1}),
> 	[{c1,3}] = ets:tab2list(counters).
> 
> Regards,
> 
> 	https://github.com/erlang/otp/pull/362
> 
> -- 
> Anthony Ramine
> 
> Le 7 août 2013 à 13:39, Ulf Wiger <ulf@REDACTED> a écrit :
> 
>> 
>> There was some discussion recently on teaching update_counter some new tricks.
>> 
>> Here is a suggestion:
>> 
>> Right now, the function takes (Tab, Key, UpOp | [UpOp]), where
>> UpOp ::== {Pos, Incr} | {Pos, Incr, Threshold, WrapTo}
>> 
>> I'd like to save the result of an operation in a temporary variable.
>> 
>> An atomic reset, for example. (let's say counter c1 has the value 17):
>> 
>> ets:update_counter(counters, c1, [{2, 0, '$1'}, {2, {'-', '$1'}}]) ->
>> [17, 0]
>> 
>> (Increment by 0 means we read the existing value, just like today).
>> 
>> Why use this instead of simply ets:insert/2? Well, for one thing, we get the old value back, so it's an atomic read-reset.
>> 
>> Sum counter:
>> 
>> ets:update_counter(counters, c2, [{2,0,'$1'}, {3,0,'$2'}, {4, {'+', '$1', '$2'}}])
>> 
>> Wrap with parameterized threshold and reset value:
>> 
>> ets:update_counter(counters, c3, [{3,0,'$1'}, {4,0,'$2'}, {2, Incr, '$1', '$2'}])
>> 
>> This assumes the following changes:
>> 
>> - A number of temp variables, like in match specs.
>> - A 3-tuple  {Pos, Incr, SaveTo}, where SaveTo is a variable name (e.g. '$1')
>> - A 5-tuple  {Pos, Incr, Threshold, WrapTo, SaveTo}
>> - The possibility to use, wherever an integer() is expected
>> VariableName | {UnaryOp, VariableName} | {BinaryOp, Var1, Var2}
>> 
>> We could also use this to e.g. store a value together with an increment operation. A reset with timestamp:
>> 
>> TS = timestamp(),  % in milliseconds
>> ets:update_counter(counters, c4, [{2, 0, '$1'}, {2, {'-', '$1'}, {3, 0, '$2'}, {3, {'-', TS, '$2'}}])
>> 
>> …a bit bizarre perhaps, but still.
>> 
>> Comments?
>> 
>> BR,
>> Ulf W
>> 
>> 
>> Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
>> http://feuerlabs.com
>> 
>> 
>> 
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
> 

Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
http://feuerlabs.com






More information about the erlang-questions mailing list