Background
I have an ets table that has, for each key, a list of items. ETS tables have O(1) complexity when using :ets.lookup
, as we all know and they are super fast, but for my specific use case, I need to ask to the ets table for more than 1 key at a time.
This means I have 2 options:
- Perform multiple
lookups
- Perform a match or select on the keys
Multiple lookups
I don’t really like this approach because it would mean my operation is not atomic. This is a big no no.
Match or Select on keys
This is my preferred approach since I want the operation to be as efficient as possible. I am also not going to look for patterns in keys, I am simply going to look directly for keys that match my spec, so it should be fast.
I do have several questions about match and select though (see Questions section)
Issue
The problem here is that I don’t know how to use :ets.match
or it’s select
variant correctly. This is an example:
iex(27)> table = :ets.new(:table, [:public])
#Reference<0.830523521.2311716867.20185>
iex(28)> :ets.insert(table, {:a, [{:banana, :orange, 10}, {:tomato, :potato, 6}]})
true
iex(29)> :ets.insert(table, {:b, [{:car, :moto, 1}, {:plane, :heli, 60}]})
true
iex(30)> :ets.tab2list(table)
[
b: [{:car, :moto, 1}, {:plane, :heli, 60}],
a: [{:banana, :orange, 10}, {:tomato, :potato, 6}]
]
ex(32)> :ets.match(table, [:a, :b]) # I want to get the values from both keys :a :b
[]
Questions
- What am I doing wrong?
- How do I optimize my match queries so they are atomic? From the docs:
Traversals using match and select functions may not need to scan the entire table depending on how the key is specified. A match pattern with a fully bound key (without any match variables) will optimize the operation to a single key lookup without any table traversal at all.
- The data on my table will never change. Does it matter if I make the table an
ordered_set
or are the gains for match and select not worth it?