其他分享
首页 > 其他分享> > erlang初涉及7_ETSDETS用法

erlang初涉及7_ETSDETS用法

作者:互联网

erlang初涉及7_ETS/DETS用法

ets、dets是两个系统模块,在erlang中可以高效存储海量数据。ETS的缩写是Erlang Term Storage(Erlang数据存储)的缩写,DETS则是Disk ETS(磁盘ETS)的缩写。今天我们来了解ETS和DETS的用法。

表的四种类型

保存的是元组,元组里的某一个元素(默认是第一个)被称为该表的键.通过键可以向表里插入和提取元组.分为四个基本的表类型

对表的几个基本操作

创建一个表

ets:new(Name,[Opt]) -> TableId : Name是一个原子,[Opt]是一列选项分为:

下面我们来看一个例子

est_test.erl

-module(ets_test).
-export([start/0]).
 
start()->
    lists:foreach(fun test_ets/1,[set,ordered_set,bag,duplicate_bag]).
test_ets(Mode)->
    TableId=ets:new(test,[Mode]),
    ets:insert(TableId,{a,1}),
    ets:insert(TableId,{b,2}),
    ets:insert(TableId,{a,1}),
    ets:insert(TableId,{a,3}),
    List=ets:tab2list(TableId),
    io:format("~-13w => ~p~n",[Mode,List]),
    %这里是格式化输出
    ets:delete(TableId).

输出运行

1>ets_test:start().
set           => [{b,2},{a,3}]
ordered_set   => [{a,3},{b,2}]
bag           => [{b,2},{a,1},{a,3}]
duplicate_bag => [{b,2},{a,1},{a,1},{a,3}]

这里我们就可以直观的发现几种类型的表有什么区别

DETS(简单涉及)

如果在打开DETS文件后没有关闭, 则Erlang将自动进行修复, 而修复可能会耗费大量的时间, 因此应在使用完后关闭DETS文件。
打开一个DETS表时, 要给出一个全局性的名字, 以便于多个进程用相同的名字和属性来共享这个表。

来个例子看看

lib_filenames_dets.erl

-module(lib_filenames_dets).
-export([open/1, close/0, test/0, filename2index/1, index2filename/1]).

open(File) ->
    io:format("dets opened:~p~n", [File]),
    Bool = filelib:is_file(File),
    %% 使用?MODULE宏获取文件名作为TableName
    case dets:open_file(?MODULE, [{file, File}]) of
        {ok, ?MODULE} ->
            case Bool of
                true  ->void;
                %% 插入键为free, 值为1的记录, 用于统计表中记录的总数
                false ->ok = dets:insert(?MODULE, {free, 1})
            end,
            true;
        {error, _Reason} ->
            io:format("cannot open dets table~n"),
            exit(eDetsOpen)
    end.

close() ->dets:close(?MODULE).

%% 将二进制格式的文件名插入到dets表
filename2index(FileName) when is_binary(FileName) ->
    %% 插入前先查询文件名是否已经存在
    case dets:lookup(?MODULE, FileName) of
        [] ->
            %% 不存在则先查询最大索引, 然后将索引-文件名, 文件名-索引, free-最大索引插入到dets表
            [{_, Free}] = dets:lookup(?MODULE, free),
            ok = dets:insert(?MODULE, [{Free, FileName}, {FileName, Free}, {free, Free+1}]), 
            Free;
        %% 存在则直接返回索引值
        [{_, N}] ->N
    end.

%% 根据索引值查询文件名
index2filename(Index) when is_integer(Index) ->
    case dets:lookup(?MODULE, Index) of
        []         ->error;
        [{_, Bin}] ->Bin
    end.

test() ->   
    %% 每次测试都重建dets表
    file:delete("./filenames.dets"),
    open("./filenames.dets"),
    %% 使用正则查找当前目录下的所有erl文件添加到dets表中
    F = lib_files_find:files(".", ".*[.](erl).*$", true),
    lists:foreach(fun(I) ->filename2index(list_to_binary(I)) end, F).

运行结果

1> c(lib_filenames_dets).
{ok,lib_filenames_dets}
2> lib_filenames_dets:test().
dets opened:"./filenames.dets"
ok
3> lib_filenames_dets:index2filename(1).
<<"./lib_trigrams.erl">>
4> lib_filenames_dets:index2filename(2).
<<"./lib_files_find.erl">>
5> lib_filenames_dets:index2filename(3).
<<"./lib_filenames_dets.erl">>
6> lib_filenames_dets:index2filename(4).
<<"./ets_test.erl">>
7> lib_filenames_dets:filename2index(list_to_binary("./ets_test.erl")).

标签:ets,ETSDETS,lib,元组,TableId,用法,filenames,dets,erlang
来源: https://blog.csdn.net/weixin_43876186/article/details/111094070