[gnome-builder] code-index: code style cleanup for map builder



commit 0c37e2deae8b655762b467782d20f0e8b0da8451
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jan 16 22:21:55 2018 -0800

    code-index: code style cleanup for map builder

 .../code-index/ide-persistent-map-builder.c        | 250 ++++++++++++---------
 .../code-index/ide-persistent-map-builder.h        |  44 ++--
 2 files changed, 172 insertions(+), 122 deletions(-)
---
diff --git a/src/plugins/code-index/ide-persistent-map-builder.c 
b/src/plugins/code-index/ide-persistent-map-builder.c
index 85ca52fe7..dd727011f 100644
--- a/src/plugins/code-index/ide-persistent-map-builder.c
+++ b/src/plugins/code-index/ide-persistent-map-builder.c
@@ -23,24 +23,28 @@
 
 #include "ide-persistent-map-builder.h"
 
-struct _IdePersistentMapBuilder
+typedef struct
 {
-  GObject      parent;
-
   /* Array of keys. */
-  GByteArray   *keys;
+  GByteArray *keys;
+
   /* Hash table of keys to remove duplicate keys. */
-  GHashTable   *keys_hash;
+  GHashTable *keys_hash;
+
   /* Array of values. */
-  GPtrArray    *values;
+  GPtrArray *values;
   /*
    * Array of key value pairs. This is pair of offset of
    * key in keys array and index of value in values array.
    */
-  GArray       *kvpairs;
+  GArray *kvpairs;
+
   /* Dictionary for metadata. */
   GVariantDict *metadata;
-};
+
+  /* Where to write the file */
+  GFile *destination;
+} BuildState;
 
 typedef struct
 {
@@ -48,8 +52,40 @@ typedef struct
   guint32 value;
 } KVPair;
 
+struct _IdePersistentMapBuilder
+{
+  GObject parent;
+
+  /* Owning thread for assertions */
+  GThread *thread;
+
+  /*
+   * The build state lets us keep all the contents together, and then
+   * pass it to the worker thread so the main thread can no longer access
+   * the existing state.
+   */
+  BuildState *state;
+};
+
+
+G_STATIC_ASSERT (sizeof (KVPair) == 8);
+
 G_DEFINE_TYPE (IdePersistentMapBuilder, ide_persistent_map_builder, G_TYPE_OBJECT)
 
+static void
+build_state_free (gpointer data)
+{
+  BuildState *state = data;
+
+  g_clear_pointer (&state->keys, g_byte_array_unref);
+  g_clear_pointer (&state->keys_hash, g_hash_table_unref);
+  g_clear_pointer (&state->values, g_ptr_array_unref);
+  g_clear_pointer (&state->kvpairs, g_array_unref);
+  g_clear_pointer (&state->metadata, g_variant_dict_unref);
+  g_clear_object (&state->destination);
+  g_slice_free (BuildState, state);
+}
+
 void
 ide_persistent_map_builder_insert (IdePersistentMapBuilder *self,
                                    const gchar             *key,
@@ -62,35 +98,38 @@ ide_persistent_map_builder_insert (IdePersistentMapBuilder *self,
   g_return_if_fail (IDE_IS_PERSISTENT_MAP_BUILDER (self));
   g_return_if_fail (key != NULL);
   g_return_if_fail (value != NULL);
+  g_return_if_fail (self->state != NULL);
+  g_return_if_fail (self->state->keys_hash != NULL);
+  g_return_if_fail (self->state->values != NULL);
+  g_return_if_fail (self->state->kvpairs != NULL);
 
   local_value = g_variant_ref_sink (value);
 
-  if ((value_index = GPOINTER_TO_UINT (g_hash_table_lookup (self->keys_hash, key))))
+  if (0 != (value_index = GPOINTER_TO_UINT (g_hash_table_lookup (self->state->keys_hash, key))))
     {
-      value_index--;
       if (replace)
         {
-          g_clear_pointer (&g_ptr_array_index (self->values, value_index), g_variant_unref);
-          g_ptr_array_index (self->values, value_index) = g_steal_pointer (&local_value);
+          g_variant_unref (g_ptr_array_index (self->state->values, value_index - 1));
+          g_ptr_array_index (self->state->values, value_index - 1) = g_steal_pointer (&local_value);
         }
     }
   else
     {
       KVPair kvpair;
 
-      kvpair.key = self->keys->len;
-      kvpair.value = self->values->len;
+      kvpair.key = self->state->keys->len;
+      kvpair.value = self->state->values->len;
 
-      g_byte_array_append (self->keys, (const guchar *)key, strlen (key) + 1);
-      g_ptr_array_add (self->values, g_steal_pointer (&local_value));
-      g_array_append_val (self->kvpairs, kvpair);
+      g_byte_array_append (self->state->keys, (const guchar *)key, strlen (key) + 1);
+      g_ptr_array_add (self->state->values, g_steal_pointer (&local_value));
+      g_array_append_val (self->state->kvpairs, kvpair);
 
       /*
        * Key in hashtable is the actual key in our map.
        * Value in hash table will point to element in values array
        * where actual value of key in our map is there.
        */
-      g_hash_table_insert (self->keys_hash,
+      g_hash_table_insert (self->state->keys_hash,
                            g_strdup (key),
                            GUINT_TO_POINTER (kvpair.value + 1));
     }
@@ -103,17 +142,16 @@ ide_persistent_map_builder_set_metadata_int64 (IdePersistentMapBuilder *self,
 {
   g_return_if_fail (IDE_IS_PERSISTENT_MAP_BUILDER (self));
   g_return_if_fail (key != NULL);
+  g_return_if_fail (self->state != NULL);
+  g_return_if_fail (self->state->metadata != NULL);
 
-  g_variant_dict_insert (self->metadata,
-                         key,
-                         "x",
-                         value);
+  g_variant_dict_insert (self->state->metadata, key, "x", value);
 }
 
-gint
-compare (KVPair       *a,
-         KVPair       *b,
-         gchar        *keys)
+static gint
+compare_keys (KVPair      *a,
+              KVPair      *b,
+              const gchar *keys)
 {
   return g_strcmp0 (keys + a->key, keys + b->key);
 }
@@ -125,65 +163,73 @@ ide_persistent_map_builder_write_worker (GTask        *task,
                                          GCancellable *cancellable)
 {
   IdePersistentMapBuilder *self = source_object;
-  GFile *destination = task_data;
-  GVariantDict dict;
+  BuildState *state = task_data;
+  g_autoptr(GError) error = NULL;
   g_autoptr(GVariant) data = NULL;
+  GVariantDict dict;
   GVariant *keys;
   GVariant *values;
   GVariant *kvpairs;
   GVariant *metadata;
-  g_autoptr(GError) error = NULL;
 
   g_assert (G_IS_TASK (task));
   g_assert (IDE_IS_PERSISTENT_MAP_BUILDER (self));
-  g_assert (G_IS_FILE (destination));
+  g_assert (state != NULL);
+  g_assert (state->keys != NULL);
+  g_assert (state->keys_hash != NULL);
+  g_assert (state->values != NULL);
+  g_assert (state->kvpairs != NULL);
+  g_assert (state->metadata != NULL);
+  g_assert (G_IS_FILE (state->destination));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
-  if (!self->keys->len)
-    g_task_return_boolean (task, TRUE);
+  if (g_task_return_error_if_cancelled (task))
+    return;
+
+  if (state->keys->len == 0)
+    {
+      g_task_return_new_error (task,
+                               G_IO_ERROR,
+                               G_IO_ERROR_INVALID_DATA,
+                               "No entries to write");
+      return;
+    }
 
   g_variant_dict_init (&dict, NULL);
 
   keys = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
-                                    self->keys->data,
-                                    self->keys->len,
+                                    state->keys->data,
+                                    state->keys->len,
                                     sizeof (guint8));
 
   values = g_variant_new_array (NULL,
-                                (GVariant * const *)(gpointer)self->values->pdata,
-                                self->values->len);
+                                (GVariant * const *)(gpointer)state->values->pdata,
+                                state->values->len);
+
+  g_array_sort_with_data (state->kvpairs,
+                          (GCompareDataFunc)compare_keys,
+                          state->keys->data);
 
-  g_array_sort_with_data (self->kvpairs, (GCompareDataFunc)compare, self->keys->data);
   kvpairs = g_variant_new_fixed_array (G_VARIANT_TYPE ("(uu)"),
-                                       self->kvpairs->data,
-                                       self->kvpairs->len,
+                                       state->kvpairs->data,
+                                       state->kvpairs->len,
                                        sizeof (KVPair));
 
-  metadata = g_variant_dict_end (self->metadata);
+  metadata = g_variant_dict_end (state->metadata);
 
-  /* Insert Keys. */
   g_variant_dict_insert_value (&dict, "keys", keys);
-  /* Insert values. */
   g_variant_dict_insert_value (&dict, "values", values);
-  /* Insert key value pairs. */
   g_variant_dict_insert_value (&dict, "kvpairs", kvpairs);
-  /* Insert metadata. */
   g_variant_dict_insert_value (&dict, "metadata", metadata);
-  /* Insert verion number. */
-  g_variant_dict_insert (&dict,
-                         "version",
-                         "i",
-                         2);
-  /* Insert byte order*/
-  g_variant_dict_insert (&dict,
-                         "byte-order",
-                         "i",
-                         G_BYTE_ORDER);
-
-  /* Write to file. */
-  data = g_variant_ref_sink (g_variant_dict_end (&dict));
-
-  if (g_file_replace_contents (destination,
+  g_variant_dict_insert (&dict, "version", "i", 2);
+  g_variant_dict_insert (&dict, "byte-order", "i", G_BYTE_ORDER);
+
+  data = g_variant_take_ref (g_variant_dict_end (&dict));
+
+  if (g_task_return_error_if_cancelled (task))
+    return;
+
+  if (g_file_replace_contents (state->destination,
                                g_variant_get_data (data),
                                g_variant_get_size (data),
                                NULL,
@@ -198,74 +244,78 @@ ide_persistent_map_builder_write_worker (GTask        *task,
 }
 
 gboolean
-ide_persistent_map_builder_write (IdePersistentMapBuilder *self,
-                                  GFile                   *destination,
-                                  gint                     io_priority,
-                                  GCancellable            *cancellable,
-                                  GError                 **error)
+ide_persistent_map_builder_write (IdePersistentMapBuilder  *self,
+                                  GFile                    *destination,
+                                  gint                      io_priority,
+                                  GCancellable             *cancellable,
+                                  GError                  **error)
 {
   g_autoptr(GTask) task = NULL;
 
   g_return_val_if_fail (IDE_IS_PERSISTENT_MAP_BUILDER (self), FALSE);
+  g_return_val_if_fail (self->thread == g_thread_self (), FALSE);
   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
   g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
+  g_return_val_if_fail (self->state != NULL, FALSE);
+  g_return_val_if_fail (self->state->destination != NULL, FALSE);
+
+  self->state->destination = g_object_ref (destination);
 
   task = g_task_new (self, cancellable, NULL, NULL);
   g_task_set_source_tag (task, ide_persistent_map_builder_write);
   g_task_set_priority (task, io_priority);
-  g_task_set_task_data (task, g_object_ref (destination), g_object_unref);
-
-  if (self->values->len)
-    ide_persistent_map_builder_write_worker (task, self, destination, cancellable);
-  else
-    g_task_return_new_error (task,
-                             G_IO_ERROR,
-                             G_IO_ERROR_INVALID_DATA,
-                             "No entries to write");
+  g_task_set_task_data (task, g_steal_pointer (&self->state), build_state_free);
+  g_task_run_in_thread_sync (task, ide_persistent_map_builder_write_worker);
 
   return g_task_propagate_boolean (task, error);
 }
 
 void
-ide_persistent_map_builder_write_async  (IdePersistentMapBuilder *self,
-                                         GFile                   *destination,
-                                         gint                     io_priority,
-                                         GCancellable            *cancellable,
-                                         GAsyncReadyCallback      callback,
-                                         gpointer                 user_data)
+ide_persistent_map_builder_write_async (IdePersistentMapBuilder *self,
+                                        GFile                   *destination,
+                                        gint                     io_priority,
+                                        GCancellable            *cancellable,
+                                        GAsyncReadyCallback      callback,
+                                        gpointer                 user_data)
 {
   g_autoptr(GTask) task = NULL;
 
   g_return_if_fail (IDE_IS_PERSISTENT_MAP_BUILDER (self));
+  g_return_if_fail (self->thread == g_thread_self ());
   g_return_if_fail (G_IS_FILE (destination));
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (self->thread == g_thread_self ());
+  g_return_if_fail (self->state != NULL);
+  g_return_if_fail (self->state->destination != NULL);
+
+  self->state->destination = g_object_ref (destination);
 
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_priority (task, io_priority);
-  g_task_set_task_data (task, g_object_ref (destination), g_object_unref);
   g_task_set_source_tag (task, ide_persistent_map_builder_write_async);
-
+  g_task_set_task_data (task, g_steal_pointer (&self->state), build_state_free);
   g_task_run_in_thread (task, ide_persistent_map_builder_write_worker);
 }
 
 /**
  * ide_persistent_map_builder_write_finish:
- * @self: An #IdePersistentMapBuilder instance.
- * @result: result of writing process
- * @error: error in writing process
+ * @self: an #IdePersistentMapBuilder
+ * @result: a #GAsyncResult provided to callback
+ * @error: location for a #GError, or %NULL
  *
- * Returns: Whether file is written or not.
+ * Returns: %TRUE if the while was written successfully; otherwise %FALSE
+ *   and @error is set.
  */
 gboolean
 ide_persistent_map_builder_write_finish (IdePersistentMapBuilder  *self,
                                          GAsyncResult             *result,
                                          GError                  **error)
 {
-  GTask *task = (GTask *)result;
-
-  g_assert (G_IS_TASK (task));
+  g_return_val_if_fail (IDE_IS_PERSISTENT_MAP_BUILDER (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (result), FALSE);
+  g_return_val_if_fail (self->thread == g_thread_self (), FALSE);
 
-  return g_task_propagate_boolean (task, error);
+  return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 static void
@@ -273,11 +323,8 @@ ide_persistent_map_builder_finalize (GObject *object)
 {
   IdePersistentMapBuilder *self = (IdePersistentMapBuilder *)object;
 
-  g_clear_pointer (&self->keys, g_byte_array_unref);
-  g_clear_pointer (&self->keys_hash, g_hash_table_unref);
-  g_clear_pointer (&self->values, g_ptr_array_unref);
-  g_clear_pointer (&self->kvpairs, g_array_unref);
-  g_clear_pointer (&self->metadata, g_variant_dict_unref);
+  g_clear_pointer (&self->state, build_state_free);
+  self->thread =  NULL;
 
   G_OBJECT_CLASS (ide_persistent_map_builder_parent_class)->finalize (object);
 }
@@ -285,11 +332,14 @@ ide_persistent_map_builder_finalize (GObject *object)
 static void
 ide_persistent_map_builder_init (IdePersistentMapBuilder *self)
 {
-  self->keys = g_byte_array_new ();
-  self->keys_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-  self->values = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref);
-  self->kvpairs = g_array_new (FALSE, FALSE, sizeof (KVPair));
-  self->metadata = g_variant_dict_new (NULL);
+  self->thread = g_thread_self ();
+
+  self->state = g_slice_new0 (BuildState);
+  self->state->keys = g_byte_array_new ();
+  self->state->keys_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  self->state->values = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref);
+  self->state->kvpairs = g_array_new (FALSE, FALSE, sizeof (KVPair));
+  self->state->metadata = g_variant_dict_new (NULL);
 }
 
 static void
@@ -300,7 +350,7 @@ ide_persistent_map_builder_class_init (IdePersistentMapBuilderClass *klass)
   object_class->finalize = ide_persistent_map_builder_finalize;
 }
 
-IdePersistentMapBuilder*
+IdePersistentMapBuilder *
 ide_persistent_map_builder_new (void)
 {
   return g_object_new (IDE_TYPE_PERSISTENT_MAP_BUILDER, NULL);
diff --git a/src/plugins/code-index/ide-persistent-map-builder.h 
b/src/plugins/code-index/ide-persistent-map-builder.h
index 9ff55bbc9..4e6d818ca 100644
--- a/src/plugins/code-index/ide-persistent-map-builder.h
+++ b/src/plugins/code-index/ide-persistent-map-builder.h
@@ -27,27 +27,27 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdePersistentMapBuilder, ide_persistent_map_builder, IDE, PERSISTENT_MAP_BUILDER, 
GObject)
 
-IdePersistentMapBuilder  *ide_persistent_map_builder_new                  (void);
-void                      ide_persistent_map_builder_insert               (IdePersistentMapBuilder  *self,
-                                                                           const gchar              *key,
-                                                                           GVariant                 *value,
-                                                                           gboolean                  
replace);
-gboolean                  ide_persistent_map_builder_write                (IdePersistentMapBuilder  *self,
-                                                                           GFile                    
*destination,
-                                                                           gint                      
io_priority,
-                                                                           GCancellable             
*cancellable,
-                                                                           GError                  **error);
-void                      ide_persistent_map_builder_write_async          (IdePersistentMapBuilder  *self,
-                                                                           GFile                    
*destination,
-                                                                           gint                      
io_priority,
-                                                                           GCancellable             
*cancellable,
-                                                                           GAsyncReadyCallback       
callback,
-                                                                           gpointer                  
user_data);
-gboolean                  ide_persistent_map_builder_write_finish         (IdePersistentMapBuilder  *self,
-                                                                           GAsyncResult             *result,
-                                                                           GError                  **error);
-void                      ide_persistent_map_builder_set_metadata_int64   (IdePersistentMapBuilder  *self,
-                                                                           const gchar              *key,
-                                                                           gint64                    value);
+IdePersistentMapBuilder *ide_persistent_map_builder_new                (void);
+void                     ide_persistent_map_builder_insert             (IdePersistentMapBuilder  *self,
+                                                                        const gchar              *key,
+                                                                        GVariant                 *value,
+                                                                        gboolean                  replace);
+void                     ide_persistent_map_builder_set_metadata_int64 (IdePersistentMapBuilder  *self,
+                                                                        const gchar              *key,
+                                                                        gint64                    value);
+gboolean                 ide_persistent_map_builder_write              (IdePersistentMapBuilder  *self,
+                                                                        GFile                    
*destination,
+                                                                        gint                      
io_priority,
+                                                                        GCancellable             
*cancellable,
+                                                                        GError                  **error);
+void                     ide_persistent_map_builder_write_async        (IdePersistentMapBuilder  *self,
+                                                                        GFile                    
*destination,
+                                                                        gint                      
io_priority,
+                                                                        GCancellable             
*cancellable,
+                                                                        GAsyncReadyCallback       callback,
+                                                                        gpointer                  user_data);
+gboolean                 ide_persistent_map_builder_write_finish       (IdePersistentMapBuilder  *self,
+                                                                        GAsyncResult             *result,
+                                                                        GError                  **error);
 
 G_END_DECLS


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