mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof-capture: Rewrite list_files() to avoid GHashTable/GPtrArray
This changes its API and ABI: it now returns an allocated array of const strings, rather than an allocated array of allocated strings. The call sites in the source tree have been adjusted accordingly. Signed-off-by: Philip Withnall <withnall@endlessm.com> Helps: #40
This commit is contained in:
@ -62,6 +62,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -1273,20 +1274,60 @@ sysprof_capture_reader_read_file (SysprofCaptureReader *self)
|
||||
return file_chunk;
|
||||
}
|
||||
|
||||
char **
|
||||
static bool
|
||||
array_append (const char ***files,
|
||||
size_t *n_files,
|
||||
size_t *n_files_allocated,
|
||||
const char *new_element)
|
||||
{
|
||||
if (*n_files == *n_files_allocated)
|
||||
{
|
||||
const char **new_files;
|
||||
|
||||
*n_files_allocated = (*n_files_allocated > 0) ? 2 * *n_files_allocated : 4;
|
||||
new_files = reallocarray (*files, *n_files_allocated, sizeof (**files));
|
||||
if (new_files == NULL)
|
||||
return false;
|
||||
*files = new_files;
|
||||
}
|
||||
|
||||
(*files)[*n_files] = new_element;
|
||||
*n_files = *n_files + 1;
|
||||
assert (*n_files <= *n_files_allocated);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
array_deduplicate (const char **files,
|
||||
size_t *n_files)
|
||||
{
|
||||
size_t last_written, next_to_read;
|
||||
|
||||
if (*n_files == 0)
|
||||
return;
|
||||
|
||||
for (last_written = 0, next_to_read = 1; last_written <= next_to_read && next_to_read < *n_files;)
|
||||
{
|
||||
if (strcmp (files[next_to_read], files[last_written]) == 0)
|
||||
next_to_read++;
|
||||
else
|
||||
files[++last_written] = files[next_to_read++];
|
||||
}
|
||||
|
||||
assert (last_written + 1 <= *n_files);
|
||||
*n_files = last_written + 1;
|
||||
}
|
||||
|
||||
const char **
|
||||
sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
||||
{
|
||||
g_autoptr(GHashTable) files = NULL;
|
||||
g_autoptr(GPtrArray) ar = NULL;
|
||||
const char **files = NULL;
|
||||
size_t n_files = 0, n_files_allocated = 0;
|
||||
SysprofCaptureFrameType type;
|
||||
GHashTableIter iter;
|
||||
const gchar *key;
|
||||
|
||||
assert (self != NULL);
|
||||
|
||||
ar = g_ptr_array_new_with_free_func (g_free);
|
||||
files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
while (sysprof_capture_reader_peek_type (self, &type))
|
||||
{
|
||||
const SysprofCaptureFileChunk *file;
|
||||
@ -1300,16 +1341,27 @@ sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
||||
if (!(file = sysprof_capture_reader_read_file (self)))
|
||||
break;
|
||||
|
||||
if (!g_hash_table_contains (files, file->path))
|
||||
g_hash_table_insert (files, g_strdup (file->path), NULL);
|
||||
if (!array_append (&files, &n_files, &n_files_allocated, file->path))
|
||||
{
|
||||
free (files);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, files);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
|
||||
g_ptr_array_add (ar, g_strdup (key));
|
||||
g_ptr_array_add (ar, NULL);
|
||||
/* Sort and deduplicate the files array. */
|
||||
qsort (files, n_files, sizeof (*files), (int (*)(const void *, const void *)) strcmp);
|
||||
array_deduplicate (files, &n_files);
|
||||
|
||||
return (char **)g_ptr_array_free (sysprof_steal_pointer (&ar), FALSE);
|
||||
/* Add a null terminator */
|
||||
if (!array_append (&files, &n_files, &n_files_allocated, NULL))
|
||||
{
|
||||
free (files);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sysprof_steal_pointer (&files);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@ -144,7 +144,7 @@ SYSPROF_AVAILABLE_IN_ALL
|
||||
const SysprofCaptureFileChunk *sysprof_capture_reader_find_file (SysprofCaptureReader *self,
|
||||
const char *path);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
char **sysprof_capture_reader_list_files (SysprofCaptureReader *self);
|
||||
const char **sysprof_capture_reader_list_files (SysprofCaptureReader *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
bool sysprof_capture_reader_read_file_fd (SysprofCaptureReader *self,
|
||||
const char *path,
|
||||
|
||||
@ -747,7 +747,7 @@ test_reader_writer_file (void)
|
||||
{
|
||||
g_autofree gchar *data = NULL;
|
||||
GByteArray *buf = g_byte_array_new ();
|
||||
g_auto(GStrv) files = NULL;
|
||||
g_autofree const gchar **files = NULL;
|
||||
SysprofCaptureWriter *writer;
|
||||
SysprofCaptureReader *reader;
|
||||
SysprofCaptureFrameType type;
|
||||
|
||||
@ -64,9 +64,9 @@ main (gint argc,
|
||||
|
||||
if (list_files)
|
||||
{
|
||||
g_auto(GStrv) files = sysprof_capture_reader_list_files (reader);
|
||||
g_autofree const gchar **files = sysprof_capture_reader_list_files (reader);
|
||||
|
||||
for (guint i = 0; files[i]; i++)
|
||||
for (gsize i = 0; files[i]; i++)
|
||||
g_print ("%s\n", files[i]);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user