data-structureserlangets

What are the differences between different ETS table types?


According to the manual there are 4 types of ETS tables:

  • set – The table is a set table: one key, one object, no order among objects. This is the default table type.
  • ordered_set – The table is a ordered_set table: one key, one object, ordered in Erlang term order, which is the order implied by the < and > operators. Tables of this type have a somewhat different behavior in some situations than tables of other types. Most notably, the ordered_set tables regard keys as equal when they compare equal, not only when they match. This means that to an ordered_set table, integer() 1 and float() 1.0 are regarded as equal. This also means that the key used to lookup an element not necessarily matches the key in the returned elements, if float()'s and integer()'s are mixed in keys of a table.
  • bag – The table is a bag table, which can have many objects, but only one instance of each object, per key.
  • duplicate_bag – The table is a duplicate_bag table, which can have many objects, including multiple copies of the same object, per key.

Though I don't really understand the differences between them from their descriptions. What are "objects" and "instances of objects" here?


Solution

  • set

    It is a regular mapping where each key is unique and refers to a single tuple. Each subsequent write to a single key will always overwrite the existing entry under that key.

    1> T = ets:new(t, [set]).
    2> ets:insert(T, {1, a}).
    3> ets:insert(T, {1, b}).
    3> ets:insert(T, {1, b}).
    4> ets:insert(T, {1.0, c}).
    5> ets:lookup(T, 1).
    [{1,b}]
    

    ordered_set

    Just like set, but keeps the elements ordered by standard comparison operators and solves equality by the == operator. Therefore keys 1 and 1.0 are treated as equivalent.

    1> T = ets:new(t, [set]).
    2> ets:insert(T, {1, a}).
    3> ets:insert(T, {1, b}).
    3> ets:insert(T, {1, b}).
    4> ets:insert(T, {1.0, c}).
    5> ets:lookup(T, 1).
    [{1.0,c}]
    

    bag

    It is a unique collection of tuples. Entries can share keys as long as they differ somewhere in the values.

    1> T = ets:new(t, [bag]).
    2> ets:insert(T, {1, a}).
    3> ets:insert(T, {1, b}).
    4> ets:insert(T, {1, b}).
    4> ets:insert(T, {1.0, c}).
    5> ets:lookup(T, 1).
    [{1,a},{1,b}]
    

    duplicate_bag

    Same as bag, but not unique. Tuples can duplicate meaning that each subsequent addition of a same element will add new entry into the table

    1> T = ets:new(t, [duplicate_bag]).
    2> ets:insert(T, {1, a}).
    3> ets:insert(T, {1, b}).
    4> ets:insert(T, {1, b}).
    4> ets:insert(T, {1.0, c}).
    5> ets:lookup(T, 1).
    [{1,a},{1,b},{1,b}]