[ostree] diff: Add --stats option



commit 1b3ef57cf43997dbb71dac0d28e97b93a451c6a5
Author: Colin Walters <walters verbum org>
Date:   Wed Jul 17 19:20:22 2013 -0400

    diff: Add --stats option
    
    This a neat way to see how many objects are shared between two
    commits.

 src/ostree/ot-builtin-diff.c |  127 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 114 insertions(+), 13 deletions(-)
---
diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c
index 143fe26..0668609 100644
--- a/src/ostree/ot-builtin-diff.c
+++ b/src/ostree/ot-builtin-diff.c
@@ -25,7 +25,12 @@
 #include "ot-builtins.h"
 #include "ostree.h"
 
+static gboolean opt_stats;
+static gboolean opt_fs_diff;
+
 static GOptionEntry options[] = {
+  { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL },
+  { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL },
   { NULL }
 };
 
@@ -57,6 +62,61 @@ parse_file_or_commit (OstreeRepo  *repo,
   return ret;
 }
 
+static GHashTable *
+reachable_set_intersect (GHashTable *a, GHashTable *b)
+{
+  GHashTable *ret = ostree_repo_traverse_new_reachable ();
+  GHashTableIter hashiter;
+  gpointer key, value;
+
+  g_hash_table_iter_init (&hashiter, a);
+  while (g_hash_table_iter_next (&hashiter, &key, &value))
+    {
+      GVariant *v = key;
+      if (g_hash_table_contains (b, v))
+        g_hash_table_insert (ret, g_variant_ref (v), v);
+    }
+
+  return ret;
+}
+
+static gboolean
+object_set_total_size (OstreeRepo    *repo,
+                       GHashTable    *reachable,
+                       guint64       *out_total,
+                       GCancellable  *cancellable,
+                       GError       **error)
+{
+  gboolean ret = FALSE;
+  GHashTableIter hashiter;
+  gpointer key, value;
+
+  *out_total = 0;
+
+  g_hash_table_iter_init (&hashiter, reachable);
+  while (g_hash_table_iter_next (&hashiter, &key, &value))
+    {
+      GVariant *v = key;
+      const char *csum;
+      OstreeObjectType objtype;
+      gs_unref_object GFile *objpath = NULL;
+      gs_unref_object GFileInfo *finfo = NULL;
+
+      ostree_object_name_deserialize (v, &csum, &objtype);
+      objpath = ostree_repo_get_object_path (repo, csum, objtype);
+      finfo = g_file_query_info (objpath, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                 cancellable, error);
+      if (!finfo)
+        goto out;
+      
+      *out_total += g_file_info_get_size (finfo);
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
 gboolean
 ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *cancellable, GError **error)
 {
@@ -68,7 +128,6 @@ ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *canc
   gs_free char *src_prev = NULL;
   gs_unref_object GFile *srcf = NULL;
   gs_unref_object GFile *targetf = NULL;
-  gs_unref_object GFile *cwd = NULL;
   gs_unref_ptrarray GPtrArray *modified = NULL;
   gs_unref_ptrarray GPtrArray *removed = NULL;
   gs_unref_ptrarray GPtrArray *added = NULL;
@@ -105,21 +164,63 @@ ostree_builtin_diff (int argc, char **argv, GFile *repo_path, GCancellable *canc
       target = argv[2];
     }
 
-  cwd = g_file_new_for_path (".");
+  if (!opt_stats && !opt_fs_diff)
+    opt_fs_diff = TRUE;
 
-  if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
-    goto out;
-  if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
-    goto out;
+  if (opt_fs_diff)
+    {
+      if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
+        goto out;
+      if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
+        goto out;
 
-  modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
-  removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-  added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-  
-  if (!ostree_diff_dirs (srcf, targetf, modified, removed, added, cancellable, error))
-    goto out;
+      modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
+      removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
+      added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
+      
+      if (!ostree_diff_dirs (srcf, targetf, modified, removed, added, cancellable, error))
+        goto out;
+
+      ostree_diff_print (srcf, targetf, modified, removed, added);
+    }
+
+  if (opt_stats)
+    {
+      gs_unref_hashtable GHashTable *reachable_a = ostree_repo_traverse_new_reachable ();
+      gs_unref_hashtable GHashTable *reachable_b = ostree_repo_traverse_new_reachable ();
+      gs_unref_hashtable GHashTable *reachable_intersection = NULL;
+      gs_free char *rev_a = NULL;
+      gs_free char *rev_b = NULL;
+      gs_free char *size = NULL;
+      guint a_size;
+      guint b_size;
+      guint64 total_common;
+
+      if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error))
+        goto out;
+      if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error))
+        goto out;
+
+      if (!ostree_repo_traverse_commit (repo, rev_a, -1, reachable_a, cancellable, error))
+        goto out;
+      if (!ostree_repo_traverse_commit (repo, rev_b, -1, reachable_b, cancellable, error))
+        goto out;
 
-  ostree_diff_print (srcf, targetf, modified, removed, added);
+      a_size = g_hash_table_size (reachable_a);
+      b_size = g_hash_table_size (reachable_b);
+      g_print ("[A] Object Count: %u\n", a_size);
+      g_print ("[B] Object Count: %u\n", b_size);
+
+      reachable_intersection = reachable_set_intersect (reachable_a, reachable_b);
+
+      g_print ("Common Object Count: %u\n", g_hash_table_size (reachable_intersection));
+
+      if (!object_set_total_size (repo, reachable_intersection, &total_common,
+                                  cancellable, error))
+        goto out;
+      size = g_format_size_full (total_common, 0);
+      g_print ("Common Object Size: %s\n", size);
+    }
 
   ret = TRUE;
  out:


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