Skip to content

Instantly share code, notes, and snippets.

@potatosalad
Last active January 20, 2023 20:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save potatosalad/0bb22fba2ea669a2e030e3ab34c87a02 to your computer and use it in GitHub Desktop.
Save potatosalad/0bb22fba2ea669a2e030e3ab34c87a02 to your computer and use it in GitHub Desktop.
% Setup
tab = ets:new(tab, [set, named_table, public]),
true = ets:insert(tab, {foo, 0}).
% Slow: O(N) operation
Key = foo,
Threshold = 100,
NewVal = 101,
MatchSpec = ets:fun2ms(fun({K, V})
when K =:= Key
andalso V < Threshold ->
{K, NewVal}
end),
ets:select_replace(tab, MatchSpec).
% Fast: O(log(N)) operation
Key = foo,
Threshold = 100,
NewVal = 101,
MatchSpec = [
{
{Key, '$1'},
[{'<', '$1', {const, Threshold}}],
[{{{const, Key}, {const, NewVal}}}]
}
],
ets:select_replace(tab, MatchSpec).
% In theory, variable pinning could allow generation of the "Fast" match spec:
Key = foo,
Threshold = 100,
NewVal = 101,
MatchSpec = ets:fun2ms(fun({^Key, V})
when V < Threshold ->
{Key, NewVal}
end),
ets:select_replace(tab, MatchSpec).
% Here is the O(N) match spec for comparison:
Key = foo,
Threshold = 100,
NewVal = 101,
MatchSpec = [
{
{'$1', '$2'},
[
{
'andalso',
{'=:=', '$1', {const, Key}},
{'<', '$2', {const, Threshold}}
}
],
[{{{const, Key}, {const, NewVal}}}]
}
].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment