libsysprof-capture: Use reallocarray() instead of GArray in writer-cat.c

This is more of a direct port than previous replacements of `GArray`
(which have had linear growth): this one implements exponential growth
of the allocated array, as `GArray` does.

It uses `qsort()` to sort the array so that it can be binary searched as
before.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Helps: #40
This commit is contained in:
Philip Withnall
2020-07-02 11:05:01 +01:00
parent 3446628cec
commit f1cb640091

View File

@ -56,6 +56,7 @@
#include "config.h" #include "config.h"
#include <assert.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -71,6 +72,13 @@ typedef struct
uint64_t dst; uint64_t dst;
} TranslateItem; } TranslateItem;
typedef struct
{
TranslateItem *items;
size_t n_items;
size_t n_items_allocated;
} TranslateTable;
enum { enum {
TRANSLATE_ADDR, TRANSLATE_ADDR,
TRANSLATE_CTR, TRANSLATE_CTR,
@ -78,10 +86,14 @@ enum {
}; };
static void static void
translate_table_clear (GArray **tables, translate_table_clear (TranslateTable *tables,
unsigned int table) unsigned int table)
{ {
sysprof_clear_pointer (&tables[table], g_array_unref); TranslateTable *table_ptr = &tables[table];
sysprof_clear_pointer (&table_ptr->items, free);
table_ptr->n_items = 0;
table_ptr->n_items_allocated = 0;
} }
static int static int
@ -100,32 +112,41 @@ compare_by_src (const void *a,
} }
static void static void
translate_table_sort (GArray **tables, translate_table_sort (TranslateTable *tables,
unsigned int table) unsigned int table)
{ {
if (tables[table]) TranslateTable *table_ptr = &tables[table];
g_array_sort (tables[table], compare_by_src);
if (table_ptr->items)
qsort (table_ptr->items, table_ptr->n_items, sizeof (*table_ptr->items), compare_by_src);
} }
static void static void
translate_table_add (GArray **tables, translate_table_add (TranslateTable *tables,
unsigned int table, unsigned int table,
uint64_t src, uint64_t src,
uint64_t dst) uint64_t dst)
{ {
TranslateTable *table_ptr = &tables[table];
const TranslateItem item = { src, dst }; const TranslateItem item = { src, dst };
if (tables[table] == NULL) if (table_ptr->n_items == table_ptr->n_items_allocated)
tables[table] = g_array_new (FALSE, FALSE, sizeof (TranslateItem)); {
table_ptr->n_items_allocated = (table_ptr->n_items_allocated > 0) ? table_ptr->n_items_allocated * 2 : 4;
table_ptr->items = reallocarray (table_ptr->items, table_ptr->n_items_allocated, sizeof (*table_ptr->items));
assert (table_ptr->items != NULL);
}
g_array_append_val (tables[table], item); table_ptr->items[table_ptr->n_items++] = item;
assert (table_ptr->n_items <= table_ptr->n_items_allocated);
} }
static uint64_t static uint64_t
translate_table_translate (GArray **tables, translate_table_translate (TranslateTable *tables,
unsigned int table, unsigned int table,
uint64_t src) uint64_t src)
{ {
TranslateTable *table_ptr = &tables[table];
const TranslateItem *item; const TranslateItem *item;
TranslateItem key = { src, 0 }; TranslateItem key = { src, 0 };
@ -135,13 +156,13 @@ translate_table_translate (GArray **tables,
return src; return src;
} }
if (tables[table] == NULL) if (table_ptr->items == NULL)
return src; return src;
item = bsearch (&key, item = bsearch (&key,
tables[table]->data, table_ptr->items,
tables[table]->len, table_ptr->n_items,
sizeof (TranslateItem), sizeof (*table_ptr->items),
compare_by_src); compare_by_src);
return item != NULL ? item->dst : src; return item != NULL ? item->dst : src;
@ -152,7 +173,7 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self,
SysprofCaptureReader *reader, SysprofCaptureReader *reader,
GError **error) GError **error)
{ {
GArray *tables[N_TRANSLATE] = { NULL }; TranslateTable tables[N_TRANSLATE] = { 0, };
SysprofCaptureFrameType type; SysprofCaptureFrameType type;
int64_t start_time; int64_t start_time;
int64_t first_start_time = INT64_MAX; int64_t first_start_time = INT64_MAX;