Skip to content

Commit 306e283

Browse files
committed
xpath OPTIMIZE track child-only axis node moves
... which should guarantee that document order is never broken so the sets do not have to be sorted. Refs sysrepo/sysrepo#2843
1 parent 03fe620 commit 306e283

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

src/xpath.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ set_init(struct lyxp_set *new, const struct lyxp_set *set)
844844
{
845845
memset(new, 0, sizeof *new);
846846
if (set) {
847+
new->non_child_axis = set->non_child_axis;
847848
new->ctx = set->ctx;
848849
new->cur_node = set->cur_node;
849850
new->root_type = set->root_type;
@@ -5613,6 +5614,7 @@ moveto_root(struct lyxp_set *set, uint32_t options)
56135614
set->type = LYXP_SET_NODE_SET;
56145615
set->used = 0;
56155616
set_insert_node(set, NULL, 0, set->root_type, 0);
5617+
set->non_child_axis = 0;
56165618
}
56175619

56185620
return LY_SUCCESS;
@@ -6026,6 +6028,7 @@ moveto_node(struct lyxp_set *set, const struct lys_module *moveto_mod, const cha
60266028
case LYXP_AXIS_PARENT:
60276029
case LYXP_AXIS_PRECEDING:
60286030
case LYXP_AXIS_PRECEDING_SIBLING:
6031+
result.non_child_axis = 1;
60296032
if (set_dup_node_check(&result, iter, iter_type, -1)) {
60306033
continue;
60316034
}
@@ -6050,8 +6053,12 @@ moveto_node(struct lyxp_set *set, const struct lys_module *moveto_mod, const cha
60506053
*set = result;
60516054
result.type = LYXP_SET_NUMBER;
60526055

6053-
/* sort the final set */
6054-
set_sort(set);
6056+
/* sort the final set if the document order could have been broken */
6057+
if (set->non_child_axis) {
6058+
set_sort(set);
6059+
} else {
6060+
assert(!set_sort(set));
6061+
}
60556062

60566063
cleanup:
60576064
lyxp_set_free_content(&result);
@@ -6756,6 +6763,7 @@ moveto_node_alldesc_child(struct lyxp_set *set, const struct lys_module *moveto_
67566763
ret_set.ctx_size = set->ctx_size;
67576764
lyxp_set_free_content(set);
67586765
memcpy(set, &ret_set, sizeof *set);
6766+
assert(!set_sort(set));
67596767

67606768
return LY_SUCCESS;
67616769
}

src/xpath.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @author Michal Vasko <[email protected]>
44
* @brief YANG XPath evaluation functions header
55
*
6-
* Copyright (c) 2015 - 2020 CESNET, z.s.p.o.
6+
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
77
*
88
* This source code is licensed under BSD 3-Clause License (the "License").
99
* You may not use this file except in compliance with the License.
@@ -287,13 +287,14 @@ struct lyxp_set {
287287
} val; /**< Evaluated object (value). */
288288

289289
/* this is valid only for type LYXP_SET_NODE_SET and LYXP_SET_SCNODE_SET */
290-
uint32_t used; /**< Number of nodes in the set. */
291-
uint32_t size; /**< Allocated size for the set. */
292-
struct hash_table *ht; /**< Hash table for quick determination of whether a node is in the set. */
290+
uint32_t used; /**< Number of nodes in the set. */
291+
uint32_t size; /**< Allocated size for the set. */
292+
struct hash_table *ht; /**< Hash table for quick determination of whether a node is in the set. */
293293

294294
/* XPath context information, this is valid only for type LYXP_SET_NODE_SET */
295-
uint32_t ctx_pos; /**< Position of the current examined node in the set. */
296-
uint32_t ctx_size; /**< Position of the last node at the time the node was examined. */
295+
uint32_t ctx_pos; /**< Position of the current examined node in the set. */
296+
uint32_t ctx_size; /**< Position of the last node at the time the node was examined. */
297+
ly_bool non_child_axis; /**< Whether any node change was performed on a non-child axis. */
297298

298299
/* general context */
299300
struct ly_ctx *ctx; /**< General context for logging. */

0 commit comments

Comments
 (0)