Adding upstream version 0.17.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
bb26c2917c
commit
739f200278
29 changed files with 2935 additions and 2272 deletions
83
create_lz.cc
83
create_lz.cc
|
@ -1,18 +1,18 @@
|
|||
/* Tarlz - Archiver with multimember lzip compression
|
||||
Copyright (C) 2013-2019 Antonio Diaz Diaz.
|
||||
/* Tarlz - Archiver with multimember lzip compression
|
||||
Copyright (C) 2013-2020 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
@ -39,9 +39,10 @@
|
|||
|
||||
namespace {
|
||||
|
||||
const Cl_options * gcl_opts = 0; // local vars needed by add_member_lz
|
||||
enum { max_packet_size = 1 << 20 };
|
||||
class Packet_courier;
|
||||
Packet_courier * courierp = 0; // local vars needed by add_member_lz
|
||||
Packet_courier * courierp = 0;
|
||||
unsigned long long partial_data_size = 0; // size of current block
|
||||
|
||||
|
||||
|
@ -156,7 +157,7 @@ public:
|
|||
If filename.empty() (end of lzip member token), move to next queue. */
|
||||
void receive_packet( const Ipacket * const ipacket )
|
||||
{
|
||||
if( ipacket->filename.size() )
|
||||
if( !ipacket->filename.empty() )
|
||||
slot_tally.get_slot(); // wait for a free slot
|
||||
xlock( &imutex );
|
||||
ipacket_queues[receive_worker_id].push( ipacket );
|
||||
|
@ -184,7 +185,7 @@ public:
|
|||
}
|
||||
xunlock( &imutex );
|
||||
if( ipacket )
|
||||
{ if( ipacket->filename.size() ) slot_tally.leave_slot(); }
|
||||
{ if( !ipacket->filename.empty() ) slot_tally.leave_slot(); }
|
||||
else
|
||||
{
|
||||
// notify muxer when last worker exits
|
||||
|
@ -270,13 +271,13 @@ int add_member_lz( const char * const filename, const struct stat *,
|
|||
if( !fill_headers( filename, *extended, header, file_size, flag ) )
|
||||
{ delete[] header; delete extended; return 0; }
|
||||
|
||||
if( solidity == bsolid &&
|
||||
if( gcl_opts->solidity == bsolid &&
|
||||
block_is_full( *extended, file_size, partial_data_size ) )
|
||||
courierp->receive_packet( new Ipacket ); // end of group
|
||||
|
||||
courierp->receive_packet( new Ipacket( filename, file_size, extended, header ) );
|
||||
|
||||
if( solidity == no_solid ) // one tar member per group
|
||||
if( gcl_opts->solidity == no_solid ) // one tar member per group
|
||||
courierp->receive_packet( new Ipacket );
|
||||
if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename );
|
||||
return 0;
|
||||
|
@ -285,31 +286,30 @@ int add_member_lz( const char * const filename, const struct stat *,
|
|||
|
||||
struct Grouper_arg
|
||||
{
|
||||
const Cl_options * cl_opts;
|
||||
Packet_courier * courier;
|
||||
const Arg_parser * parser;
|
||||
bool dereference;
|
||||
};
|
||||
|
||||
|
||||
/* Package metadata of the files to be archived and pass them to the
|
||||
courier for distribution to workers. */
|
||||
courier for distribution to workers.
|
||||
*/
|
||||
extern "C" void * grouper( void * arg )
|
||||
{
|
||||
const Grouper_arg & tmp = *(const Grouper_arg *)arg;
|
||||
const Cl_options & cl_opts = *tmp.cl_opts;
|
||||
Packet_courier & courier = *tmp.courier;
|
||||
const Arg_parser & parser = *tmp.parser;
|
||||
const bool dereference = tmp.dereference;
|
||||
|
||||
for( int i = 0; i < parser.arguments(); ++i ) // parse command line
|
||||
for( int i = 0; i < cl_opts.parser.arguments(); ++i ) // parse command line
|
||||
{
|
||||
const int code = parser.code( i );
|
||||
const std::string & arg = parser.argument( i );
|
||||
const int code = cl_opts.parser.code( i );
|
||||
const std::string & arg = cl_opts.parser.argument( i );
|
||||
const char * filename = arg.c_str();
|
||||
if( code == 'C' && chdir( filename ) != 0 )
|
||||
{ show_file_error( filename, "Error changing working directory", errno );
|
||||
cleanup_and_fail(); }
|
||||
if( code ) continue; // skip options
|
||||
if( parser.argument( i ).empty() ) continue; // skip empty names
|
||||
if( cl_opts.parser.argument( i ).empty() ) continue; // skip empty names
|
||||
std::string deslashed; // arg without trailing slashes
|
||||
unsigned len = arg.size();
|
||||
while( len > 1 && arg[len-1] == '/' ) --len;
|
||||
|
@ -321,13 +321,13 @@ extern "C" void * grouper( void * arg )
|
|||
{ show_file_error( filename, "Can't stat input file", errno );
|
||||
set_error_status( 1 ); }
|
||||
else if( nftw( filename, add_member_lz, 16,
|
||||
dereference ? 0 : FTW_PHYS ) != 0 )
|
||||
cleanup_and_fail(); // write error or oom
|
||||
else if( solidity == dsolid ) // end of group
|
||||
cl_opts.dereference ? 0 : FTW_PHYS ) != 0 )
|
||||
cleanup_and_fail(); // write error or OOM
|
||||
else if( cl_opts.solidity == dsolid ) // end of group
|
||||
courier.receive_packet( new Ipacket );
|
||||
}
|
||||
|
||||
if( solidity == bsolid && partial_data_size ) // finish last block
|
||||
if( cl_opts.solidity == bsolid && partial_data_size ) // finish last block
|
||||
{ partial_data_size = 0; courierp->receive_packet( new Ipacket ); }
|
||||
courier.finish(); // no more packets to send
|
||||
return 0;
|
||||
|
@ -336,7 +336,8 @@ extern "C" void * grouper( void * arg )
|
|||
|
||||
/* Writes ibuf to encoder. To minimize dictionary size, it does not read
|
||||
from encoder until encoder's input buffer is full or finish is true.
|
||||
Sends opacket to courier and allocates new obuf each time obuf is full. */
|
||||
Sends opacket to courier and allocates new obuf each time obuf is full.
|
||||
*/
|
||||
void loop_encode( const uint8_t * const ibuf, const int isize,
|
||||
uint8_t * & obuf, int & opos, Packet_courier & courier,
|
||||
LZ_Encoder * const encoder, const int worker_id,
|
||||
|
@ -395,7 +396,8 @@ struct Worker_arg
|
|||
|
||||
|
||||
/* Get ipackets from courier, compress headers and file data, and give the
|
||||
opackets produced to courier. */
|
||||
opackets produced to courier.
|
||||
*/
|
||||
extern "C" void * cworker( void * arg )
|
||||
{
|
||||
const Worker_arg & tmp = *(const Worker_arg *)arg;
|
||||
|
@ -502,7 +504,8 @@ extern "C" void * cworker( void * arg )
|
|||
|
||||
|
||||
/* Get from courier the processed and sorted packets, and write
|
||||
their contents to the output archive. */
|
||||
their contents to the output archive.
|
||||
*/
|
||||
void muxer( Packet_courier & courier, const int outfd )
|
||||
{
|
||||
while( true )
|
||||
|
@ -521,24 +524,24 @@ void muxer( Packet_courier & courier, const int outfd )
|
|||
|
||||
|
||||
// init the courier, then start the grouper and the workers and call the muxer
|
||||
int encode_lz( const char * const archive_namep, const Arg_parser & parser,
|
||||
int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
|
||||
const int dictionary_size, const int match_len_limit,
|
||||
const int num_workers, const int outfd, const int out_slots,
|
||||
const int debug_level, const bool dereference )
|
||||
const int outfd )
|
||||
{
|
||||
const int in_slots = 65536; // max small files (<=512B) in 64 MiB
|
||||
const int num_workers = cl_opts.num_workers;
|
||||
const int total_in_slots = ( INT_MAX / num_workers >= in_slots ) ?
|
||||
num_workers * in_slots : INT_MAX;
|
||||
gcl_opts = &cl_opts;
|
||||
|
||||
/* If an error happens after any threads have been started, exit must be
|
||||
called before courier goes out of scope. */
|
||||
Packet_courier courier( num_workers, total_in_slots, out_slots );
|
||||
Packet_courier courier( num_workers, total_in_slots, cl_opts.out_slots );
|
||||
courierp = &courier; // needed by add_member_lz
|
||||
|
||||
Grouper_arg grouper_arg;
|
||||
grouper_arg.cl_opts = &cl_opts;
|
||||
grouper_arg.courier = &courier;
|
||||
grouper_arg.parser = &parser;
|
||||
grouper_arg.dereference = dereference;
|
||||
|
||||
pthread_t grouper_thread;
|
||||
int errcode = pthread_create( &grouper_thread, 0, grouper, &grouper_arg );
|
||||
|
@ -582,7 +585,7 @@ int encode_lz( const char * const archive_namep, const Arg_parser & parser,
|
|||
{ show_file_error( archive_namep, "Error closing archive", errno );
|
||||
retval = 1; }
|
||||
|
||||
if( debug_level & 1 )
|
||||
if( cl_opts.debug_level & 1 )
|
||||
std::fprintf( stderr,
|
||||
"any worker tried to consume from grouper %8u times\n"
|
||||
"any worker had to wait %8u times\n"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue