• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "selinux_map.h"
16 #include <stdlib.h>
17 #include <string.h>
18 
19 static const int32_t MAX_BUCKET = 32;
20 
GenerateHashCode(const char * key,uint32_t len)21 static int GenerateHashCode(const char *key, uint32_t len)
22 {
23     int code = 0;
24     for (size_t i = 0; i < len; i++) {
25         code += key[i] - 'A';
26     }
27     return code;
28 }
29 
GroupNodeNodeCompare(const HashNode * node1,const HashNode * node2)30 static int GroupNodeNodeCompare(const HashNode *node1, const HashNode *node2)
31 {
32     ParamHashNode *groupNode1 = HASHMAP_ENTRY(node1, ParamHashNode, hashNode);
33     ParamHashNode *groupNode2 = HASHMAP_ENTRY(node2, ParamHashNode, hashNode);
34     return strcmp(groupNode1->name, groupNode2->name);
35 }
36 
GroupNodeKeyCompare(const HashNode * node1,const char * key)37 static int GroupNodeKeyCompare(const HashNode *node1, const char *key)
38 {
39     ParamHashNode *groupNode1 = HASHMAP_ENTRY(node1, ParamHashNode, hashNode);
40     return strncmp(groupNode1->name, key, groupNode1->nameLen);
41 }
42 
GroupNodeGetNodeHashCode(const HashNode * node)43 static int GroupNodeGetNodeHashCode(const HashNode *node)
44 {
45     ParamHashNode *groupNode = HASHMAP_ENTRY(node, ParamHashNode, hashNode);
46     return GenerateHashCode(groupNode->name, groupNode->nameLen);
47 }
48 
GroupNodeFree(const HashNode * node)49 static void GroupNodeFree(const HashNode *node)
50 {
51     ParamHashNode *groupNode = HASHMAP_ENTRY(node, ParamHashNode, hashNode);
52     free(groupNode);
53 }
54 
HashMapCreate(HashTab ** handle)55 int32_t HashMapCreate(HashTab **handle)
56 {
57     if (handle == NULL) {
58         return -1;
59     }
60 
61     HashTab *tab = (HashTab *)calloc(1, sizeof(HashTab) + sizeof(HashNode *) * MAX_BUCKET);
62     if (tab == NULL) {
63         return -1;
64     }
65     *handle = tab;
66     return 0;
67 }
68 
GetHashNodeByNode(HashNode * root,const HashNode * nodeKey)69 static HashNode *GetHashNodeByNode(HashNode *root, const HashNode *nodeKey)
70 {
71     while (root != NULL) {
72         int ret = GroupNodeNodeCompare(root, nodeKey);
73         if (ret == 0) {
74             return root;
75         }
76         root = root->next;
77     }
78     return NULL;
79 }
80 
GetHashNodeByKey(HashNode * root,const char * key)81 static HashNode *GetHashNodeByKey(HashNode *root, const char *key)
82 {
83     while (root != NULL) {
84         int ret = GroupNodeKeyCompare(root, key);
85         if (ret == 0) {
86             return root;
87         }
88         root = root->next;
89     }
90     return NULL;
91 }
92 
HashMapAdd(HashTab * handle,HashNode * node)93 int32_t HashMapAdd(HashTab *handle, HashNode *node)
94 {
95     if (handle == NULL || !(node != NULL && node->next == NULL)) {
96         return -1;
97     }
98     int hashCode = GroupNodeGetNodeHashCode(node);
99     hashCode = (hashCode < 0) ? -hashCode : hashCode;
100     hashCode = hashCode % MAX_BUCKET;
101 
102     // check key exist
103     HashNode *tmp = GetHashNodeByNode(handle->buckets[hashCode], node);
104     if (tmp != NULL) {
105         return -1;
106     }
107     node->next = handle->buckets[hashCode];
108     handle->buckets[hashCode] = node;
109     return 0;
110 }
111 
HashMapGet(HashTab * handle,const char * key,uint32_t len)112 HashNode *HashMapGet(HashTab *handle, const char *key, uint32_t len)
113 {
114     int hashCode = GenerateHashCode(key, len);
115     hashCode = (hashCode < 0) ? -hashCode : hashCode;
116     hashCode = hashCode % MAX_BUCKET;
117 
118     return GetHashNodeByKey(handle->buckets[hashCode], key);
119 }
120 
HashListFree(HashNode * root)121 static void HashListFree(HashNode *root)
122 {
123     if (root == NULL) {
124         return;
125     }
126     HashNode *node = root;
127     while (node != NULL) {
128         HashNode *next = node->next;
129         GroupNodeFree(node);
130         node = next;
131     }
132 }
133 
HashMapDestroy(HashTab * handle)134 void HashMapDestroy(HashTab *handle)
135 {
136     if (handle == NULL) {
137         return;
138     }
139     for (int i = 0; i < MAX_BUCKET; i++) {
140         HashListFree(handle->buckets[i]);
141     }
142     free(handle);
143 }
144