line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
DynGig::Range::Cluster - Extends DynGig::Range::String. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=cut |
6
|
|
|
|
|
|
|
package DynGig::Range::Cluster; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 VERSION |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Version 0.01 |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=cut |
13
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
24052
|
use base DynGig::Range::String; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
811
|
|
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
24463
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
18
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
23
|
|
19
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
58
|
|
20
|
|
|
|
|
|
|
|
21
|
1
|
|
|
1
|
|
599
|
use DynGig::Range::Cluster::Client; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
1023
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my %_ENV; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 DESCRIPTION |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head2 setenv( timeout => seconds, server => server ) |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Sets DynGig::Range::Cluster::Client parameter. Returns object/class. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
sub setenv |
33
|
|
|
|
|
|
|
{ |
34
|
0
|
|
|
0
|
1
|
|
my $this = shift @_; |
35
|
|
|
|
|
|
|
|
36
|
0
|
|
|
|
|
|
%_ENV = ( cluster => DynGig::Range::Cluster::Client->new( @_ ) ); |
37
|
0
|
|
|
|
|
|
return $this; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head1 SEE ALSO |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
See DynGig::Range::String for additional methods. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 GRAMMAR |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
Tokenizer and parser implement the base class BNF with the |
47
|
|
|
|
|
|
|
following differences. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=cut |
50
|
|
|
|
|
|
|
sub _parse |
51
|
|
|
|
|
|
|
{ |
52
|
0
|
|
|
0
|
|
|
my ( $this, $input ) = @_; |
53
|
0
|
|
|
|
|
|
my $token = $this->_tokenize( $input, qr/[{}:=%()]/, qr/[-&]/ ); |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
$this += $this->_expression( $token, +{ '}' => 0, ')' => 0 } ); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub _valid |
59
|
|
|
|
|
|
|
{ |
60
|
0
|
|
|
0
|
|
|
my ( $this, $token, $lex ) = @_; |
61
|
|
|
|
|
|
|
|
62
|
0
|
0
|
|
|
|
|
return 0 unless @$token; |
63
|
0
|
0
|
0
|
|
|
|
return ref $token->[0] || $token->[0] eq '{' unless $lex; |
64
|
0
|
0
|
0
|
|
|
|
return ref $token->[0] || $token->[0] !~ /[-+&}:=%()]/ if $lex == 2; |
65
|
0
|
|
|
|
|
|
return $token->[0] =~ /[-+&]/; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head2 ::= | |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head2 ::= '(' ':' ')' |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
| '(' '%' ')' |
73
|
|
|
|
|
|
|
| '(' '=' ')' |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head2 SYMBOLS |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
I: |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
':' : given cluster name ( left operand ), get attribute keys by value. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
'%' : given cluster name ( left operand ), get attribute values by key. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
'=' : get cluster names with attribute key = value. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=cut |
86
|
|
|
|
|
|
|
sub _range |
87
|
|
|
|
|
|
|
{ |
88
|
0
|
|
|
0
|
|
|
my ( $this, $token, $scope ) = @_; |
89
|
|
|
|
|
|
|
|
90
|
0
|
0
|
|
|
|
|
croak 'private method' unless $this->isa( ( caller )[0] ); |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
my $range = bless shift @$token, ref $this; |
93
|
|
|
|
|
|
|
|
94
|
0
|
0
|
0
|
|
|
|
return $range unless @$token && $token->[0] eq '('; |
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
my $type = ')'; |
97
|
0
|
|
|
|
|
|
my $count = $scope->{$type}; |
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
$this->_balance( $token, $scope, $type ); |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
my $key = $this->_expression( $token, $scope ); |
102
|
0
|
|
|
|
|
|
my $op = shift @$token; |
103
|
|
|
|
|
|
|
|
104
|
0
|
0
|
0
|
|
|
|
unless ( @$token && $op && $op =~ /[:=%]/ ) |
|
|
|
0
|
|
|
|
|
105
|
|
|
|
|
|
|
{ |
106
|
0
|
|
|
|
|
|
splice @$token; |
107
|
0
|
|
|
|
|
|
return $this->new(); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
my $value = $this->_expression( $token, $scope ); |
111
|
|
|
|
|
|
|
|
112
|
0
|
0
|
|
|
|
|
$this->_balance( $token, $scope, $type, $count ) |
113
|
|
|
|
|
|
|
? $this->_cluster( $op, $range, $key, $value ) : $range->clear(); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub _cluster |
117
|
|
|
|
|
|
|
{ |
118
|
0
|
|
|
0
|
|
|
my ( $this, $op ) = splice @_, 0, 2; |
119
|
0
|
|
|
|
|
|
my $range = $this->new(); |
120
|
|
|
|
|
|
|
|
121
|
0
|
0
|
|
|
|
|
map { return $range if $_->empty() } @_; |
|
0
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
|
123
|
0
|
|
0
|
|
|
|
my $cluster = $_ENV{cluster} || croak "'cluster' not set"; |
124
|
0
|
|
|
|
|
|
my ( $table, $key, $value ) = map { scalar $_->list() } @_; |
|
0
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
for my $table ( @$table ) |
127
|
|
|
|
|
|
|
{ |
128
|
0
|
|
|
|
|
|
for my $key ( @$key ) |
129
|
|
|
|
|
|
|
{ |
130
|
0
|
0
|
|
|
|
|
if ( $op eq ':' ) |
|
|
0
|
|
|
|
|
|
131
|
|
|
|
|
|
|
{ |
132
|
0
|
|
|
|
|
|
$range += $this->new |
133
|
|
|
|
|
|
|
( |
134
|
0
|
|
|
|
|
|
map { $cluster->$table( cluster => $key, value => $_ ) } |
135
|
|
|
|
|
|
|
@$value |
136
|
|
|
|
|
|
|
); |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
elsif ( $op eq '=' ) |
139
|
|
|
|
|
|
|
{ |
140
|
0
|
|
|
|
|
|
$range += $this->new |
141
|
|
|
|
|
|
|
( |
142
|
0
|
|
|
|
|
|
map { $cluster->$table( key => $key, value => $_ ) } |
143
|
|
|
|
|
|
|
@$value |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
else |
147
|
|
|
|
|
|
|
{ |
148
|
0
|
|
|
|
|
|
$range += $this->new |
149
|
|
|
|
|
|
|
( |
150
|
0
|
|
|
|
|
|
map { $cluster->$table( cluster => $key, key => $_ ) } |
151
|
|
|
|
|
|
|
@$value |
152
|
|
|
|
|
|
|
); |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
0
|
|
|
|
|
|
return $range; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head1 MODULES |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::Client |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Cluster client |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::Cache |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Caching server. Implements DynGig::Range::Cluster::Interface. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::Server |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
Cluster server. Implements DynGig::Range::Cluster::Interface. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::Interface |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
Extends DynGig::Util::TCPServer. |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::Config |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Cluster configuration methods |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head2 DynGig::Range::Cluster::EZDB |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Extends DynGig::Util::EZDB |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head1 AUTHOR |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
Kan Liu |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head1 COPYRIGHT and LICENSE |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Copyright (c) 2010. Kan Liu |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
This program is free software; you may redistribute it and/or modify |
195
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=cut |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
1; |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
__END__ |