line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package File::BetweenTree; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Copyright (C) 2013 by Mitsuru Yasuda. All rights reserved. |
4
|
|
|
|
|
|
|
# mail bugs, comments and feedback to dsyrtm@gmail.com |
5
|
|
|
|
|
|
|
|
6
|
6
|
|
|
6
|
|
183882
|
use strict; |
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
270
|
|
7
|
6
|
|
|
6
|
|
32
|
use warnings; |
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
198
|
|
8
|
6
|
|
|
6
|
|
31
|
use Carp ':DEFAULT', 'confess'; |
|
6
|
|
|
|
|
17
|
|
|
6
|
|
|
|
|
1337
|
|
9
|
6
|
|
|
6
|
|
37
|
use Fcntl qw(:seek O_RDONLY); |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
19892
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = '1.02'; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new { |
14
|
5
|
|
|
5
|
1
|
4327062
|
my ($class, $file, $recsep) = @_; |
15
|
5
|
|
|
|
|
14
|
my $self; |
16
|
|
|
|
|
|
|
|
17
|
5
|
50
|
33
|
|
|
137
|
$self->{_sep_} = $recsep || ($^O =~ /win32/i) ? "\015\012" |
|
|
50
|
|
|
|
|
|
18
|
|
|
|
|
|
|
:($^O =~ /mac/i) ? "\015" : "\012"; |
19
|
5
|
|
|
|
|
21
|
bless($self, $class); |
20
|
5
|
50
|
|
|
|
674
|
sysopen $self->{fh}, $file, O_RDONLY or return; |
21
|
5
|
|
|
|
|
27
|
binmode $self->{fh}; |
22
|
|
|
|
|
|
|
|
23
|
5
|
|
|
|
|
30
|
return $self; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
sub search { |
26
|
5
|
|
|
5
|
1
|
94
|
my($self, |
27
|
|
|
|
|
|
|
$my_min, |
28
|
|
|
|
|
|
|
$my_max, |
29
|
|
|
|
|
|
|
$mode, |
30
|
|
|
|
|
|
|
$result_limit, |
31
|
|
|
|
|
|
|
$result_offset, |
32
|
|
|
|
|
|
|
$order_by, |
33
|
|
|
|
|
|
|
$col_sep, |
34
|
|
|
|
|
|
|
$col_num, |
35
|
|
|
|
|
|
|
) = @_; |
36
|
5
|
|
|
|
|
12
|
$my_max = '' ? $my_min : $my_max; |
37
|
5
|
|
50
|
|
|
38
|
$result_limit ||= 1000; |
38
|
5
|
|
50
|
|
|
36
|
$result_offset ||= 0; |
39
|
5
|
|
100
|
|
|
30
|
$order_by ||= 'ASC'; |
40
|
5
|
|
50
|
|
|
33
|
$col_sep ||= ','; |
41
|
5
|
|
100
|
|
|
29
|
$col_num ||= 0; |
42
|
5
|
|
100
|
|
|
33
|
$mode ||= 0; |
43
|
|
|
|
|
|
|
|
44
|
5
|
50
|
33
|
|
|
63
|
croak "0 mode, only the number" if |
|
|
|
66
|
|
|
|
|
45
|
|
|
|
|
|
|
!$mode && ($my_min =~ /[^\-\.\d]/ || $my_max =~ /[^\-\.\d]/); |
46
|
|
|
|
|
|
|
|
47
|
5
|
|
|
|
|
16
|
my $read_size = 1 << 12; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# debug reverse |
50
|
5
|
100
|
100
|
|
|
70
|
if (!$mode && ( $my_min > $my_max )) { |
|
|
50
|
66
|
|
|
|
|
51
|
1
|
|
|
|
|
4
|
($my_min, $my_max) = ($my_max, $my_min); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
elsif ($mode && ($my_min cmp $my_max) eq 1 ) { |
54
|
0
|
|
|
|
|
0
|
($my_min, $my_max) = ($my_max, $my_min); |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
5
|
|
|
|
|
53
|
seek $self->{fh}, 0, SEEK_END; |
58
|
5
|
|
|
|
|
20
|
my $size = tell $self->{fh}; |
59
|
|
|
|
|
|
|
|
60
|
5
|
|
|
|
|
18
|
$self->{col_sep} = $col_sep; |
61
|
5
|
|
|
|
|
12
|
$self->{col_num} = $col_num; |
62
|
5
|
|
|
|
|
9
|
my($row,$tip,$str); |
63
|
|
|
|
|
|
|
|
64
|
5
|
|
|
|
|
25
|
my $_var = int ($size / 2); |
65
|
5
|
|
|
|
|
12
|
my $_pos = $_var; |
66
|
5
|
|
|
|
|
11
|
my $_min = 0; |
67
|
5
|
|
|
|
|
9
|
my $_top = 0;# minimum of _max |
68
|
5
|
|
|
|
|
11
|
my $_max = $size; |
69
|
5
|
|
|
|
|
9
|
while (1) { |
70
|
21
|
|
|
|
|
70
|
($str,$tip,$row)=$self->scoop($_pos); |
71
|
21
|
|
|
|
|
50
|
$_var = int ($_var / 2); |
72
|
|
|
|
|
|
|
# want to approach the my_max |
73
|
21
|
100
|
|
|
|
141
|
if ($mode) { |
74
|
3
|
100
|
66
|
|
|
26
|
if ( ($my_max cmp $str) eq -1 && ( $_max > $_pos ) ) { |
|
|
50
|
33
|
|
|
|
|
75
|
2
|
|
|
|
|
3
|
$_max = $_pos; $self->{_mon_} .= "<=|"; |
|
2
|
|
|
|
|
5
|
|
76
|
|
|
|
|
|
|
} elsif (($my_max cmp $str) eq 1 && ($_top < $_pos)) { |
77
|
1
|
|
|
|
|
2
|
$_top = $_pos; $self->{_mon_} .= "=>|"; |
|
1
|
|
|
|
|
4
|
|
78
|
0
|
|
|
|
|
0
|
} else { $self->{_mon_} .= " |" } |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
else { |
81
|
18
|
100
|
66
|
|
|
136
|
if ( ($my_max-$str) < 0 && ( $_max > $_pos ) ) { |
|
|
100
|
66
|
|
|
|
|
82
|
1
|
|
|
|
|
2
|
$_max = $_pos; $self->{_mon_} .= "<=|"; |
|
1
|
|
|
|
|
4
|
|
83
|
|
|
|
|
|
|
} elsif (($my_max-$str) > 0 && ($_top < $_pos)) { |
84
|
5
|
|
|
|
|
8
|
$_top = $_pos; $self->{_mon_} .= "=>|"; |
|
5
|
|
|
|
|
15
|
|
85
|
12
|
|
|
|
|
27
|
} else { $self->{_mon_} .= " |" } |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# adjust the minimum value |
89
|
21
|
100
|
100
|
|
|
165
|
if ( |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
90
|
|
|
|
|
|
|
( $mode && ($my_min cmp $str) < 1 ) || |
91
|
|
|
|
|
|
|
(!$mode && $my_min <= $str) |
92
|
|
|
|
|
|
|
) { |
93
|
10
|
|
|
|
|
61
|
$self->{_mon_} .= "<- $_pos $_var\n"; |
94
|
10
|
|
|
|
|
34
|
$_pos -= $_var; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
else { |
97
|
11
|
|
|
|
|
38
|
$self->{_mon_} .= "-> $_pos $_var | min\n"; |
98
|
11
|
|
|
|
|
99
|
$_min = $_pos; $_pos += $_var; |
|
11
|
|
|
|
|
18
|
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
21
|
100
|
|
|
|
64
|
last if( $_var < $read_size );# |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# adjust the maximum value |
106
|
5
|
|
|
|
|
14
|
$_var = int(($_max - $_top) / 2); |
107
|
5
|
|
|
|
|
10
|
$_pos = $_top + $_var; |
108
|
5
|
|
|
|
|
10
|
while (1) { |
109
|
15
|
|
|
|
|
41
|
($str,$tip,$row)=$self->scoop($_pos); |
110
|
15
|
|
|
|
|
98
|
$_var = int ($_var / 2); |
111
|
15
|
100
|
66
|
|
|
157
|
if (($mode && ($my_max cmp $str) >= 0 |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
112
|
|
|
|
|
|
|
|| (!$mode && $my_max >= $str))){ |
113
|
10
|
|
|
|
|
14
|
$_pos += $_var; |
114
|
10
|
|
|
|
|
32
|
$self->{_mon_} .= "=>| $_pos $_var\n"; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
else { |
117
|
|
|
|
|
|
|
|
118
|
5
|
|
|
|
|
35
|
$_max = $_pos + $tip; $_pos -= $_var; |
|
5
|
|
|
|
|
8
|
|
119
|
5
|
|
|
|
|
20
|
$self->{_mon_} .= "<=| $_pos $_var | max\n"; |
120
|
|
|
|
|
|
|
} |
121
|
15
|
100
|
|
|
|
42
|
last if( $_var < $read_size );# |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Locate The Data From Block |
125
|
5
|
|
|
|
|
12
|
my (@z, @_add); |
126
|
0
|
|
|
|
|
0
|
my ($dat, $ll, $_z, $_s, $count, $spare); |
127
|
5
|
|
|
|
|
10
|
my $t = ''; |
128
|
5
|
|
|
|
|
11
|
my $_sep = ''; |
129
|
5
|
|
|
|
|
33
|
$self->{_mon_} = "roughly_offset_addr:$_min " |
130
|
|
|
|
|
|
|
."search_length:".($_max-$_min)."\n\n" |
131
|
|
|
|
|
|
|
. $self->{_mon_}; |
132
|
|
|
|
|
|
|
|
133
|
5
|
100
|
|
|
|
27
|
if ($order_by =~ /DESC/i) { |
134
|
1
|
|
|
|
|
4
|
my $read_pos = $_max; |
135
|
1
|
|
|
|
|
2
|
while (1) { |
136
|
|
|
|
|
|
|
|
137
|
1
|
|
|
|
|
3
|
$count++; |
138
|
|
|
|
|
|
|
|
139
|
1
|
|
|
|
|
1
|
$read_pos -= $read_size; |
140
|
1
|
50
|
|
|
|
5
|
if ($read_pos < 0) { $read_size += $read_pos; $read_pos = 0 } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
141
|
|
|
|
|
|
|
|
142
|
1
|
|
|
|
|
10
|
seek $self->{fh}, $read_pos, 0; |
143
|
1
|
|
|
|
|
16
|
read $self->{fh}, $dat, $read_size; |
144
|
|
|
|
|
|
|
|
145
|
1
|
|
|
|
|
2
|
$dat .= $t; |
146
|
1
|
|
|
|
|
343
|
@z = reverse split $self->{_sep_}, $dat; |
147
|
1
|
50
|
33
|
|
|
34
|
shift @z if ($count eq 1 && $_max ne $size ); |
148
|
|
|
|
|
|
|
|
149
|
1
|
|
|
|
|
4
|
for $ll ( 1 .. $#z ){ |
150
|
|
|
|
|
|
|
|
151
|
294
|
|
|
|
|
978
|
$_z = shift @z; |
152
|
294
|
|
|
|
|
656
|
$_s = (split $col_sep, $_z)[$col_num]; |
153
|
|
|
|
|
|
|
|
154
|
294
|
50
|
33
|
|
|
671
|
unless (!$mode && $_s =~ /[^\-\.\d]/) { |
155
|
294
|
50
|
33
|
|
|
2370
|
push @_add, $_z if (( |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
156
|
|
|
|
|
|
|
(!$mode && $my_min <= $_s && $_s <= $my_max ) || |
157
|
|
|
|
|
|
|
( $mode && ($my_min cmp $_s) < 1 && ($_s cmp $my_max) < 1 )) |
158
|
|
|
|
|
|
|
&& (--$result_offset < 0) |
159
|
|
|
|
|
|
|
&& (--$result_limit >= 0)); |
160
|
|
|
|
|
|
|
|
161
|
294
|
50
|
33
|
|
|
2528
|
$spare = $_z if( |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
162
|
|
|
|
|
|
|
(!$spare && !$mode && $my_min >= $_s) || |
163
|
|
|
|
|
|
|
(!$spare && $mode && ($my_min cmp $_s) >= 0) ); |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
294
|
100
|
|
|
|
588
|
last if $result_limit <= 0; |
167
|
|
|
|
|
|
|
} |
168
|
1
|
|
|
|
|
4
|
$t = shift @z; |
169
|
1
|
|
50
|
|
|
22
|
$_s = (split $col_sep, $t)[$col_num] || ''; |
170
|
|
|
|
|
|
|
|
171
|
1
|
0
|
0
|
|
|
6
|
push @_add, $t if(($read_pos eq 0) |
|
|
|
33
|
|
|
|
|
172
|
|
|
|
|
|
|
&&((!$mode && $my_min <= $_s && $_s <= $my_max ) |
173
|
|
|
|
|
|
|
||( $mode && ($my_min cmp $_s) < 1 && ($_s cmp $my_max) < 1 ))); |
174
|
|
|
|
|
|
|
|
175
|
1
|
50
|
33
|
|
|
30
|
last if ($read_pos <= $_min || $result_limit <= 0); |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
else { # AEC |
180
|
|
|
|
|
|
|
|
181
|
4
|
|
|
|
|
16
|
my $read_pos = $_min; |
182
|
4
|
|
|
|
|
7
|
my $eof = 1; |
183
|
4
|
|
|
|
|
6
|
while (1) { |
184
|
|
|
|
|
|
|
|
185
|
5
|
|
|
|
|
12
|
$count++; |
186
|
|
|
|
|
|
|
|
187
|
5
|
|
|
|
|
663
|
seek $self->{fh}, $read_pos, 0; |
188
|
5
|
|
|
|
|
81
|
read $self->{fh}, $dat, $read_size; |
189
|
|
|
|
|
|
|
|
190
|
5
|
|
|
|
|
29
|
$dat = $t . $_sep . $dat; |
191
|
|
|
|
|
|
|
#$_sep = $dat =~ /($self->{_sep_})$/ ? $1 : ''; |
192
|
5
|
100
|
|
|
|
106
|
$_sep = $dat =~ s/($self->{_sep_})$// ? $1 : ''; |
193
|
|
|
|
|
|
|
|
194
|
5
|
|
|
|
|
643
|
@z = split $self->{_sep_}, $dat; |
195
|
5
|
100
|
100
|
|
|
1284
|
shift @z if ($count eq 1 && $_min ne 0); |
196
|
|
|
|
|
|
|
|
197
|
5
|
|
|
|
|
12
|
$read_pos += $read_size; |
198
|
5
|
100
|
|
|
|
16
|
$eof = 0 if ($read_pos >= $_max); |
199
|
|
|
|
|
|
|
|
200
|
5
|
|
|
|
|
20
|
for $ll ( $eof .. $#z ){ |
201
|
|
|
|
|
|
|
|
202
|
783
|
|
|
|
|
1050
|
$_z = shift @z; |
203
|
783
|
|
|
|
|
11698
|
$_s = (split $col_sep, $_z)[$col_num]; |
204
|
|
|
|
|
|
|
|
205
|
783
|
50
|
33
|
|
|
3441
|
unless (!$mode && $_s =~ /[^\-\.\d]/) { |
206
|
783
|
50
|
33
|
|
|
5516
|
push @_add, $_z if (( |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
207
|
|
|
|
|
|
|
( $mode && ($my_min cmp $_s) < 1 && ($_s cmp $my_max) < 1) || |
208
|
|
|
|
|
|
|
(!$mode && $my_min <= $_s && $_s <= $my_max )) |
209
|
|
|
|
|
|
|
&& (--$result_offset < 0) |
210
|
|
|
|
|
|
|
&& (--$result_limit >= 0)); |
211
|
|
|
|
|
|
|
|
212
|
783
|
100
|
33
|
|
|
4676
|
$spare = $_z if( # && $#z >= 0 |
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
213
|
|
|
|
|
|
|
( $mode && ($my_min cmp $_s) >= 0) ) || |
214
|
|
|
|
|
|
|
(!$mode && $my_min >= $_s); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
783
|
100
|
|
|
|
1604
|
last if $result_limit <= 0; |
218
|
|
|
|
|
|
|
} |
219
|
5
|
|
|
|
|
14
|
$t = shift @z; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
last if |
222
|
5
|
100
|
66
|
|
|
44
|
($read_pos >= $_max || $read_pos > $size || $result_limit <= 0); |
|
|
|
100
|
|
|
|
|
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
5
|
|
|
|
|
31
|
$self->{_mon_} = "file_read:$count " . $self->{_mon_}; |
227
|
|
|
|
|
|
|
|
228
|
5
|
100
|
|
|
|
20
|
$spare = '' unless defined $spare; |
229
|
5
|
100
|
|
|
|
132
|
return @_add ? \@_add : ['NULL', $spare]; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
sub scoop { |
233
|
36
|
|
|
36
|
0
|
64
|
my ($self, $_pos) = @_; |
234
|
36
|
|
|
|
|
45
|
my ($row, $tip); |
235
|
36
|
|
|
|
|
284
|
seek $self->{fh}, $_pos, 0; read $self->{fh}, $row, 1024; |
|
36
|
|
|
|
|
530
|
|
236
|
36
|
|
|
|
|
331
|
($tip, $row) = split /$self->{_sep_}/, $row; $tip = length($tip)+1; |
|
36
|
|
|
|
|
96
|
|
237
|
36
|
|
|
|
|
142
|
my $str = (split($self->{col_sep}, $row))[$self->{col_num}]; |
238
|
36
|
|
|
|
|
139
|
return ($str,$tip,$row); |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
sub mon { |
241
|
0
|
|
|
0
|
0
|
0
|
"Process:\n-----------------------\n". |
242
|
|
|
|
|
|
|
shift->{_mon_}; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
sub DESTROY { |
245
|
5
|
|
|
5
|
|
3418
|
my $self = shift; |
246
|
5
|
50
|
|
|
|
24177
|
defined $self->{fh} && close $self->{fh}; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
sub view { |
249
|
|
|
|
|
|
|
# |
250
|
|
|
|
|
|
|
# viewing by specifying a pointer |
251
|
|
|
|
|
|
|
# |
252
|
|
|
|
|
|
|
# Example: |
253
|
|
|
|
|
|
|
# print $bt->view(0, 1024); |
254
|
|
|
|
|
|
|
# |
255
|
0
|
|
|
0
|
0
|
|
my ($self, $offset_byts, $length) = @_; |
256
|
0
|
|
|
|
|
|
my $dat; |
257
|
0
|
|
|
|
|
|
seek $self->{fh}, $offset_byts, 0; |
258
|
0
|
|
|
|
|
|
read $self->{fh}, $dat, $length; |
259
|
0
|
|
|
|
|
|
join "\n", split $self->{_sep_}, $dat; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
__END__ |