File Coverage

lib/PEF/CacheLRU.pm
Criterion Covered Total %
statement 56 59 94.9
branch 12 16 75.0
condition n/a
subroutine 9 10 90.0
pod 6 6 100.0
total 83 91 91.2


line stmt bran cond sub pod time code
1             package PEF::CacheLRU;
2 1     1   44399 use strict;
  1         7  
  1         133  
3 1     1   10 use warnings;
  1         4  
  1         125  
4             use constant {
5 1         2460 NEXT => 0,
6             PREV => 1,
7             KEY => 2,
8             VALUE => 3,
9             HEAD => 0,
10             TAIL => 1,
11             NODES => 2,
12             SIZE => 3,
13             MAXSIZE => 4,
14 1     1   12 };
  1         12  
15              
16             our $VERSION = "0.01";
17              
18             sub new {
19 4     4 1 19 my ($class, $max_size) = @_;
20 4         15 my $self = bless [[undef, undef], undef, {}, 0, $max_size,], $class;
21 4         14 $self->[TAIL] = $self->[HEAD];
22 4         11 $self;
23             }
24              
25             sub max_size {
26 0     0 1 0 $_[0]->[MAXSIZE];
27             }
28              
29             sub size {
30 1     1 1 28 $_[0]->[SIZE];
31             }
32              
33             sub _promote {
34 1043     1043   1644 my ($self, $node) = @_;
35 1043         1225 my $pre = $node->[PREV];
36 1043         1144 $node->[PREV] = undef;
37 1043         1258 $pre->[NEXT] = $node->[NEXT];
38 1043         1149 $pre->[NEXT][PREV] = $pre;
39 1043         1228 $node->[NEXT] = $self->[HEAD];
40 1043         1126 $self->[HEAD] = $node;
41 1043         1666 $self->[HEAD][NEXT][PREV] = $self->[HEAD];
42             }
43              
44             sub remove {
45 1     1 1 3 my ($self, $key) = @_;
46 1 50       5 return if not exists $self->[NODES]{$key};
47 1         3 my $node = $self->[NODES]{$key};
48 1         2 --$self->[SIZE];
49 1 50       4 if ($node == $self->[HEAD]) {
50 0         0 $self->[HEAD] = $node->[NEXT];
51 0         0 $self->[HEAD][PREV] = undef;
52             } else {
53 1         3 my $pre = $node->[PREV];
54 1         2 $pre->[NEXT] = $node->[NEXT];
55 1         2 $node->[NEXT][PREV] = $pre;
56             }
57 1         3 delete $self->[NODES]{$node->[KEY]};
58 1         2 $node->[NEXT] = undef;
59 1         1 $node->[PREV] = undef;
60 1         6 $node->[VALUE];
61             }
62              
63             sub set {
64 1754     1754 1 7393 my ($self, $key, $value) = @_;
65 1754 100       3970 if (my $node = $self->[NODES]{$key}) {
66 1         2 $node->[VALUE] = $value;
67 1 50       11 $self->_promote($node) if $node != $self->[HEAD];
68             } else {
69 1753         4439 $self->[HEAD] = [$self->[HEAD], undef, $key, $value];
70 1753         2754 $self->[HEAD][NEXT][PREV] = $self->[HEAD];
71 1753         3184 $self->[NODES]{$key} = $self->[HEAD];
72 1753 100       4173 if (++$self->[SIZE] > $self->[MAXSIZE]) {
73 1742         2384 my $pre_least = $self->[TAIL][PREV];
74 1742 50       3807 if (my $pre = $pre_least->[PREV]) {
75 1742         3099 delete $self->[NODES]{$pre_least->[KEY]};
76 1742         2425 $pre->[NEXT] = $self->[TAIL];
77 1742         2191 $self->[TAIL][PREV] = $pre;
78 1742         2102 $pre_least->[NEXT] = undef;
79 1742         2117 $pre_least->[PREV] = undef;
80 1742         3528 --$self->[SIZE];
81             }
82             }
83             }
84 1754         3791 $value;
85             }
86              
87             sub get {
88 3032     3032 1 14718 my ($self, $key) = @_;
89 3032 100       6383 if (my $node = $self->[NODES]{$key}) {
90 1282 100       3483 $self->_promote($node) if $node != $self->[HEAD];
91 1282         2749 $node->[VALUE];
92             } else {
93 1750         3248 return;
94             }
95             }
96              
97             1;
98              
99             __END__