File Coverage

blib/lib/KiokuDB/Collapser/Buffer.pm
Criterion Covered Total %
statement 82 86 95.3
branch 27 32 84.3
condition 9 12 75.0
subroutine 18 19 94.7
pod 0 15 0.0
total 136 164 82.9


line stmt bran cond sub pod time code
1             package KiokuDB::Collapser::Buffer;
2 20     20   91 use Moose;
  20         24  
  20         129  
3              
4 20     20   100380 use Hash::Util::FieldHash::Compat qw(idhash);
  20         37  
  20         216  
5 20     20   11791 use Set::Object;
  20         99344  
  20         849  
6              
7 20     20   121 use namespace::clean -except => 'meta';
  20         28  
  20         186  
8              
9             has live_objects => (
10             isa => "KiokuDB::LiveObjects",
11             is => "ro",
12             required => 1,
13             );
14              
15             has _objects => (
16             isa => "HashRef",
17             is => "ro",
18             default => sub { idhash my %hash },
19             );
20              
21             sub object_to_id {
22 4987     4987 0 6840 my ( $self, $object ) = @_;
23 4987         129207 $self->_objects->{$object};
24             }
25              
26             sub merged_objects_to_ids {
27 1546     1546 0 3953 my ( $self, @objects ) = @_;
28              
29 1546         47532 my $l = $self->live_objects;
30              
31 1546 100       3460 map { $self->object_to_id($_) || $l->object_to_id($_) } @objects;
  2525         5741  
32             }
33              
34             has _ids => (
35             isa => "HashRef",
36             is => "ro",
37             default => sub { return {} },
38             );
39              
40             has _entry_args => (
41             isa => "HashRef",
42             is => "ro",
43             default => sub { return {} },
44             );
45              
46             sub id_to_object {
47 0     0 0 0 my ( $self, $id ) = @_;
48              
49 0 0       0 if ( defined ( my $obj = $self->_ids->{$id} ) ) {
50 0         0 return $obj;
51             } else {
52 0         0 return $self->live_objects->id_to_object($id);
53             }
54             }
55              
56             has entries => (
57             traits => ["Hash"],
58             isa => "HashRef",
59             reader => "_entries",
60             default => sub { return {} },
61             handles => {
62             entries => "values",
63             ids => "keys",
64             },
65             );
66              
67             sub id_to_entry {
68 66     66 0 149 my ( $self, $id ) = @_;
69 66         2016 $self->_entries->{$id};
70             }
71              
72             has intrinsic => (
73             isa => "HashRef",
74             is => "ro",
75             default => sub { idhash my %hash },
76             );
77              
78             sub intrinsic_entry {
79 2462     2462 0 2733 my ( $self, $obj ) = @_;
80 2462         64284 $self->intrinsic->{$obj};
81             }
82              
83             sub insert_intrinsic {
84 104     104 0 152 my ( $self, $object, $entry ) = @_;
85 104         2933 $self->intrinsic->{$object} = $entry;
86             }
87              
88             # a list of the IDs of all simple entries
89             has simple_entries => (
90             isa => 'ArrayRef',
91             is => "ro",
92             default => sub { [] },
93             );
94              
95             # first_class keeps track of the simple references which are first class
96             # (either weak or shared, and must have an entry)
97             has first_class => (
98             isa => 'Set::Object',
99             is => "ro",
100             default => sub { Set::Object->new },
101             );
102              
103             has options => (
104             isa => 'HashRef',
105             is => "ro",
106             default => sub { {} },
107             );
108              
109             sub insert {
110 17768     17768 0 28442 my ( $self, $id, $object, @args ) = @_;
111              
112 17768         480583 $self->_objects->{$object} = $id;
113 17768         454920 $self->_ids->{$id} = $object;
114 17768 50       49153 $self->_entry_args->{$id} = \@args if @args;
115             }
116              
117             sub insert_entry {
118 9487     9487 0 16915 my ( $self, $id, $entry, $object, @args ) = @_;
119              
120 9487         289405 $self->_entries->{$id} = $entry;
121 9487         20055 $self->insert($id, $object, @args);
122             }
123              
124             sub compact_entries {
125 1545     1545 0 2737 my $self = shift;
126              
127 1545         46286 my ( $entries, $fc, $simple, $options ) = ( $self->_entries, $self->first_class, $self->simple_entries, $self->options );
128              
129             # unify non shared simple references
130 1545 100       6637 if ( my @flatten = grep { not $fc->includes($_) } @$simple ) {
  6289         14657  
131 682         1186 my %flatten;
132 682         1188 @flatten{@flatten} = delete @{$entries}{@flatten};
  682         7423  
133              
134 682         5121 $self->compact_entry($_, \%flatten) for values %$entries;
135             }
136             }
137              
138             sub compact_entry {
139 8557     8557 0 9228 my ( $self, $entry, $flatten ) = @_;
140              
141 8557         185949 my $data = $entry->data;
142              
143 8557 100       13951 if ( $self->compact_data($data, $flatten) ) {
144 4         123 $entry->_data($data);
145             }
146             }
147              
148             sub compact_data {
149 17366     17366 0 17662 my ( $self, $data, $flatten ) = @_;
150              
151 17366 100 100     35020 if ( ref $data eq 'KiokuDB::Reference' ) {
    100          
    100          
    100          
    100          
152 8648         201750 my $id = $data->id;
153              
154 8648 100       19188 if ( my $entry = $flatten->{$id} ) {
155             # replace reference with data from entry, so that the
156             # simple data is inlined, and mark that entry for removal
157 6059         10869 $self->compact_entry($entry, $flatten);
158              
159 6059 100 66     132142 if ( $entry->tied or $entry->class ) {
160 4         129 $entry->clear_id;
161 4         8 $_[1] = $entry;
162             } else {
163 6055         127079 $_[1] = $entry->data;
164             }
165 6059         147408 return 1;
166             }
167             } elsif ( ref($data) eq 'ARRAY' ) {
168 6033   66     12751 ref && $self->compact_data($_, $flatten) for @$data;
169             } elsif ( ref($data) eq 'HASH' ) {
170 2388   66     10704 ref && $self->compact_data($_, $flatten) for values %$data;
171             } elsif ( ref($data) eq 'SCALAR' || ref($data) eq 'REF' ) {
172 43         120 $self->compact_data($$data, $flatten);
173             } elsif ( ref($data) eq 'KiokuDB::Entry' ) {
174 90         194 $self->compact_entry($data, $flatten);
175             } else {
176             # passthrough
177             }
178              
179 11307         44089 return;
180             }
181              
182             sub imply_root {
183 972     972 0 2205 my ( $self, @ids ) = @_;
184              
185 972         30913 my $entries = $self->_entries;
186              
187 972         1993 foreach my $id ( @ids ) {
188 1679 100       5216 my $entry = $entries->{$id} or next;
189 1514 50       41161 next if $entry->has_root; # set by typemap
190 1514         35391 $entry->root(1);
191             }
192             }
193              
194             sub commit {
195 1500     1500 0 2972 my ( $self, $backend ) = @_;
196              
197 1500         4498 $self->insert_to_backend($backend);
198 1500         15300 $self->update_entries( in_storage => 1 );
199             }
200              
201             sub insert_to_backend {
202 1500     1500 0 2569 my ( $self, $backend ) = @_;
203              
204 1500         2381 $backend->insert(values %{ $self->_entries });
  1500         45153  
205             }
206              
207             sub update_entries {
208 1507     1507 0 3084 my ( $self, @shared_args ) = @_;
209              
210 1507         46373 my ( $e, $o ) = ( $self->_entries, $self->_ids );
211              
212 1507         40386 my $l = $self->live_objects;
213              
214 1507         41516 my $args = $self->_entry_args;
215              
216 1507         5297 foreach my $id ( keys %$e ) {
217 3374         7236 my ( $object, $entry ) = ( $o->{$id}, $e->{$id} );
218              
219 3374 50       3352 my @args = @{ $args->{$id} || [] }; # FIXME XXX FIXME FIXME XXX BLAH BLAH
  3374         15124  
220              
221 3374         12815 $l->register_entry( $id => $entry, @shared_args );
222              
223 3374 100       10087 unless ( $l->object_to_id($object) ) {
224 2037         5786 $l->register_object( $id => $object, @args );
225             } else {
226 1337         5479 $l->update_object_entry( $object, $entry, @args );
227             }
228             }
229             }
230              
231             __PACKAGE__->meta->make_immutable;
232              
233             __PACKAGE__
234              
235             __END__