• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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