[system] / trunk / pg / lib / WeBWorK / EquationCache.pm Repository:
ViewVC logotype

Annotation of /trunk/pg/lib/WeBWorK/EquationCache.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2409 - (view) (download) (as text)

1 : sh002i 1524 ################################################################################
2 :     # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
3 :     # $Id$
4 :     ################################################################################
5 :    
6 :     package WeBWorK::EquationCache;
7 :    
8 :     =head1 NAME
9 :    
10 :     WeBWorK::EquationCache - create and cache images of TeX equations.
11 :    
12 :     =head1 SYNPOSIS
13 :    
14 :     my $cache = WeBWorK::EquationCache->new(cacheDB => "/path/to/equationcache.db");
15 :     my $imageName = $cache->lookup('\[3x^2\]');
16 :    
17 :     =head1 DESCRIPTION
18 :    
19 :     WeBWorK::PG::EquationCache maintains a list of unique identifiers for TeX
20 :     strings. The unique identifier is based on an MD5 hash of the TeX string, and a
21 :     sequence number. Before calcuating the MD5 hash of a TeX string, all whitespace
22 :     is removed.
23 :    
24 :     =head2 FILE FORMAT
25 :    
26 :     The cache database file is a text file consisting of lines of the following
27 :     form:
28 :    
29 :     md5_hash sequence_number tex_string
30 :    
31 :     Any amount of whitespace may separate the fields. Lines which do not conform to
32 :     this format are ignored. Any string of characters beginning with `#' and
33 :     extending to the end of the line is also ignored.
34 :    
35 :     =cut
36 :    
37 :     use strict;
38 :     use warnings;
39 :     use Digest::MD5 qw(md5_hex);
40 :     use Fcntl qw(:DEFAULT :flock);
41 :     BEGIN { O_RDWR; O_CREAT; LOCK_EX } # get rid of "subroutine redefined" warnings
42 :    
43 :     =head1 METHODS
44 :    
45 :     =over
46 :    
47 :     =item new(%options)
48 :    
49 :     Returns a new EquationCache object. C<%options> must contain the following
50 :     entries:
51 :    
52 :     cacheDB => path to image cache database file
53 :    
54 : jj 2409 If cacheDB is the empty string, don't use a cache file and assume that there
55 :     are no md5 collisions.
56 :    
57 : sh002i 1524 =cut
58 :    
59 :     sub new {
60 :     my ($invocant, %options) = @_;
61 :     my $class = ref $invocant || $invocant;
62 :     my $self = {
63 :     %options,
64 :     };
65 :    
66 :     bless $self, $class;
67 :     }
68 :    
69 :     =item lookup
70 :    
71 :     Looks up a TeX string in the database. A unique identifier for the cached image
72 :     is returned. If necessary, the string is added to the database.
73 :    
74 :     =cut
75 :    
76 :     sub lookup {
77 :     my ($self, $tex) = @_;
78 :     $tex =~ s/\s+//g;
79 :     my $md5 = md5_hex($tex);
80 :    
81 :     my $db = $self->{cacheDB};
82 : jj 2409 unless($db) { return($md5 ."1"); }
83 : sh002i 1524 sysopen(DB, $db, O_RDWR|O_CREAT)
84 :     or die "failed to create/open cacheDB $db: $!";
85 :     flock(DB, LOCK_EX)
86 :     or die "failed to write-lock cacheDB $db: $!";
87 :    
88 :     my $line = 0;
89 :     my $max = 0;
90 :     my $match = 0;
91 :     local $/ = "\n";
92 :     while (<DB>) {
93 :     # find matching MD5 hashes
94 :     next unless m/^$md5\s+(\d+)\s+(.*)$/;
95 :     if ($tex = $2) {
96 :     # the TeX string matches: use this instance number and stop looking
97 :     $match = $1;
98 :     last;
99 :     } else {
100 :     # the TeX string doesn't match: record instance number and keep looking
101 :     $max = $1 if $1 > $max;
102 :     }
103 :     }
104 :    
105 :     unless ($match) {
106 :     # no match: invent a new instance number and add TeX string to DB
107 :     $match = $max + 1;
108 :     seek(DB, 0, 2); # we should already be at EOF, but what the hell.
109 :     print DB "$md5\t$match\t$tex\n";
110 :     }
111 :    
112 :     close(DB);
113 :     return "$md5$match";
114 :     }
115 :    
116 :     1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9