erlang ets中safe_fixtable的用法分析

原创
2021/12/23 18:19
阅读数 334

该方法主要使用在通过迭代的方式下遍历整个的ets数据

  • 如使用ets:next()或者ets:match_object方法或者ets:select方法迭代的遍历整个ets数据

作用

  • 如果出现数据的删除,可以平滑的处理这些迭代器的使用,不至于因为删除而导致的迭代报错
  • 即使设置了ets:safe_fixtable(Tab, true)也是可以在另外一个进程删除数据,并且删除也是有效的
  • 注意一旦设置了之后也要设置回ets:safe_fixtable(Tab, false)

erlang网站信息翻译

  • 删除一个正在fixed的ets对象,他是不是立刻释放内存的,直到进程释放了这个fix。并且如果加了fix操作,则table的性能会明显的变慢。
  • 可以使用info(Tab, safe_fixed_monotonic_time)来展示进程fix的table信息。如果多个进程都在fix table则需要报警,或者fix table过长时间,也需要报警。
  • 对于ordered_set类型的ets,以及一次性全部读取的数据,则没有必要加载fix table
  • 一个进程fixtable,则这个table会一直fix,直到进程主动的释放或者进程关闭。

测试点

  • 不添加safe_fixtable,在迭代ets时,添加ets数据,有时会展示在迭代中,有些事不能展示在迭代中
  • 不添加safe_fixtable,在迭代ets时,删除ets数据,回导致迭代报错
  • 不添加safe_fixtable,在迭代ets时,修改ets的原有数据,可以展示最新的数据
  • 添加safe_fixtable时,在迭代ets时,添加ets数据,有时会展示在迭代中,有些是不能展示在迭代中
  • 添加safe_fixtable时,在迭代ets时,删除ets数据,可以正常迭代完成,迭代中不会包含删除的信息
  • 添加safe_fixtable时,在迭代ets时,修改ets的原有数据,可以展示最新的数据

不加safe_fix的报错信息

测试代码

%% 当前的代码注释了safe_fixtable,则会出现迭代调用报错
%% 放开safe_fixtable之后,则迭代正常,跳过了删除的数据信息,可以正常的执行完迭代,'$end_of_table'返回
-record(map, {
    id = 0,             %% 地图编号id,每个副本唯一
    map_id = 0,         %% 基础地形图id
    map_cell = []      %% 地图标记 [#map_cell{}]
}).
test_ets_fix_up() ->

    ets:delete(ets_fix_up),

    ets:new(ets_fix_up, [{keypos, #map.id},named_table, public, set]),

    ets:insert(ets_fix_up,
        [#map{id = 1, map_id = 1111,map_cell = [111111]},
        #map{id = 2, map_id = 222,map_cell = [111111]},
        #map{id = 3, map_id = 333,map_cell = [111111]},
        #map{id = 4, map_id = 4444,map_cell = [111111]}]
    ),

    spawn(
        fun() ->
%%            ets:safe_fixtable(ets_fix_up, true),
            Key = ets:first(ets_fix_up),

            io:format("111111 key  = ~p ~n", [Key]),
            timer:sleep(3000),
            Key1 = ets:next(ets_fix_up, Key),
            io:format("22222 key1  = ~p ~n", [Key1]),
            timer:sleep(3000),

            Key2 = ets:next(ets_fix_up, Key1),
            io:format("333333 key2  = ~p ~n", [Key2]),
            timer:sleep(3000),

            Key3 = ets:next(ets_fix_up, Key2),
            io:format("444444 key3  = ~p ~n", [Key3]),
            timer:sleep(3000),

            Key4 = ets:next(ets_fix_up, Key3),
            io:format("555555 key4  = ~p ~n", [Key4]),
            timer:sleep(3000)

%%            ets:safe_fixtable(ets_fix_up, false)
        end),


    spawn(
        fun() ->
            timer:sleep(2000),
%%            ets:delete(ets_fix_up,2),

            ets:insert(ets_fix_up, #map{id = 2, map_id = 1111,map_cell = [111111]}),
            ets:insert(ets_fix_up, #map{id = 3, map_id = 1111,map_cell = [111111]}),

            io:format("spawn2 = del= ~p ~n", [2]),
%%            ets:delete(ets_fix_up,3),
            io:format("spawn2 6s del = ~p ~n", [3])

        end),

    ok.
展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部
返回顶部
顶部