Gosuke Miyashita about feed

Deduped::AnyDBM_File

16 September 2006

前回のエントリ について、宮川さんから「AnyDBM_File をつかうといいかも」というアドバイスを頂いたので、Deduped::AnyDBM_File を書いてみた。

package Plagger::Rule::Deduped::AnyDBM_File;
use strict;
use base qw( Plagger::Rule::Deduped::Base );
use UNIVERSAL::require;
use Fcntl;

sub import {
my ( $class, @arguments ) = @_;

@AnyDBM_File::ISA = () if @arguments;
for ( @arguments ) {
    push @AnyDBM_File::ISA, $_ . '_File';
}

AnyDBM_File->require;

}

sub init {
my($self, $rule) = @_;

$self->{path} = $rule->{path} || Plagger->context->cache->path_to('Deduped.db');
tie my %cache, 'AnyDBM_File', $self->{path}, O_RDWR|O_CREAT, 0666
    or Plagger->context->error("Can't open DB_File $self->{path}: $!");
$self->{db} = \%cache;

}

sub find_entry {
my($self, $url) = @_;
my $value = $self->{db}->{$url};
return $value;
}

sub create_entry {
my($self, $url, $digest) = @_;
$self->{db}->{$url} = $digest;
}

sub DESTROY {
my $self = shift;
untie $self->{db};
}

1;

以下の様な感じで、利用するモジュールを NDBM_File, DB_File, GDBM_File, SDBM_File, ODBM_File の中から選べます。(何も指定しなければ DB_File が使われる。_File は省略する。)

    rule:
      module: Deduped
      engine: GDBM

また、現在の Rule::Deduped では、Rule::Deduped::$self->{engine} を呼び出すようになっているけれど、上記 NDBM, DB, GDBM, SDBM, ODBM のいずれかが指定された場合には、Rule::Deduped::AnyDBM_File を呼び出す必要があるため、Rule::Deduped も少しいじってみた。

Index: lib/Plagger/Rule/Deduped.pm
===================================================================
--- lib/Plagger/Rule/Deduped.pm	(revision 1688)
+++ lib/Plagger/Rule/Deduped.pm	(working copy)
@@ -6,11 +6,19 @@

sub init {
my $self = shift;

こうすると現在の Deduped::DB_File も、Deduped::AnyDBM_File で吸収できます。