ets(3)

MODULE
ets - Built-in Term Storage

DESCRIPTION

This module acts as an interface to the Erlang built-in term storage BIFs. The module provides the ability to store very large quantities of data in an Erlang system, and to have constant access time to this data. Data is organized as a set of dynamic tables. Each table is created by a process. When the process terminates, the table is automatically destroyed. A table can store tuples. Every table has access rights set at creation.

Tables are divided into three different types, set, bag and duplicate_bag. A set table can only have one tuple associated with each key, a bag table can have multiple tuples associated with a single key whereas a duplicate_bag table can have multiple identical objects in the same table.

In the current implementation, every object insert and look-up operation results in one copy of the object.

This module merely provides insert and look-up functionality. It does not include any lock functionality, neither does it provide transaction services. Because tables are concurrently accessible from several processes, the behavior is undefined if one process is in a next/match loop collecting objects from a table, and another process writes to the table simultaneously.

If desired, locking and transactions must be implemented on top of these functions.

There is no automatic garbage collection for tables. The table is not destroyed automatically if there are no references to it from a process. The table has to be destroyed explicitly at user level. It is destroyed if the owner terminates, or with delete/1.

'$end_of_table' should not be used as a key since this atom is used to mark the end of the table when using first/next.

In general, the functions will exit with reason badarg if any argument is of the wrong format, or if the table ID is invalid.

EXPORTS

new(Name, Type)

    Creates a new table and returns a table identifier which can be used in subsequent operations. This table ID can also be sent to other processes so that a table can be shared between processes. It is completely location transparent and can be sent to processes at other nodes. Accordingly, the table identifier can be used as a location transparent store. Large amounts of data can be distributed to locations where it can be stored.

    The parameter Type is a list which defaults to [set, protected] if [] is specified. The list may contain the following atoms:

        *   set The table is a set table - one key, one object.

        *   bag The table is a bag table which can have multiple objects per key.

        *   duplicate_bag The table is a duplicate_bag table which can have multiple copies of the same object.

        *   public The table is open to both read and write operations. Any process may read or write to the table. If this option is used, the ets table can be seen as a shared memory segment which is shared by all Erlang processes.

        *   protected The owner can read and write to the table. Other processes can only read the table.

        *   private Only the owner process can read or write to the table.

        *   named_table If this option is present, the table can be accessed by name. With this option, it is possible to have globally accessible tables without passing the table identifier around.

        *   {keypos, Pos} By default, the first element of each tuple inserted in a table is the key. However, this might not always be appropriate. In particular, we do not want the first element to be the key if we want to insert Erlang records in a table. When creating a table, it is possible to specify which tuple position is the key.

insert(Tab, Object)

    Inserts Object into the table Tab. The object must be a tuple with a size equal to or greater than one. If the table was created with the keypos option, the size can also be supplied there. By default, the first element of the object is the key of the object. Returns true.

lookup(Tab, Key)

    Searches the table Tab for object(s) with the key Key and returns a list of the found object(s). Insert and look-up times in tables are constant, regardless of the size of the table.

    The following example illustrates:
    1>T=ets:new(mytab, [bag, public]).
    {6, <0.19.0>}
    2>ets:insert(T, {a, 2, xx, yy}).
    true
    3>ets:insert(T, {a, 2, {peter, pan}, 77}).
    true
    4>ets:lookup(T, a).
    [{a, 2, xx, yy}, {a, 2, {peter, pan}, 77}]
    5>ets:insert(T, {b, 123, {peter,  pan}, 77}).
    true
    6>ets:lookup(T, b).
    [{b, 123, {peter, pan}, 77}]

    If the table is of type set, the function returns either [], or a list of maximum length of one (there can be only be one object with a single key in a set).

    If the table is of type bag or duplicate_bag , a look-up returns a list of arbitrary length. It is also worthwhile to note that bag tables have the following two properties.

        *   The same object cannot occur twice in the same table (no duplicates).

        *   The time order of object insertions is preserved. If object{x, X} is inserted before object {x, Y}, the call ets:lookup(T, x) is guaranteed to return the list [{x, X}, {x, Y}], as opposed to the list [{x, Y}, {x, X}]

lookup_element(Tab, Key, Pos)

    This function looks up the pos'th element of the object in table Tab, with key Key. If no such object exists, the function exists with reason badarg. If the table is of type bag or duplicate_bag, a list of the elements is returned.

delete(Tab, Key) -> true

    Deletes object(s) with the key Key in the table Tab. Returns true, or exits with reason badarg if Tab is not a valid Table.

delete(Tab)

    Deletes the table Tab. Returns true.

update_counter(Tab, Key, Incr)

    In a table of type set, an efficient way of managing counters is to use an object {..., Key, Int} to associate a counter with Key. The function update_counter/3 destructively changes the object with key Key by adding the integer value Incr to the counter. The return value is the new value of the counter. Note that if records are stored in the table - i.e., {keypos, 2} has been specified for the table - the layout of a counter object is {record_name, Key, Int}.

    This function fails with badarg if:

        *   no object with the right key exists

        *   the object in the counter position is not an integer

        *   the table is of type duplicate_bag or bag

        *   the object in the table has the wrong arity.

first(Tab)

    Returns the 'first' Key in the table Tab. There is no apparent order among the objects in a table, but there is an internal order known only by the table itself. Returns '$end_of_table' if there is no first key (the table is empty).

next(Tab, Key)

    Returns the 'next' table key after Key. '$end_of_table' is returned if the object associated with Key is the 'last' object in the table. The function fails with badarg if there is no object with the key Key. .

slot(Tab, I)

    This is another way of traversing a table. The first slot of a table is 0 and the table can be traversed with consecutive calls to slot/2. Each call returns a list of objects. '$end_of_table' is returned when the end of the table is reached. This function fails with badarg if the I argument is out of range.

fixtable(Tab, true|false)

    This function toggles the table ability to "rehash" itself. It is primarily used by the Mnesia DBMS to implement functions which allow write operations in a table, although the table is in the process of being copied to disk or to another node.

all()

    Returns a list of all tables on this node.

match(Tab, Pattern)

    Tries to match the object(s) in table Tab with the pattern Pattern. Pattern may contain '_' , which matches any object, bound parts, and variables. Pattern variables are given the notations $0 .. $9. If successful, the result of the call is a list of variable bindings. The reason for providing a matching function is to scan large portions of a table, searching for a particular object without having to copy the entire table from the table space to the user space.

    The following interaction with the Erlang shell illustrates how to use the match/2 function:

    7>ets:match(T, {a, 2, '$1', '$2'}).
     [[{peter, pan}, 77], [xx, yy]]

    The call to match/2 returned an ordered list of the variable bindings which is the first object that matched the pattern, bound the variable $1 to {peter, pan}, and the variable $2 to 77. The second object which matched the pattern bound the variable $1 to xx, and the variable $2 to yy. The pattern '_' can be used as a wild-card. It matches everything, but it does not bind any variables.
    8>ets:match(T, {a, 2, '$1', '_'}).
     [[{peter, pan}], [xx]]

    [] is returned if no match is found.

    The first part of the objects are used as keys in the tables and a match request with the first part of the bound pattern - not a variable or an underscore - is very efficient. However, if the key part of the pattern is a variable, the entire table must be searched. The search time can be substantial if the table is very large.

    The special case where the pattern is a single variable will collect the entire table.
    9>ets:match(T, '$1').
     [[{a, 2, {peter, pan}, 77}], [{a, 2, xx, yy}],
      [{b, 123, {peter, pan}, 77}]]

match_object(Tab, Pattern)

    Tries to match the object(s) in table Tab with the pattern Pattern. Pattern may contain '_' , which matches any object, bound parts, and variables. Pattern variables are given the notations $0 .. $9. The result is a list of matching objects (i.e complete table objects). This function differs from match/2 in that it returns comlete objects and does not return any variable bindings. It is thus not very meaningful to use pattern variables, it will have exactly the same effect as using '_'.

    The following interaction with the Erlang shell illustrates how to use the match_object/2 function:

    7>ets:match(T, {a, 2, '$1', '$2'}).
     [{a, 2, peter, pan}, {a, 2, captain, hook}]

    The call to match_object/2 returned an ordered list of objects that matched the pattern,

    [] is returned if no match is found.

    The first part of the objects are used as keys in the tables and a match request with the first part of the bound pattern - not a variable or an underscore - is very efficient. However, if the key part of the pattern is a variable, the entire table must be searched. The search time can be substantial if the table is very large.

    The special case where the pattern is a single variable or '_' will collect the entire table.

match_delete(Tab, Pattern)

    Deletes object(s) which match Pattern in the table Tab. This can be especially useful in combination with bag type tables. If the first element of Pattern is a variable, the entire table must be searched. Returns true.

info(Tab)

    Returns a tagged structure which describes the table with the following tags:

        *   memory The number of words allocated to the table.

        *   owner The Pid of the owner of the table.

        *   size The number of objects inserted in the table.

        *   type Type bag, duplicate_bag or type set.

        *   protection Public, protected, or private.

        *   node The name of the node where Tab is actually stored.

        *   name The name of the table, as given to new/2.

        *   named_table true or false.

        *   keypos The position of the tuples which are the key position. The default is 1.

    info/1 returns undefined if the table does not exist.

info(Tab, Item)

    Same as above, but only for the information that is associated with Item.

tab2file(Tab, Filename)

    Dumps a table in the Erlang external term format to the file called Filename. Returns ok, or {error, Reason}. The function may crash if bad arguments are specified. The implementation of this function is not efficient.

file2tab(Filename)

    Reads a file produced by the tab2file/2 function and returns {ok, Tab} if the operation is successful, or {error, Reason} if it fails.

tab2list(Tab)

    Returns a list of all objects in the table.

i()

    Displays a list of all local ets tables on the tty.

i(Item)

    Browses an ets table on the tty. The Item argument is the identifier displayed in the left most field by the i() function.

AUTHOR
 Claes Wikstrom, Tony Rogvall -  klacke@erix.ericsson.se