liveBook · Manning

Key-value store

As explained in Elixir in Action, Third Edition

A key-value store is a data structure that associates each key with a corresponding value.

A key-value store associates arbitrary keys with values. In Elixir, it can serve as a compact example of process state, message passing, and callback-based design. section 2.8 section 6.1.3

A process-backed implementation typically:

  • Keeps a map as its state and handles put and get requests with separate clauses. section 6.1.3
  • Hides generic message-passing code behind start, put, and get interface functions. section 6.1.3
  • Uses GenServer for a conventional implementation, but may encounter a single-process bottleneck under concurrency. section 10.3
  • Considers ETS for shared key-value structures when performance and scalability matter, while recognizing its limited applicability. section 10.3

Basic interaction

Start the store, put :some_key with :some_value, then get the key to receive :some_value. section 6.1.3

Listing 10.7 GenServer-powered key-value store (key_value/lib/key_value.ex)
defmodule KeyValue do
 use GenServer

 def start_link do
   GenServer.start_link(__MODULE__, nil, name: __MODULE__)
 end

 def put(key, value) do
   GenServer.cast(__MODULE__, {:put, key, value})
 end

 def get(key) do
   GenServer.call(__MODULE__, {:get, key})
 end

 def init(_) do
   {:ok, %{}}
 end

 def handle_cast({:put, key, value}, store) do
   {:noreply, Map.put(store, key, value)}
 end

 def handle_call({:get, key}, _, store) do
   {:reply, Map.get(store, key), store}
 end
end

Inspect a complete GenServer-backed implementation using a map, asynchronous puts, and synchronous gets. section 10.3

How Elixir in Action, Third Edition covers it

How deep it goes
Builds implementations with maps, callbacks, wrappers, benchmarks, and concurrency observations, but does not develop a production storage system.
Examples
Uses put/get interactions, GenServer code, one-million-key load tests, and concurrent-client benchmarks.
What it assumes
Assumes Elixir maps, functions, processes, and message passing while reinforcing callbacks and interface boundaries.
What you can do after
Build it from scratch as a process-backed store and evaluate when ETS may improve shared-access performance.
How it connects
Connects maps, processes, GenServer, Agent, message passing, and ETS tables.

Also explained in

Compare how 8 books explain key-value store →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Elixir in Action, Third Edition. The section links point to the parts of the book it draws on.