1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_ERR
18
19 #include "bsl_sal.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_log.h"
22 #include "bsl_binlog_id.h"
23 #include "avl.h"
24
25 // Maximum height of the AVL tree.
26 #define AVL_MAX_HEIGHT 64
27
GetMaxHeight(uint32_t a,uint32_t b)28 static uint32_t GetMaxHeight(uint32_t a, uint32_t b)
29 {
30 if (a >= b) {
31 return a;
32 } else {
33 return b;
34 }
35 }
36
GetAvlTreeHeight(const BSL_AvlTree * node)37 static uint32_t GetAvlTreeHeight(const BSL_AvlTree *node)
38 {
39 if (node == NULL) {
40 return 0;
41 } else {
42 return node->height;
43 }
44 }
45
UpdateAvlTreeHeight(BSL_AvlTree * node)46 static void UpdateAvlTreeHeight(BSL_AvlTree *node)
47 {
48 if (node != NULL) {
49 uint32_t leftHeight = GetAvlTreeHeight(node->leftNode);
50 uint32_t rightHeight = GetAvlTreeHeight(node->rightNode);
51 if (node->height >= AVL_MAX_HEIGHT) {
52 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
53 "avl tree height exceed max limit", 0, 0, 0, 0);
54 return;
55 }
56 node->height = GetMaxHeight(leftHeight, rightHeight) + 1u;
57 }
58 }
59
BSL_AVL_MakeLeafNode(BSL_ElementData data)60 BSL_AvlTree *BSL_AVL_MakeLeafNode(BSL_ElementData data)
61 {
62 BSL_AvlTree *curNode = (BSL_AvlTree *)BSL_SAL_Malloc(sizeof(BSL_AvlTree));
63 if (curNode == NULL) {
64 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
65 "MALLOC for avl tree node failed", 0, 0, 0, 0);
66 return NULL;
67 }
68
69 curNode->height = 1;
70 curNode->rightNode = NULL;
71 curNode->leftNode = NULL;
72 curNode->data = data;
73
74 return curNode;
75 }
76
77 /**
78 * @brief AVL rotate left
79 * @param root [IN] Root node to be rotated
80 * @return rNode Root node after rotation
81 */
AVL_RotateLeft(BSL_AvlTree * root)82 static BSL_AvlTree *AVL_RotateLeft(BSL_AvlTree *root)
83 {
84 /* Rotate Left
85 10 20
86 5 20 --Rotate Left---> 10 30
87 30 5 40
88 40
89
90 In this case, the input root node is 10, and the output node is 20. */
91 BSL_AvlTree *rNode = root->rightNode;
92 BSL_AvlTree *lNode = rNode->leftNode;
93 root->rightNode = lNode;
94 rNode->leftNode = root;
95 UpdateAvlTreeHeight(root);
96 UpdateAvlTreeHeight(rNode);
97 return rNode;
98 }
99
100 /**
101 * @brief AVL rotate right
102 * @param root [IN] Root node to be rotated
103 * @return lNode Root node after rotation
104 */
AVL_RotateRight(BSL_AvlTree * root)105 static BSL_AvlTree *AVL_RotateRight(BSL_AvlTree *root)
106 {
107 /* Rotate Right
108 40 30
109 / \ / \
110 30 50 --Rotate Right---> 20 40
111 20 35 10 35 50
112 10
113 In this case, the input root node is 40, and the output node is 30. */
114 BSL_AvlTree *lNode = root->leftNode;
115 BSL_AvlTree *rNode = lNode->rightNode;
116 root->leftNode = rNode;
117 lNode->rightNode = root;
118 UpdateAvlTreeHeight(root);
119 UpdateAvlTreeHeight(lNode);
120 return lNode;
121 }
122
123 /**
124 * @brief AVL Right Balance
125 * @param root [IN] Root node to be balanced
126 * @return root: root node after balancing
127 */
AVL_RebalanceRight(BSL_AvlTree * root)128 static BSL_AvlTree *AVL_RebalanceRight(BSL_AvlTree *root)
129 {
130 // The height difference between the left and right subtrees is only 1.
131 if ((GetAvlTreeHeight(root->leftNode) + 1u) >= GetAvlTreeHeight(root->rightNode)) {
132 UpdateAvlTreeHeight(root);
133 return root;
134 }
135 /* The height of the left subtree is greater than that of the right subtree. Rotate right and then left. */
136 BSL_AvlTree *curNode = root->rightNode;
137 if (GetAvlTreeHeight(curNode->leftNode) > GetAvlTreeHeight(curNode->rightNode)) {
138 root->rightNode = AVL_RotateRight(curNode);
139 }
140 return AVL_RotateLeft(root);
141 }
142
143 /**
144 * @brief AVL Left Balance
145 * @param root [IN] Root node to be balanced
146 * @return root: root node after balancing
147 */
AVL_RebalanceLeft(BSL_AvlTree * root)148 static BSL_AvlTree *AVL_RebalanceLeft(BSL_AvlTree *root)
149 {
150 // The height difference between the left and right subtrees is only 1.
151 if ((GetAvlTreeHeight(root->rightNode) + 1u) >= GetAvlTreeHeight(root->leftNode)) {
152 UpdateAvlTreeHeight(root);
153 return root;
154 }
155 /* The height of the right subtree is greater than that of the left subtree. Rotate left and then right. */
156 BSL_AvlTree *curNode = root->leftNode;
157 if (GetAvlTreeHeight(curNode->rightNode) > GetAvlTreeHeight(curNode->leftNode)) {
158 root->leftNode = AVL_RotateLeft(curNode);
159 }
160 return AVL_RotateRight(root);
161 }
162
AVL_FreeData(BSL_ElementData data,BSL_AVL_DATA_FREE_FUNC freeFunc)163 static void AVL_FreeData(BSL_ElementData data, BSL_AVL_DATA_FREE_FUNC freeFunc)
164 {
165 if (freeFunc != NULL) {
166 freeFunc(data);
167 }
168 }
169
BSL_AVL_InsertNode(BSL_AvlTree * root,uint64_t nodeId,BSL_AvlTree * node)170 BSL_AvlTree *BSL_AVL_InsertNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AvlTree *node)
171 {
172 if (root == NULL) {
173 node->nodeId = nodeId;
174 return node;
175 }
176
177 if (root->nodeId > nodeId) {
178 // If the nodeId is smaller than the root nodeId, insert the left subtree.
179 root->leftNode = BSL_AVL_InsertNode(root->leftNode, nodeId, node);
180
181 return AVL_RebalanceLeft(root);
182 } else if (root->nodeId < nodeId) {
183 // If the nodeId is greater than the root nodeId, insert the right subtree.
184 root->rightNode = BSL_AVL_InsertNode(root->rightNode, nodeId, node);
185
186 return AVL_RebalanceRight(root);
187 }
188
189 /* if the keys are the same and cannot be inserted */
190 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
191 "AVL tree insert key nodeId(%llu) already exist", nodeId, 0, 0, 0);
192 return NULL;
193 }
194
BSL_AVL_SearchNode(BSL_AvlTree * root,uint64_t nodeId)195 BSL_AvlTree *BSL_AVL_SearchNode(BSL_AvlTree *root, uint64_t nodeId)
196 {
197 BSL_AvlTree *curNode = root;
198 while (curNode != NULL) {
199 // match the node
200 if (curNode->nodeId == nodeId) {
201 break;
202 } else if (curNode->nodeId > nodeId) {
203 // If the nodeId is smaller than the root nodeId, search the left subtree.
204 curNode = curNode->leftNode;
205 } else {
206 // If the nodeId is greater than the root nodeId, search the right subtree.
207 curNode = curNode->rightNode;
208 }
209 }
210
211 // If the specified node cannot be found, NULL is returned.
212 return curNode;
213 }
214
215 /**
216 * @brief Delete the specified AVL node that has both the left and right subnodes.
217 * @param rmNodeChild [IN] Child node of the AVL node to be deleted
218 * removeNode [IN] Avl node to be deleted.
219 * @return root Return the deleted root node of the AVL tree.
220 */
AVL_DeleteNodeWithTwoChilds(BSL_AvlTree * rmNodeChild,BSL_AvlTree * removeNode)221 static BSL_AvlTree *AVL_DeleteNodeWithTwoChilds(BSL_AvlTree *rmNodeChild, BSL_AvlTree *removeNode)
222 {
223 if (rmNodeChild == NULL || removeNode == NULL) {
224 return NULL;
225 }
226
227 if (rmNodeChild->rightNode == NULL) {
228 // Connect the left node and the grandfather node regardless of whether rmNodeChild has a left node.
229 BSL_AvlTree *curNode = rmNodeChild->leftNode;
230 removeNode->nodeId = rmNodeChild->nodeId;
231 removeNode->data = rmNodeChild->data;
232
233 BSL_SAL_FREE(rmNodeChild);
234 return curNode;
235 }
236
237 rmNodeChild->rightNode = AVL_DeleteNodeWithTwoChilds(rmNodeChild->rightNode, removeNode);
238 return AVL_RebalanceLeft(rmNodeChild);
239 }
240
BSL_AVL_DeleteNode(BSL_AvlTree * root,uint64_t nodeId,BSL_AVL_DATA_FREE_FUNC func)241 BSL_AvlTree *BSL_AVL_DeleteNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AVL_DATA_FREE_FUNC func)
242 {
243 if (root == NULL) {
244 return root;
245 }
246
247 if (root->nodeId == nodeId) {
248 if (root->leftNode == NULL) {
249 if (root->rightNode == NULL) {
250 // Both the left and right nodes are NULL.
251 AVL_FreeData(root->data, func);
252 BSL_SAL_FREE(root);
253 return NULL;
254 } else {
255 // Only have the right node.
256 BSL_AvlTree *curNode = root->rightNode;
257 AVL_FreeData(root->data, func);
258 BSL_SAL_FREE(root);
259 return (curNode);
260 }
261 } else if (root->rightNode == NULL) {
262 // Only have the right node.
263 BSL_AvlTree *curNode = root->leftNode;
264 AVL_FreeData(root->data, func);
265 BSL_SAL_FREE(root);
266 return (curNode);
267 } else {
268 // There are left and right nodes.
269 AVL_FreeData(root->data, func);
270 root->leftNode = AVL_DeleteNodeWithTwoChilds(root->leftNode, root);
271 return AVL_RebalanceRight(root);
272 }
273 }
274
275 if (root->nodeId > nodeId) {
276 root->leftNode = BSL_AVL_DeleteNode(root->leftNode, nodeId, func);
277 return AVL_RebalanceRight(root);
278 } else {
279 root->rightNode = BSL_AVL_DeleteNode(root->rightNode, nodeId, func);
280 return AVL_RebalanceLeft(root);
281 }
282 }
283
BSL_AVL_DeleteTree(BSL_AvlTree * root,BSL_AVL_DATA_FREE_FUNC func)284 void BSL_AVL_DeleteTree(BSL_AvlTree *root, BSL_AVL_DATA_FREE_FUNC func)
285 {
286 if (root == NULL) {
287 return;
288 }
289
290 BSL_AVL_DeleteTree(root->leftNode, func);
291 BSL_AVL_DeleteTree(root->rightNode, func);
292 AVL_FreeData(root->data, func);
293 BSL_SAL_FREE(root);
294 }
295
296 #endif /* HITLS_BSL_ERR */
297