diff options
author | Colin Walters <walters@verbum.org> | 2016-02-25 11:07:30 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2016-02-26 08:19:01 -0500 |
commit | 5345573470f6c1929f00ff06572cb28b073e1d2f (patch) | |
tree | 50553f0e3a0644636545a43d8c16ae95a3fcc91b | |
parent | 7fdf07271031cd4a88af9280b41ece5dc7c1d580 (diff) | |
download | ostree-5345573470f6c1929f00ff06572cb28b073e1d2f.tar.gz |
deltas: Add a compression size heuristic for endianness detection
I see when analyzing a delta here that due to byteswapping a negative
compression ratio of 540%, 66%, and 28%. Let's arbitrarily pick 20%
as a threshold for detecting byetswapping.
-rw-r--r-- | src/libostree/ostree-repo-static-delta-core.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index 0669f691..d84f0019 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -705,6 +705,7 @@ _ostree_delta_get_endianness (GVariant *superblock, { g_autoptr(GVariant) meta_entries = NULL; guint n_parts; guint i; + gboolean is_byteswapped = FALSE; g_variant_get_child (superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries); n_parts = g_variant_n_children (meta_entries); @@ -721,15 +722,36 @@ _ostree_delta_get_endianness (GVariant *superblock, total_objects += n_objects; total_size += size; total_usize += usize; + + if (size > usize) + { + double ratio = ((double)size)/((double)usize); + + /* This should really never happen where compressing things makes it more than 50% bigger. + */ + if (ratio > 1.2) + { + is_byteswapped = TRUE; + break; + } + } + } + + if (!is_byteswapped) + { + /* If the average object size is greater than 4GiB, let's assume + * we're dealing with opposite endianness. I'm fairly confident + * no one is going to be shipping peta- or exa- byte size ostree + * deltas, period. Past the gigabyte scale you really want + * bittorrent or something. + */ + if ((total_size / total_objects) > G_MAXUINT32) + { + is_byteswapped = TRUE; + } } - /* If the average object size is greater than 4GiB, let's assume - * we're dealing with opposite endianness. I'm fairly confident - * no one is going to be shipping peta- or exa- byte size ostree - * deltas, period. Past the gigabyte scale you really want - * bittorrent or something. - */ - if ((total_size / total_objects) > G_MAXUINT32) + if (is_byteswapped) { switch (G_BYTE_ORDER) { |