Store a list in Erlang ETS

1.4k views Asked by At

I am trying to insert a list into ETS to pull out later and for some reason it is saying it is a bad arg. I'm not sure if I'm inserting it incorrectly.

Is it just not possible to insert a list into ETS?

The offending line is ets:insert(table, [{parsed_file, UUIDs}]).

Here is the code:

readUUID(Id, Props) ->
    fun () -> 
        %%TableBool = proplists:get_value(table_bool, Props, <<"">>),
        [{_, Parsed}] = ets:lookup(table, parsed_bool),
        case Parsed of
          true  ->
            {uuids, UUIDs} = ets:lookup(table, parsed_bool),
            Index = random:uniform(length(UUIDs)),
            list_to_binary(lists:nth(Index, UUIDs));
          false -> 
            [{_, Dir}] = ets:lookup(table, config_dir),
            File = proplists:get_value(uuid_file, Props, <<"">>),
            UUIDs = parse_file(filename:join([Dir, "config", File])),
            ets:insert(table, [{parsed_file, {uuids, UUIDs}}]),
            ets:insert(table, [{parsed_bool, true}]),
            Index = random:uniform(length(UUIDs)),
            list_to_binary(lists:nth(Index, UUIDs))
        end
    end.

parse_file(File) ->
  {ok, Data} = file:read_file(File),
  parse(Data, []).

parse([], Done) ->
  lists:reverse(Done);

parse(Data, Done) ->
  {Line, Rest} = case re:split(Data, "\n", [{return, list}, {parts, 2}]) of
                   [L,R] -> {L,R};
                   [L]   -> {L,[]}
                 end,
  parse(Rest, [Line|Done]).
2

There are 2 answers

0
Derek Brown On BEST ANSWER

If you create the table in the same proc with something like

ets:new(table, [set, named_table, public]).

then you should be ok. Default permissions are protected, where only creating process can write.

0
rvirding On

As a follow on to my comment about ets tables only containing tuples and what ets:lookup/2 returns the following line in your code:

        {uuids, UUIDs} = ets:lookup(table, parsed_bool),

WILL ALWAYS GENERATE AN ERROR as ets:lookup/2 returns a list. The call 3 lines above may succeed. It seems like you are trying to do 2 lookups in table with key parsed_bool and expect to get 2 different types of answers: {_, Parsed} and {uuids, UUIDs}. Remember that ETS does not provide key-value tables but tables of tuples where one of the elements, default the first, is the key and doing ets:lookup/2 returns a list of the tuples with that key. How many you can get back depends on the properties of the table.

Check out the documentation of ETS tables.