Commit ea9d0767 authored by Christian Hergert's avatar Christian Hergert
Browse files

code-index: code style cleanup and improve lock usage

parent c9d9d112
......@@ -32,12 +32,11 @@
struct _IdeCodeIndexIndex
{
IdeObject parent;
IdeObject parent_instance;
GMutex mutex;
GHashTable *directories;
GPtrArray *indexes;
GMutex update_entries;
};
typedef struct
......@@ -92,6 +91,7 @@ populate_task_data_free (PopulateTaskData *data)
}
g_clear_pointer (&data->fuzzy_matches, dzl_heap_unref);
g_slice_free (PopulateTaskData, data);
}
......@@ -114,10 +114,9 @@ fuzzy_match_compare (const FuzzyMatch *a,
/* This function will load indexes and returns them */
static DirectoryIndex *
ide_code_index_index_real_load_index (IdeCodeIndexIndex *self,
GFile *directory,
GCancellable *cancellable,
GError **error)
directory_index_new (GFile *directory,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GFile) keys_file = NULL;
g_autoptr(GFile) names_file = NULL;
......@@ -125,7 +124,6 @@ ide_code_index_index_real_load_index (IdeCodeIndexIndex *self,
g_autoptr(IdePersistentMap) symbol_keys = NULL;
g_autoptr(DirectoryIndex) dir_index = NULL;
g_assert (IDE_IS_CODE_INDEX_INDEX (self));
g_assert (G_IS_FILE (directory));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
......@@ -148,7 +146,21 @@ ide_code_index_index_real_load_index (IdeCodeIndexIndex *self,
return g_steal_pointer (&dir_index);
}
/* This function will load index of a directory and update old index pointer (if exists) */
/**
* ide_code_index_index_load:
* @self: a #IdeCodeIndexIndex
* @directory: a #GFile of the directory to load
* @cancellable: a #GCancellable or %NULL
* @error: a #GError or %NULL
*
* This function will load the index of a directory and update old index
* pointer if it exists.
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set.
*
* Thread safety: you may call this function from a thread so long as the
* thread has a reference to @self.
*/
gboolean
ide_code_index_index_load (IdeCodeIndexIndex *self,
GFile *directory,
......@@ -156,6 +168,7 @@ 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;
......@@ -163,27 +176,22 @@ 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 (NULL == (dir_index = ide_code_index_index_real_load_index (self,
directory,
cancellable,
error)))
{
return FALSE;
}
if (!(dir_index = directory_index_new (directory, cancellable, error)))
return FALSE;
dir_name = g_file_get_path (directory);
g_mutex_lock (&self->update_entries);
locker = g_mutex_locker_new (&self->mutex);
if (g_hash_table_lookup_extended (self->directories,
dir_name,
NULL,
&value))
if (g_hash_table_lookup_extended (self->directories, dir_name, NULL, &value))
{
guint i = GPOINTER_TO_UINT (value);
g_assert (i < self->indexes->len);
g_assert (self->indexes->len > 0);
/* update current directory index by clearing old one */
g_clear_pointer (&g_ptr_array_index (self->indexes, i), (GDestroyNotify)directory_index_free);
directory_index_free (g_ptr_array_index (self->indexes, i));
g_ptr_array_index (self->indexes, i) = g_steal_pointer (&dir_index);
}
else
......@@ -195,60 +203,66 @@ ide_code_index_index_load (IdeCodeIndexIndex *self,
g_ptr_array_add (self->indexes, g_steal_pointer (&dir_index));
}
g_mutex_unlock (&self->update_entries);
return TRUE;
}
/*
/**
* ide_code_index_index_load_if_nmod:
* @self: a #IdeCodeIndexIndex
* @directory: a #GFile of the directory to load
* @files: (element-type Gio.File): a #GPtrArray of #GFile
* @mod_time: the modified time
* @cancellable: (nullable): a #GCancellable or %NULL
* @error: a location for a #GError, or %NULL
*
* This function will load index from directory if it is not modified. This
* fuction will only load if all "files"(GPtrArray) and only those "files"
* are there in index.
* fuction will only load if all "files" (GPtrArray) and only those "files" are
* there in index.
*
* Returns: %TRUE if there were no modifications; otherwise %FALSE. It is possible
* for %FALSE to be returned and @error will not be set.
*
* Thread safety: You may call this function from a thread, given that the thread has
* it's own reference to @self.
*/
gboolean
ide_code_index_index_load_if_nmod (IdeCodeIndexIndex *self,
GFile *directory,
GPtrArray *files,
GTimeVal mod_time,
GCancellable *cancellable,
GError **error)
ide_code_index_index_load_if_nmod (IdeCodeIndexIndex *self,
GFile *directory,
GPtrArray *files,
GTimeVal mod_time,
GCancellable *cancellable,
GError **error)
{
g_autoptr(DirectoryIndex) dir_index = NULL;
gpointer value = NULL;
DzlFuzzyIndex *symbol_names;
GTimeVal index_mod_time;
g_autoptr(GFile) names_file = NULL;
g_autoptr(GFileInfo) file_info = NULL;
g_autoptr(GFile) names_file = NULL;
g_autofree gchar *dir_name = NULL;
GTimeVal index_mod_time;
gpointer value = NULL;
g_return_val_if_fail (IDE_IS_CODE_INDEX_INDEX (self), FALSE);
g_return_val_if_fail (G_IS_FILE (directory), FALSE);
g_return_val_if_fail (files != NULL, FALSE);
dir_index = ide_code_index_index_real_load_index (self, directory, cancellable, error);
if (dir_index == NULL)
if (!(dir_index = directory_index_new (directory, cancellable, error)))
return FALSE;
symbol_names = dir_index->symbol_names;
/*
* Return false if current number of files in directory != number of files that are
* indexed previously in the same directory.
*/
if (dzl_fuzzy_index_get_metadata_uint32 (symbol_names, "n_files") != files->len)
if (dzl_fuzzy_index_get_metadata_uint32 (dir_index->symbol_names, "n_files") != files->len)
return FALSE;
/* Return false if files are modified after they are indexed. */
names_file = g_file_get_child (directory, "SymbolNames");
if (NULL == (file_info = g_file_query_info (names_file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
cancellable,
error)))
{
return FALSE;
}
file_info = g_file_query_info (names_file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
cancellable,
error);
if (file_info == NULL)
return FALSE;
g_file_info_get_modification_time (file_info, &index_mod_time);
......@@ -260,23 +274,25 @@ ide_code_index_index_load_if_nmod (IdeCodeIndexIndex *self,
/* Return false if all current files in directory are not there in index. */
for (guint i = 0; i < files->len; i++)
{
g_autofree gchar *file_name = NULL;
GFile *file = g_ptr_array_index (files, i);
g_autofree gchar *path = g_file_get_path (file);
file_name = g_file_get_path (g_ptr_array_index (files, i));
if (!dzl_fuzzy_index_get_metadata_uint32 (symbol_names, file_name))
if (!dzl_fuzzy_index_get_metadata_uint32 (dir_index->symbol_names, path))
return FALSE;
}
dir_name = g_file_get_path (directory);
g_mutex_lock (&self->update_entries);
g_mutex_lock (&self->mutex);
if (g_hash_table_lookup_extended (self->directories, dir_name, NULL, &value))
{
guint i = GPOINTER_TO_UINT (value);
g_clear_pointer (&g_ptr_array_index (self->indexes, i), (GDestroyNotify)directory_index_free);
g_assert (i < self->indexes->len);
g_assert (self->indexes->len > 0);
directory_index_free (g_ptr_array_index (self->indexes, i));
g_ptr_array_index (self->indexes, i) = g_steal_pointer (&dir_index);
}
else
......@@ -284,24 +300,22 @@ ide_code_index_index_load_if_nmod (IdeCodeIndexIndex *self,
g_hash_table_insert (self->directories,
g_steal_pointer (&dir_name),
GUINT_TO_POINTER (self->indexes->len));
g_ptr_array_add (self->indexes, g_steal_pointer (&dir_index));
}
g_mutex_unlock (&self->update_entries);
g_mutex_unlock (&self->mutex);
return TRUE;
}
/* Create a new IdeCodeIndexSearchResult based on match from fuzzy index */
static IdeCodeIndexSearchResult *
ide_code_index_index_new_search_result (IdeCodeIndexIndex *self,
const FuzzyMatch *fuzzy_match)
ide_code_index_index_create_search_result (IdeContext *context,
const FuzzyMatch *fuzzy_match)
{
g_autoptr(IdeFile) file = NULL;
g_autoptr(IdeSourceLocation) location = NULL;
g_autoptr(GString) subtitle = NULL;
IdeContext *context;
const gchar *key;
const gchar *icon_name;
const gchar *shortname;
......@@ -315,7 +329,7 @@ ide_code_index_index_new_search_result (IdeCodeIndexIndex *self,
guint flags;
gchar num [20];
g_assert (IDE_IS_CODE_INDEX_INDEX (self));
g_assert (IDE_IS_CONTEXT (context));
g_assert (fuzzy_match != NULL);
value = dzl_fuzzy_index_match_get_document (fuzzy_match->match);
......@@ -326,7 +340,6 @@ ide_code_index_index_new_search_result (IdeCodeIndexIndex *self,
if (kind == IDE_SYMBOL_VARIABLE)
return NULL;
context = ide_object_get_context (IDE_OBJECT (self));
key = dzl_fuzzy_index_match_get_key (fuzzy_match->match);
g_snprintf (num, sizeof num, "%u", file_id);
......@@ -338,31 +351,35 @@ ide_code_index_index_new_search_result (IdeCodeIndexIndex *self,
score = dzl_fuzzy_index_match_get_score (fuzzy_match->match);
subtitle = g_string_new (NULL);
if (NULL != (shortname = strrchr (path, G_DIR_SEPARATOR)))
g_string_append (subtitle, shortname + 1);
if ((kind == IDE_SYMBOL_FUNCTION) && !(flags & IDE_SYMBOL_FLAGS_IS_DEFINITION))
/* translators: "Declaration" is the forward-declaration (usually a header file), not the implementation */
g_string_append_printf (subtitle, " (%s)", _("Declaration"));
return ide_code_index_search_result_new (key + 2,
subtitle->str,
icon_name,
location,
score);
{
/* translators: "Declaration" is describing a function that is defined in a header
* file (.h) rather than a source file (.c).
*/
g_string_append_printf (subtitle, " (%s)", _("Declaration"));
}
return ide_code_index_search_result_new (key + 2, subtitle->str, icon_name, location, score);
}
static void
ide_code_index_index_query_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
ide_code_index_index_query_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
IdeCodeIndexIndex *self;
DzlFuzzyIndex *index = (DzlFuzzyIndex *)object;
g_autoptr(GTask) task = (GTask *)user_data;
g_autoptr(GListModel) list = NULL;
g_autoptr(GMutexLocker) locker = NULL;
g_autoptr(GError) error = NULL;
IdeCodeIndexIndex *self;
PopulateTaskData *data;
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (DZL_IS_FUZZY_INDEX (index));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (G_IS_TASK (task));
......@@ -370,14 +387,19 @@ ide_code_index_index_query_cb (GObject *object,
self = g_task_get_source_object (task);
g_assert (IDE_IS_CODE_INDEX_INDEX (self));
locker = g_mutex_locker_new (&self->mutex);
data = g_task_get_task_data (task);
g_assert (data != NULL);
if (NULL != (list = dzl_fuzzy_index_query_finish (index, result, &error)))
list = dzl_fuzzy_index_query_finish (index, result, &error);
g_assert (!list || G_IS_LIST_MODEL (list));
if (list != NULL)
{
if (g_list_model_get_n_items (list))
{
FuzzyMatch fuzzy_match;
FuzzyMatch fuzzy_match = {0};
fuzzy_match.index = index;
fuzzy_match.match = g_list_model_get_item (list, 0);
......@@ -411,9 +433,8 @@ ide_code_index_index_query_cb (GObject *object,
}
else
{
g_autoptr(GPtrArray) results = NULL;
results = g_ptr_array_new_with_free_func (g_object_unref);
g_autoptr(GPtrArray) results = g_ptr_array_new_with_free_func (g_object_unref);
IdeContext *context = ide_object_get_context (IDE_OBJECT (self));
/*
* Extract match from heap with max score, get next item from the list from which
......@@ -426,7 +447,7 @@ ide_code_index_index_query_cb (GObject *object,
dzl_heap_extract (data->fuzzy_matches, &fuzzy_match);
item = ide_code_index_index_new_search_result (self, &fuzzy_match);
item = ide_code_index_index_create_search_result (context, &fuzzy_match);
if (item != NULL)
g_ptr_array_add (results, item);
......@@ -447,7 +468,9 @@ ide_code_index_index_query_cb (GObject *object,
}
}
g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref);
g_task_return_pointer (task,
g_steal_pointer (&results),
(GDestroyNotify)g_ptr_array_unref);
}
}
......@@ -459,20 +482,25 @@ ide_code_index_index_populate_async (IdeCodeIndexIndex *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GMutexLocker) locker = NULL;
g_autoptr(GTask) task = NULL;
PopulateTaskData *data;
g_auto(GStrv) str = NULL;
PopulateTaskData *data;
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_CODE_INDEX_INDEX (self));
g_return_if_fail (query != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, ide_code_index_index_populate_async);
g_task_set_priority (task, G_PRIORITY_LOW);
data = g_slice_new0 (PopulateTaskData);
data->max_results = max_results;
data->curr_index = 0;
data->fuzzy_matches = dzl_heap_new (sizeof(FuzzyMatch), (GCompareFunc)fuzzy_match_compare);
data->fuzzy_matches = dzl_heap_new (sizeof (FuzzyMatch),
(GCompareFunc)fuzzy_match_compare);
/* Replace "<symbol type prefix><space>" with <symbol code>INFORMATION SEPARATOR ONE */
......@@ -508,6 +536,8 @@ ide_code_index_index_populate_async (IdeCodeIndexIndex *self,
g_task_set_task_data (task, data, (GDestroyNotify)populate_task_data_free);
locker = g_mutex_locker_new (&self->mutex);
if (data->curr_index < self->indexes->len)
{
DirectoryIndex *dir_index = g_ptr_array_index (self->indexes, data->curr_index);
......@@ -518,13 +548,13 @@ ide_code_index_index_populate_async (IdeCodeIndexIndex *self,
cancellable,
ide_code_index_index_query_cb,
g_steal_pointer (&task));
return;
}
g_task_return_pointer (task,
g_ptr_array_new_with_free_func (g_object_unref),
(GDestroyNotify) g_ptr_array_unref);
else
{
g_task_return_pointer (task,
g_ptr_array_new_with_free_func (g_object_unref),
(GDestroyNotify) g_ptr_array_unref);
}
}
GPtrArray *
......@@ -532,6 +562,7 @@ ide_code_index_index_populate_finish (IdeCodeIndexIndex *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
g_return_val_if_fail (IDE_IS_CODE_INDEX_INDEX (self), NULL);
g_return_val_if_fail (G_IS_TASK (result), NULL);
......@@ -539,16 +570,16 @@ ide_code_index_index_populate_finish (IdeCodeIndexIndex *self,
}
IdeSymbol *
ide_code_index_index_lookup_symbol (IdeCodeIndexIndex *self,
const gchar *key)
ide_code_index_index_lookup_symbol (IdeCodeIndexIndex *self,
const gchar *key)
{
g_autoptr(IdeSourceLocation) declaration = NULL;
g_autoptr(IdeSourceLocation) definition = NULL;
g_autoptr(IdeFile) file = NULL;
g_autoptr(GMutexLocker) locker = NULL;
g_autofree gchar *name = NULL;
IdeSymbolKind kind = IDE_SYMBOL_NONE;
IdeSymbolFlags flags = IDE_SYMBOL_FLAGS_NONE;
DirectoryIndex *dir_index;
DzlFuzzyIndex *symbol_names = NULL;
const gchar *path;
guint32 file_id = 0;
......@@ -556,22 +587,20 @@ ide_code_index_index_lookup_symbol (IdeCodeIndexIndex *self,
guint32 line_offset = 0;
gchar num[20];
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
g_return_val_if_fail (IDE_IS_CODE_INDEX_INDEX (self), NULL);
g_return_val_if_fail (key != NULL, NULL);
if (dzl_str_empty0 (key))
return NULL;
g_debug ("Searching declaration with key: %s", key);
g_message ("Searching declaration with key:%s\n", key);
locker = g_mutex_locker_new (&self->mutex);
for (guint i = 0; i < self->indexes->len; i++)
{
const DirectoryIndex *dir_index = g_ptr_array_index (self->indexes, i);
g_autoptr(GVariant) variant = NULL;
dir_index = g_ptr_array_index (self->indexes, i);
variant = ide_persistent_map_lookup_value (dir_index->symbol_keys, key);
if (variant == NULL)
if (!(variant = ide_persistent_map_lookup_value (dir_index->symbol_keys, key)))
continue;
symbol_names = dir_index->symbol_names;
......@@ -592,8 +621,7 @@ ide_code_index_index_lookup_symbol (IdeCodeIndexIndex *self,
path = dzl_fuzzy_index_get_metadata_string (symbol_names, num);
file = ide_file_new_for_path (ide_object_get_context (IDE_OBJECT (self)), path);
g_debug ("symbol location found, %s %d:%d\n", path, line, line_offset);
g_debug ("Symbol location found at %s %d:%d\n", path, line, line_offset);
if (flags & IDE_SYMBOL_FLAGS_IS_DEFINITION)
definition = ide_source_location_new (file, line - 1, line_offset - 1, 0);
......@@ -611,7 +639,7 @@ ide_code_index_index_finalize (GObject *object)
g_clear_pointer (&self->directories, g_hash_table_unref);
g_clear_pointer (&self->indexes, g_ptr_array_unref);
g_mutex_clear (&self->update_entries);
g_mutex_clear (&self->mutex);
G_OBJECT_CLASS (ide_code_index_index_parent_class)->finalize (object);
}
......@@ -622,7 +650,7 @@ ide_code_index_index_init (IdeCodeIndexIndex *self)
self->directories = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
self->indexes = g_ptr_array_new_with_free_func ((GDestroyNotify)directory_index_free);
g_mutex_init (&self->update_entries);
g_mutex_init (&self->mutex);
}
static void
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment