Is ets:insert/2 (with multiple objects) isolated with respect to concurrent readers?
Chris Newcombe
chris.newcombe@REDACTED
Tue Jun 30 20:23:36 CEST 2009
Please could the isolation behavior be officially documented for
ets:insert, ets:insert_new, and ets:delete_all_objects?
I'd like to insert multiple items into an ETS table with both
atomicity and isolation.
i.e. I don't want concurrent readers to observe in-progress writes in
which some but not all of the objects have been inserted.
The ETS man pages don't explicitly say that either ets:insert/2 or
ets:insert_new/2 are isolated in this regard.
delete_all_objects(Tab) is documented as "The deletion is atomic."
But the unqualified word "atomic" doesn't necessarily imply isolation.
e.g. It could reasonably mean that the delete operation has
run-to-completion-without-errors semantics, without saying anything
about whether concurrent readers are able to observe intermediate
states during the deletion.
Slide #40 of Ulf's recent presentation on multicore (
http://ulf.wiger.net/weblog/wp-content/uploads/2009/01/damp09-erlang-multicore.pdf
)
says that "ets:insert(Objects) is atomic". But that property doesn't
seem to be documented in the ETS man-pages (see below) -- and it again
"atomic" doesn't necessarily imply isolation anyway..
Ulf's code on that slide suggests he was actually talking about
insert_new. The documentation for insert_new does say that all of the
collision-tests are done before anything is inserted, so it is atomic
with respect to the behavior of that particular insert_new operation
(all items will be inserted or none will, and conflicting writes are
prevented). But it doesn't actually say that while the items are
being inserted, concurrent readers cannot observe intermediate states
(subsets of the new rows).
If necessary I will work around the issue with ets:replace trick. But
as that has it's own messy issues (see
http://erlang.org/pipermail/erlang-questions/2007-April/025866.html ),
I'd really like to avoid it if possible.
many thanks,
Chris
>From R13B01 man page:
insert(Tab, ObjectOrObjects) -> true
Types:
Tab = tid() | atom()
ObjectOrObjects = tuple() | [tuple()]
Inserts the object or all of the objects in the list ObjectOrObjects
into the table Tab. If the table is a set and the key of the inserted
objects matches the key of any object in the table, the old object
will be replaced. If the table is an ordered_set and the key of the
inserted object compares equal to the key of any object in the table,
the old object is also replaced. If the list contains more than one
object with matching keys and the table is a set, one will be
inserted, which one is not defined. The same thing holds for
ordered_set, but will also happen if the keys compare equal.
insert_new(Tab, ObjectOrObjects) -> bool()
Types:
Tab = tid() | atom()
ObjectOrObjects = tuple() | [tuple()]
This function works exactly like insert/2, with the exception that
instead of overwriting objects with the same key (in the case of set
or ordered_set) or adding more objects with keys already existing in
the table (in the case of bag and duplicate_bag), it simply returns
false. If ObjectOrObjects is a list, the function checks every key
prior to inserting anything. Nothing will be inserted if not all keys
present in the list are absent from the table.
More information about the erlang-questions
mailing list