data parser CHANGE optimize going through siblings
Explicitely provide the first sibling to the data parser functions
to speed up the parser especially in case of many top-level nodes
(e.g. lists and leaflists).
diff --git a/src/parser_json.c b/src/parser_json.c
index 994fcda..1c2f2db 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -435,9 +435,9 @@
}
static unsigned int
-json_get_value(struct lyd_node_leaf_list *leaf, const char *data, int options)
+json_get_value(struct lyd_node_leaf_list *leaf, struct lyd_node *first_sibling, const char *data, int options)
{
- struct lyd_node_leaf_list *new, *diter;
+ struct lyd_node_leaf_list *new;
struct lys_type *stype;
struct ly_ctx *ctx;
unsigned int len = 0, r;
@@ -541,8 +541,7 @@
leaf->next = (struct lyd_node *)new;
/* fix the "last" pointer */
- for (diter = leaf; diter->prev != (struct lyd_node *)leaf; diter = (struct lyd_node_leaf_list *)diter->prev);
- diter->prev = (struct lyd_node *)new;
+ first_sibling->prev = (struct lyd_node *)new;
new->schema = leaf->schema;
@@ -748,7 +747,8 @@
static unsigned int
json_parse_data(struct ly_ctx *ctx, const char *data, const struct lys_node *schema_parent, struct lyd_node **parent,
- struct lyd_node *prev, struct attr_cont **attrs, int options, struct unres_data *unres)
+ struct lyd_node *first_sibling, struct lyd_node *prev, struct attr_cont **attrs, int options,
+ struct unres_data *unres)
{
unsigned int len = 0;
unsigned int r;
@@ -757,7 +757,7 @@
char *name, *prefix = NULL, *str = NULL;
const struct lys_module *module = NULL;
struct lys_node *schema = NULL;
- struct lyd_node *result = NULL, *new, *list, *diter = NULL, *first_sibling;
+ struct lyd_node *result = NULL, *new, *list, *diter = NULL;
struct lyd_attr *attr;
struct attr_cont *attrs_aux;
@@ -986,13 +986,7 @@
prev->next = result;
/* fix the "last" pointer */
- if (*parent) {
- diter = (*parent)->child;
- } else {
- for (diter = prev; diter->prev != prev; diter = diter->prev);
- }
- diter->prev = result;
- first_sibling = diter;
+ first_sibling->prev = result;
} else {
result->prev = result;
first_sibling = result;
@@ -1006,7 +1000,7 @@
/* type specific processing */
if (schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
/* type detection and assigning the value */
- r = json_get_value((struct lyd_node_leaf_list *)result, &data[len], options);
+ r = json_get_value((struct lyd_node_leaf_list *)result, first_sibling, &data[len], options);
if (!r) {
goto error;
}
@@ -1040,7 +1034,7 @@
len++;
len += skip_ws(&data[len]);
- r = json_parse_data(ctx, &data[len], NULL, &result, diter, &attrs_aux, options, unres);
+ r = json_parse_data(ctx, &data[len], NULL, &result, result->child, diter, &attrs_aux, options, unres);
if (!r) {
goto error;
}
@@ -1094,7 +1088,7 @@
len++;
len += skip_ws(&data[len]);
- r = json_parse_data(ctx, &data[len], NULL, &list, diter, &attrs_aux, options, unres);
+ r = json_parse_data(ctx, &data[len], NULL, &list, list->child, diter, &attrs_aux, options, unres);
if (!r) {
goto error;
}
@@ -1252,7 +1246,7 @@
len++;
len += skip_ws(&data[len]);
- r = json_parse_data(ctx, &data[len], parent, &next, iter, &attrs, options, unres);
+ r = json_parse_data(ctx, &data[len], parent, &next, result, iter, &attrs, options, unres);
if (!r) {
goto error;
}