erlang - 从 ets 表中删除日期戳早于 10 秒的所有记录

标签 erlang elixir data-cleaning ets cache-expiration

我在 elixir 应用程序中有一个 ets 集合表。我需要清理 updated_at 字段超过 10 秒的记录。有没有一种方法可以设置过期或手动设置而不遍历所有记录?我根据大于给定时间的时间戳匹配记录。

示例记录:

key: key_1
record: %{id: key_1, updated_at: ~N[2018-12-19 10:08:47.803075]}

到目前为止我有这段代码

def clean_stale(previous_key) do
  if previous_key == :"$end_of_table" do
    :ok
  else
    device = get(previous_key)
    next_key = :ets.next(__MODULE__, previous_key)
    if NaiveDateTime.diff(NaiveDateTime.utc_now, device.last_recorded_at) > 10 do
      remove(device.id)
    end
    clean_stale(next_key)
  end
end

最佳答案

如果您将“更新时间”存储为整数而不是 NaiveDateTime结构,您可以使用匹配规范。

例如,获取当前时间作为自 Unix 纪元以来的秒数:

> DateTime.to_unix(DateTime.utc_now())
1545215338

你可以这样做:

iex(3)> :ets.new(:foo, [:public, :named_table])
:foo
iex(4)> :ets.insert(:foo, {:key1, DateTime.to_unix(DateTime.utc_now())})
true
iex(5)> :ets.insert(:foo, {:key2, DateTime.to_unix(DateTime.utc_now())})
true
iex(6)> :ets.tab2list(:foo)
[key2: 1545215144, key1: 1545215140]
iex(7)> :ets.select_delete(:foo, [{{:_, :"$1"}, [{:<, :"$1", 1545215144}], [true]}])
1
iex(8)> :ets.tab2list(:foo)
[key2: 1545215144]

在调用 ets:select_delete/2 时, 我通过一个 match specification .它由三部分组成:

  • {:_, :"$1"} ,我对表中的记录执行匹配。在这个例子中,我有一个包含两个元素的元组。我忽略了带有 :_ 的键, 并将时间戳分配给具有 :"$1" 的匹配变量.
  • [{:<, :"$1", 1545215144}] ,我指定我只想匹配时间戳在这个时间之前的记录。在您的情况下,您将计算过去十秒的时间并将该值放在这里。
  • [true] ,我指定我要返回 true用于匹配记录,在 select_delete 的情况下意思是“删除这条记录”。

所以在调用select_delete之后, 只有第二条记录保留在表中。


如果时间戳在 map 内部,您可以使用 map_get访问它并比较它:

:ets.select_delete(:foo, [{{:_, :"$1"},
                           [{:<, {:map_get, :updated_at, :"$1"}, 1545215339}],
                           [true]}])

或者(在 Erlang/OTP 18.0 及更高版本中)匹配映射值:

:ets.select_delete(:foo, [{{:_, #{updated_at: :"$1"}},
                           [{:<, :"$1", 1545215339}],
                           [true]}])

关于erlang - 从 ets 表中删除日期戳早于 10 秒的所有记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53848991/

相关文章:

database - 从 mnesia 中选择随机记录

erlang - 如何使用非 gen_servers 的工作人员运行主管?

erlang - 获取有效 system_info 原子的完整列表

python - Pandas:在列值中查找空格+不常用字符的最快方法是什么?

python - 获取干净数据: Beautiful Soup is enough or I must use Regex as well?

erlang - 用于为Erlang系统建模的工具

elixir - 如何在 phoenix/elixir 中启用 Elm 0.18 的调试标志

macros - 使用模块注释作为方法属性

elixir - 预加载关联和分页

r - 如何在具有大量 NA 的时间序列数据框中找到值最多的区间?