[elixir! #0032] 在 elixir 中使用 ets (2) —- 匹配查詢

LJZN發表於2019-02-16

上次我們介紹了 ets 表的基本配置方法, 這次我們將通過 phoenix pubsub 的原始碼來了解 ets 中的一些其他操作方法.

新建 ets 表

    ^local = :ets.new(local, [:duplicate_bag, :named_table, :public,
                              read_concurrency: true, write_concurrency: true])
    ^gc = :ets.new(gc, [:duplicate_bag, :named_table, :public,
                        read_concurrency: true, write_concurrency: true])

這裡 ets 表中元素允許重複的 bag, 同時允許併發讀寫, 最大限度提升效能.

插入新資料

    true = :ets.insert(gc, {pid, topic})
    true = :ets.insert(local, {topic, {pid, opts[:fastlane]}})

新的資料以 {key, value} 的形式插入.

匹配並刪除

    true = :ets.match_delete(gc, {pid, topic})
    true = :ets.match_delete(local, {topic, {pid, :_}})

匹配 ets 表中的資料, 允許使用 :_ 作為萬用字元.

查詢某個 key 對應的 bag 中的某個位置的元素

      shard
      |> local_for_shard(pubsub_server)
      |> :ets.lookup_element(topic, 2)

因為是 duplicate_bag, 所以會檢索 key 對應的每個 bag, 並返回一個列表, 包含每個 bag 中的第二個元素(位置從 1 開始). 如果 key 不存在, 則會報 :badarg 的錯誤.

匹配並返回特定的元素的列表

    shard
    |> local_for_shard(pubsub_server)
    |> :ets.select([{{:`$1`, :_}, [], [:`$1`]}])
    |> Enum.uniq

這與 lookup_element 類似, 不同的是這不需要提供確切的 key, 而是通過模式匹配來篩選. 例如返回 ets 表中的所有 key.

相關文章