Copyright © 2023, Fred Youhanaie
Authors: Fred Youhanaie (fyrlang@anydata.co.uk).
Low level access functions for the tuple space.
These are the functions that directly access the espace
tables. They replace the original gen_server
based access
methods.
espace
modules.
add_pattern/4* | add a pattern for a waiting client. |
add_tuple/2 | add a Tuple to the tuple space. |
check_match/5* | Search for a pattern and return the matching tuple. |
check_tuple/3* | Check Tuple against the patterns currently being waited for
by in or rd clients. |
check_waitlist/2* | Start the scan of the table of clients waiting for Tuple . |
get_tuple/3 | perform a data input operation. |
add_pattern(Inst_name::atom(), Cli_ref::reference(), Pattern::tuple(), Cli_pid::pid()) -> true
add a pattern for a waiting client.
For each blocking client, we keep a unique reference, the pattern being blocked on, and the client pid.add_tuple(Inst_name::atom(), Tuple::tuple()) -> done
add a Tuple
to the tuple space.
This function implements the out
operation. It is also called at
the end of an eval
operation.
Tuple
is added to the tuple space, the patterns table is
searched for any clients waiting for such a tuple. The search is
performed in a separate concurrent process, so that the calling
client process can continue with its own tasks.
check_match(Inst_name::atom(), Espace_op::in | rd | inp | rdp, Pattern::tuple(), Tab_id::ets:tid(), X5::'$end_of_table' | term()) -> {nomatch} | {nomatch, reference()} | {match, {list(), tuple()}}
Search for a pattern and return the matching tuple.
We first look for a match and if a match is found, we get the
entire record. Since multiple processes may be actively looking for
the same tuple, we make sure that the same tuple cannot be taken
(in
or inp
) by more than one process.
nomatch
, depending on the type of the operation.
check_tuple(Tuple::tuple(), Tab_id::ets:tid(), Key::'$end_of_table' | integer()) -> done
Check Tuple
against the patterns currently being waited for
by in
or rd
clients.
The whole patterns (tspatt
) table is scanned sequentially. As
matching patterns are found, the corresponding client is notified
to retry the in
or rd
operation.
It is possible that more than one process may be scanning for the
same target pattern. However, only one of them will notify the
client, which will be the first process to successfully take
the
ETS record from the patterns table.
Each record in the table is accessed 2-3 times:
first/next
scan.check_waitlist(Inst_name::atom(), Tuple::tuple()) -> done
Start the scan of the table of clients waiting for Tuple
.
get_tuple(Inst_name::atom(), Espace_op::in | rd | inp | rdp, Pattern::tuple()) -> {nomatch} | {nomatch, reference()} | {match, {list(), tuple()}}
perform a data input operation.
Performs one of the in
, rd
, inp
or rdp
operations.
Multiple processes may access the ETS table concurrently, and even
"compete" for the same tuple. We will ensure that in the case of
in
and inp
only one of them will succeed in taking the tuple.
{match, {list(), tuple()}}
, where
the list()
will contain the $N
fields in Pattern
, and the
tuple()
is the entire matched tuple record. If match is not
found, we return {nomatch}
for inp
and rdp
, and {nomatch,
reference()}
for in
and rd
. For the latter the calling process
should wait/block for two types of messages {reference(), retry,}
and {reference(), quit}
. These messages are handled in the
espace
module.
Generated by EDoc