deltas: Don't try to rollsum/bsdiff .xz files

Fedora switched to 'xz' compress kernel modules, and recently
[RHEL7 did too](https://bugzilla.redhat.com/show_bug.cgi?id=1367496).
This compression defeats bsdiff.

While we have a "rollsum-able" test, we don't have a "bsdiff-able" test as it'd
be very expensive (we'd have to bsdiff, then apply it and compare the result).

Let's do the tactical quick fix here and just not try to delta files ending in
`.xz.`. This avoids us using bsdiff pointlessly for over 4000 files, which is
quite a notable speed increase for generating deltas.

Closes: #1333
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-11-07 17:52:12 -05:00 committed by Atomic Bot
parent 3cf53f7c58
commit 9856ed3840

View File

@ -217,6 +217,37 @@ string_array_nonempty_intersection (GPtrArray *a,
return FALSE;
}
static gboolean
sizename_is_delta_candidate (OstreeDeltaContentSizeNames *sizename)
{
/* Don't build candidates for the empty object */
if (sizename->size == 0)
return FALSE;
/* Look for known non-delta-able files (currently just compression like xz) */
for (guint i = 0; i < sizename->basenames->len; i++)
{
const char *name = sizename->basenames->pdata[i];
/* We could replace this down the line with g_content_type_guess() or so,
* but it's not clear to me that's a major win; we'd still need to
* maintain a list of compression formats, and this doesn't require
* allocation.
* NB: We explicitly don't have .gz here in case someone might be
* using --rsyncable for that.
*/
const char *dot = strrchr (name, '.');
if (!dot)
continue;
const char *extension = dot+1;
/* Don't add .gz here, see above */
if (g_str_equal (extension, "xz") || g_str_equal (extension, "bz2"))
return FALSE;
}
/* Let's try it */
return TRUE;
}
/*
* Build up a map of files with matching basenames and similar size,
* and use it to find apparently similar objects.
@ -258,7 +289,7 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo,
&to_sizes,
cancellable, error))
goto out;
/* Iterate over all newly added objects, find objects which have
* similar basename and sizes.
*
@ -277,8 +308,7 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo,
const guint64 max_threshold = to_sizenames->size *
(1.0+similarity_percent_threshold/100.0);
/* Don't build candidates for the empty object */
if (to_sizenames->size == 0)
if (!sizename_is_delta_candidate (to_sizenames))
continue;
for (fuzzy = 0; fuzzy < 2 && !found; fuzzy++)
@ -286,12 +316,8 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo,
for (j = lower; j < upper; j++)
{
OstreeDeltaContentSizeNames *from_sizenames = from_sizes->pdata[j];
/* Don't build candidates for the empty object */
if (from_sizenames->size == 0)
{
continue;
}
if (!sizename_is_delta_candidate (from_sizenames))
continue;
if (from_sizenames->size < min_threshold)
{