[ostree/wip/packfile-rebase2] core: More packfile



commit f123cd95c940449f03aad7b6b9c8f605a15fc38d
Author: Colin Walters <walters verbum org>
Date:   Sat Mar 24 14:45:57 2012 -0400

    core: More packfile

 src/libostree/ostree-core.c    |   35 +++++++----
 src/libostree/ostree-repo.c    |   27 ++++++--
 src/ostree/ot-builtin-repack.c |  136 ++++++++++++++++++++-------------------
 3 files changed, 113 insertions(+), 85 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index d57dca3..98f6845 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -636,40 +636,49 @@ GVariant *
 ostree_checksum_to_bytes (const char *sha256)
 {
   guchar result[32];
-  guint i = 0;
+  guint i;
+  guint j;
 
-  for (i = 0; i < 32; i += 2)
+  for (i = 0, j = 0; i < 32; i += 1, j += 2)
     {
       gint big, little;
 
-      g_assert (sha256[i]);
-      g_assert (sha256[i+1]);
+      g_assert (sha256[j]);
+      g_assert (sha256[j+1]);
 
-      big = g_ascii_xdigit_value (sha256[i]);
-      little = g_ascii_xdigit_value (sha256[i+1]);
+      big = g_ascii_xdigit_value (sha256[j]);
+      little = g_ascii_xdigit_value (sha256[j+1]);
 
-      result[i] += (big << 4) | little;
+      result[i] = (big << 4) | little;
     }
   
   return g_variant_new_fixed_array (G_VARIANT_TYPE ("y"),
-                                    result, 32, 1);
+                                    (guchar*)result, 32, 1);
 }
 
 char *
 ostree_checksum_from_bytes (GVariant *csum_bytes)
 {
-  GString *ret = g_string_new ("");
+  static const gchar hexchars[] = "0123456789abcdef";
+  char *ret;
   const guchar *bytes;
   gsize n_elts;
-  guint i;
+  guint i, j;
 
   bytes = g_variant_get_fixed_array (csum_bytes, &n_elts, 1);
   g_assert (n_elts == 32);
+
+  ret = g_malloc (65);
   
-  for (i = 0; i < 32; i++)
-    g_string_append_printf (ret, "%x", bytes[i]);
+  for (i = 0, j = 0; i < 32; i++, j += 2)
+    {
+      guchar byte = bytes[i];
+      ret[j] = hexchars[byte >> 4];
+      ret[j+1] = hexchars[byte & 0xF];
+    }
+  ret[j] = '\0';
 
-  return g_string_free (ret, FALSE);
+  return ret;
 }
 
 GVariant *
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 323c6da..51b0508 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -2512,6 +2512,7 @@ ostree_repo_load_pack_index (OstreeRepo    *self,
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GVariant *ret_variant = NULL;
   GFile *path = NULL;
+  const char *header;
   
   ret_variant = g_hash_table_lookup (priv->pack_index_mappings, sha256);
   if (ret_variant)
@@ -2529,6 +2530,15 @@ ostree_repo_load_pack_index (OstreeRepo    *self,
                            g_variant_ref (ret_variant));
     }
 
+  g_variant_get_child (ret_variant, 0, "&s", &header);
+
+  if (strcmp (header, "OSTv0PACKINDEX") != 0)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Invalid pack version, expected 'OSTv0PACKINDEX'");
+      goto out;
+    }
+
   ret = TRUE;
   ot_transfer_out_value (out_variant, &ret_variant);
  out:
@@ -2890,23 +2900,27 @@ list_objects_in_index (OstreeRepo                     *self,
   if (!ostree_repo_load_pack_index (self, pack_checksum, &index_variant, cancellable, error))
     goto out;
 
-  contents = g_variant_get_child_value (index_variant, 3);
+  contents = g_variant_get_child_value (index_variant, 2);
   g_variant_iter_init (&content_iter, contents);
 
-  while (g_variant_iter_loop (&content_iter, "(&u ayt)", &objtype_u32, &csum_bytes, &offset))
+  while (g_variant_iter_loop (&content_iter, "(u ayt)", &objtype_u32, &csum_bytes, &offset))
     {
       GVariant *obj_key;
       GVariant *objdata;
-      OstreeObjectType objtype = (OstreeObjectType)objtype_u32;
+      OstreeObjectType objtype;
       GVariantBuilder pack_contents_builder;
       gboolean is_loose;
 
+      objtype = (OstreeObjectType) GUINT32_FROM_BE (objtype_u32);
+      offset = GUINT64_FROM_BE (offset);
+
       g_variant_builder_init (&pack_contents_builder,
                               G_VARIANT_TYPE_STRING_ARRAY);
       
       g_free (checksum);
       checksum = ostree_checksum_from_bytes (csum_bytes);
       obj_key = ostree_object_name_serialize (checksum, objtype);
+      ot_util_variant_take_ref (obj_key);
 
       objdata = g_hash_table_lookup (inout_objects, obj_key);
       if (!objdata)
@@ -2922,7 +2936,7 @@ list_objects_in_index (OstreeRepo                     *self,
 
           while (g_variant_iter_loop (current_packs_iter, "&s", &current_pack_checksum))
             {
-              g_variant_builder_add (&pack_contents_builder, current_pack_checksum);
+              g_variant_builder_add (&pack_contents_builder, "s", current_pack_checksum);
             }
           g_variant_iter_free (current_packs_iter);
         }
@@ -2930,8 +2944,8 @@ list_objects_in_index (OstreeRepo                     *self,
       objdata = g_variant_new ("(b as)", is_loose,
                                g_variant_builder_end (&pack_contents_builder));
       g_hash_table_replace (inout_objects,
-                            ot_util_variant_take_ref (obj_key),
-                            ot_util_variant_take_ref (objdata));
+                            obj_key,
+                            g_variant_ref (objdata));
     }
 
   ret = TRUE;
@@ -3176,6 +3190,7 @@ ostree_repo_load_variant (OstreeRepo  *self,
       
       g_variant_get (container_variant, "(uv)",
                      &actual_type, &ret_variant);
+      actual_type = GUINT32_FROM_BE (actual_type);
       ot_util_variant_take_ref (ret_variant);
 
       if (actual_type != expected_type)
diff --git a/src/ostree/ot-builtin-repack.c b/src/ostree/ot-builtin-repack.c
index ceefd6d..f2e7ce5 100644
--- a/src/ostree/ot-builtin-repack.c
+++ b/src/ostree/ot-builtin-repack.c
@@ -127,17 +127,20 @@ write_padding (GOutputStream    *output,
                GError          **error)
 {
   gboolean ret = FALSE;
-  guint padding;
+  guint bits;
   char padding_nuls[7] = {0, 0, 0, 0, 0, 0, 0};
 
   if (alignment == 8)
-    padding = 8 - ((*inout_offset) & 7);
+    bits = ((*inout_offset) & 7);
   else
-    padding = 4 - ((*inout_offset) & 3);
+    bits = ((*inout_offset) & 3);
 
-  if (!write_bytes_update_checksum (output, (guchar*)padding_nuls, padding,
-                                    checksum, inout_offset, cancellable, error))
-    goto out;
+  if (bits > 0)
+    {
+      if (!write_bytes_update_checksum (output, (guchar*)padding_nuls, alignment - bits,
+                                        checksum, inout_offset, cancellable, error))
+        goto out;
+    }
   
   ret = TRUE;
  out:
@@ -225,7 +228,7 @@ create_pack_file (OtRepackData        *data,
   GFileInfo *object_file_info = NULL;
   GFileInputStream *object_input = NULL;
   GConverter *compressor = NULL;
-  GConverterOutputStream *compressed_object_output = NULL;
+  GConverterInputStream *compressed_object_input = NULL;
   guint i;
   guint64 offset;
   gsize bytes_read;
@@ -279,10 +282,9 @@ create_pack_file (OtRepackData        *data,
       guint32 objtype_u32;
       OstreeObjectType objtype;
       char buf[4096];
-      guint64 obj_bytes_written;
       guint64 expected_objsize;
       guint64 objsize;
-      GOutputStream *write_object_out;
+      GInputStream *read_object_in;
       guchar entry_flags = 0;
       GVariant *index_entry;
 
@@ -294,8 +296,10 @@ create_pack_file (OtRepackData        *data,
         goto out;
 
       /* offset points to aligned header size */
-      index_entry = g_variant_new ("(uayt)",
-                                   (guint32)objtype, ostree_checksum_to_bytes (checksum), offset);
+      index_entry = g_variant_new ("(u ayt)",
+                                   GUINT32_TO_BE ((guint32)objtype),
+                                   ostree_checksum_to_bytes (checksum),
+                                   offset);
       g_ptr_array_add (index_content_list, g_variant_ref_sink (index_entry));
 
       if (objtype == OSTREE_OBJECT_TYPE_DIR_TREE
@@ -338,47 +342,42 @@ create_pack_file (OtRepackData        *data,
       g_assert_cmpint (objsize, ==, expected_objsize);
 
       g_clear_object (&object_data_stream);
-      object_data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, NULL, NULL);
+      object_data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
       
       if (entry_flags & OSTREE_PACK_FILE_ENTRY_FLAG_GZIP)
         {
           g_clear_object (&compressor);
           compressor = (GConverter*)g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, OT_GZIP_COMPRESSION_LEVEL);
           
-          g_clear_object (&compressed_object_output);
-          compressed_object_output = (GConverterOutputStream*)g_object_new (G_TYPE_CONVERTER_OUTPUT_STREAM,
-                                                                            "converter", compressor,
-                                                                            "base-stream", object_data_stream,
-                                                                            "close-base-stream", TRUE,
-                                                                            NULL);
-          write_object_out = (GOutputStream*)compressed_object_output;
+          g_clear_object (&compressed_object_input);
+          compressed_object_input = (GConverterInputStream*)g_object_new (G_TYPE_CONVERTER_INPUT_STREAM,
+                                                                          "converter", compressor,
+                                                                          "base-stream", object_input,
+                                                                          "close-base-stream", TRUE,
+                                                                          NULL);
+          read_object_in = (GInputStream*)compressed_object_input;
         }
       else
         {
-          write_object_out = (GOutputStream*)object_data_stream;
+          read_object_in = (GInputStream*)object_input;
         }
 
-      obj_bytes_written = 0;
       do
         {
-          if (!g_input_stream_read_all ((GInputStream*)object_input, buf, sizeof(buf), &bytes_read, cancellable, error))
+          if (!g_input_stream_read_all (read_object_in, buf, sizeof(buf), &bytes_read, cancellable, error))
             goto out;
-          g_checksum_update (pack_checksum, (guint8*)buf, bytes_read);
           if (bytes_read > 0)
             {
-              if (!g_output_stream_write_all (write_object_out, buf, bytes_read, &bytes_written, cancellable, error))
+              g_checksum_update (pack_checksum, (guint8*)buf, bytes_read);
+              if (!g_output_stream_write_all (pack_out, buf, bytes_read, &bytes_written, cancellable, error))
                 goto out;
-              offset += bytes_written;
-              obj_bytes_written += bytes_written;
             }
         }
       while (bytes_read > 0);
 
-      if (!g_output_stream_close (write_object_out, cancellable, error))
+      if (!g_input_stream_close (read_object_in, cancellable, error))
         goto out;
 
-      g_assert_cmpint (obj_bytes_written, ==, objsize);
-
       ot_clear_gvariant (&packed_object);
       packed_object = g_variant_new ("(uy ay@ay)", GUINT32_TO_BE ((guint32)objtype),
                                      entry_flags,
@@ -416,7 +415,7 @@ create_pack_file (OtRepackData        *data,
     }
   g_clear_object (&pack_temppath);
 
-  g_variant_builder_init (&index_content_builder, G_VARIANT_TYPE ("a(sut)"));
+  g_variant_builder_init (&index_content_builder, G_VARIANT_TYPE ("a(uayt)"));
   g_ptr_array_sort (index_content_list, compare_index_content);
   for (i = 0; i < index_content_list->len; i++)
     {
@@ -467,7 +466,7 @@ create_pack_file (OtRepackData        *data,
   g_clear_object (&object_path);
   g_clear_object (&object_input);
   g_clear_object (&compressor);
-  g_clear_object (&compressed_object_output);
+  g_clear_object (&compressed_object_input);
   g_clear_object (&object_file_info);
   if (pack_checksum)
     g_checksum_free (pack_checksum);
@@ -536,12 +535,12 @@ cluster_objects_stupidly (OtRepackData      *data,
       size = g_file_info_get_attribute_uint64 (object_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
 
       g_ptr_array_add (object_list,
-                       g_variant_ref_sink (g_variant_new ("(sut)", checksum, objtype, size)));
+                       g_variant_ref_sink (g_variant_new ("(sut)", checksum, (guint32)objtype, size)));
     }
 
   g_ptr_array_sort (object_list, compare_object_data_by_size);
 
-  ret_clusters = g_ptr_array_new ();
+  ret_clusters = g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref);
 
   current_size = 0;
   current_offset = 0;
@@ -555,7 +554,7 @@ cluster_objects_stupidly (OtRepackData      *data,
       if (current_size + objsize > data->pack_size || i == (object_list->len - 1))
         {
           guint j;
-          GPtrArray *current = g_ptr_array_new ();
+          GPtrArray *current = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref);
           for (j = current_offset; j < i; j++)
             {
               g_ptr_array_add (current, g_variant_ref (object_list->pdata[j]));
@@ -670,13 +669,11 @@ static gboolean
 do_stats_gather_loose (OtRepackData  *data,
                        GHashTable    *objects,
                        GHashTable   **out_loose,
-                       GHashTable   **out_loose_and_packed,
                        GCancellable  *cancellable,
                        GError       **error)
 {
   gboolean ret = FALSE;
   GHashTable *ret_loose = NULL;
-  GHashTable *ret_loose_and_packed = NULL;
   guint n_loose = 0;
   guint n_loose_and_packed = 0;
   guint n_packed = 0;
@@ -691,9 +688,6 @@ do_stats_gather_loose (OtRepackData  *data,
   ret_loose = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
                                      (GDestroyNotify) g_variant_unref,
                                      NULL);
-  ret_loose_and_packed = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
-                                                (GDestroyNotify) g_variant_unref,
-                                                NULL);
 
   g_hash_table_iter_init (&hash_iter, objects);
   while (g_hash_table_iter_next (&hash_iter, &key, &value))
@@ -714,20 +708,26 @@ do_stats_gather_loose (OtRepackData  *data,
       
       if (is_loose && is_packed)
         {
-          GVariant *copy = g_variant_ref (serialized_key);
-          g_hash_table_replace (ret_loose_and_packed, copy, copy);
+          g_print ("loose+packed: %s.%u\n", checksum, objtype);
           n_loose_and_packed++;
         }
       else if (is_loose)
         {
           GVariant *copy = g_variant_ref (serialized_key);
           g_hash_table_replace (ret_loose, copy, copy);
+          g_print ("loose: %s.%u\n", checksum, objtype);
           n_loose++;
         }
       else if (g_variant_n_children (pack_array) > 1)
-        n_dup_packed++;
+        {
+          g_print ("dup-packed: %s.%u\n", checksum, objtype);
+          n_dup_packed++;
+        }
       else
-        n_packed++;
+        {
+          g_print ("packed: %s.%u\n", checksum, objtype);
+          n_packed++;
+        }
           
       switch (objtype)
         {
@@ -762,12 +762,9 @@ do_stats_gather_loose (OtRepackData  *data,
 
   ret = TRUE;
   ot_transfer_out_value (out_loose, &ret_loose);
-  ot_transfer_out_value (out_loose_and_packed, &ret_loose_and_packed);
  /* out: */
   if (ret_loose)
     g_hash_table_unref (ret_loose);
-  if (ret_loose_and_packed)
-    g_hash_table_unref (ret_loose_and_packed);
   return ret;
 }
 
@@ -783,7 +780,6 @@ ostree_builtin_repack (int argc, char **argv, GFile *repo_path, GError **error)
   guint i;
   GPtrArray *clusters = NULL;
   GHashTable *loose_objects = NULL;
-  GHashTable *loose_and_packed_objects = NULL;
   GHashTableIter hash_iter;
   gpointer key, value;
   GFile *objpath = NULL;
@@ -821,30 +817,12 @@ ostree_builtin_repack (int argc, char **argv, GFile *repo_path, GError **error)
   if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, cancellable, error))
     goto out;
 
-  if (!do_stats_gather_loose (&data, objects, &loose_objects, &loose_and_packed_objects, cancellable, error))
+  if (!do_stats_gather_loose (&data, objects, &loose_objects, cancellable, error))
     goto out;
 
   g_print ("\n");
   g_print ("Using pack size: %" G_GUINT64_FORMAT "\n", data.pack_size);
 
-  if (!opt_keep_loose)
-    {
-      g_hash_table_iter_init (&hash_iter, loose_and_packed_objects);
-      while (g_hash_table_iter_next (&hash_iter, &key, &value))
-        {
-          GVariant *variant = key;
-          const char *checksum;
-          OstreeObjectType objtype;
-
-          ostree_object_name_deserialize (variant, &checksum, &objtype);
-
-          g_clear_object (&objpath);
-          objpath = ostree_repo_get_object_path (data.repo, checksum, objtype);
-          if (!g_file_delete (objpath, cancellable, error))
-            goto out;
-        }
-    }
-
   if (!cluster_objects_stupidly (&data, loose_objects, &clusters, cancellable, error))
     goto out;
   
@@ -866,6 +844,32 @@ ostree_builtin_repack (int argc, char **argv, GFile *repo_path, GError **error)
         }
     }
 
+  if (!opt_analyze_only && !opt_keep_loose)
+    {
+      g_hash_table_iter_init (&hash_iter, objects);
+      while (g_hash_table_iter_next (&hash_iter, &key, &value))
+        {
+          GVariant *serialized_key = key;
+          GVariant *objdata = value;
+          const char *checksum;
+          OstreeObjectType objtype;
+          gboolean is_loose;
+          GVariant *pack_array;
+
+          ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
+
+          g_variant_get (objdata, "(b as)", &is_loose, &pack_array);
+
+          if (is_loose && g_variant_n_children (pack_array) > 0)
+            {
+              g_clear_object (&objpath);
+              objpath = ostree_repo_get_object_path (data.repo, checksum, objtype);
+              if (!ot_gfile_unlink (objpath, cancellable, error))
+                goto out;
+            }
+        }
+    }
+
   ret = TRUE;
  out:
   g_clear_object (&objpath);



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