LoginSignup
19
6

More than 1 year has passed since last update.

はじめに

みなさんErlang Term Storage(ETS)を使ってますか?
依存関係なしでElixirから利用できるので便利ですよね。

確かにETSの関数はちょっとクセがあるので使いにくい面もあります。
そこでElixirのMap風のインターフェイスでETSを使えるようにしたらもっと気軽にできるのではと思い、取り組んでみました。

ETSとは

気軽にETSを使う

  • 最低限これだけあれば気軽にETSを使えます。
  • あらかじめ名前付きのETSテーブルを作れるようにしておきます。
  • 値の挿入と取得もモジュール経由ででき便利です。

自前のETSモジュールを作る

defmodule MyEts do
  def init, do: :ets.new(__MODULE__, [:set, :named_table])

  def get(key, default \\ nil) do
    case :ets.lookup(__MODULE__, key) do
      [] -> default
      [{_, value} | _] -> value
    end
  end

  def put(key, value), do: :ets.insert(__MODULE__, [{key, value}])

  def delete(key), do: :ets.delete(__MODULE__, key)
end

テーブルを作る

MyEts.init()

テーブルに値を挿入

MyEts.put(:feeling, "awesome")

テーブルから値を取得

MyEts.get(:feeling)

テーブルから値を削除

MyEts.delete(:feeling)

その他の関数

db = :ets.new(:example_db, [:set, :named_table])
for i <- 0..9, do: :ets.insert(db, [{i, i**2}])

# キーの範囲を指定して複数の値を取得
match_spec = :ets.fun2ms(fn { key, value } when key in 3..5 -> value end)
:ets.select(db, match_spec)

Match Spec

  • Match Specと呼ばれるErlang独自のクエリ言語で検索できる仕組みがあります。
  • Match Specは自力で書いてもいいのですが、:ets.fun2ms/1関数(もしくはex2msというHexパッケージが提供するEx2ms.fun/1マクロ)が便利です。
  • ややこしいですが、慣れると楽しめそうです。

Erlang:ets.fun2ms/1Elixirで使うとたまに謎のコンパイル関連エラーが出て怖いのでElixir用のex2msパッケージを使うと無難そうです。

# :ets.fun2ms(fn { key, value } when key in 3..5 -> value end)
[
  {{:"$1", :"$2"},
   [
     {:andalso, {:is_integer, :"$1"},
      {:andalso, {:>=, :"$1", 3}, {:"=<", :"$1", 5}}}
   ], [:"$2"]}
]

一例としてex_ratedというHexパッケージでは、ある条件で古いデータを消去する目的でMatch Specを使ってます。

エラー

  • Erlang特有のわかりにくいエラーメッセージが出ることがあります。
# 2回同じ名前のテーブルを生成した場合に出るエラー
iex> :ets.new(:example_table, [:set, :named_table])
:example_table

iex> :ets.new(:example_table, [:set, :named_table])
** (ArgumentError) errors were found at the given arguments:

  * 2nd argument: invalid options

    (stdlib 4.0.1) :ets.new(:example_table, [:set, :named_table])
    iex:2: (file)

DETS

  • ETSがインメモリのデータストレージであるのに対して、DETSはディスクベースのストレージです。
  • 関数はETSと似ています。
  • ディスクベースなのでデータベースファイルを開いて、使用後に閉じる必要があります。

@zacky1972先生のvarious_map

さらに@zacky1972先生がさまざまなMapの実装をされています。

さいごに

Elixirを楽しみましょう!

各コミュニティの詳細は、「Elixirコミュニティの歩き方 -国内オンライン編-」をご覧ください

image.png

image.png

各種Elixirイベントの開催予定は、「Elixirイベントカレンダー」から確認/参加できます :calendar:

image.png

ご参考までに

19
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
6