Iptrie.get_and_update
You're seeing just the function
get_and_update
, go back to Iptrie module for more information.
Specs
get_and_update( t(), prefix(), (nil | {bitstring(), any()} -> {any(), any()} | :pop) ) :: {any(), t()}
Updates a key,value-pair in trie
by invoking fun
with the result of an
exact match.
The callback fun
is called with:
{bits, original_value}
if an exact match was found, ornil
, in case the searchprefix
is not present in thetrie
where bits
are the actual bits of given prefix
as retrieved from
the corresponding radix tree in given trie
.
The callback function should return:
{current_value, new_value}
, or:pop
.
When {current_value, new_value}
is returned:
- the
new_value
is stored in the trie under givenprefix
, and {current_value, trie}
is returned.
When the callback passes back :pop
:
- the
{prefix, original_value}
-pair is deleted from thetrie
, and {original_value, trie}
is returned.
If the callback passes back :pop
when its argument was nil
then {nil, trie}
is returned, where trie
is unchanged.
If something similar is required, but based on a longest prefix match, perhaps
Iptrie.update/3
or Iptrie.update/4
is better suited.
Example
iex> counter = fn {_, v} -> {v, v + 1}
...> nil -> {0, 1}
...> end
iex> ipt = new()
iex> {org, ipt} = get_and_update(ipt, "1.1.1.1", counter)
iex> org
0
iex> get(ipt, "1.1.1.1")
{"1.1.1.1", 1}
iex> {org, ipt} = get_and_update(ipt, "1.1.1.1/24", counter)
iex> org
0
iex> get(ipt, "1.1.1.0/24")
{"1.1.1.0/24", 1}
iex> {org, ipt} = get_and_update(ipt, "1.1.1.0/24", fn _ -> :pop end)
iex> org
1
iex> get(ipt, "1.1.1.0/24")
nil
# aggregate stats on a /24
iex> count = fn {_, v} -> {v, v + 1}
...> nil -> {0, 1}
...> end
iex> track = fn ip -> Pfx.new(ip) |> Pfx.keep(24) end
iex>
iex> ipt = new()
iex> {_, ipt} = get_and_update(ipt, track.("1.1.1.1"), count)
iex> {_, ipt} = get_and_update(ipt, track.({1, 1, 1, 2}), count)
iex> {_, ipt} = get_and_update(ipt, track.("acdc::/64"), count)
iex> {org, ipt} = get_and_update(ipt, track.({{1, 1, 1, 3}, 32}), count)
iex> org
2
iex> get(ipt, "1.1.1.0/24")
{"1.1.1.0/24", 3}
iex> get(ipt, "acdc::/24")
{"acdc:0:0:0:0:0:0:0/24", 1}
# note that Pfx.keep({1, 1, 1, 2}, 24) yields {1, 1, 1, 0} since its
# return value mimicks its argument and thus results in a full prefix,
# hence the need for track.(ip)