1
# Just some routines related to the Memoize module that are used in
2
# more than one place in XMLTV. But not general enough to merge back
5
# $Id: Memoize.pm,v 1.15 2006/01/11 18:01:38 mattiasholmlund Exp $
8
package XMLTV::Memoize;
13
# Use Log::TraceMessages if installed.
15
eval { require Log::TraceMessages };
21
*t = \&Log::TraceMessages::t;
22
*d = \&Log::TraceMessages::d;
26
# Add an undocumented option to cache things in a DB_File database.
27
# You need to decide which subroutines should be cached: see
28
# XMLTV::Get_nice for how to memoize web page fetches. Call like
31
# if (check_argv('fred', 'jim')) {
32
# # The subs fred() and jim() are now memoized.
35
# If the user passed a --cache option to your program, this will be
36
# removed from @ARGV and caching will be turned on. The optional
37
# argument to --cache gives the filename to use.
39
# Currently it is assumed that the function gives the same result in
40
# both scalar and list context.
42
# Note that the Memoize module is not loaded unless --cache options
45
# Returns a ref to a list of code references for the memoized
46
# versions, if memoization happened (but does install the memoized
47
# versions under the original names too). Returns undef if no
48
# memoization was wanted.
51
# local $Log::TraceMessages::On = 1;
53
my $p = new Getopt::Long::Parser(config => ['passthrough']);
57
my $result = $p->getoptions('cache:s' => \$opt_cache,
58
'quiet' => \$opt_quiet );
59
die "failure processing --cache option" if not $result;
60
unshift @ARGV, "--quiet" if $opt_quiet;
62
return undef if not defined $opt_cache;
64
if ($opt_cache eq '') {
65
# --cache given, but no filename. Guess one.
66
my $basename = File::Basename::basename($0);
67
$filename = "$basename.cache";
70
$filename = $opt_cache;
72
print STDERR "using cache $filename\n" unless $opt_quiet;
77
my @tie_args = ('DB_File', $filename,
78
POSIX::O_RDWR() | POSIX::O_CREAT(), 0666);
80
# $from_caller is a sub which converts a function name into one
81
# seen from the caller's namespace. Namespaces do not nest, so if
82
# it already has :: it should be left alone.
84
my $caller = caller();
86
my $from_caller = sub( $ ) {
89
return "${caller}::$_";
93
# Annoyingly tie(%cache, @tie_args) doesn't work
95
tie %cache, 'DB_File', $filename,
96
POSIX::O_RDWR() | POSIX::O_CREAT(), 0666;
99
my $r = Memoize::memoize($from_caller->($_),
100
SCALAR_CACHE => [ HASH => \%cache ],
101
LIST_CACHE => 'MERGE');
102
die "could not memoize $_" if not $r;