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



commit 80f8d03057c089b7207953da506b245aef828035
Author: Colin Walters <walters verbum org>
Date:   Thu Mar 29 10:57:53 2012 -0400

    core: More pack work

 src/libostree/ostree-core.h  |    2 +-
 src/libostree/ostree-repo.c  |  415 +++++++++++++++++++++++++++++------------
 src/libostree/ostree-repo.h  |   13 ++
 src/libotutil/ot-gio-utils.c |   33 ++++-
 src/libotutil/ot-gio-utils.h |    5 +
 src/ostree/ot-builtin-pack.c |  135 +++++++-------
 6 files changed, 413 insertions(+), 190 deletions(-)
---
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 801b784..0e4d154 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -102,7 +102,7 @@ typedef enum {
  * a{sv} - Metadata
  * a(say) - (pack file checksum, bloom filter)
  */
-#define OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT G_VARIANT_TYPE ("(sa{sv}a(say))")
+#define OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT G_VARIANT_TYPE ("(sa{sv}a(ayay))")
 
 /* Pack index
  * s - OSTv0PACKINDEX
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index dc55da6..b7fe0d6 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -1532,6 +1532,299 @@ ostree_repo_stage_commit (OstreeRepo *self,
   return ret;
 }
 
+static gboolean
+list_files_in_dir_matching (GFile                  *dir,
+                            const char             *prefix,
+                            const char             *suffix,
+                            GPtrArray             **out_files,
+                            GCancellable           *cancellable,
+                            GError                **error)
+{
+  gboolean ret = FALSE;
+  GError *temp_error = NULL;
+  GFileEnumerator *enumerator = NULL;
+  GFileInfo *file_info = NULL;
+  GPtrArray *ret_files = NULL;
+
+  g_return_val_if_fail (prefix != NULL || suffix != NULL, FALSE);
+
+  ret_files = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
+
+  enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, 
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                          cancellable, 
+                                          error);
+  if (!enumerator)
+    goto out;
+  
+  while ((file_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)) != NULL)
+    {
+      const char *name;
+      guint32 type;
+
+      name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); 
+      type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
+
+      if (type != G_FILE_TYPE_REGULAR)
+        goto loop_next;
+
+      if (prefix)
+        {
+          if (!g_str_has_prefix (name, prefix))
+            goto loop_next;
+        }
+      if (suffix)
+        {
+          if (!g_str_has_suffix (name, suffix))
+            goto loop_next;
+        }
+
+      g_ptr_array_add (ret_files, g_file_get_child (dir, name));
+      
+    loop_next:
+      g_clear_object (&file_info);
+    }
+  if (temp_error != NULL)
+    {
+      g_propagate_error (error, temp_error);
+      goto out;
+    }
+  if (!g_file_enumerator_close (enumerator, cancellable, error))
+    goto out;
+
+  ret = TRUE;
+  ot_transfer_out_value (out_files, &ret_files);
+ out:
+  if (ret_files)
+    g_ptr_array_unref (ret_files);
+  g_clear_object (&file_info);
+  g_clear_object (&enumerator);
+  return ret;
+}
+
+static char *
+get_checksum_from_pack_name (const char *name)
+{
+  const char *dash;
+  const char *dot;
+
+  dash = strchr (name, '-');
+  g_assert (dash);
+  dot = strrchr (name, '.');
+  g_assert (dot);
+
+  g_assert_cmpint (dot - (dash + 1), ==, 64);
+  
+  return g_strndup (dash + 1, 64);
+}
+
+static gboolean
+list_pack_indexes_from_dir (OstreeRepo              *self,
+                            GPtrArray              **out_indexes,
+                            GCancellable            *cancellable,
+                            GError                 **error)
+{
+  gboolean ret = FALSE;
+  GPtrArray *index_files = NULL;
+  GPtrArray *ret_indexes = NULL;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  guint i;
+
+  if (!list_files_in_dir_matching (priv->pack_dir,
+                                   "ostpack-", ".index",
+                                   &index_files, 
+                                   cancellable, error))
+    goto out;
+
+  ret_indexes = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free);
+  for (i = 0; i < index_files->len; i++)
+    {
+      GFile *index_path = index_files->pdata[i];
+      const char *basename = ot_gfile_get_basename_cached (index_path);
+      g_ptr_array_add (ret_indexes, get_checksum_from_pack_name (basename));
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_indexes, &ret_indexes);
+ out:
+  if (index_files)
+    g_ptr_array_unref (index_files);
+  if (ret_indexes)
+    g_ptr_array_unref (ret_indexes);
+  return ret;
+}
+
+gboolean
+ostree_repo_list_pack_indexes (OstreeRepo              *self,
+                               GPtrArray              **out_indexes,
+                               GCancellable            *cancellable,
+                               GError                 **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  GFile *superindex_path = NULL;
+  GPtrArray *ret_indexes = NULL;
+  GVariant *superindex_variant = NULL;
+  GVariantIter *variant_iter = NULL;
+  const char *magic;
+  GVariant *checksum;
+  GVariant *bloom;
+
+  superindex_path = g_file_get_child (priv->pack_dir, "index");
+
+  ret_indexes = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free);
+
+  if (g_file_query_exists (superindex_path, cancellable))
+    {
+      if (!ot_util_variant_map (superindex_path, OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT,
+                                &superindex_variant, error))
+        goto out;
+
+      g_variant_get (superindex_variant, "(&s a{sv}a(ayay))",
+                     &magic, NULL, &variant_iter);
+
+      if (strcmp (magic, "OSTv0SUPERPACKINDEX") != 0)
+        {
+          g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Invalid header in super pack index");
+          goto out;
+        }
+
+      while (g_variant_iter_loop (variant_iter, "(@ay ay)",
+                                  &checksum, &bloom))
+        g_ptr_array_add (ret_indexes, ostree_checksum_from_bytes (checksum));
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_indexes, &ret_indexes);
+ out:
+  ot_clear_gvariant (&superindex_variant);
+  g_clear_object (&superindex_path);
+  if (variant_iter)
+    g_variant_iter_free (variant_iter);
+  if (ret_indexes)
+    g_ptr_array_unref (ret_indexes);
+  return ret;
+}
+
+static gboolean
+create_index_bloom (OstreeRepo          *self,
+                    const char          *pack_checksum,
+                    GVariant           **out_bloom,
+                    GCancellable        *cancellable,
+                    GError             **error)
+{
+  gboolean ret = FALSE;
+  GVariant *ret_bloom;
+
+  /* TODO - compute bloom filter */
+
+  ret_bloom = g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), NULL, 0, 1);
+  g_variant_ref_sink (ret_bloom);
+
+  ret = TRUE;
+  ot_transfer_out_value (out_bloom, &ret_bloom);
+  /* out: */
+  ot_clear_gvariant (&ret_bloom);
+  return ret;
+}
+
+gboolean
+ostree_repo_regenerate_pack_index (OstreeRepo       *self,
+                                   GCancellable     *cancellable,
+                                   GError          **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  GFile *index_path = NULL;
+  GPtrArray *pack_indexes = NULL;
+  GVariantBuilder *index_content_builder = NULL;
+  GVariant *index_variant = NULL;
+  guint i;
+
+  if (!list_pack_indexes_from_dir (self, &pack_indexes, cancellable, error))
+    goto out;
+
+  index_path = g_file_get_child (priv->pack_dir, "index");
+
+  index_content_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ayay)"));
+  
+  for (i = 0; i < pack_indexes->len; i++)
+    {
+      const char *pack_checksum = pack_indexes->pdata[i];
+      GVariant *bloom;
+
+      if (!create_index_bloom (self, pack_checksum, &bloom, cancellable, error))
+        goto out;
+
+      g_variant_builder_add (index_content_builder,
+                             "(@ay ay)",
+                             ostree_checksum_to_bytes (pack_checksum),
+                             bloom);
+      g_variant_unref (bloom);
+    }
+
+  index_variant = g_variant_new ("(s a{sv}@a(ayay))",
+                                 "OSTv0SUPERPACKINDEX",
+                                 g_variant_new_array (G_VARIANT_TYPE ("{sv}"),
+                                                      NULL, 0),
+                                 g_variant_builder_end (index_content_builder));
+  g_variant_ref_sink (index_variant);
+
+  if (!ot_util_variant_save (index_path, index_variant,
+                             cancellable, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  ot_clear_gvariant (&index_variant);
+  if (index_content_builder)
+    g_variant_builder_unref (index_content_builder);
+  g_clear_object (&index_path);
+  if (pack_indexes)
+    g_ptr_array_unref (pack_indexes);
+  return ret;
+}
+
+gboolean
+ostree_repo_add_pack_file (OstreeRepo       *self,
+                           const char       *pack_checksum,
+                           GFile            *index_path,
+                           GFile            *data_path,
+                           GCancellable     *cancellable,
+                           GError          **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  char *dest_name = NULL;
+  GFile *pack_index_path = NULL;
+  GFile *pack_data_path = NULL;
+
+  if (!ot_gfile_ensure_directory (priv->pack_dir, FALSE, error))
+    goto out;
+
+  g_free (dest_name);
+  dest_name = g_strconcat ("ostpack-", pack_checksum, ".data", NULL);
+  pack_data_path = g_file_get_child (priv->pack_dir, dest_name);
+
+  if (!ot_gfile_rename (data_path, pack_data_path, cancellable, error))
+    goto out;
+
+  g_free (dest_name);
+  dest_name = g_strconcat ("ostpack-", pack_checksum, ".index", NULL);
+  pack_index_path = g_file_get_child (priv->pack_dir, dest_name);
+
+  if (!ot_gfile_rename (index_path, pack_index_path, cancellable, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  g_clear_object (&pack_index_path);
+  g_clear_object (&pack_data_path);
+  g_free (dest_name);
+  return ret;
+}
+
 static GVariant *
 create_tree_variant_from_hashes (GHashTable            *file_checksums,
                                  GHashTable            *dir_contents_checksums,
@@ -2351,76 +2644,6 @@ list_loose_object_dir (OstreeRepo             *self,
 }
 
 static gboolean
-list_files_in_dir_matching (GFile                  *dir,
-                            const char             *prefix,
-                            const char             *suffix,
-                            GPtrArray             **out_files,
-                            GCancellable           *cancellable,
-                            GError                **error)
-{
-  gboolean ret = FALSE;
-  GError *temp_error = NULL;
-  GFileEnumerator *enumerator = NULL;
-  GFileInfo *file_info = NULL;
-  GPtrArray *ret_files = NULL;
-
-  g_return_val_if_fail (prefix != NULL || suffix != NULL, FALSE);
-
-  ret_files = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-
-  enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, 
-                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                          cancellable, 
-                                          error);
-  if (!enumerator)
-    goto out;
-  
-  while ((file_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)) != NULL)
-    {
-      const char *name;
-      guint32 type;
-
-      name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); 
-      type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
-
-      if (type != G_FILE_TYPE_REGULAR)
-        goto loop_next;
-
-      if (prefix)
-        {
-          if (!g_str_has_prefix (name, prefix))
-            goto loop_next;
-        }
-      if (suffix)
-        {
-          if (!g_str_has_suffix (name, suffix))
-            goto loop_next;
-        }
-
-      g_ptr_array_add (ret_files, g_file_get_child (dir, name));
-      
-    loop_next:
-      g_clear_object (&file_info);
-    }
-  if (temp_error != NULL)
-    {
-      g_propagate_error (error, temp_error);
-      goto out;
-    }
-  if (!g_file_enumerator_close (enumerator, cancellable, error))
-    goto out;
-
-  ret = TRUE;
-  ot_transfer_out_value (out_files, &ret_files);
- out:
-  if (ret_files)
-    g_ptr_array_unref (ret_files);
-  g_clear_object (&file_info);
-  g_clear_object (&enumerator);
-  return ret;
-}
-
-static gboolean
 list_loose_objects (OstreeRepo                     *self,
                     GHashTable                     *inout_objects,
                     GCancellable                   *cancellable,
@@ -2473,22 +2696,6 @@ list_loose_objects (OstreeRepo                     *self,
   return ret;
 }
 
-static char *
-get_checksum_from_pack_name (const char *name)
-{
-  const char *dash;
-  const char *dot;
-
-  dash = strchr (name, '-');
-  g_assert (dash);
-  dot = strrchr (name, '.');
-  g_assert (dot);
-
-  g_assert_cmpint (dot - (dash + 1), ==, 64);
-  
-  return g_strndup (dash + 1, 64);
-}
-
 GFile *
 ostree_repo_get_pack_index_path (OstreeRepo *self,
                                  const char *checksum)
@@ -2896,42 +3103,6 @@ list_packed_objects (OstreeRepo                     *self,
   return ret;
 }
 
-gboolean
-ostree_repo_list_pack_indexes (OstreeRepo              *self,
-                               GPtrArray              **out_indexes,
-                               GCancellable            *cancellable,
-                               GError                 **error)
-{
-  gboolean ret = FALSE;
-  GPtrArray *index_files = NULL;
-  GPtrArray *ret_indexes = NULL;
-  OstreeRepoPrivate *priv = GET_PRIVATE (self);
-  guint i;
-
-  if (!list_files_in_dir_matching (priv->pack_dir,
-                                   "ostpack-", ".index",
-                                   &index_files, 
-                                   cancellable, error))
-    goto out;
-
-  ret_indexes = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free);
-  for (i = 0; i < index_files->len; i++)
-    {
-      GFile *index_path = index_files->pdata[i];
-      const char *basename = ot_gfile_get_basename_cached (index_path);
-      g_ptr_array_add (ret_indexes, get_checksum_from_pack_name (basename));
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_indexes, &ret_indexes);
- out:
-  if (index_files)
-    g_ptr_array_unref (index_files);
-  if (ret_indexes)
-    g_ptr_array_unref (ret_indexes);
-  return ret;
-}
-
 static gboolean
 find_object_in_packs (OstreeRepo        *self,
                       const char        *checksum,
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index f4c9915..e293cfb 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -230,6 +230,19 @@ gboolean      ostree_repo_stage_commit (OstreeRepo   *self,
                                         GCancellable *cancellable,
                                         GError      **error);
 
+gboolean
+ostree_repo_regenerate_pack_index (OstreeRepo       *self,
+                                   GCancellable     *cancellable,
+                                   GError          **error);
+
+
+gboolean     ostree_repo_add_pack_file (OstreeRepo       *self,
+                                        const char       *checksum,
+                                        GFile            *pack_index_path,
+                                        GFile            *pack_data_path,
+                                        GCancellable     *cancellable,
+                                        GError          **error);
+
 typedef enum {
   OSTREE_REPO_CHECKOUT_MODE_NONE = 0,
   OSTREE_REPO_CHECKOUT_MODE_USER = 1
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index 0ca520c..6d2ca73 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -85,7 +85,8 @@ ot_gfile_ensure_directory (GFile     *dir,
  *
  * Like g_file_delete(), except this function does not follow Unix
  * symbolic links, and will delete a symbolic link even if it's
- * pointing to a nonexistent file.
+ * pointing to a nonexistent file.  In other words, this function
+ * merely wraps the raw Unix function unlink().
  *
  * Returns: %TRUE on success, %FALSE on error
  */
@@ -105,6 +106,36 @@ ot_gfile_unlink (GFile          *path,
   return TRUE;
 }
 
+/**
+ * ot_gfile_rename:
+ * @from: Current path
+ * @to: New path
+ * @cancellable: a #GCancellable
+ * @error: a #GError
+ *
+ * This function wraps the raw Unix function rename().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+ot_gfile_rename (GFile          *from,
+                 GFile          *to,
+                 GCancellable   *cancellable,
+                 GError        **error)
+{
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
+
+  if (rename (ot_gfile_get_path_cached (from),
+              ot_gfile_get_path_cached (to)) < 0)
+    {
+      ot_util_set_error_from_errno (error, errno);
+      return FALSE;
+    }
+  return TRUE;
+
+}
+
 gboolean
 ot_gfile_load_contents_utf8 (GFile         *file,
                              char         **contents_out,
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 9b837e1..c5831d3 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -44,6 +44,11 @@ const char *ot_gfile_get_basename_cached (GFile *file);
 
 gboolean ot_gfile_ensure_directory (GFile *dir, gboolean with_parents, GError **error);
 
+gboolean ot_gfile_rename (GFile          *src,
+                          GFile          *dest,
+                          GCancellable   *cancellable,
+                          GError        **error);
+
 gboolean ot_gfile_unlink (GFile          *path,
                           GCancellable   *cancellable,
                           GError        **error);
diff --git a/src/ostree/ot-builtin-pack.c b/src/ostree/ot-builtin-pack.c
index d290dea..cdef0f0 100644
--- a/src/ostree/ot-builtin-pack.c
+++ b/src/ostree/ot-builtin-pack.c
@@ -35,6 +35,7 @@
 #define OT_GZIP_COMPRESSION_LEVEL (8)
 
 static gboolean opt_analyze_only;
+static gboolean opt_reindex_only;
 static gboolean opt_keep_loose;
 static char* opt_pack_size;
 static char* opt_int_compression;
@@ -51,6 +52,7 @@ static GOptionEntry options[] = {
   { "internal-compression", 0, 0, G_OPTION_ARG_STRING, &opt_int_compression, "Compress objects using COMPRESSION", "COMPRESSION" },
   { "external-compression", 0, 0, G_OPTION_ARG_STRING, &opt_ext_compression, "Compress entire packfiles using COMPRESSION", "COMPRESSION" },
   { "analyze-only", 0, 0, G_OPTION_ARG_NONE, &opt_analyze_only, "Just analyze current state", NULL },
+  { "reindex-only", 0, 0, G_OPTION_ARG_NONE, &opt_reindex_only, "Regenerate pack index", NULL },
   { "keep-loose", 0, 0, G_OPTION_ARG_NONE, &opt_keep_loose, "Don't delete loose objects", NULL },
   { NULL }
 };
@@ -437,25 +439,6 @@ create_pack_file (OtRepackData        *data,
   if (!g_output_stream_close (pack_out, cancellable, error))
     goto out;
 
-  pack_dir = g_file_resolve_relative_path (ostree_repo_get_path (data->repo),
-                                           "objects/pack");
-  if (!ot_gfile_ensure_directory (pack_dir, FALSE, error))
-    goto out;
-
-  pack_name = g_strconcat ("ostpack-", g_checksum_get_string (pack_checksum), ".data", NULL);
-  pack_file_path = g_file_get_child (pack_dir, pack_name);
-
-  if (rename (ot_gfile_get_path_cached (pack_temppath),
-              ot_gfile_get_path_cached (pack_file_path)) < 0)
-    {
-      ot_util_set_error_from_errno (error, errno);
-      g_prefix_error (error, "Failed to rename pack file '%s' to '%s': ",
-                      ot_gfile_get_path_cached (pack_temppath),
-                      ot_gfile_get_path_cached (pack_file_path));
-      goto out;
-    }
-  g_clear_object (&pack_temppath);
-
   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++)
@@ -479,20 +462,16 @@ create_pack_file (OtRepackData        *data,
   if (!g_output_stream_close (index_out, cancellable, error))
     goto out;
 
-  g_free (pack_name);
-  pack_name = g_strconcat ("ostpack-", g_checksum_get_string (pack_checksum), ".index", NULL);
-  pack_index_path = g_file_get_child (pack_dir, pack_name);
+  if (!ostree_repo_add_pack_file (data->repo,
+                                  g_checksum_get_string (pack_checksum),
+                                  index_temppath,
+                                  pack_temppath,
+                                  cancellable,
+                                  error))
+    goto out;
 
-  if (rename (ot_gfile_get_path_cached (index_temppath),
-              ot_gfile_get_path_cached (pack_index_path)) < 0)
-    {
-      ot_util_set_error_from_errno (error, errno);
-      g_prefix_error (error, "Failed to rename pack file '%s' to '%s': ",
-                      ot_gfile_get_path_cached (index_temppath),
-                      ot_gfile_get_path_cached (pack_index_path));
-      goto out;
-    }
-  g_clear_object (&index_temppath);
+  if (!ostree_repo_regenerate_pack_index (data->repo, cancellable, error))
+    goto out;
 
   g_print ("Created pack file '%s' with %u objects\n", g_checksum_get_string (pack_checksum), objects->len);
 
@@ -831,6 +810,57 @@ do_stats_gather_loose (OtRepackData  *data,
   return ret;
 }
 
+static gboolean
+do_incremental_pack (OtRepackData          *data,
+                     GCancellable          *cancellable,
+                     GError               **error)
+{
+  gboolean ret = FALSE;
+  GHashTable *objects = NULL;
+  guint i;
+  GPtrArray *clusters = NULL;
+  GHashTable *loose_objects = NULL;
+
+  if (!ostree_repo_list_objects (data->repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects,
+                                 cancellable, error))
+    goto out;
+
+  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 (!cluster_objects_stupidly (data, loose_objects, &clusters, cancellable, error))
+    goto out;
+  
+  if (clusters->len > 0)
+    g_print ("Going to create %u packfiles\n", clusters->len);
+  else
+    g_print ("Nothing to do\n");
+  
+  for (i = 0; i < clusters->len; i++)
+    {
+      GPtrArray *cluster = clusters->pdata[i];
+      
+      if (!opt_analyze_only)
+        {
+          if (!create_pack_file (data, cluster, cancellable, error))
+            goto out;
+        }
+    }
+
+  ret = TRUE;
+ out:
+  if (clusters)
+    g_ptr_array_unref (clusters);
+  if (loose_objects)
+    g_hash_table_unref (loose_objects);
+  if (objects)
+    g_hash_table_unref (objects);
+  return ret;
+}
+
 gboolean
 ostree_builtin_pack (int argc, char **argv, GFile *repo_path, GError **error)
 {
@@ -838,11 +868,7 @@ ostree_builtin_pack (int argc, char **argv, GFile *repo_path, GError **error)
   GOptionContext *context;
   OtRepackData data;
   OstreeRepo *repo = NULL;
-  GHashTable *objects = NULL;
   GCancellable *cancellable = NULL;
-  guint i;
-  GPtrArray *clusters = NULL;
-  GHashTable *loose_objects = NULL;
 
   memset (&data, 0, sizeof (data));
 
@@ -874,32 +900,15 @@ ostree_builtin_pack (int argc, char **argv, GFile *repo_path, GError **error)
   if (!parse_compression_string (opt_ext_compression, &data.ext_compression, error))
     goto out;
 
-  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, cancellable, error))
-    goto out;
-
-  g_print ("\n");
-  g_print ("Using pack size: %" G_GUINT64_FORMAT "\n", data.pack_size);
-
-  if (!cluster_objects_stupidly (&data, loose_objects, &clusters, cancellable, error))
-    goto out;
-  
-  if (clusters->len > 0)
-    g_print ("Going to create %u packfiles\n", clusters->len);
+  if (opt_reindex_only)
+    {
+      if (!ostree_repo_regenerate_pack_index (repo, cancellable, error))
+        goto out;
+    }
   else
-    g_print ("Nothing to do\n");
-  
-  for (i = 0; i < clusters->len; i++)
     {
-      GPtrArray *cluster = clusters->pdata[i];
-      
-      if (!opt_analyze_only)
-        {
-          if (!create_pack_file (&data, cluster, cancellable, error))
-            goto out;
-        }
+      if (!do_incremental_pack (&data, cancellable, error))
+        goto out;
     }
 
   ret = TRUE;
@@ -907,11 +916,5 @@ ostree_builtin_pack (int argc, char **argv, GFile *repo_path, GError **error)
   if (context)
     g_option_context_free (context);
   g_clear_object (&repo);
-  if (clusters)
-    g_ptr_array_unref (clusters);
-  if (loose_objects)
-    g_hash_table_unref (loose_objects);
-  if (objects)
-    g_hash_table_unref (objects);
   return ret;
 }



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