1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**
* @file tree_data_sorted.h
* @author Adam Piecek <piecek@cesnet.cz>
* @brief Binary search tree (BST) for sorting data nodes.
*
* Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/
;
;
;
/* This functionality applies to list and leaf-list with the "ordered-by system" statement,
* which is implicit. The BST is implemented using a Red-black tree and is used for sorting nodes.
* For example, a list of valid users would typically be sorted alphabetically. This tree is saved
* in the first instance of the leaf-list/list in the metadata named lyds_tree. Thanks to the tree,
* it is possible to insert a sibling data node in such a way that the order of the nodes is preserved.
* The decision whether the value is greater or less takes place in the callback function ::lyplg_type_sort_clb
* in the corresponding type.
*
* Parameters always must be from the same context.
*/
/**
* @brief BST and 'lyds_tree' metadata pool.
*
* The structure stores a free Red-black tree and metadata, which can be reused. Thanks to this,
* it is possible to work with data more efficiently and thus prevent repeated allocation and freeing of memory.
*/
;
/**
* @brief Check that ordering is supported for the @p node.
*
* If the function returns 0 for a given node, other lyds_* or rb_* functions must not be called for this node.
*
* @param[in] node Node to check. Expected (leaf-)list or list with key(s).
* @return 1 if @p node can be sorted.
*/
ly_bool ;
/**
* @brief Determine if the data node supports lyds and if the node is a 'leader'.
*
* @param[in] NODE Data node (struct lyd_node) to check.
* @return 1 if @p NODE is the first instance of the (leaf-)list with lyds support.
*/
/**
* @brief Create the 'lyds_tree' metadata.
*
* @param[in] leader First instance of the (leaf-)list. If the node already contains the metadata,
* then nothing happens. The BST is unchanged or empty.
* @param[out] meta Newly created 'lyds_tree' metadata.
* @return LY_ERR value.
*/
LY_ERR ;
/**
* @brief Create new BST node.
*
* @param[in] node Data node to link with new red-black node.
* @param[out] rbn Created red-black node.
* @return LY_SUCCESS on success.
*/
LY_ERR ;
/**
* @brief Insert the @p node into BST and into @p leader's siblings.
*
* Sibling data nodes of the @p leader are also modified for sorting to take place.
* The function automatically take care of lyds_create_metadata() and lyds_create_tree() calls.
* Hash for data nodes is not added.
*
* @param[in,out] first_sibling First sibling node, used for optimization.
* @param[in,out] leader First instance of the (leaf-)list. After executing the function,
* @p leader does not have to be be first if @p node was inserted before @p leader.
* @param[in] node A single (without siblings) node or tree to be inserted. It must be unlinked.
* @return LY_ERR value.
*/
LY_ERR ;
/**
* @brief Insert the @p node into BST and into @p leader's siblings and use @p pool.
*
* @param[in] parent Parent to insert into, NULL for top-level sibling.
* @param[in,out] first_sibling First sibling, NULL if no top-level sibling exist yet.
* Can be also NULL if @p parent is set.
* @param[in,out] leader First instance of the (leaf-)list. It can be set to NULL or even incorrectly set,
* in which case the leader is found inside the function. It is convenient to keep the found pointer
* at the caller and be used during the next call.
* @param[in] node Individual node (without siblings) to insert.
* @param[in,out] pool Pool from which the lyds data will be reused. If empty, data is allocated as needed.
* @return LY_ERR value.
*/
LY_ERR ;
/**
* @brief Unlink (remove) the specified data node from BST.
*
* Pointers in sibling data nodes (lyd_node) are NOT modified. This means that the data node is NOT unlinked.
* Even if the BST will remain empty, lyds_tree metadata will remain.
* Hash for data nodes is not removed.
*
* @param[in,out] leader First instance of (leaf-)list. If it is NULL, nothing happens.
* @param[in] node Some instance of (leaf-)list to be unlinked.
*/
void ;
/**
* @brief Unlink lyds data from @p leader and add them to the pool.
*
* @param[in] leader First instance of the (leaf-)list.
* @param[in,out] pool Pool to add lyds data to.
*/
void ;
/**
* @brief Clear lyds data in pool, memory deallocation.
*
* @param[in,out] pool Pool from which the lyds data will be released. Pointers will be set to NULL.
*/
void ;
/**
* @brief Split the (leaf-)list in two.
*
* The second (leaf-)list is unlinked from the rest of the data nodes.
* The hash for the data nodes is removed.
*
* @param[in,out] first_sibling First sibling node, used for optimization.
* @param[in] leader First instance of (leaf-)list.
* @param[in] node Node in the (leaf-)list from which the second (leaf-)list will start.
* @param[out] next Data node located after the second (leaf-)list.
* The rest of the (leaf-)list nodes will belong under the second (leaf-)list.
*/
void ;
/**
* @brief Merge source (leaf-)list nodes into destination (leaf-)list nodes.
*
* Pointers in sibling data nodes (lyd_node) are modified.
* The hash for the data nodes will be adjusted.
*
* @param[in,out] first_dst First sibling node, destination.
* @param[in,out] leader_dst Destination (leaf-)list, first instance. It may not contain
* the lyds_tree metadata or BST. After merge @p leader_dst can be reset to new leader.
* @param[in,out] first_src First sibling node, source.
* @param[in] leader_src Source (leaf-)list, first instance. It may not contain the lyds_tree metadata or BST.
* @param[out] next Data node located after source (leaf-)list.
* On error, points to data node which failed to merge.
* @return LY_ERR value.
*/
LY_ERR ;
/**
* @brief Compare (sort) 2 data nodes.
*
* @param[in] node1 The first node to compare.
* @param[in] node2 The second node to compare.
* @return Negative number if val1 < val2,
* @return Zero if val1 == val2,
* @return Positive number if val1 > val2.
*/
int ;
/**
* @brief Release the metadata including BST.
*
* No more nodes can be inserted after the function is executed.
*
* @param[in] node Data node of the type (leaf-)list that may contain metadata and BST.
*/
void ;
/**
* @brief Release all BST nodes including the root.
*
* @param[in] rbt Root of the Red-black tree.
*/
void ;
/* _LYDS_TREE_H_ */