[ostree/wip/packfile-rebase2: 11/11] core: Delete loose objects
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/packfile-rebase2: 11/11] core: Delete loose objects
- Date: Thu, 22 Mar 2012 03:14:50 +0000 (UTC)
commit 999f2eb292e44f191a591d60626e32f5cadd7887
Author: Colin Walters <walters verbum org>
Date: Wed Mar 21 23:12:38 2012 -0400
core: Delete loose objects
src/libostree/ostree-repo.c | 156 ++++++++++++++++++++++++++++------------
src/libostree/ostree-repo.h | 1 +
src/ostree/ostree-pull.c | 17 ++++-
src/ostree/ot-builtin-repack.c | 44 +++++++++++-
4 files changed, 165 insertions(+), 53 deletions(-)
---
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 7cc8081..c9b6b72 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -781,48 +781,6 @@ get_pending_object_path (OstreeRepo *self,
return ret;
}
-gboolean
-ostree_repo_find_object (OstreeRepo *self,
- OstreeObjectType objtype,
- const char *checksum,
- GFile **out_stored_path,
- GFile **out_pending_path,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- GFile *object_path = NULL;
- struct stat stbuf;
-
- g_return_val_if_fail (out_stored_path, FALSE);
- g_return_val_if_fail (out_pending_path, FALSE);
-
- object_path = ostree_repo_get_object_path (self, checksum, objtype);
-
- *out_stored_path = NULL;
- *out_pending_path = NULL;
- if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0)
- {
- *out_stored_path = object_path;
- object_path = NULL;
- }
- else
- {
- g_clear_object (&object_path);
- object_path = get_pending_object_path (self, checksum, objtype);
- if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0)
- {
- *out_pending_path = object_path;
- object_path = NULL;
- }
- }
-
- ret = TRUE;
- /* out: */
- g_clear_object (&object_path);
- return ret;
-}
-
static GFileInfo *
dup_file_info_owned_by_me (GFileInfo *file_info)
{
@@ -1008,6 +966,7 @@ stage_object_impl (OstreeRepo *self,
GFile *temp_file = NULL;
GFile *stored_path = NULL;
GFile *pending_path = NULL;
+ char *pack_checksum = NULL;
const char *actual_checksum;
g_return_val_if_fail (priv->in_transaction, FALSE);
@@ -1019,7 +978,9 @@ stage_object_impl (OstreeRepo *self,
if (expected_checksum)
{
- if (!ostree_repo_find_object (self, objtype, expected_checksum, &stored_path, &pending_path,
+ if (!ostree_repo_find_object (self, objtype, expected_checksum,
+ &stored_path, &pending_path,
+ &pack_checksum,
cancellable, error))
goto out;
}
@@ -1027,7 +988,7 @@ stage_object_impl (OstreeRepo *self,
g_assert (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
g_assert (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META);
- if (stored_path == NULL && pending_path == NULL)
+ if (stored_path == NULL && pending_path == NULL && pack_checksum == NULL)
{
if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
{
@@ -1088,7 +1049,7 @@ stage_object_impl (OstreeRepo *self,
}
else
{
- g_assert (stored_path != NULL);
+ g_assert (stored_path != NULL || pack_checksum != NULL);
/* Nothing to do */
}
@@ -1101,6 +1062,7 @@ stage_object_impl (OstreeRepo *self,
g_clear_object (&temp_info);
g_clear_object (&stored_path);
g_clear_object (&pending_path);
+ g_free (pack_checksum);
ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -2827,7 +2789,7 @@ ostree_repo_load_pack_entry (OstreeRepo *self,
goto out;
index_contents = g_variant_get_child_value (index, 3);
-
+
if (!bsearch_in_pack_index (index_contents, entry_sha256, objtype, &offset))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -2986,6 +2948,108 @@ ostree_repo_list_pack_indexes (OstreeRepo *self,
return ret;
}
+static gboolean
+find_object_in_packs (OstreeRepo *self,
+ const char *checksum,
+ OstreeObjectType objtype,
+ char **out_pack_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GPtrArray *index_checksums = NULL;
+ char *ret_pack_checksum = NULL;
+ GFile *index_path = NULL;
+ GVariant *index_variant = NULL;
+ GVariant *index_contents = NULL;
+ guint i;
+
+ if (!ostree_repo_list_pack_indexes (self, &index_checksums, cancellable, error))
+ goto out;
+
+ for (i = 0; i < index_checksums->len; i++)
+ {
+ const char *pack_checksum = index_checksums->pdata[i];
+ guint64 offset;
+
+ g_clear_object (&index_path);
+ index_path = get_pack_index_path (self, pack_checksum);
+
+ ot_clear_gvariant (&index_variant);
+ if (!ostree_repo_load_pack_index (self, pack_checksum, &index_variant, cancellable, error))
+ goto out;
+
+ ot_clear_gvariant (&index_contents);
+ index_contents = g_variant_get_child_value (index_variant, 3);
+
+ if (!bsearch_in_pack_index (index_contents, checksum, objtype, &offset))
+ continue;
+
+ ret_pack_checksum = g_strdup (checksum);
+ break;
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_pack_checksum, &ret_pack_checksum);
+ out:
+ g_free (ret_pack_checksum);
+ if (index_checksums)
+ g_ptr_array_unref (index_checksums);
+ g_clear_object (&index_path);
+ ot_clear_gvariant (&index_variant);
+ ot_clear_gvariant (&index_contents);
+ return ret;
+}
+
+gboolean
+ostree_repo_find_object (OstreeRepo *self,
+ OstreeObjectType objtype,
+ const char *checksum,
+ GFile **out_stored_path,
+ GFile **out_pending_path,
+ char **out_pack_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GFile *object_path = NULL;
+ char *ret_pack_checksum = NULL;
+ struct stat stbuf;
+
+ g_return_val_if_fail (out_stored_path, FALSE);
+ g_return_val_if_fail (out_pending_path, FALSE);
+
+ object_path = ostree_repo_get_object_path (self, checksum, objtype);
+
+ *out_stored_path = NULL;
+ *out_pending_path = NULL;
+ if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0)
+ {
+ *out_stored_path = object_path;
+ object_path = NULL;
+ }
+ else
+ {
+ g_clear_object (&object_path);
+ object_path = get_pending_object_path (self, checksum, objtype);
+ if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0)
+ {
+ *out_pending_path = object_path;
+ object_path = NULL;
+ }
+ if (!find_object_in_packs (self, checksum, objtype, &ret_pack_checksum,
+ cancellable, error))
+ goto out;
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_pack_checksum, &ret_pack_checksum);
+out:
+ g_clear_object (&object_path);
+ g_free (ret_pack_checksum);
+ return ret;
+}
+
/**
* ostree_repo_list_objects:
* @self:
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 29c6504..2fc4508 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -97,6 +97,7 @@ gboolean ostree_repo_find_object (OstreeRepo *self,
const char *checksum,
GFile **out_stored_path,
GFile **out_pending_path,
+ char **out_pack_checksum,
GCancellable *cancellable,
GError **error);
diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c
index 40f3d46..619042e 100644
--- a/src/ostree/ostree-pull.c
+++ b/src/ostree/ostree-pull.c
@@ -226,6 +226,7 @@ fetch_and_store_object (OstreeRepo *repo,
GInputStream *input = NULL;
GFile *stored_path = NULL;
GFile *pending_path = NULL;
+ char *pack_checksum = NULL;
GFile *temp_path = NULL;
GVariant *ret_metadata = NULL;
gboolean ret_is_pending;
@@ -233,10 +234,11 @@ fetch_and_store_object (OstreeRepo *repo,
g_assert (objtype != OSTREE_OBJECT_TYPE_RAW_FILE);
if (!ostree_repo_find_object (repo, objtype, checksum,
- &stored_path, &pending_path, NULL, error))
+ &stored_path, &pending_path, &pack_checksum,
+ cancellable, error))
goto out;
- if (!(stored_path || pending_path))
+ if (!(stored_path || pending_path || pack_checksum))
{
if (!fetch_object (repo, soup, baseuri, checksum, objtype, &temp_path, cancellable, error))
goto out;
@@ -286,6 +288,7 @@ fetch_and_store_object (OstreeRepo *repo,
g_clear_object (&input);
g_clear_object (&stored_path);
g_clear_object (&pending_path);
+ g_free (pack_checksum);
return ret;
}
@@ -310,6 +313,7 @@ fetch_and_store_tree_recurse (OstreeRepo *repo,
GFile *content_temp_path = NULL;
GFile *stored_path = NULL;
GFile *pending_path = NULL;
+ char *pack_checksum = NULL;
GInputStream *input = NULL;
if (!fetch_and_store_object (repo, soup, base_uri, rev, OSTREE_OBJECT_TYPE_DIR_TREE,
@@ -339,19 +343,23 @@ fetch_and_store_tree_recurse (OstreeRepo *repo,
g_clear_object (&stored_path);
g_clear_object (&pending_path);
+ g_free (pack_checksum);
+ pack_checksum = NULL;
/* If we're fetching from an archive into a bare repository, we need
* to explicitly check for raw file types locally.
*/
if (ostree_repo_get_mode (repo) == OSTREE_REPO_MODE_BARE)
{
if (!ostree_repo_find_object (repo, OSTREE_OBJECT_TYPE_RAW_FILE, checksum,
- &stored_path, &pending_path, cancellable, error))
+ &stored_path, &pending_path, &pack_checksum,
+ cancellable, error))
goto out;
}
else
{
if (!ostree_repo_find_object (repo, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT, checksum,
- &stored_path, &pending_path, cancellable, error))
+ &stored_path, &pending_path, &pack_checksum,
+ cancellable, error))
goto out;
}
@@ -451,6 +459,7 @@ fetch_and_store_tree_recurse (OstreeRepo *repo,
g_clear_object (&input);
g_clear_object (&stored_path);
g_clear_object (&pending_path);
+ g_free (pack_checksum);
if (content_temp_path)
{
(void) unlink (ot_gfile_get_path_cached (content_temp_path));
diff --git a/src/ostree/ot-builtin-repack.c b/src/ostree/ot-builtin-repack.c
index afa4864..40c92f9 100644
--- a/src/ostree/ot-builtin-repack.c
+++ b/src/ostree/ot-builtin-repack.c
@@ -35,6 +35,7 @@
#define OT_GZIP_COMPRESSION_LEVEL (8)
static gboolean opt_analyze_only;
+static gboolean opt_keep_loose;
static char* opt_pack_size;
static char* opt_int_compression;
static char* opt_ext_compression;
@@ -50,6 +51,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 },
+ { "keep-loose", 0, 0, G_OPTION_ARG_NONE, &opt_keep_loose, "Don't delete loose objects", NULL },
{ NULL }
};
@@ -660,11 +662,13 @@ 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;
@@ -679,6 +683,9 @@ 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))
@@ -698,14 +705,19 @@ do_stats_gather_loose (OtRepackData *data,
is_packed = g_variant_n_children (pack_array) > 0;
if (is_loose && is_packed)
- n_loose_and_packed++;
+ {
+ GVariant *copy = g_variant_ref (serialized_key);
+ g_hash_table_replace (ret_loose_and_packed, copy, copy);
+ n_loose++;
+ n_loose_and_packed++;
+ }
else if (is_loose)
{
GVariant *copy = g_variant_ref (serialized_key);
g_hash_table_replace (ret_loose, copy, copy);
n_loose++;
}
- else if (g_variant_n_children (pack_array) > 0)
+ else if (g_variant_n_children (pack_array) > 1)
n_dup_packed++;
else
n_packed++;
@@ -743,9 +755,12 @@ 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;
}
@@ -761,6 +776,10 @@ 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;
memset (&data, 0, sizeof (data));
@@ -788,12 +807,30 @@ 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, cancellable, error))
+ if (!do_stats_gather_loose (&data, objects, &loose_objects, &loose_and_packed_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;
@@ -817,6 +854,7 @@ ostree_builtin_repack (int argc, char **argv, GFile *repo_path, GError **error)
ret = TRUE;
out:
+ g_clear_object (&objpath);
if (context)
g_option_context_free (context);
g_clear_object (&repo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]