Using an in Memory Map across Modules

Novice in Elixir coming from C#/C++ programming, hope you can assist.

The type of programming I’m doing relies on objects being stored in memory. For instance I need a lookup map which is loaded from a file.

Other modules will then access this lookup with something like:

my_value = lookup_module.lookup_table[key]

Analogous to a class.value in OO programming.

Well at least that is the thinking, but I have been unable to get this working in Elixir.

Can you please advise the best practice on how one would implement such an architecture in Elixir?

Well, maps as created by %{} are exactly that… They are maps in memory. So you can create them and pass them around, accessing is easy as map_variable[key].

Or you can store it in ETS which might be more optimized than passing around a map if you use a lot of processes and want to avoid copying the full map around or if you need mutability. You need to use functions from :ets to access and build it. It is common to wrap those into an own module.

Or you can use persistent terms if you need access from multiple processes but do not need writes (that often), similar to ETS, you need to use functions :persistent_term for access but its common to wrap them.

What is not possible though, is having some syntax like you propose, as we do not have static variables in a module. Modules only provide functions.

You could mimik your syntax by creating a function which loads the full map from ETS or PS or disk again and returns it, but that would be inefficient, as you’d always need to fully copy the map into your current process for a single key you access.

Elixir is not C#, Elixir is not even class oriented, nor is it mutable, nor does it run on the CLR. There are just things you can’t do due to either different syntax or because of different internals of the VM or because of other things.

3 Likes

Thx, I will investigate the proposed options. Yes, quite a learning curve getting my brain around the Elixir way of doing things. :grinning:

Lookup maps of decent size that change rarely/never has a great alternative here: https://github.com/discordapp/fastglobal

1 Like

Is fastglobal still relevant when you have persistent_term/atomics/etc in Erlang? (Assuming you’re on recent OTP.) Does it do something different?

5 Likes

Thx will lookup.

The Agent process is also a viable option. https://hexdocs.pm/elixir/Agent.html

1 Like

Thx will investigate.

If it’s a map that is loaded once and done then persistent_term’ing it might be useful, but honestly I’d just use ETS. It’s already cross process, has multiple ways to look up info, etc…

1 Like

If it makes sense for the data you’re loading from a file, and if you have it available at compile time, you could compile your lookup module with the data already in it, so you could call LookupModule.lookup("my_table", "my_key"), and your module would have generated something like def lookup("my_table", "my_key"), do: "my_data"

1 Like

That is literally what fastglobal does.

Also :persistent_term.