File Coverage

blib/lib/MemcacheDB/Dump.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package MemcacheDB::Dump;
2 3     3   53751 use strict;
  3         6  
  3         115  
3 3     3   21 use warnings;
  3         5  
  3         115  
4              
5 3     3   27 use Carp;
  3         6  
  3         249  
6 3     3   3031 use BerkeleyDB;
  0            
  0            
7              
8             our $VERSION = "0.04";
9              
10             sub new {
11             my ($class, $path) = @_;
12             tie my %bdb, "BerkeleyDB::Btree",
13             -Filename => $path,
14             -Flags => DB_RDONLY or carp "open $path failed";
15              
16             bless { bdb => \%bdb }, $class;
17             }
18              
19             sub DESTROY {
20             my $self = shift;
21             untie %{ $self->{bdb} };
22             }
23              
24             sub run {
25             my ($self) = @_;
26             my %ret;
27             while ( my ($key, $val) = each %{ $self->{bdb} } ) {
28             $ret{$key} = getBody($val);
29             }
30             \%ret;
31             }
32              
33             sub keys {
34             my ($self) = @_;
35             keys %{ $self->{bdb} };
36             }
37              
38             sub get {
39             my ($self, $key) = @_;
40             exists $self->{bdb}->{$key} or return;
41             getBody($self->{bdb}->{$key});
42             }
43              
44             sub getBody {
45             my ($val) = @_;
46             itemBody(itemDecode($val));
47             }
48              
49             # MemcacheDB is just fread an item struct below.
50             # https://code.google.com/p/memcachedb/source/browse/branches/memcachedb-1.2.0/memcachedb.h#179
51             #XXX this is NOT sane way to extract C struct. because your C compiler may put other padding bytes for the alignment.
52             sub itemDecode {
53             my ($val) = @_;
54             my ($nBytes, $nSuffix, $nKey, $padA, $padB, @body) = unpack("LC4C*", $val);
55             {
56             nBytes => $nBytes,
57             nSuffix => $nSuffix,
58             nKey => $nKey,
59             body => \@body,
60             };
61             }
62              
63             sub itemBody {
64             my ($item) = @_;
65             my $offset = $item->{nKey} + $item->{nSuffix} + 1;
66             my $length = $item->{nBytes} - 1 - 2; # -2 for remove \r\n padding
67             pack "C*", @{ $item->{body} }[ $offset .. $offset+$length ];
68             }
69              
70             sub _pp {
71             my ($bin) = @_;
72             my @list = unpack("C*", $bin);
73             join "", map { ($_ >= 32 && $_ <= 126) ? chr($_) : sprintf("\\x%02X", $_) } @list;
74             }
75              
76             1;
77             __END__