[gnome-builder] code-index: avoid reloading unchanged indexes



commit 71aeb2c70309d079eecf13b0a1b0af46a9fe56d9
Author: Christian Hergert <chergert redhat com>
Date:   Mon Feb 4 22:30:31 2019 -0800

    code-index: avoid reloading unchanged indexes
    
    This reduces churn a bit, which is nice for larger projects.

 src/plugins/code-index/ide-code-index-index.c | 68 ++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 2 deletions(-)
---
diff --git a/src/plugins/code-index/ide-code-index-index.c b/src/plugins/code-index/ide-code-index-index.c
index d6220b851..17127d8fd 100644
--- a/src/plugins/code-index/ide-code-index-index.c
+++ b/src/plugins/code-index/ide-code-index-index.c
@@ -46,6 +46,7 @@ typedef struct
   GFile            *source_directory;
   DzlFuzzyIndex    *symbol_names;
   IdePersistentMap *symbol_keys;
+  guint64           mtime;
 } DirectoryIndex;
 
 typedef struct
@@ -75,6 +76,28 @@ static void directory_index_free (DirectoryIndex *data);
 DZL_DEFINE_COUNTER (code_indexes, "Code Indexes", "Instances", "Number of loaded code indexes")
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (DirectoryIndex, directory_index_free)
 
+static guint64
+newest_mtime (GFile        *a,
+              GFile        *b,
+              GCancellable *cancellable)
+{
+  g_autoptr(GFileInfo) ainfo = NULL;
+  g_autoptr(GFileInfo) binfo = NULL;
+  guint64 aval = 0;
+  guint64 bval = 0;
+
+  ainfo = g_file_query_info (a, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, cancellable, NULL);
+  binfo = g_file_query_info (b, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, cancellable, NULL);
+
+  if (ainfo)
+    aval = g_file_info_get_attribute_uint64 (ainfo, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
+  if (binfo)
+    bval = g_file_info_get_attribute_uint64 (binfo, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
+  return aval > bval ? aval : bval;
+}
+
 static void
 directory_index_free (DirectoryIndex *data)
 {
@@ -153,12 +176,49 @@ directory_index_new (GFile         *directory,
   dir_index->symbol_names = g_steal_pointer (&symbol_names);
   dir_index->directory = g_file_dup (directory);
   dir_index->source_directory = g_file_dup (source_directory);
+  dir_index->mtime = newest_mtime (keys_file, names_file, cancellable);
 
   DZL_COUNTER_INC (code_indexes);
 
   return g_steal_pointer (&dir_index);
 }
 
+static gboolean
+can_ignore_reload (IdeCodeIndexIndex *self,
+                   GFile             *directory,
+                   GCancellable      *cancellable)
+{
+  g_autofree gchar *dir_name = NULL;
+  gboolean ret = FALSE;
+  gpointer value;
+
+  g_assert (IDE_IS_CODE_INDEX_INDEX (self));
+  g_assert (G_IS_FILE (directory));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  dir_name = g_file_get_path (directory);
+
+  g_mutex_lock (&self->mutex);
+
+  if (g_hash_table_lookup_extended (self->directories, dir_name, NULL, &value))
+    {
+      g_autoptr(GFile) keys_file = g_file_get_child (directory, "SymbolKeys");
+      g_autoptr(GFile) names_file = g_file_get_child (directory, "SymbolNames");
+      guint i = GPOINTER_TO_UINT (value);
+      DirectoryIndex *info = g_ptr_array_index (self->indexes, i);
+      guint64 mtime = newest_mtime (keys_file, names_file, cancellable);
+
+      g_assert (i < self->indexes->len);
+      g_assert (self->indexes->len > 0);
+
+      ret = mtime <= info->mtime;
+    }
+
+  g_mutex_unlock (&self->mutex);
+
+  return ret;
+}
+
 /**
  * ide_code_index_index_load:
  * @self: a #IdeCodeIndexIndex
@@ -183,7 +243,6 @@ ide_code_index_index_load (IdeCodeIndexIndex   *self,
                            GError             **error)
 {
   g_autoptr(DirectoryIndex) dir_index = NULL;
-  g_autoptr(GMutexLocker) locker = NULL;
   g_autofree gchar *dir_name = NULL;
   gpointer value;
 
@@ -191,13 +250,16 @@ ide_code_index_index_load (IdeCodeIndexIndex   *self,
   g_return_val_if_fail (G_IS_FILE (directory), FALSE);
   g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
 
+  if (can_ignore_reload (self, directory, cancellable))
+    return TRUE;
+
   dir_name = g_file_get_path (directory);
   g_debug ("Loading code index from %s", dir_name);
 
   if (!(dir_index = directory_index_new (directory, source_directory, cancellable, error)))
     return FALSE;
 
-  locker = g_mutex_locker_new (&self->mutex);
+  g_mutex_lock (&self->mutex);
 
   if (g_hash_table_lookup_extended (self->directories, dir_name, NULL, &value))
     {
@@ -219,6 +281,8 @@ ide_code_index_index_load (IdeCodeIndexIndex   *self,
       g_ptr_array_add (self->indexes, g_steal_pointer (&dir_index));
     }
 
+  g_mutex_unlock (&self->mutex);
+
   return TRUE;
 }
 


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