AC-Yenta
view release on metacpan or search on metacpan
lib/AC/Yenta/Store/Map.pm view on Meta::CPAN
# -*- perl -*-
# Copyright (c) 2009 AdCopy
# Author: Jeff Weisberg
# Created: 2009-Mar-30 19:21 (EDT)
# Function: storage maps
#
# $Id$
package AC::Yenta::Store::Map;
use AC::Yenta::Store::File;
use AC::Yenta::Store::Merkle;
use AC::Yenta::Debug 'map';
use AC::Yenta::Conf;
use AC::Cache;
use strict;
our @ISA = 'AC::Yenta::Store::Merkle';
my $DEFAULT = 'bdb';
my %BACKEND ;
my $CACHESIZE = 1024; # gives us ~90% cache hit rate
sub add_backend {
my $class = shift;
my $name = shift;
my $impl = shift;
$BACKEND{$name} = $impl;
}
sub new {
my $class = shift;
my $name = shift;
my $bkend = shift;
my $conf = shift;
unless( $bkend ){
# from extension, or default
my($ext) = $conf->{dbfile} =~ /\.(.+)$/;
$bkend = $ext if $BACKEND{$ext};
}
my $c = $BACKEND{$bkend || $DEFAULT};
unless( $c ){
problem("invalid storage backend: $bkend - ignoring map");
return ;
}
debug("configuring map $name with $c");
my $db = $c->new( $name, $conf );
my $fs = AC::Yenta::Store::File->new( $name, $conf );
my $me = bless {
name => $name,
conf => $conf,
db => $db,
fs => $fs,
merkle_height => 16,
vers_cache => AC::Cache->new( $CACHESIZE ),
}, $class;
$me->merkle_init();
return $me;
}
my($cachechk, $cachemiss, $cacheT);
sub _versget {
my $me = shift;
my $key = shift;
$cachechk ++;
my $d = $me->{vers_cache}->fetch( $key );
return @$d if $d;
$cachemiss ++;
my $db = $me->{db};
my($versions, $foundver) = $db->get($me->{name}, 'vers', $key);
my @d = split /\s+/, $versions;
$me->{vers_cache}->store( $key, \@d );
return @d;
}
sub _versput {
my $me = shift;
my $key = shift;
my $db = $me->{db};
$db->put($me->{name}, 'vers', $key, join(' ', @_));
$me->{vers_cache}->store( $key, \@_ );
}
sub _versdel {
my $me = shift;
my $key = shift;
$me->{vers_cache}->remove( $key );
}
sub get {
my $me = shift;
my $key = shift;
my $ver = shift;
my $db = $me->{db};
my @versions = $me->_versget( $key );
return unless @versions;
debug("found ver: @versions");
if( $ver ){
$ver = encode_version($ver);
return unless grep { $_ eq $ver } @versions;
( run in 1.145 second using v1.01-cache-2.11-cpan-39bf76dae61 )