mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +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 <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -1273,20 +1274,60 @@ sysprof_capture_reader_read_file (SysprofCaptureReader *self)
|
|||||||
return file_chunk;
|
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)
|
sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
||||||
{
|
{
|
||||||
g_autoptr(GHashTable) files = NULL;
|
const char **files = NULL;
|
||||||
g_autoptr(GPtrArray) ar = NULL;
|
size_t n_files = 0, n_files_allocated = 0;
|
||||||
SysprofCaptureFrameType type;
|
SysprofCaptureFrameType type;
|
||||||
GHashTableIter iter;
|
|
||||||
const gchar *key;
|
|
||||||
|
|
||||||
assert (self != NULL);
|
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))
|
while (sysprof_capture_reader_peek_type (self, &type))
|
||||||
{
|
{
|
||||||
const SysprofCaptureFileChunk *file;
|
const SysprofCaptureFileChunk *file;
|
||||||
@ -1300,16 +1341,27 @@ sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
|||||||
if (!(file = sysprof_capture_reader_read_file (self)))
|
if (!(file = sysprof_capture_reader_read_file (self)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!g_hash_table_contains (files, file->path))
|
if (!array_append (&files, &n_files, &n_files_allocated, file->path))
|
||||||
g_hash_table_insert (files, g_strdup (file->path), NULL);
|
{
|
||||||
|
free (files);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, files);
|
/* Sort and deduplicate the files array. */
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
|
qsort (files, n_files, sizeof (*files), (int (*)(const void *, const void *)) strcmp);
|
||||||
g_ptr_array_add (ar, g_strdup (key));
|
array_deduplicate (files, &n_files);
|
||||||
g_ptr_array_add (ar, NULL);
|
|
||||||
|
|
||||||
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
|
bool
|
||||||
|
|||||||
@ -144,7 +144,7 @@ SYSPROF_AVAILABLE_IN_ALL
|
|||||||
const SysprofCaptureFileChunk *sysprof_capture_reader_find_file (SysprofCaptureReader *self,
|
const SysprofCaptureFileChunk *sysprof_capture_reader_find_file (SysprofCaptureReader *self,
|
||||||
const char *path);
|
const char *path);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
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
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
bool sysprof_capture_reader_read_file_fd (SysprofCaptureReader *self,
|
bool sysprof_capture_reader_read_file_fd (SysprofCaptureReader *self,
|
||||||
const char *path,
|
const char *path,
|
||||||
|
|||||||
@ -747,7 +747,7 @@ test_reader_writer_file (void)
|
|||||||
{
|
{
|
||||||
g_autofree gchar *data = NULL;
|
g_autofree gchar *data = NULL;
|
||||||
GByteArray *buf = g_byte_array_new ();
|
GByteArray *buf = g_byte_array_new ();
|
||||||
g_auto(GStrv) files = NULL;
|
g_autofree const gchar **files = NULL;
|
||||||
SysprofCaptureWriter *writer;
|
SysprofCaptureWriter *writer;
|
||||||
SysprofCaptureReader *reader;
|
SysprofCaptureReader *reader;
|
||||||
SysprofCaptureFrameType type;
|
SysprofCaptureFrameType type;
|
||||||
|
|||||||
@ -64,9 +64,9 @@ main (gint argc,
|
|||||||
|
|
||||||
if (list_files)
|
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]);
|
g_print ("%s\n", files[i]);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
Reference in New Issue
Block a user