[ostree] deltas: Add a compression size heuristic for endianness detection



commit 5345573470f6c1929f00ff06572cb28b073e1d2f
Author: Colin Walters <walters verbum org>
Date:   Thu Feb 25 11:07:30 2016 -0500

    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.

 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 0669f69..d84f001 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)
           {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]