Experimenting with ETS in an IEx window

Let's begin by messing around a little bit with ETS inside of an IEx window. We can go to our application directory and run a new IEx session with iex -S mix:

$ iex -S mix
Erlang/OTP 20 [erts-9.1.5] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

We'll start this off simply enough. We'll create a table that can store a little bit of information in a set. Again, we can store any data structure that Elixir can understand, so this can actually be really handy! We can create a table with the :ets.new(table_name, [:type])command . This will return a table reference to us that we can use elsewhere to insert and fetch information. We can then use that same variable to insert data via :ets.insert(table_reference, {:key, value}). If we want to look up information, we can do it via the :ets.lookup(table_reference, :key) call! Let's see what this looks like in action:

iex(1)> table = :ets.new(:test_data, [:set])
#Reference<0.1390637660.3349544961.156677>
iex(2)> :ets.insert(table, {:key1, "value"})
true
iex(3)> :ets.lookup(table, :key1)
[key1: "value"]
iex(4)> :ets.insert(table, {:key2, %{username: "test"}})
true
iex(5)> :ets.lookup(table, :key2)
[key2: %{username: "test"}]

Let's explore some more of the options available to us to create tables. The first option that we saw is the type of the table, which can be any of the following:

  • :set: This is the default type for tables; you are allowed to enter in one value per key, and all keys must be unique (much like a regular set)
  • :ordered_set: Similar to :set, but the set itself is ordered by the keys
  • :bag: You can have multiple items per key, but the items have to be unique (per key)
  • :duplicate_bag: Similar to a regular bag, but the items do not have to be unique anymore

You can also control who else (that is, which another process) is allowed to access the information in these tables. The three options available to you are as follows:

  • public: Any process can read or write information from these
  • protected: The default choice; only writable by the owner process, but any process can read information
  • private: Read and write are limited solely to the process that owns the tables

Finally, there's another option available to us called :named_table. This allows us to reference a table by using an atom instead of relying on storing a variable that we can use to grab the information. Let's take a look at using that to access ETS tables instead of holding on to a variable:

iex(6)> :ets.new(:test, [:bag, :named_table])
:test
iex(7)> :ets.insert(:test, {:user1, "Brandon"})
true
iex(8)> :ets.insert(:test, {:user1, "Richey"})
true
iex(9)> :ets.lookup(:test, :user1)
[user1: "Brandon", user1: "Richey"]

Here, you can see that we used the :bag table type, so we can store lots of different information in our bag, but no duplicates. If we try, nothing will happen:

iex(10)> :ets.insert(:test, {:user1, "Brandon"})
true
iex(11)> :ets.lookup(:test, :user1)
[user1: "Brandon", user1: "Richey"]

No error message, but nothing else either, so that's fine! Another thing we can do is delete entries in the tables using :ets.delete(table, key):

iex(12)> :ets.delete(:test, :user1)
true

It's worth noting that a lot of the returns for functionality coming out of ETS tend to be a little stranger and more difficult to deal with than the standard returns that you see in a lot of standard Elixir libraries. There's less reliance on the {:ok, result} pattern, so it can admittedly sometimes be a little frustrating when trying to grab data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset