[gvfs/wip/rishi/goa: 7/7] Introduce dir_entries and fix a bug in copy
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/rishi/goa: 7/7] Introduce dir_entries and fix a bug in copy
- Date: Thu, 27 Aug 2015 18:31:18 +0000 (UTC)
commit 8acc84a1a543d859ff9c96d42e67e657d7092547
Author: Debarshi Ray <debarshir gnome org>
Date: Thu Aug 27 20:28:50 2015 +0200
Introduce dir_entries and fix a bug in copy
daemon/gvfsbackendgoogle.c | 173 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 141 insertions(+), 32 deletions(-)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index a5ca53e..d8cbf47 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -55,6 +55,7 @@ struct _GVfsBackendGoogle
GDataDocumentsService *service;
GDataEntry *root;
GHashTable *entries;
+ GHashTable *dir_entries;
GHashTable *lookaside;
GHashTable *monitors;
GRecMutex mutex;
@@ -86,6 +87,65 @@ G_DEFINE_TYPE(GVfsBackendGoogle, g_vfs_backend_google, G_VFS_TYPE_BACKEND)
/* ---------------------------------------------------------------------------------------------------- */
+typedef struct
+{
+ gchar *title_or_id;
+ gchar *parent_id;
+} DirEntriesKey;
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+DirEntriesKey *
+dir_entries_key_new (const gchar *title_or_id, const gchar *parent_id)
+{
+ DirEntriesKey *k;
+
+ k = g_slice_new (DirEntriesKey);
+ k->title_or_id = g_strdup (title_or_id);
+ k->parent_id = g_strdup (parent_id);
+ return k;
+}
+
+static void
+dir_entries_key_free (gpointer data)
+{
+ DirEntriesKey *k = (DirEntriesKey *) data;
+
+ if (k == NULL)
+ return;
+
+ g_free (k->title_or_id);
+ g_free (k->parent_id);
+ g_slice_free (DirEntriesKey, k);
+}
+
+guint
+entries_in_folder_hash (gconstpointer key)
+{
+ DirEntriesKey *k = (DirEntriesKey *) key;
+ guint hash1;
+ guint hash2;
+
+ hash1 = g_str_hash (k->title_or_id);
+ hash2 = g_str_hash (k->parent_id);
+ return hash1 ^ hash2;
+}
+
+gboolean
+entries_in_folder_equal (gconstpointer a, gconstpointer b)
+{
+ DirEntriesKey *k_a = (DirEntriesKey *) a;
+ DirEntriesKey *k_b = (DirEntriesKey *) b;
+
+ if (g_strcmp0 (k_a->title_or_id, k_b->title_or_id) == 0 &&
+ g_strcmp0 (k_a->parent_id, k_b->parent_id) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
insert_lookaside (GVfsBackendGoogle *self,
const gchar *parent_id,
@@ -745,6 +805,60 @@ get_parent_basename (const gchar *filename)
/* ---------------------------------------------------------------------------------------------------- */
static void
+insert_entry (GVfsBackendGoogle *self,
+ GDataEntry *entry)
+{
+ DirEntriesKey *k;
+ const gchar *id;
+ const gchar *title;
+ gchar *parent_id;
+
+ id = gdata_entry_get_id (entry);
+ g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (entry));
+
+ parent_id = get_parent_id (entry);
+ if (parent_id == NULL)
+ return;
+
+ k = dir_entries_key_new (id, parent_id);
+ g_hash_table_insert (self->dir_entries, k, g_object_ref (entry));
+
+ title = gdata_entry_get_title (entry);
+ k = dir_entries_key_new (title, parent_id);
+ g_hash_table_insert (self->dir_entries, k, g_object_ref (entry));
+
+ g_free (parent_id);
+}
+
+static void
+remove_entry (GVfsBackendGoogle *self,
+ GDataEntry *entry)
+{
+ DirEntriesKey *k;
+ const gchar *id;
+ const gchar *title;
+ gchar *parent_id;
+
+ id = gdata_entry_get_id (entry);
+ g_hash_table_remove (self->entries, id);
+
+ parent_id = get_parent_id (entry);
+ if (parent_id == NULL)
+ return;
+
+ k = dir_entries_key_new (id, parent_id);
+ g_hash_table_remove (self->dir_entries, k);
+ dir_entries_key_free (k);
+
+ title = gdata_entry_get_title (entry);
+ k = dir_entries_key_new (title, parent_id);
+ g_hash_table_remove (self->dir_entries, k);
+ dir_entries_key_free (k);
+
+ g_free (parent_id);
+}
+
+static void
rebuild_entries (GVfsBackendGoogle *self,
GCancellable *cancellable,
GError **error)
@@ -782,6 +896,7 @@ rebuild_entries (GVfsBackendGoogle *self,
if (!succeeded_once)
{
g_hash_table_remove_all (self->entries);
+ g_hash_table_remove_all (self->dir_entries);
succeeded_once = TRUE;
}
@@ -792,10 +907,7 @@ rebuild_entries (GVfsBackendGoogle *self,
for (l = entries; l != NULL; l = l->next)
{
GDataEntry *entry = GDATA_ENTRY (l->data);
- const gchar *id;
-
- id = gdata_entry_get_id (entry);
- g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (entry));
+ insert_entry (self, entry);
}
gdata_query_next_page (GDATA_QUERY (query));
@@ -834,7 +946,6 @@ create_document (GVfsBackendGoogle *self,
GDataDocumentsFolder *parent;
GError *local_error;
gboolean is_root;
- const gchar *id;
gchar *parent_id = NULL;
gchar *parent_path = NULL;
gchar *path = NULL;
@@ -881,8 +992,7 @@ create_document (GVfsBackendGoogle *self,
if (local_error != NULL)
goto out;
- id = gdata_entry_get_id (GDATA_ENTRY (new_document));
- g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_document));
+ insert_entry (self, GDATA_ENTRY (new_document));
path = get_entry_path (self, GDATA_ENTRY (new_document));
if (path != NULL)
@@ -924,9 +1034,8 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
GDataEntry *source_entry;
GError *error;
gboolean is_folder;
- gboolean is_root;
+ gboolean destination_is_root;
gboolean is_volatile_source;
- const gchar *id;
const gchar *real_destination_parent_path;
const gchar *real_parent_path;
const gchar *real_source;
@@ -996,8 +1105,8 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
destination_parent_path = g_strdup (real_destination_parent_path);
}
- is_folder_or_root (destination_parent_path, NULL, NULL, &is_root);
- if (is_root)
+ is_folder_or_root (destination_parent_path, NULL, NULL, &destination_is_root);
+ if (destination_is_root)
{
destination_parent = GDATA_DOCUMENTS_FOLDER (self->root);
}
@@ -1020,6 +1129,16 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
}
source_entry = g_hash_table_lookup (self->entries, source_id);
+
+ if (!destination_is_root && destination_parent == NULL)
+ destination_parent = g_hash_table_lookup (self->entries, destination_parent_id);
+
+ if (source_entry == NULL || destination_parent == NULL)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
+ goto out;
+ }
+
is_folder_or_root (source, source_entry, &is_folder, NULL);
if (is_folder)
{
@@ -1030,13 +1149,6 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
goto out;
}
- destination_parent = g_hash_table_lookup (self->entries, destination_parent_id);
- if (source_entry == NULL || destination_parent == NULL)
- {
- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
- goto out;
- }
-
error = NULL;
new_entry = gdata_documents_service_add_entry_to_folder (self->service,
GDATA_DOCUMENTS_ENTRY (source_entry),
@@ -1050,8 +1162,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
goto out;
}
- id = gdata_entry_get_id (GDATA_ENTRY (new_entry));
- g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_entry));
+ insert_entry (self, GDATA_ENTRY (new_entry));
path = get_entry_path (self, GDATA_ENTRY (new_entry));
if (path != NULL)
@@ -1248,7 +1359,7 @@ g_vfs_backend_google_delete (GVfsBackend *_self,
goto out;
}
- g_hash_table_remove (self->entries, id);
+ remove_entry (self, entry);
if (path != NULL)
g_hash_table_foreach (self->monitors, emit_delete_event, (gpointer) path);
@@ -1384,7 +1495,6 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self,
gboolean is_display_name;
gboolean is_root;
gboolean needs_rebuild = FALSE;
- const gchar *id;
const gchar *real_parent_path;
gchar *parent_id = NULL;
gchar *parent_path = NULL;
@@ -1489,8 +1599,7 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self,
goto out;
}
- id = gdata_entry_get_id (GDATA_ENTRY (new_entry));
- g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_entry));
+ insert_entry (self, GDATA_ENTRY (new_entry));
path = get_entry_path (self, GDATA_ENTRY (new_entry));
if (path != NULL)
@@ -1672,7 +1781,6 @@ g_vfs_backend_google_push (GVfsBackend *_self,
gboolean is_root;
gboolean needs_overwrite = FALSE;
const gchar *content_type;
- const gchar *id;
const gchar *title;
gchar *basename = NULL;
gchar *parent_id = NULL;
@@ -1899,8 +2007,7 @@ g_vfs_backend_google_push (GVfsBackend *_self,
goto out;
}
- id = gdata_entry_get_id (GDATA_ENTRY (new_document));
- g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_document));
+ insert_entry (self, GDATA_ENTRY (new_document));
path = get_entry_path (self, GDATA_ENTRY (new_document));
if (path != NULL)
@@ -2404,7 +2511,6 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self,
GError *error;
gboolean is_root;
gboolean is_volatile;
- const gchar *new_id;
gchar *escaped_filename = NULL;
gchar *id = NULL;
gchar *unescaped_filename = NULL;
@@ -2472,10 +2578,8 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self,
goto out;
}
- g_hash_table_remove (self->entries, id);
-
- new_id = gdata_entry_get_id (new_entry);
- g_hash_table_insert (self->entries, g_strdup (new_id), g_object_ref (new_entry));
+ remove_entry (self, entry);
+ insert_entry (self, new_entry);
g_hash_table_foreach (self->monitors, emit_attribute_changed_event, (gpointer) filename);
@@ -2826,6 +2930,7 @@ g_vfs_backend_google_dispose (GObject *_self)
g_clear_object (&self->root);
g_clear_object (&self->client);
g_clear_pointer (&self->entries, (GDestroyNotify) g_hash_table_unref);
+ g_clear_pointer (&self->dir_entries, (GDestroyNotify) g_hash_table_unref);
G_OBJECT_CLASS (g_vfs_backend_google_parent_class)->dispose (_self);
}
@@ -2884,6 +2989,10 @@ g_vfs_backend_google_init (GVfsBackendGoogle *self)
g_vfs_backend_set_prefered_filename_encoding (G_VFS_BACKEND (self), "google-drive");
self->entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ self->dir_entries = g_hash_table_new_full (entries_in_folder_hash,
+ entries_in_folder_equal,
+ dir_entries_key_free,
+ g_object_unref);
self->lookaside = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
self->monitors = g_hash_table_new (NULL, NULL);
g_rec_mutex_init (&self->mutex);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]