Skip to content

Commit e2aaea9

Browse files
committed
filterx/expr-literal-container: use plist to store list of key-values
Signed-off-by: Balazs Scheidler <[email protected]>
1 parent 458b08e commit e2aaea9

File tree

1 file changed

+51
-43
lines changed

1 file changed

+51
-43
lines changed

lib/filterx/expr-literal-container.c

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "filterx/object-primitive.h"
2727
#include "filterx/object-dict.h"
2828
#include "filterx/object-list.h"
29+
#include "filterx/filterx-plist.h"
2930

3031
/* Object Members (e.g. key-value) */
3132

@@ -91,28 +92,42 @@ struct FilterXLiteralContainer_
9192
{
9293
FilterXExpr super;
9394
FilterXObject *(*create_container)(FilterXLiteralContainer *self);
94-
GList *elements;
95+
FilterXPointerList elements;
9596
};
9697

9798
gsize
9899
filterx_literal_container_len(FilterXExpr *s)
99100
{
100-
GList *elements = NULL;
101-
102-
elements = ((FilterXLiteralContainer *) s)->elements;
103-
return g_list_length(elements);
101+
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
102+
return filterx_pointer_list_get_length(&self->elements);
104103
}
105104

106-
static FilterXObject *
107-
_literal_container_eval(FilterXExpr *s)
105+
/*
106+
* This is an inline version with two variants,
107+
*
108+
* "fastpath" == TRUE means we * are doing this at eval time by which point
109+
* we already did a filterx_plist_seal()
110+
*
111+
* "fastpath" == FALSE means we are still doing this at compilation time and
112+
* seal is yet to be called.
113+
*/
114+
static inline FilterXObject *
115+
_literal_container_eval_adaptive(FilterXExpr *s, gboolean fastpath)
108116
{
109117
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
110118

111119
FilterXObject *result = self->create_container(self);
112120
filterx_object_cow_prepare(&result);
113-
for (GList *link = self->elements; link; link = link->next)
121+
122+
gsize len = filterx_pointer_list_get_length(&self->elements);
123+
for (gsize i = 0; i < len; i++)
114124
{
115-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
125+
FilterXLiteralElement *elem;
126+
127+
if (fastpath)
128+
elem = (FilterXLiteralElement *) filterx_pointer_list_index_fast(&self->elements, i);
129+
else
130+
elem = (FilterXLiteralElement *) filterx_pointer_list_index(&self->elements, i);
116131

117132
FilterXObject *key = NULL;
118133
if (elem->key)
@@ -145,22 +160,29 @@ _literal_container_eval(FilterXExpr *s)
145160
return NULL;
146161
}
147162

163+
static FilterXObject *
164+
_literal_container_eval(FilterXExpr *s)
165+
{
166+
return _literal_container_eval_adaptive(s, TRUE);
167+
}
168+
148169
static FilterXExpr *
149170
_literal_container_optimize(FilterXExpr *s)
150171
{
151172
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
152173

153174
gboolean literal = TRUE;
154-
for (GList *link = self->elements; link; link = link->next)
175+
gsize len = filterx_pointer_list_get_length(&self->elements);
176+
for (gsize i = 0; i < len; i++)
155177
{
156-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
178+
FilterXLiteralElement *elem = (FilterXLiteralElement *) filterx_pointer_list_index(&self->elements, i);
157179

158180
_literal_element_optimize(elem);
159181
if (!elem->literal)
160182
literal = FALSE;
161183
}
162184
if (literal)
163-
return filterx_literal_new(_literal_container_eval(s));
185+
return filterx_literal_new(_literal_container_eval_adaptive(s, FALSE));
164186

165187
return NULL;
166188
}
@@ -170,21 +192,12 @@ _literal_container_init(FilterXExpr *s, GlobalConfig *cfg)
170192
{
171193
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
172194

173-
for (GList *link = self->elements; link; link = link->next)
195+
filterx_pointer_list_seal(&self->elements);
196+
if (!filterx_pointer_list_foreach(&self->elements, (FilterXPointerListForeachFunc) _literal_element_init, cfg))
174197
{
175-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
176-
177-
if (!_literal_element_init(elem, cfg))
178-
{
179-
for (GList *deinit_link = self->elements; deinit_link != link; deinit_link = deinit_link->next)
180-
{
181-
elem = (FilterXLiteralElement *) deinit_link->data;
182-
_literal_element_deinit(elem, cfg);
183-
}
184-
return FALSE;
185-
}
198+
filterx_pointer_list_foreach(&self->elements, (FilterXPointerListForeachFunc) _literal_element_deinit, cfg);
199+
return FALSE;
186200
}
187-
188201
return filterx_expr_init_method(s, cfg);
189202
}
190203

@@ -193,12 +206,7 @@ _literal_container_deinit(FilterXExpr *s, GlobalConfig *cfg)
193206
{
194207
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
195208

196-
for (GList *link = self->elements; link; link = link->next)
197-
{
198-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
199-
_literal_element_deinit(elem, cfg);
200-
}
201-
209+
filterx_pointer_list_foreach(&self->elements, (FilterXPointerListForeachFunc) _literal_element_deinit, cfg);
202210
filterx_expr_deinit_method(s, cfg);
203211
}
204212

@@ -207,7 +215,7 @@ _literal_container_free(FilterXExpr *s)
207215
{
208216
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
209217

210-
g_list_free_full(self->elements, (GDestroyNotify) _literal_element_free);
218+
filterx_pointer_list_clear(&self->elements, (GDestroyNotify) _literal_element_free);
211219
filterx_expr_free_method(s);
212220
}
213221

@@ -220,18 +228,20 @@ _literal_container_init_instance(FilterXLiteralContainer *self, const gchar *typ
220228
self->super.init = _literal_container_init;
221229
self->super.deinit = _literal_container_deinit;
222230
self->super.free_fn = _literal_container_free;
231+
filterx_pointer_list_init(&self->elements);
223232
}
224233

225234
/* Literal dict objects */
226235

227236
gboolean
228237
filterx_literal_dict_foreach(FilterXExpr *s, FilterXLiteralDictForeachFunc func, gpointer user_data)
229238
{
230-
GList *elements = ((FilterXLiteralContainer *) s)->elements;
239+
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
231240

232-
for (GList *link = elements; link; link = link->next)
241+
gsize len = filterx_pointer_list_get_length(&self->elements);
242+
for (gsize i = 0; i < len; i++)
233243
{
234-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
244+
FilterXLiteralElement *elem = (FilterXLiteralElement *) filterx_pointer_list_index(&self->elements, i);
235245

236246
if (!func(elem->key, elem->value, user_data))
237247
return FALSE;
@@ -253,7 +263,7 @@ filterx_literal_dict_new(GList *elements)
253263

254264
_literal_container_init_instance(self, FILTERX_EXPR_TYPE_NAME(literal_dict));
255265
self->create_container = _literal_dict_create;
256-
self->elements = elements;
266+
filterx_pointer_list_add_list(&self->elements, elements);
257267

258268
return &self->super;
259269
}
@@ -263,17 +273,15 @@ filterx_literal_dict_new(GList *elements)
263273
gboolean
264274
filterx_literal_list_foreach(FilterXExpr *s, FilterXLiteralListForeachFunc func, gpointer user_data)
265275
{
266-
GList *elements = ((FilterXLiteralContainer *) s)->elements;
276+
FilterXLiteralContainer *self = (FilterXLiteralContainer *) s;
267277

268-
gsize i = 0;
269-
for (GList *link = elements; link; link = link->next)
278+
gsize len = filterx_pointer_list_get_length(&self->elements);
279+
for (gsize i = 0; i < len; i++)
270280
{
271-
FilterXLiteralElement *elem = (FilterXLiteralElement *) link->data;
281+
FilterXLiteralElement *elem = (FilterXLiteralElement *) filterx_pointer_list_index(&self->elements, i);
272282

273283
if (!func(i, elem->value, user_data))
274284
return FALSE;
275-
276-
i++;
277285
}
278286

279287
return TRUE;
@@ -292,7 +300,7 @@ filterx_literal_list_new(GList *elements)
292300

293301
_literal_container_init_instance(self, FILTERX_EXPR_TYPE_NAME(literal_list));
294302
self->create_container = _literal_list_create;
295-
self->elements = elements;
303+
filterx_pointer_list_add_list(&self->elements, elements);
296304

297305
return &self->super;
298306
}

0 commit comments

Comments
 (0)