26
26
#include "filterx/object-primitive.h"
27
27
#include "filterx/object-dict.h"
28
28
#include "filterx/object-list.h"
29
+ #include "filterx/filterx-plist.h"
29
30
30
31
/* Object Members (e.g. key-value) */
31
32
@@ -91,28 +92,42 @@ struct FilterXLiteralContainer_
91
92
{
92
93
FilterXExpr super ;
93
94
FilterXObject * (* create_container )(FilterXLiteralContainer * self );
94
- GList * elements ;
95
+ FilterXPointerList elements ;
95
96
};
96
97
97
98
gsize
98
99
filterx_literal_container_len (FilterXExpr * s )
99
100
{
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 );
104
103
}
105
104
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 )
108
116
{
109
117
FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
110
118
111
119
FilterXObject * result = self -> create_container (self );
112
120
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 ++ )
114
124
{
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 );
116
131
117
132
FilterXObject * key = NULL ;
118
133
if (elem -> key )
@@ -145,22 +160,29 @@ _literal_container_eval(FilterXExpr *s)
145
160
return NULL ;
146
161
}
147
162
163
+ static FilterXObject *
164
+ _literal_container_eval (FilterXExpr * s )
165
+ {
166
+ return _literal_container_eval_adaptive (s , TRUE);
167
+ }
168
+
148
169
static FilterXExpr *
149
170
_literal_container_optimize (FilterXExpr * s )
150
171
{
151
172
FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
152
173
153
174
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 ++ )
155
177
{
156
- FilterXLiteralElement * elem = (FilterXLiteralElement * ) link -> data ;
178
+ FilterXLiteralElement * elem = (FilterXLiteralElement * ) filterx_pointer_list_index ( & self -> elements , i ) ;
157
179
158
180
_literal_element_optimize (elem );
159
181
if (!elem -> literal )
160
182
literal = FALSE;
161
183
}
162
184
if (literal )
163
- return filterx_literal_new (_literal_container_eval ( s ));
185
+ return filterx_literal_new (_literal_container_eval_adaptive ( s , FALSE ));
164
186
165
187
return NULL ;
166
188
}
@@ -170,21 +192,12 @@ _literal_container_init(FilterXExpr *s, GlobalConfig *cfg)
170
192
{
171
193
FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
172
194
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 ))
174
197
{
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;
186
200
}
187
-
188
201
return filterx_expr_init_method (s , cfg );
189
202
}
190
203
@@ -193,12 +206,7 @@ _literal_container_deinit(FilterXExpr *s, GlobalConfig *cfg)
193
206
{
194
207
FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
195
208
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 );
202
210
filterx_expr_deinit_method (s , cfg );
203
211
}
204
212
@@ -207,7 +215,7 @@ _literal_container_free(FilterXExpr *s)
207
215
{
208
216
FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
209
217
210
- g_list_free_full ( self -> elements , (GDestroyNotify ) _literal_element_free );
218
+ filterx_pointer_list_clear ( & self -> elements , (GDestroyNotify ) _literal_element_free );
211
219
filterx_expr_free_method (s );
212
220
}
213
221
@@ -220,18 +228,20 @@ _literal_container_init_instance(FilterXLiteralContainer *self, const gchar *typ
220
228
self -> super .init = _literal_container_init ;
221
229
self -> super .deinit = _literal_container_deinit ;
222
230
self -> super .free_fn = _literal_container_free ;
231
+ filterx_pointer_list_init (& self -> elements );
223
232
}
224
233
225
234
/* Literal dict objects */
226
235
227
236
gboolean
228
237
filterx_literal_dict_foreach (FilterXExpr * s , FilterXLiteralDictForeachFunc func , gpointer user_data )
229
238
{
230
- GList * elements = (( FilterXLiteralContainer * ) s ) -> elements ;
239
+ FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
231
240
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 ++ )
233
243
{
234
- FilterXLiteralElement * elem = (FilterXLiteralElement * ) link -> data ;
244
+ FilterXLiteralElement * elem = (FilterXLiteralElement * ) filterx_pointer_list_index ( & self -> elements , i ) ;
235
245
236
246
if (!func (elem -> key , elem -> value , user_data ))
237
247
return FALSE;
@@ -253,7 +263,7 @@ filterx_literal_dict_new(GList *elements)
253
263
254
264
_literal_container_init_instance (self , FILTERX_EXPR_TYPE_NAME (literal_dict ));
255
265
self -> create_container = _literal_dict_create ;
256
- self -> elements = elements ;
266
+ filterx_pointer_list_add_list ( & self -> elements , elements ) ;
257
267
258
268
return & self -> super ;
259
269
}
@@ -263,17 +273,15 @@ filterx_literal_dict_new(GList *elements)
263
273
gboolean
264
274
filterx_literal_list_foreach (FilterXExpr * s , FilterXLiteralListForeachFunc func , gpointer user_data )
265
275
{
266
- GList * elements = (( FilterXLiteralContainer * ) s ) -> elements ;
276
+ FilterXLiteralContainer * self = (FilterXLiteralContainer * ) s ;
267
277
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 ++ )
270
280
{
271
- FilterXLiteralElement * elem = (FilterXLiteralElement * ) link -> data ;
281
+ FilterXLiteralElement * elem = (FilterXLiteralElement * ) filterx_pointer_list_index ( & self -> elements , i ) ;
272
282
273
283
if (!func (i , elem -> value , user_data ))
274
284
return FALSE;
275
-
276
- i ++ ;
277
285
}
278
286
279
287
return TRUE;
@@ -292,7 +300,7 @@ filterx_literal_list_new(GList *elements)
292
300
293
301
_literal_container_init_instance (self , FILTERX_EXPR_TYPE_NAME (literal_list ));
294
302
self -> create_container = _literal_list_create ;
295
- self -> elements = elements ;
303
+ filterx_pointer_list_add_list ( & self -> elements , elements ) ;
296
304
297
305
return & self -> super ;
298
306
}
0 commit comments