Hey,
I need help to find a scalable and efficient solution to:
- Store large number of elements (username)
- Table is not static => element gets removed from the table when process is demonitored
- Being able to return random elements efficiently
The context is that I’m storing some users based on criterias in different ETS tables and wants to be able to return those in my UI as part of a search.
First thing:
I’m dealing with username as keys, and at the same time, I think the easiest way to get random elements from an ETS table is to use sequential number as keys
i.e
:ets.lookup(tab, Enum.random(1..1000))
So I though about using 3 ETS tables:
- The first to store the username with corresponding index “usernames”
- The second to store all the user indexes “user_indexes”
- the last one to increment the total count of user added to get the next index “count”
Add user scenario
- Get the next index from “count”
- Add a new index in “user_indexes”
- Add corresponding username in “usernames” with that index
- Monitor the process
That’s my initial idea but the problem is that when users gets removed from the table, the indexes are not sequential anymore ({1..4,..6..400..})
In that situation the lookup function I use to get random elements would not return the expected results
:ets.lookup(tab, Enum.random(1..200))
There’s an other solution which is to work directly on the username keys
first = :ets.first(tab)
:ets.lookup(tab, first)
func = fn key->
if function_that_may_return_true() do
key = case :ets.next(tab, key) do
:'$end_of_table' -> throw :reached_end_of_table
key -> func.(key)
end
else
:ets.lookup(tab, key)
end
end
Though that solution is not efficient for large tables.
At this point I’m not sure what I could do ?
Cheers




















