Parent Directory
|
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 |