Skip to content

Commit

Permalink
Merge pull request #107 from rpaulo/master
Browse files Browse the repository at this point in the history
libarchive: use lzma_stream_encoder_mt() if it's available.
  • Loading branch information
kientzle committed Mar 5, 2015
2 parents 180a8cb + b2686da commit 41c4da4
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 19 deletions.
7 changes: 4 additions & 3 deletions configure.ac
Expand Up @@ -12,13 +12,13 @@ m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCAT_VERSION_S],LIBARCHIVE_VERSION_S())

AC_PREREQ(2.65)
AC_PREREQ([2.69])

#
# Now starts the "real" configure script.
#

AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[libarchive-discuss@googlegroups.com])
AC_INIT([libarchive],[LIBARCHIVE_VERSION_S()],[libarchive-discuss@googlegroups.com])
# Make sure the srcdir contains "libarchive" directory
AC_CONFIG_SRCDIR([libarchive])
# Use auxiliary subscripts from this subdirectory (cleans up root)
Expand Down Expand Up @@ -364,6 +364,7 @@ AC_ARG_WITH([lzma],
if test "x$with_lzma" != "xno"; then
AC_CHECK_HEADERS([lzma.h])
AC_CHECK_LIB(lzma,lzma_stream_decoder)
AC_CHECK_FUNCS([lzma_stream_encoder_mt])
fi

AC_ARG_WITH([lzo2],
Expand Down Expand Up @@ -472,7 +473,7 @@ fi

# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
# AC_TYPE_UID_T defaults to "int", which is incorrect for MinGW
# la_TYPE_UID_T defaults to "int", which is incorrect for MinGW
# and MSVC. Use a customized version.
la_TYPE_UID_T
AC_TYPE_MODE_T
Expand Down
37 changes: 32 additions & 5 deletions libarchive/archive_write_add_filter_xz.c
Expand Up @@ -100,6 +100,7 @@ archive_write_add_filter_lzip(struct archive *a)

struct private_data {
int compression_level;
uint32_t threads;
lzma_stream stream;
lzma_filter lzmafilters[2];
lzma_options_lzma lzma_opt;
Expand Down Expand Up @@ -151,6 +152,7 @@ common_setup(struct archive_write_filter *f)
}
f->data = data;
data->compression_level = LZMA_PRESET_DEFAULT;
data->threads = 1;
f->open = &archive_compressor_xz_open;
f->close = archive_compressor_xz_close;
f->free = archive_compressor_xz_free;
Expand Down Expand Up @@ -221,16 +223,30 @@ archive_compressor_xz_init_stream(struct archive_write_filter *f,
{
static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
int ret;
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
lzma_mt mt_options;
#endif

data->stream = lzma_stream_init_data;
data->stream.next_out = data->compressed;
data->stream.avail_out = data->compressed_buffer_size;
if (f->code == ARCHIVE_FILTER_XZ)
ret = lzma_stream_encoder(&(data->stream),
data->lzmafilters, LZMA_CHECK_CRC64);
else if (f->code == ARCHIVE_FILTER_LZMA)
if (f->code == ARCHIVE_FILTER_XZ) {
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
if (data->threads != 1) {
bzero(&mt_options, sizeof(mt_options));
mt_options.threads = data->threads;
mt_options.timeout = 300;
mt_options.filters = data->lzmafilters;
mt_options.check = LZMA_CHECK_CRC64;
ret = lzma_stream_encoder_mt(&(data->stream),
&mt_options);
} else
#endif
ret = lzma_stream_encoder(&(data->stream),
data->lzmafilters, LZMA_CHECK_CRC64);
} else if (f->code == ARCHIVE_FILTER_LZMA) {
ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt);
else { /* ARCHIVE_FILTER_LZIP */
} else { /* ARCHIVE_FILTER_LZIP */
int dict_size = data->lzma_opt.dict_size;
int ds, log2dic, wedges;

Expand Down Expand Up @@ -373,6 +389,17 @@ archive_compressor_xz_options(struct archive_write_filter *f,
if (data->compression_level > 6)
data->compression_level = 6;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
if (value == NULL)
return (ARCHIVE_WARN);
data->threads = (int)strtoul(value, NULL, 10);
if (data->threads == 0 && errno != 0) {
data->threads = 1;
return (ARCHIVE_WARN);
}
if (data->threads == 0)
data->threads = lzma_cputhreads();
return (ARCHIVE_OK);
}

/* Note: The "warn" return is just to inform the options
Expand Down
52 changes: 41 additions & 11 deletions libarchive/archive_write_set_format_xar.c
Expand Up @@ -114,7 +114,7 @@ enum sumalg {
#define MAX_SUM_SIZE 20
#define MD5_NAME "md5"
#define SHA1_NAME "sha1"

enum enctype {
NONE,
GZIP,
Expand Down Expand Up @@ -242,6 +242,7 @@ struct xar {
enum sumalg opt_sumalg;
enum enctype opt_compression;
int opt_compression_level;
uint32_t opt_threads;

struct chksumwork a_sumwrk; /* archived checksum. */
struct chksumwork e_sumwrk; /* extracted checksum. */
Expand Down Expand Up @@ -317,7 +318,7 @@ static int compression_end_bzip2(struct archive *, struct la_zstream *);
static int compression_init_encoder_lzma(struct archive *,
struct la_zstream *, int);
static int compression_init_encoder_xz(struct archive *,
struct la_zstream *, int);
struct la_zstream *, int, int);
#if defined(HAVE_LZMA_H)
static int compression_code_lzma(struct archive *,
struct la_zstream *, enum la_zaction);
Expand Down Expand Up @@ -380,9 +381,10 @@ archive_write_set_format_xar(struct archive *_a)
/* Set default checksum type. */
xar->opt_toc_sumalg = CKSUM_SHA1;
xar->opt_sumalg = CKSUM_SHA1;
/* Set default compression type and level. */
/* Set default compression type, level, and number of threads. */
xar->opt_compression = GZIP;
xar->opt_compression_level = 6;
xar->opt_threads = 1;

a->format_data = xar;

Expand Down Expand Up @@ -493,6 +495,21 @@ xar_options(struct archive_write *a, const char *key, const char *value)
}
return (ARCHIVE_OK);
}
if (strcmp(key, "threads") == 0) {
if (value == NULL)
return (ARCHIVE_FAILED);
xar->opt_threads = (int)strtoul(value, NULL, 10);
if (xar->opt_threads == 0 && errno != 0) {
xar->opt_threads = 1;
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
"Illegal value `%s'",
value);
return (ARCHIVE_FAILED);
}
if (xar->opt_threads == 0)
xar->opt_threads = lzma_cputhreads();
}

/* Note: The "warn" return is just to inform the options
* supervisor that we didn't handle it. It will generate
Expand Down Expand Up @@ -805,7 +822,7 @@ xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,

if (value == NULL)
return (ARCHIVE_OK);

r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
if (r < 0) {
archive_set_error(&a->archive,
Expand Down Expand Up @@ -1875,7 +1892,7 @@ file_cmp_node(const struct archive_rb_node *n1,

return (strcmp(f1->basename.s, f2->basename.s));
}

static int
file_cmp_key(const struct archive_rb_node *n, const void *key)
{
Expand Down Expand Up @@ -2494,7 +2511,7 @@ file_init_hardlinks(struct xar *xar)
static const struct archive_rb_tree_ops rb_ops = {
file_hd_cmp_node, file_hd_cmp_key,
};

__archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
}

Expand Down Expand Up @@ -2848,13 +2865,16 @@ compression_init_encoder_lzma(struct archive *a,

static int
compression_init_encoder_xz(struct archive *a,
struct la_zstream *lastrm, int level)
struct la_zstream *lastrm, int level, int threads)
{
static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
lzma_stream *strm;
lzma_filter *lzmafilters;
lzma_options_lzma lzma_opt;
int r;
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
lzma_mt mt_options;
#endif

if (lastrm->valid)
compression_end(a, lastrm);
Expand All @@ -2879,7 +2899,17 @@ compression_init_encoder_xz(struct archive *a,
lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */

*strm = lzma_init_data;
r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
if (threads > 1) {
bzero(&mt_options, sizeof(mt_options));
mt_options.threads = threads;
mt_options.timeout = 300;
mt_options.filters = lzmafilters;
mt_options.check = LZMA_CHECK_CRC64;
r = lzma_stream_encoder_mt(strm, &mt_options);
} else
#endif
r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
switch (r) {
case LZMA_OK:
lastrm->real_stream = strm;
Expand Down Expand Up @@ -2979,10 +3009,11 @@ compression_init_encoder_lzma(struct archive *a,
}
static int
compression_init_encoder_xz(struct archive *a,
struct la_zstream *lastrm, int level)
struct la_zstream *lastrm, int level, int threads)
{

(void) level; /* UNUSED */
(void) threads; /* UNUSED */
if (lastrm->valid)
compression_end(a, lastrm);
return (compression_unsupported_encoder(a, lastrm, "xz"));
Expand Down Expand Up @@ -3015,7 +3046,7 @@ xar_compression_init_encoder(struct archive_write *a)
case XZ:
r = compression_init_encoder_xz(
&(a->archive), &(xar->stream),
xar->opt_compression_level);
xar->opt_compression_level, xar->opt_threads);
break;
default:
r = ARCHIVE_OK;
Expand Down Expand Up @@ -3178,4 +3209,3 @@ getalgname(enum sumalg sumalg)
}

#endif /* Support xar format */

0 comments on commit 41c4da4

Please sign in to comment.