Re: [PATCHv5 03/17] gitweb/lib - Very simple file based cache
From: Thomas Adam <hidden>
Date: 2016-06-15 22:49:43
On 6 October 2010 23:01, Jakub Narebski [off-list ref] wrote:
+# creates get_depth() and set_depth($depth) etc. methods
+foreach my $i (qw(depth root namespace)) {
+ my $field = $i;
+ no strict 'refs';For each item, you'll set "no strict refs"? This might be better off outside the loop. It's still scoped appropriately inside the subroutine.
+ my $file = $self->path_to_key($key); + return undef unless (defined $file && -f $file);
PBP (Perl Best Practises) will tell you that explicitly returning undef is discouraged -- "undef" should be reserved for those errors you cannot handle, not ones you don't want to.
+ + # Fast slurp, adapted from File::Slurp::read, with unnecessary options removed + # via CHI::Driver::File (from CHI-0.33) + my $buf = ''; + open my $read_fh, '<', $file + or return undef;
Ditto.
+ binmode $read_fh, ':raw';
+
+ my $size_left = -s $read_fh;
+
+ while ($size_left > 0) {
+ my $read_cnt = sysread($read_fh, $buf, $size_left, length($buf));
+ return undef unless defined $read_cnt;Ditto.
+ last if $read_cnt == 0; + $size_left -= $read_cnt; + #last if $size_left <= 0; + } + + close $read_fh + or die "Couldn't close file '$file' opened for reading: $!"; + return $buf; +}
"use Carp;" would be more useful here, and hence croak() and confess().
+sub store {
+ my ($self, $key, $data) = @_;
+
+ my $dir;
+ my $file = $self->path_to_key($key, \$dir);
+ return undef unless (defined $file && defined $dir);See above.
+ # ensure that directory leading to cache file exists
+ if (!-d $dir) {
+ eval { mkpath($dir, 0, 0777); 1 }
+ or die "Couldn't create leading directory '$dir' (mkpath): $!";
+ }Why is this eval()ed? It will still return false and set $! appropriately.
+ # generate a temporary file
+ my ($temp_fh, $tempname) = $self->_tempfile_to_path($file, $dir);
+ chmod 0666, $tempname
+ or warn "Couldn't change permissions to 0666 / -rw-rw-rw- for '$tempname': $!";
+
+ # Fast spew, adapted from File::Slurp::write, with unnecessary options removed
+ # via CHI::Driver::File (from CHI-0.33)
+ my $write_fh = $temp_fh;
+ binmode $write_fh, ':raw';
+
+ my $size_left = length($data);
+ my $offset = 0;
+
+ while ($size_left > 0) {
+ my $write_cnt = syswrite($write_fh, $data, $size_left, $offset);
+ return undef unless defined $write_cnt;Again, with the undef.
+ $size_left -= $write_cnt;
+ $offset += $write_cnt; # == length($data);
+ }
+
+ close $temp_fh
+ or die "Couldn't close temporary file '$tempname' opened for writing: $!";
+ rename($tempname, $file)
+ or die "Couldn't rename temporary file '$tempname' to '$file': $!";
+}
+
+# get size of an element associated with the $key (not the size of whole cache)
+sub get_size {
+ my ($self, $key) = @_;
+
+ my $path = $self->path_to_key($key)
+ or return undef;Again with the undef
+ if (-f $path) {
+ return -s $path;
+ }
+ return 0;
+}
+
+# ......................................................................
+# interface methods
+
+# Removing and expiring
+
+# $cache->remove($key)
+#
+# Remove the data associated with the $key from the cache.
+sub remove {
+ my ($self, $key) = @_;
+
+ my $file = $self->path_to_key($key)
+ or return undef;
+ return undef unless -f $file;Again with the undef.
+ unlink($file)
+ or die "Couldn't remove file '$file': $!";
+}
+
+# Getting and setting
+
+# $cache->set($key, $data);
+#
+# Associates $data with $key in the cache, overwriting any existing entry.
+# Returns $data.
+sub set {
+ my ($self, $key, $data) = @_;
+
+ return unless (defined $key && defined $data);return what?
+ $self->store($key, $data);
+
+ return $data;
+}
+
+# $data = $cache->get($key);
+#
+# Returns the data associated with $key. If $key does not exist
+# or has expired, returns undef.
+sub get {
+ my ($self, $key) = @_;
+
+ my $data = $self->fetch($key)
+ or return undef;
+
+ return $data;
+}
+
+# $data = $cache->compute($key, $code);
+#
+# Combines the get and set operations in a single call. Attempts to
+# get $key; if successful, returns the value. Otherwise, calls $code
+# and uses the return value as the new value for $key, which is then
+# returned.
+sub compute {
+ my ($self, $key, $code) = @_;
+
+ my $data = $self->get($key);
+ if (!defined $data) {
+ $data = $code->($self, $key);
+ $self->set($key, $data);
+ }
Can you guarantee $code here?
unless( defined $code and ref $code eq 'CODE' )
{
....
}
Wouldn't it be easier to eval{} this and checj $@?
[...]
-- Thomas Adam