File Coverage

blib/lib/KinoSearch1/Index/CompoundFileWriter.pm
Criterion Covered Total %
statement 45 45 100.0
branch 4 8 50.0
condition n/a
subroutine 8 8 100.0
pod 1 3 33.3
total 58 64 90.6


line stmt bran cond sub pod time code
1             package KinoSearch1::Index::CompoundFileWriter;
2 34     34   202 use strict;
  34         74  
  34         1182  
3 34     34   191 use warnings;
  34         71  
  34         9989  
4 34     34   424 use KinoSearch1::Util::ToolSet;
  34         73  
  34         5381  
5 34     34   220 use base qw( KinoSearch1::Util::Class );
  34         92  
  34         3373  
6              
7             BEGIN {
8 34     34   330 __PACKAGE__->init_instance_vars(
9             # constructor params / members
10             invindex => undef,
11             filename => undef,
12             # members
13             entries => undef,
14             merged => 0,
15             );
16             }
17              
18             sub init_instance {
19 61     61 1 127 my $self = shift;
20 61         450 $self->{entries} = {};
21             }
22              
23             # Add a file to the list of files-to-merge.
24             sub add_file {
25 553     553 0 889 my ( $self, $filename ) = @_;
26 553 50       1370 croak("filename '$filename' already added")
27             if $self->{entries}{$filename};
28 553         2631 $self->{entries}{$filename} = 1;
29             }
30              
31             # Write a compound file.
32             sub finish {
33 61     61 0 177 my $self = shift;
34 61         161 my $invindex = $self->{invindex};
35 61         124 my $filename = $self->{filename};
36 61         114 my @files_to_merge = keys %{ $self->{entries} };
  61         418  
37 61 50       251 croak('no entries defined') unless @files_to_merge;
38              
39             # ensure that the file only gets written once; open the outfile
40 61 50       445 croak('merge already performed') if $self->{merged};
41 61         129 $self->{merged} = 1;
42 61 50       235 $invindex->delete_file($filename) if $invindex->file_exists($filename);
43 61         251 my $outstream = $invindex->open_outstream($filename);
44              
45             # write number of files, plus data_offset placeholders
46 61         152 my @to_write = map { ( 0, $_ ) } @files_to_merge;
  553         1018  
47 61         228 unshift @to_write, scalar @files_to_merge;
48 61         246 my $template = 'V' . ( 'QT' x scalar @files_to_merge );
49 61         450 $outstream->lu_write( $template, @to_write );
50              
51             # copy data
52 61         129 my @data_offsets;
53 61         132 my $out_fh = $outstream;
54 61         150 for my $file (@files_to_merge) {
55 553         1569 push @data_offsets, $outstream->tell;
56 553         1538 my $instream = $invindex->open_instream($file);
57 553         39055 $outstream->absorb($instream);
58             }
59              
60             # rewrite number of files, plus real data offsets
61 61         693 $outstream->seek(0);
62 61         885 @to_write = map { ( shift @data_offsets, $_ ) } @files_to_merge;
  553         1384  
63 61         250 unshift @to_write, scalar @files_to_merge;
64 61         466 $outstream->lu_write( $template, @to_write );
65              
66 61         241 $outstream->close;
67             }
68              
69             1;
70              
71             __END__