File Coverage

blib/lib/Data/Range/Compare/Stream/Iterator/Consolidate/OverlapAsColumn.pm
Criterion Covered Total %
statement 109 110 99.0
branch 31 36 86.1
condition 2 3 66.6
subroutine 26 26 100.0
pod 11 19 57.8
total 179 194 92.2


line stmt bran cond sub pod time code
1             package Data::Range::Compare::Stream::Iterator::Consolidate::OverlapAsColumn;
2              
3 3     3   3292 use strict;
  3         5  
  3         81  
4 3     3   14 use warnings;
  3         6  
  3         85  
5 3     3   13 use Carp qw(croak);
  3         5  
  3         141  
6              
7 3     3   13 use base qw(Data::Range::Compare::Stream::Iterator::Consolidate);
  3         6  
  3         252  
8 3     3   2294 use Data::Range::Compare::Stream::Iterator::Array;
  3         5  
  3         101  
9              
10 3     3   15 use constant NEW_ARRAY_ITERATOR_FROM=>'Data::Range::Compare::Stream::Iterator::Array';
  3         5  
  3         182  
11 3     3   12 use constant NEW_CHILD_CONSOLIDATOR_FROM=>'Data::Range::Compare::Stream::Iterator::Consolidate::OverlapAsColumn';
  3         6  
  3         3242  
12              
13             sub new {
14 44     44 0 161 my ($class,$it,$cmp,%args)=@_;
15 44 50       265 croak('Required Arguments are: $iterator,$compare') unless defined($cmp);
16 44         212 my $self=$class->SUPER::new($it,compare=>$cmp,buffer=>[],%args);
17 44         122 return $self;
18             }
19              
20 50     50 1 104 sub get_child { $_[0]->{consolidator} }
21              
22             sub delete_from_root {
23 2     2 1 4 my ($self)=@_;
24 2 100       5 if($self->has_child) {
25 1         4 my $child=$self->get_child;
26 1         3 delete $child->{root_iterator};
27             }
28 2 50       7 if($self->is_child) {
29 2         5 my $root=$self->get_root;
30 2         4 delete @{$root}{qw(iterator_array consolidator)};
  2         35  
31             }
32             }
33              
34             sub get_child_column_id {
35 4     4 1 15 my ($self)=@_;
36 4 50       11 return undef unless $self->has_child;
37 4         11 $self->get_child->get_column_id;
38             }
39              
40             sub on_consolidate {
41 88     88 1 164 my ($self,$new_range,$last_range,$next_range)=@_;
42              
43 88         152 my $cmp=$self->{compare};
44 88         109 my $iterator;
45              
46 88 100       230 if(defined($self->{iterator_array})) {
47 61         105 $iterator=$self->{iterator_array};
48 61         199 $iterator->insert_range($next_range);
49             } else {
50 27         166 $iterator=$self->{iterator_array}=$self->NEW_ARRAY_ITERATOR_FROM->new(sorted=>1);
51 27         102 $iterator->insert_range($next_range);
52 27         134 my $consolidator=$self->{consolidator}=$self->NEW_CHILD_CONSOLIDATOR_FROM->new($iterator,$cmp);
53 27         74 $consolidator->{root_iterator}=$self;
54             }
55              
56             }
57              
58             sub get_root_column_id {
59 34     34 1 59 my ($self)=@_;
60 34 50       76 return $self->get_root->get_column_id if $self->is_child;
61 0         0 $self->get_column_id
62             }
63              
64 369     369 0 1247 sub is_child { defined($_[0]->{root_iterator}) }
65              
66 1     1 0 4 sub is_root { !$_[0]->is_child }
67 11     11 0 46 sub has_child { defined($_[0]->{iterator_array}) }
68 3     3 0 10 sub has_root { defined($_[0]->get_root)}
69              
70 181     181 1 329 sub get_compare { $_[0]->{compare} }
71              
72             sub get_root {
73 220     220 1 307 my ($self)=@_;
74 220         553 $self->{root_iterator};
75             }
76              
77             sub has_next {
78 476     476 0 5645 my ($self)=@_;
79              
80 476 100       552 return 1 if $#{$self->{buffer}}!=-1;
  476         1604  
81 373 100       1115 return 1 if $self->SUPER::has_next;
82              
83 256 100       592 if($self->is_child) {
84 181         347 my $cmp=$self->get_compare;
85 181         343 my $root=$self->get_root;
86 181 100       571 if($root->SUPER::has_next) {
87 20         51 $root->push_to_buffer;
88 20 100       28 return 1 if $#{$self->{buffer}}!=-1;
  20         106  
89             }
90             }
91 244         883 return 0;
92             }
93              
94 5     5 1 18 sub get_current_result { $_[0]->{current_result} }
95              
96             sub get_next {
97 88     88 1 157 my ($self)=@_;
98              
99 88 100 66     114 if($#{$self->{buffer}}==-1 and $self->SUPER::has_next) {
  88         407  
100 33         90 $self->push_to_buffer;
101             }
102 88         150 my $result=shift @{$self->{buffer}};
  88         179  
103 88         170 $self->{current_result}=$result;
104 88         262 return $result;
105              
106             }
107              
108 13     13 1 2978 sub buffer_count { 1 + $#{$_[0]->{buffer}} }
  13         83  
109              
110 2     2 0 12 sub get_buffer { $_[0]->{buffer} }
111              
112 252     252 0 848 sub iterator_has_next { $_[0]->{iterator}->has_next }
113              
114             sub push_to_buffer {
115 98     98 1 152 my ($self)=@_;
116              
117 98         118 my $overlapping_range;
118 98 100       245 if(defined($self->{last_range})) {
119 38         76 $overlapping_range=$self->{last_range};
120 38         81 $self->{last_range}=undef;
121             } else {
122 60         205 $overlapping_range=$self->{iterator}->get_next;
123 60         132 $self->{last_range}=$overlapping_range;
124             }
125 98 50       275 return 0 unless defined($overlapping_range);
126              
127 98         132 my $result=$overlapping_range;
128 98         142 my $pushed_to_child=0;
129 98 100       194 if($self->iterator_has_next) {
130 66         153 OVERLAP_CHECK: while($self->iterator_has_next) {
131            
132 129         474 my $next_range=$self->{iterator}->get_next;
133            
134 129 100       429 if($overlapping_range->overlap($next_range)) {
135            
136 88         368 $overlapping_range=$overlapping_range->get_overlapping_range([$overlapping_range,$next_range]);
137 88         302 $self->on_consolidate($overlapping_range,$result,$next_range);
138 88         140 $pushed_to_child++;
139 88         287 $self->{last_range}=undef;
140            
141             } else {
142            
143 41         68 $self->{last_range}=$next_range;
144 41         90 last OVERLAP_CHECK;
145            
146             }
147             }
148             } else {
149 32         58 $self->{last_range}=undef;
150             }
151              
152 98 100       276 if($pushed_to_child) {
153 45         117 my $child=$self->get_child;
154 45         141 $child->push_to_buffer;
155 45 100       179 $self->{compare}->insert_consolidator($child) unless defined($child->get_column_id);
156             }
157              
158              
159 98         159 push @{$self->{buffer}},$self->RESULT_CLASS->new($result,$result,$result);
  98         530  
160 98         218 return 1;
161             }
162              
163             1;