Skip to content

Commit

Permalink
xml/filterx-parse-xml: replace GQueue with GArray
Browse files Browse the repository at this point in the history
To save a lot of allocations.

Signed-off-by: Attila Szakacs <[email protected]>
  • Loading branch information
alltilla committed Sep 18, 2024
1 parent 107e107 commit fc22cf8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 41 deletions.
24 changes: 13 additions & 11 deletions modules/xml/filterx-parse-windows-eventlog-xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,11 @@ _convert_to_dict(GMarkupParseContext *context, XmlElemContext *elem_context, GEr
return !(*error);
}

static XmlElemContext *
_prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, GError **error)
static gboolean
_prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, XmlElemContext *new_elem_context,
GError **error)
{
XmlElemContext *new_elem_context = xml_elem_context_new(last_elem_context->current_obj, NULL);
xml_elem_context_init(new_elem_context, last_elem_context->current_obj, NULL);

FilterXObject *new_elem_key = filterx_string_new(new_elem_name, -1);
FilterXObject *existing_obj = NULL;
Expand Down Expand Up @@ -132,11 +133,11 @@ _prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, GEr

if (*error)
{
xml_elem_context_free(new_elem_context);
new_elem_context = NULL;
xml_elem_context_destroy(new_elem_context);
return FALSE;
}

return new_elem_context;
return TRUE;
}

static void
Expand Down Expand Up @@ -226,7 +227,7 @@ _start_elem(FilterXGeneratorFunctionParseXml *s,
FilterXParseXmlState *st, GError **error)
{
FilterXParseWEVTState *state = (FilterXParseWEVTState *) st;
XmlElemContext *last_elem_context = g_queue_peek_head(state->super.xml_elem_context_stack);
XmlElemContext *last_elem_context = xml_elem_context_stack_peek_last(state->super.xml_elem_context_stack);

_push_position(state, element_name);

Expand All @@ -245,10 +246,11 @@ _start_elem(FilterXGeneratorFunctionParseXml *s,
return;
}

XmlElemContext *new_elem_context = _prepare_elem(element_name, last_elem_context, error);
if (!new_elem_context)
XmlElemContext new_elem_context = { 0 };
if (!_prepare_elem(element_name, last_elem_context, &new_elem_context, error))
return;
g_queue_push_head(state->super.xml_elem_context_stack, new_elem_context);

xml_elem_context_stack_push(&state->super.xml_elem_context_stack, &new_elem_context);

_collect_attrs(attribute_names, attribute_values, state, error);
}
Expand All @@ -270,7 +272,7 @@ _text(FilterXGeneratorFunctionParseXml *s,
FilterXParseXmlState *st, GError **error)
{
FilterXParseWEVTState *state = (FilterXParseWEVTState *) st;
XmlElemContext *elem_context = g_queue_peek_head(state->super.xml_elem_context_stack);
XmlElemContext *elem_context = xml_elem_context_stack_peek_last(state->super.xml_elem_context_stack);

if (!filterx_object_is_type(elem_context->current_obj, &FILTERX_TYPE_NAME(dict)) ||
!state->has_named_data)
Expand Down
56 changes: 29 additions & 27 deletions modules/xml/filterx-parse-xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
*/

#define FILTERX_FUNC_PARSE_XML_USAGE "Usage: parse_xml(raw_xml)"

#define XML_ELEM_CTX_STACK_INIT_SIZE (8)

static void _set_error(GError **error, const gchar *format, ...) G_GNUC_PRINTF(2, 0);
static void
Expand Down Expand Up @@ -112,34 +112,33 @@ xml_elem_context_set_parent_obj(XmlElemContext *self, FilterXObject *parent_obj)
}

void
xml_elem_context_free(XmlElemContext *self)
xml_elem_context_destroy(XmlElemContext *self)
{
xml_elem_context_set_current_obj(self, NULL);
xml_elem_context_set_parent_obj(self, NULL);
g_free(self);
}

XmlElemContext *
xml_elem_context_new(FilterXObject *parent_obj, FilterXObject *current_obj)
void
xml_elem_context_init(XmlElemContext *self, FilterXObject *parent_obj, FilterXObject *current_obj)
{
XmlElemContext *self = g_new0(XmlElemContext, 1);
xml_elem_context_set_parent_obj(self, parent_obj);
xml_elem_context_set_current_obj(self, current_obj);
return self;
}


void
filterx_parse_xml_state_init_instance(FilterXParseXmlState *self)
{
self->xml_elem_context_stack = g_queue_new();
self->xml_elem_context_stack = g_array_sized_new(FALSE, FALSE, sizeof(XmlElemContext), XML_ELEM_CTX_STACK_INIT_SIZE);
self->free_fn = filterx_parse_xml_state_free_method;
}

void
filterx_parse_xml_state_free_method(FilterXParseXmlState *self)
{
g_queue_free_full(self->xml_elem_context_stack, (GDestroyNotify) xml_elem_context_free);
for (guint i = 0; i < self->xml_elem_context_stack->len; i++)
xml_elem_context_destroy(&g_array_index(self->xml_elem_context_stack, XmlElemContext, i));
g_array_free(self->xml_elem_context_stack, TRUE);
}

static FilterXParseXmlState *
Expand Down Expand Up @@ -235,14 +234,15 @@ _store_nth_elem(XmlElemContext *new_elem_context, FilterXObject *existing_obj, F
xml_elem_context_set_parent_obj(new_elem_context, existing_obj);
}

static XmlElemContext *
_prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, gboolean has_attrs, GError **error)
static gboolean
_prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, gboolean has_attrs,
XmlElemContext *new_elem_context, GError **error)
{
g_assert(filterx_object_is_type(last_elem_context->current_obj, &FILTERX_TYPE_NAME(dict)));

const gchar *new_elem_repr;
FilterXObject *new_elem_obj = _create_object_for_new_elem(last_elem_context->current_obj, has_attrs, &new_elem_repr);
XmlElemContext *new_elem_context = xml_elem_context_new(last_elem_context->current_obj, new_elem_obj);
xml_elem_context_init(new_elem_context, last_elem_context->current_obj, new_elem_obj);

FilterXObject *new_elem_key = filterx_string_new(new_elem_name, -1);
FilterXObject *existing_obj = NULL;
Expand Down Expand Up @@ -273,8 +273,7 @@ _prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, gbo
_set_error(error, "failed to unset existing unexpected node");
goto exit;
}
xml_elem_context_free(new_elem_context);
new_elem_context = _prepare_elem(new_elem_name, last_elem_context, has_attrs, error);
_prepare_elem(new_elem_name, last_elem_context, has_attrs, new_elem_context, error);

exit:
filterx_object_unref(new_elem_key);
Expand All @@ -283,11 +282,11 @@ _prepare_elem(const gchar *new_elem_name, XmlElemContext *last_elem_context, gbo

if (*error)
{
xml_elem_context_free(new_elem_context);
new_elem_context = NULL;
xml_elem_context_destroy(new_elem_context);
return FALSE;
}

return new_elem_context;
return TRUE;
}

static void
Expand Down Expand Up @@ -387,7 +386,7 @@ filterx_parse_xml_start_elem_method(FilterXGeneratorFunctionParseXml *self,
const gchar **attribute_names, const gchar **attribute_values,
FilterXParseXmlState *state, GError **error)
{
XmlElemContext *last_elem_context = g_queue_peek_head(state->xml_elem_context_stack);
XmlElemContext *last_elem_context = xml_elem_context_stack_peek_last(state->xml_elem_context_stack);

if (!filterx_object_is_type(last_elem_context->current_obj, &FILTERX_TYPE_NAME(dict)))
{
Expand All @@ -401,23 +400,23 @@ filterx_parse_xml_start_elem_method(FilterXGeneratorFunctionParseXml *self,
}

gboolean has_attrs = !!attribute_names[0];
XmlElemContext *new_elem_context = _prepare_elem(element_name, last_elem_context, has_attrs, error);
if (!new_elem_context)

XmlElemContext new_elem_context = { 0 };
if (!_prepare_elem(element_name, last_elem_context, has_attrs, &new_elem_context, error))
return;

g_queue_push_head(state->xml_elem_context_stack, new_elem_context);
xml_elem_context_stack_push(&state->xml_elem_context_stack, &new_elem_context);

if (has_attrs)
_collect_attrs(element_name, new_elem_context, attribute_names, attribute_values, error);
_collect_attrs(element_name, &new_elem_context, attribute_names, attribute_values, error);
}

void
filterx_parse_xml_end_elem_method(FilterXGeneratorFunctionParseXml *self,
GMarkupParseContext *context, const gchar *element_name,
FilterXParseXmlState *state, GError **error)
{
XmlElemContext *elem_context = g_queue_pop_head(state->xml_elem_context_stack);
xml_elem_context_free(elem_context);
xml_elem_context_stack_remove_last(&state->xml_elem_context_stack);
}

static gchar *
Expand Down Expand Up @@ -533,7 +532,7 @@ filterx_parse_xml_text_method(FilterXGeneratorFunctionParseXml *self,
GMarkupParseContext *context, const gchar *text, gsize text_len,
FilterXParseXmlState *state, GError **error)
{
XmlElemContext *elem_context = g_queue_peek_head(state->xml_elem_context_stack);
XmlElemContext *elem_context = xml_elem_context_stack_peek_last(state->xml_elem_context_stack);
const gchar *element_name = g_markup_parse_context_get_element(context);

gsize stripped_text_len;
Expand Down Expand Up @@ -635,8 +634,11 @@ _parse(FilterXGeneratorFunctionParseXml *self, const gchar *raw_xml, gsize raw_x

FilterXParseXmlState *state = self->create_state();;
gpointer user_data[] = { self, state };
XmlElemContext *root_elem_context = xml_elem_context_new(NULL, fillable);
g_queue_push_head(state->xml_elem_context_stack, root_elem_context);

XmlElemContext root_elem_context = { 0 };
xml_elem_context_init(&root_elem_context, NULL, fillable);
xml_elem_context_stack_push(&state->xml_elem_context_stack, &root_elem_context);

GMarkupParseContext *context = g_markup_parse_context_new(&scanner_callbacks, 0, user_data, NULL);

GError *error = NULL;
Expand Down
26 changes: 23 additions & 3 deletions modules/xml/filterx-parse-xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ FilterXExpr *filterx_generator_function_parse_xml_new(FilterXFunctionArgs *args,
typedef struct FilterXParseXmlState_ FilterXParseXmlState;
struct FilterXParseXmlState_
{
GQueue *xml_elem_context_stack;
GArray *xml_elem_context_stack;

void (*free_fn)(FilterXParseXmlState *self);
};
Expand All @@ -56,12 +56,32 @@ typedef struct XmlElemContext_
FilterXObject *parent_obj;
} XmlElemContext;

XmlElemContext *xml_elem_context_new(FilterXObject *parent_obj, FilterXObject *current_obj);
void xml_elem_context_free(XmlElemContext *self);
void xml_elem_context_init(XmlElemContext *self, FilterXObject *parent_obj, FilterXObject *current_obj);
void xml_elem_context_destroy(XmlElemContext *self);
void xml_elem_context_set_current_obj(XmlElemContext *self, FilterXObject *current_obj);
void xml_elem_context_set_parent_obj(XmlElemContext *self, FilterXObject *parent_obj);


static inline void
xml_elem_context_stack_push(GArray **xml_elem_context_stack, XmlElemContext *elem_context)
{
*xml_elem_context_stack = g_array_append_vals(*xml_elem_context_stack, elem_context, 1);
}

static inline XmlElemContext *
xml_elem_context_stack_peek_last(GArray *xml_elem_context_stack)
{
return &g_array_index(xml_elem_context_stack, XmlElemContext, xml_elem_context_stack->len - 1);
}

static inline void
xml_elem_context_stack_remove_last(GArray **xml_elem_context_stack)
{
xml_elem_context_destroy(xml_elem_context_stack_peek_last(*xml_elem_context_stack));
*xml_elem_context_stack = g_array_remove_index(*xml_elem_context_stack, (*xml_elem_context_stack)->len - 1);
}


typedef struct FilterXGeneratorFunctionParseXml_ FilterXGeneratorFunctionParseXml;
struct FilterXGeneratorFunctionParseXml_
{
Expand Down

0 comments on commit fc22cf8

Please sign in to comment.