hi Sean,

there are several ways to approach this problem and perhaps I will outline
two possible ways below.

Before adding a new ID to the context, one could search all existing IDs in
the context with the SEC 'while' action, looping over all IDs one by one,
and comparing each previously stored ID with the new ID value. However, it
is more efficient to implement that functionality in one 'lcall' action
that would take all stored IDs as an input parameter for a 3-line Perl
function, and do all processing inside that function. Here is an example
rule that illustrates that approach:

type=single
ptype=regexp
pattern=add ID (\d+)
desc=add new ID to perl hash
action=copy CONTEXT %id_list; \
       lcall %ret %id_list $1 -> ( sub { my(@keys) = split(/\n/, $_[0]); \
                                   my(%hash) = map { $_ => 1 } @keys; \
                                   return !exists($hash{$_[1]}); } ); \
       if %ret ( add CONTEXT $1 )

In this rule, all IDs that have been previously stored to CONTEXT are
written into the action list variable %id_list, so that IDs are separated
with newlines in that variable. In the Perl function that 'lcall' action
invokes, the list of stored IDs is the first parameter and the new ID value
the second one. Also, the function returns true if the new value is not
present in the list, and false if it is already there. Inside the function,
the list of IDs is turned into a hash table (%hash), and a new value is
searched from this hash table with a key lookup. Finally, the SEC 'if'
action checks the function return value and adds the new ID to CONTEXT only
if the function returned true.

This approach has the drawback that you have to build the Perl hash table
before each attempt to add a new ID to the context. It is much cheaper not
to use the context when you are storing the IDs, but keep them in a Perl
hash during this process, moving them over to a context when you start the
cleanup procedure. Here is an example how this could be done:

type=single
ptype=regexp
pattern=add ID (\d+)
desc=add new ID to perl hash
action=lcall %o $1 -> ( sub { $hash{$_[0]} = 1 } );

type=single
ptype=regexp
pattern=process IDs
desc=process all IDs from hash and clear the hash
action=lcall %id_list -> ( sub { keys(%hash) } ); \
       fill CONTEXT %id_list; \
       lcall %o -> ( sub { %hash = () } )

As you can see, the first rule creates a key with the value of 1 for each
observed ID in the hash table (if the key already exists in the table, this
operation simply overwrites its value, and is thus a no-op). The second
rule implements a cleanup procedure for all stored IDs. First, the Perl
function of the 'lcall' action returns a list of all keys from the hash
table. The keys will be joined into a string, using newlines as separators,
and this string is assigned to the action list variable %id_list. The
'fill' action will then write the value of the %id_list variable into
CONTEXT. Since %id_list holds a multiline string, each line from that
string will become a separate line in the event store of CONTEXT. Finally,
another 'lcall' action will clear the Perl hash table.

With the above approach, the ID values are tracked with the help of the
Perl hash table, and the context is created at a cleanup stage when all IDs
are processed together. Since I don't know the nature of the cleanup
process, the second rule is just setting up CONTEXT for that without any
further action. If the cleanup process involves some Perl code or invoking
an external script, having CONTEXT might not even be needed, but you could
directly pass the %id_list variable to the cleanup code or cleanup script.

Hopefully these examples were able to provide some ideas on how to tackle
the problem you have.

kind regards,
risto


It’s late and my Perl is years rusty. Does anyone already have a routine
> that will do this? Basically I’m using an event store to track of a list of
> id’s so I can clean something up. I need a way to add a string to the event
> store only if it’s not already in there.
>
>
>
> Thanks.
> _______________________________________________
> Simple-evcorr-users mailing list
> Simple-evcorr-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users
>
_______________________________________________
Simple-evcorr-users mailing list
Simple-evcorr-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users

Reply via email to