File Coverage

lib/AnyEvent/Memcached/Buckets.pm
Criterion Covered Total %
statement 64 76 84.2
branch 15 26 57.6
condition 5 10 50.0
subroutine 7 9 77.7
pod 0 6 0.0
total 91 127 71.6


line stmt bran cond sub pod time code
1             package #hide
2             AnyEvent::Memcached::Buckets;
3              
4 6     6   1035 use common::sense 2;m{
  6         136  
  6         43  
5             use strict;
6             use warnings;
7             }x;
8 6     6   435 use Carp;
  6         67  
  6         8693  
9              
10             sub new {
11 2     2 0 42 my $self = bless {}, shift;
12 2         9 my %args = @_;
13 2         13 $self->set_servers(delete $args{servers});
14 2         6 $self;
15             }
16              
17             sub set_servers {
18 2     2 0 6 my $self = shift;
19 2 50       10 my $list = shift or return;
20 2 50       10 $list = [$list] unless ref $list eq 'ARRAY';
21 2   50     20 $self->{servers} = $list || [];
22 2         10 $self->_init_buckets;
23 2         4 return $self;
24             }
25              
26             sub peers {
27 0     0 0 0 my $self = shift;
28 0 0       0 @{$self->{servers}} or croak "servers not set during peers";
  0         0  
29 0         0 $self->{peers};
30             }
31              
32             sub _init_buckets {
33 2     2   4 my $self = shift;
34 2 50       5 @{$self->{servers}} or croak "servers not set during _init_buckets";
  2         10  
35 2 50       10 if ($self->{buckets}) {
36 0         0 @{ $self->{buckets} } = ();
  0         0  
37             } else {
38 2         7 $self->{buckets} = [];
39             }
40 2         5 my $bu = $self->{buckets};
41 2         4 my $i = 0;
42 2         4 foreach my $v (@{$self->{servers}}) {
  2         7  
43 10         15 my $peer;
44 10         21 my $buck = [ 0+@$bu ];
45 10 100       26 if (ref $v eq "ARRAY") {
46 2         5 $peer = $v->[0];
47 2         20 for (1..$v->[1]) {
48 6         18 push @$bu, $v->[0];
49             }
50 2         7 push @$buck, $buck->[0]+1 .. $#$bu;
51             } else {
52 8         14 push @$bu, $peer = $v;
53             }
54 10         56 my ($host,$port) = $peer =~ /^(.+?)(?:|:(\d+))$/;
55 10 100       30 if ( exists $self->{peers}{$peer} ) {
56 2         4 push @{ $self->{peers}{$peer}{bucks} }, @$buck;
  2         14  
57             } else {
58 8   100     8 push @{ $self->{srv} ||= [] }, $peer;
  8         36  
59 8         48 $self->{peers}{$peer} = {
60 8         14 index => $#{ $self->{srv} },
61             bucks => $buck,
62             host => $host,
63             port => $port,
64             };
65             }
66             }
67 2         4 return;
68             }
69              
70              
71             sub peer {
72 82     82 0 103 my $self = shift;
73 82         94 my $hash = shift;
74 82 50       85 @{$self->{servers}} or croak "servers not set during peer";
  82         204  
75 82         142 return $self->{buckets}[ $hash % @{ $self->{buckets} } ];
  82         277  
76             }
77              
78             sub next {
79 41     41 0 43 my $self = shift;
80 41         44 my $srv = shift;
81 41 50       32 @{$self->{servers}} or croak "servers not set during next";
  41         96  
82 41 50       107 my $peer = $self->{peers}{$srv} or croak "No such server in buckets: $srv";
83 41         62 my %args = @_;
84 41   50     149 my $by = $args{by} || 1;
85 41         56 my $next = ( $peer->{index} + $by ) % @{$self->{srv}};
  41         77  
86 41 50       97 my $nsrv = $self->{srv}[$next] or die "Cant find next server by index $next";
87 41 50       72 $nsrv = $nsrv->[0] if ref $nsrv;
88             #warn R::Dump($nsrv);
89 41 100       42 if ( ( my @bucks = @{ $self->{peers}{$nsrv}{bucks} } ) > 1 ) {
  41         141  
90 5   50     21 my $which = $bucks[ ( $args{hash} || 0 ) % @bucks ];
91             #warn "many buckets (@bucks) for $nsrv. using $which ($self->{buckets}[ $which ])";
92 5         19 return $self->{buckets}[ $which ];
93             } else {
94 36         115 return $nsrv;
95             }
96             }
97             sub prev {
98 0     0 0   my $self = shift;
99 0           my $srv = shift;
100 0           my %args = @_;
101 0   0       my $by = $args{by} || 1;
102 0           $self->next( $srv, %args, by => @{$self->{srv}}-$by );
  0            
103             }
104              
105             1;