chrestomanci has asked for the wisdom of the Perl Monks concerning the following question:
Greetings wise brothers, I have a question.
I am working on a DBIx::Class table, where one row contains a regular expression stored as a plain string My current code looks like this:
package MyCompany::Result::WatchString; use base qw/DBIx::Class::Result/; use strict; __PACKAGE__->table('tblWatchString'); __PACKAGE__->add_columns( 'id', { data_type => 'int', is_auto_increment => 1 }, 'comment', { data_type => 'varchar', size => 30 }, # +Appears in logging messages 'log_level', { data_type => 'int', }, # +Log4perl log level. 'match_string', { data_type => 'varchar', size => 200 }, # +String in the VLC output to match on. ); sub match_re { my $self = shift; my $match_string = $self->match_string; my $matcher = qr/\Q$match_string\E/; return $matcher; }
In the main program, I then compare a large number of string against all the rows in the database. eg
my $logger = Log::Log4perl->get_logger(); open INPUT, '-|', '/some/program/with/verbose/output'; while( my $line <INPUT> ) { foreach my $watch_string ( $schema->resultset('WatchString')->all +) { if( $line =~ $watch_string->match_re() ) { # Do stuff my $log_message = join(' ', 'Interesting output '. $watch_ +string->comment, $line); $logger->log( $watch_string->log_level, $log_message); } } }
The problem is that $watch_string->match_re() is getting called a huge number of times, and the regular expression gets re-compiled every time. The algorithm is crying out for some sort of caching, but I can't work out how.
I have tried modifying match_re() to just cache the compiled regular expression in $self->{'_cached_re'} but the cache is not persistent between invocations.
I have read The DBIx::Class FAQ entry on this, but I could not get either the Moose or the Class::Accessor::Grouped method to work. When I tried Moose, my builder function got called every time, and the data did not appear to be cached. With Class::Accessor::Grouped the data was never stored.
I have tried using DBIx::Class::InflateColumn and creating an inflate method that returns the compiled regular expression, but it is getting called every time, and is not being cached.
I have tried DBIx::Class::VirtualColumns but when I tried to install via the CPAN client the tests failed.
There must be a way to do this, can anyone point me in the right direction, or point out what I have been doing wrong.
Thanks.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: How to cache a regular expression in a DBIx::Class object
by Your Mother (Archbishop) on Apr 08, 2011 at 18:09 UTC | |
by chrestomanci (Priest) on Apr 08, 2011 at 21:19 UTC | |
|
Re: How to cache a regular expression in a DBIx::Class object
by moritz (Cardinal) on Apr 08, 2011 at 15:57 UTC | |
by chrestomanci (Priest) on Apr 08, 2011 at 21:04 UTC | |
by moritz (Cardinal) on Apr 09, 2011 at 11:31 UTC | |
|
Re: How to cache a regular expression in a DBIx::Class object
by wind (Priest) on Apr 08, 2011 at 16:51 UTC |