param_trie.c 15.6 KB
Newer Older
Z
zhong_ning 已提交
1
/*
Z
zhong_ning 已提交
2
 * Copyright (c) 2021 Huawei Device Co., Ltd.
Z
zhong_ning 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Z
zhong_ning 已提交
16
#include "param_trie.h"
Z
zhong_ning 已提交
17 18 19

#include <errno.h>
#include <fcntl.h>
S
sun_fan 已提交
20
#include <string.h>
Z
zhong_ning 已提交
21 22 23 24 25 26
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

S
sun_fan 已提交
27
#include "param_utils.h"
Z
zhong_ning 已提交
28
#include "sys_param.h"
Z
zhong_ning 已提交
29

S
sun_fan 已提交
30
static int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, uint32_t spaceSize, int readOnly)
Z
zhong_ning 已提交
31
{
S
sun_fan 已提交
32
    PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace");
4
411148299@qq.com 已提交
33
    PARAM_CHECK(spaceSize <= PARAM_WORKSPACE_MAX, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace");
Z
zhong_ning 已提交
34
    PARAM_CHECK(workSpace->allocTrieNode != NULL,
S
sun_fan 已提交
35
        return PARAM_CODE_INVALID_PARAM, "Invalid allocTrieNode %s", workSpace->fileName);
Z
zhong_ning 已提交
36
    PARAM_CHECK(workSpace->compareTrieNode != NULL,
S
sun_fan 已提交
37
        return PARAM_CODE_INVALID_PARAM, "Invalid compareTrieNode %s", workSpace->fileName);
X
xionglei6 已提交
38
    PARAM_LOGV("InitWorkSpace %s readOnly %d", workSpace->fileName, readOnly);
Z
zhong_ning 已提交
39 40
    CheckAndCreateDir(workSpace->fileName);

S
sun_fan 已提交
41
    int fd = open(workSpace->fileName, mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
Z
zhong_ning 已提交
42
    PARAM_CHECK(fd >= 0, return PARAM_CODE_INVALID_NAME,
4
411148299@qq.com 已提交
43
        "Open file %s mode %x fail error %d", workSpace->fileName, mode, errno);
Z
zhong_ning 已提交
44 45

    if (!readOnly) {
S
sun_fan 已提交
46
        ftruncate(fd, spaceSize);
Z
zhong_ning 已提交
47 48
    }
    void *areaAddr = (void *)mmap(NULL, spaceSize, prot, MAP_SHARED, fd, 0);
4
411148299@qq.com 已提交
49 50
    PARAM_CHECK(areaAddr != MAP_FAILED && areaAddr != NULL, close(fd);
        return PARAM_CODE_ERROR_MAP_FILE, "Failed to map memory error %d", errno);
Z
zhong_ning 已提交
51 52 53
    close(fd);

    if (!readOnly) {
S
sun_fan 已提交
54 55 56 57 58 59 60
        workSpace->area = (ParamTrieHeader *)areaAddr;
        workSpace->area->trieNodeCount = 0;
        workSpace->area->paramNodeCount = 0;
        workSpace->area->securityNodeCount = 0;
        workSpace->area->dataSize = spaceSize - sizeof(ParamTrieHeader);
        workSpace->area->currOffset = 0;
        uint32_t offset = workSpace->allocTrieNode(workSpace, "#", 1);
Z
zhong_ning 已提交
61 62
        workSpace->area->firstNode = offset;
    } else {
S
sun_fan 已提交
63
        workSpace->area = (ParamTrieHeader *)areaAddr;
Z
zhong_ning 已提交
64
    }
X
xionglei6 已提交
65
    PARAM_LOGV("InitWorkSpace success, readOnly %d currOffset %u firstNode %u dataSize %u",
Z
zhong_ning 已提交
66
        readOnly, workSpace->area->currOffset, workSpace->area->firstNode, workSpace->area->dataSize);
Z
zhong_ning 已提交
67 68 69
    return 0;
}

S
sun_fan 已提交
70
static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen)
Z
zhong_ning 已提交
71
{
S
sun_fan 已提交
72 73
    uint32_t len = keyLen + sizeof(ParamTrieNode) + 1;
    len = PARAM_ALIGN(len);
Z
zhong_ning 已提交
74
    PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0,
Z
zhong_ning 已提交
75
        "Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize);
S
sun_fan 已提交
76 77
    ParamTrieNode *node = (ParamTrieNode*)(workSpace->area->data + workSpace->area->currOffset);
    node->length = keyLen;
Z
zhong_ning 已提交
78
    int ret = memcpy_s(node->key, keyLen, key, keyLen);
S
sun_fan 已提交
79
    PARAM_CHECK(ret == EOK, return 0, "Failed to copy key");
Z
zhong_ning 已提交
80 81 82 83 84 85
    node->key[keyLen] = '\0';
    node->left = 0;
    node->right = 0;
    node->child = 0;
    node->dataIndex = 0;
    node->labelIndex = 0;
S
sun_fan 已提交
86
    uint32_t offset = workSpace->area->currOffset;
Z
zhong_ning 已提交
87
    workSpace->area->currOffset += len;
S
sun_fan 已提交
88
    workSpace->area->trieNodeCount++;
Z
zhong_ning 已提交
89 90 91
    return offset;
}

4
411148299@qq.com 已提交
92
static int CompareParamTrieNode(const ParamTrieNode *node, const char *key, uint32_t keyLen)
Z
zhong_ning 已提交
93
{
S
sun_fan 已提交
94 95 96 97
    if (node->length > keyLen) {
        return -1;
    } else if (node->length < keyLen) {
        return 1;
Z
zhong_ning 已提交
98
    }
S
sun_fan 已提交
99
    return strncmp(node->key, key, keyLen);
Z
zhong_ning 已提交
100 101
}

S
sun_fan 已提交
102
int InitWorkSpace(const char *fileName, WorkSpace *workSpace, int onlyRead)
Z
zhong_ning 已提交
103
{
S
sun_fan 已提交
104 105 106 107 108 109 110
    PARAM_CHECK(fileName != NULL, return PARAM_CODE_INVALID_NAME, "Invalid fileName");
    PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid workSpace");
    if (workSpace->area != NULL) {
        return 0;
    }
    workSpace->compareTrieNode = CompareParamTrieNode;
    workSpace->allocTrieNode = AllocateParamTrieNode;
4
411148299@qq.com 已提交
111 112 113
    int ret = strcpy_s(workSpace->fileName, sizeof(workSpace->fileName), fileName);
    PARAM_CHECK(ret == 0, return ret, "Failed to copy file name %s", fileName);
    int openMode;
S
sun_fan 已提交
114 115 116 117 118 119 120 121 122 123
    int prot = PROT_READ;
    if (onlyRead) {
        openMode = O_RDONLY;
    } else {
        openMode = O_CREAT | O_RDWR | O_TRUNC;
        prot = PROT_READ | PROT_WRITE;
    }
    ret = InitWorkSpace_(workSpace, openMode, prot, PARAM_WORKSPACE_MAX, onlyRead);
    PARAM_CHECK(ret == 0, return ret, "Failed to init workspace  %s", workSpace->fileName);
    return ret;
Z
zhong_ning 已提交
124 125
}

S
sun_fan 已提交
126
void CloseWorkSpace(WorkSpace *workSpace)
Z
zhong_ning 已提交
127
{
S
sun_fan 已提交
128 129 130
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return, "The workspace is null");
    munmap((char *)workSpace->area, workSpace->area->dataSize);
    workSpace->area = NULL;
Z
zhong_ning 已提交
131 132
}

4
411148299@qq.com 已提交
133
static ParamTrieNode *GetTrieRoot(const WorkSpace *workSpace)
Z
zhong_ning 已提交
134
{
4
411148299@qq.com 已提交
135
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return NULL, "The workspace is null");
S
sun_fan 已提交
136
    return (ParamTrieNode *)(workSpace->area->data + workSpace->area->firstNode);
Z
zhong_ning 已提交
137 138
}

S
sun_fan 已提交
139
static void GetNextKey(const char **remainingKey, char **subKey, uint32_t *subKeyLen)
Z
zhong_ning 已提交
140
{
S
sun_fan 已提交
141 142 143 144 145
    *subKey = strchr(*remainingKey, '.');
    if (*subKey != NULL) {
        *subKeyLen = *subKey - *remainingKey;
    } else {
        *subKeyLen = strlen(*remainingKey);
Z
zhong_ning 已提交
146 147 148
    }
}

S
sun_fan 已提交
149
static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, const char *key, uint32_t keyLen)
Z
zhong_ning 已提交
150
{
4
411148299@qq.com 已提交
151
    if (current == NULL || workSpace == NULL || key == NULL) {
S
sun_fan 已提交
152
        return NULL;
Z
zhong_ning 已提交
153
    }
S
sun_fan 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166
    ParamTrieNode *subTrie = NULL;
    int ret = workSpace->compareTrieNode(current, key, keyLen);
    if (ret == 0) {
        return current;
    }
    if (ret < 0) {
        subTrie = GetTrieNode(workSpace, current->left);
        if (subTrie == NULL) {
            uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen);
            PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key);
            SaveIndex(&current->left, offset);
            return GetTrieNode(workSpace, current->left);
        }
Z
zhong_ning 已提交
167
    } else {
S
sun_fan 已提交
168 169 170 171 172 173 174
        subTrie = GetTrieNode(workSpace, current->right);
        if (subTrie == NULL) {
            uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen);
            PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key);
            SaveIndex(&current->right, offset);
            return GetTrieNode(workSpace, current->right);
        }
Z
zhong_ning 已提交
175
    }
S
sun_fan 已提交
176
    return AddToSubTrie(workSpace, subTrie, key, keyLen);
Z
zhong_ning 已提交
177 178
}

S
sun_fan 已提交
179
ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen)
Z
zhong_ning 已提交
180
{
S
sun_fan 已提交
181
    PARAM_CHECK(key != NULL && keyLen > 0, return NULL, "Invalid param ");
4
411148299@qq.com 已提交
182
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid workSpace %s", key);
Z
zhong_ning 已提交
183 184
    PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid param %s", key);
    PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid param %s", key);
Z
zhong_ning 已提交
185
    const char *remainingKey = key;
S
sun_fan 已提交
186
    ParamTrieNode *current = GetTrieRoot(workSpace);
Z
zhong_ning 已提交
187
    PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key);
Z
zhong_ning 已提交
188
    while (1) {
S
sun_fan 已提交
189
        uint32_t subKeyLen = 0;
Z
zhong_ning 已提交
190
        char *subKey = NULL;
Z
zhong_ning 已提交
191
        GetNextKey(&remainingKey, &subKey, &subKeyLen);
Z
zhong_ning 已提交
192 193 194 195
        if (!subKeyLen) {
            return NULL;
        }
        if (current->child != 0) { // 如果child存在,则检查是否匹配
S
sun_fan 已提交
196 197
            ParamTrieNode *next = GetTrieNode(workSpace, current->child);
            current = AddToSubTrie(workSpace, next, remainingKey, subKeyLen);
Z
zhong_ning 已提交
198
        } else {
S
sun_fan 已提交
199 200 201 202
            uint32_t dataOffset = workSpace->allocTrieNode(workSpace, remainingKey, subKeyLen);
            PARAM_CHECK(dataOffset != 0, return NULL, "Failed to allocate key %s", key);
            SaveIndex(&current->child, dataOffset);
            current = (ParamTrieNode *)GetTrieNode(workSpace, current->child);
Z
zhong_ning 已提交
203 204 205 206 207 208 209 210 211 212 213 214
        }
        if (current == NULL) {
            return NULL;
        }
        if (subKey == NULL || strcmp(subKey, ".") == 0) {
            break;
        }
        remainingKey = subKey + 1;
    }
    return current;
}

4
411148299@qq.com 已提交
215
static ParamTrieNode *FindSubTrie(const WorkSpace *workSpace,
S
sun_fan 已提交
216
    ParamTrieNode *current, const char *key, uint32_t keyLen, uint32_t *matchLabel)
Z
zhong_ning 已提交
217
{
S
sun_fan 已提交
218 219
    if (current == NULL) {
        return NULL;
Z
zhong_ning 已提交
220 221
    }

S
sun_fan 已提交
222 223 224 225 226
    ParamTrieNode *subTrie = NULL;
    int ret = workSpace->compareTrieNode(current, key, keyLen);
    if (ret == 0) {
        if (matchLabel != NULL && current->labelIndex != 0) { // 有效前缀
            *matchLabel = current->labelIndex;
Z
zhong_ning 已提交
227
        }
S
sun_fan 已提交
228 229 230 231 232 233
        return current;
    }
    if (ret < 0) {
        subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->left);
        if (subTrie == NULL) {
            return NULL;
Z
zhong_ning 已提交
234
        }
S
sun_fan 已提交
235 236 237 238
    } else {
        subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->right);
        if (subTrie == NULL) {
            return NULL;
Z
zhong_ning 已提交
239 240
        }
    }
S
sun_fan 已提交
241
    return FindSubTrie(workSpace, subTrie, key, keyLen, matchLabel);
Z
zhong_ning 已提交
242 243
}

4
411148299@qq.com 已提交
244
ParamTrieNode *FindTrieNode(const WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel)
Z
zhong_ning 已提交
245
{
S
sun_fan 已提交
246
    PARAM_CHECK(key != NULL && keyLen > 0, return NULL, "Invalid key ");
4
411148299@qq.com 已提交
247
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid workSpace %s", key);
S
sun_fan 已提交
248 249
    PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid alloc function %s", key);
    PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid compare function %s", key);
Z
zhong_ning 已提交
250
    const char *remainingKey = key;
S
sun_fan 已提交
251
    ParamTrieNode *current = GetTrieRoot(workSpace);
Z
zhong_ning 已提交
252
    PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key);
S
sun_fan 已提交
253 254 255 256 257 258 259
    if (matchLabel != NULL) {
        *matchLabel = current->labelIndex;
    }
    int ret = workSpace->compareTrieNode(current, key, keyLen);
    if (ret == 0) {
        return current;
    }
Z
zhong_ning 已提交
260
    while (1) {
S
sun_fan 已提交
261
        uint32_t subKeyLen = 0;
Z
zhong_ning 已提交
262
        char *subKey = NULL;
Z
zhong_ning 已提交
263
        GetNextKey(&remainingKey, &subKey, &subKeyLen);
Z
zhong_ning 已提交
264
        if (!subKeyLen) {
S
sun_fan 已提交
265
            return NULL;
Z
zhong_ning 已提交
266
        }
S
sun_fan 已提交
267 268 269
        if (current->child != 0) {
            ParamTrieNode *next = GetTrieNode(workSpace, current->child);
            current = FindSubTrie(workSpace, next, remainingKey, subKeyLen, matchLabel);
Z
zhong_ning 已提交
270
        } else {
S
sun_fan 已提交
271
            current = FindSubTrie(workSpace, current, remainingKey, subKeyLen, matchLabel);
Z
zhong_ning 已提交
272 273
        }
        if (current == NULL) {
S
sun_fan 已提交
274 275 276
            return NULL;
        } else if (matchLabel != NULL && current->labelIndex != 0) {
            *matchLabel = current->labelIndex;
Z
zhong_ning 已提交
277 278 279 280 281 282
        }
        if (subKey == NULL || strcmp(subKey, ".") == 0) {
            break;
        }
        remainingKey = subKey + 1;
    }
S
sun_fan 已提交
283
    return current;
Z
zhong_ning 已提交
284 285
}

4
411148299@qq.com 已提交
286 287
static int TraversalSubTrieNode(const WorkSpace *workSpace,
    const ParamTrieNode *current, TraversalTrieNodePtr walkFunc, void *cookie)
Z
zhong_ning 已提交
288
{
S
sun_fan 已提交
289 290
    if (current == NULL) {
        return 0;
Z
zhong_ning 已提交
291
    }
S
sun_fan 已提交
292 293 294 295 296
    walkFunc(workSpace, (ParamTrieNode *)current, cookie);
    TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->child), walkFunc, cookie);
    TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->left), walkFunc, cookie);
    TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->right), walkFunc, cookie);
    return 0;
Z
zhong_ning 已提交
297 298
}

4
411148299@qq.com 已提交
299 300
int TraversalTrieNode(const WorkSpace *workSpace,
    const ParamTrieNode *root, TraversalTrieNodePtr walkFunc, void *cookie)
Z
zhong_ning 已提交
301
{
Z
zhong_ning 已提交
302
    PARAM_CHECK(walkFunc != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param");
4
411148299@qq.com 已提交
303 304
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid workSpace");
    ParamTrieNode *current = (ParamTrieNode *)root;
S
sun_fan 已提交
305 306 307
    if (root == NULL) {
        current = GetTrieRoot(workSpace);
    }
Z
zhong_ning 已提交
308 309 310
    if (current == NULL) {
        return 0;
    }
S
sun_fan 已提交
311 312 313 314 315
    walkFunc(workSpace, (ParamTrieNode *)current, cookie);
    TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->child), walkFunc, cookie);
    if (root == NULL) {
        TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->left), walkFunc, cookie);
        TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->right), walkFunc, cookie);
Z
zhong_ning 已提交
316 317 318 319
    }
    return 0;
}

S
sun_fan 已提交
320
uint32_t AddParamSecruityNode(WorkSpace *workSpace, const ParamAuditData *auditData)
Z
zhong_ning 已提交
321
{
4
411148299@qq.com 已提交
322
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid param");
S
sun_fan 已提交
323
    PARAM_CHECK(auditData != NULL && auditData->name != NULL, return 0, "Invalid auditData");
4
411148299@qq.com 已提交
324
    const uint32_t labelLen = (auditData->label == NULL) ? 0 : strlen(auditData->label);
S
sun_fan 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    uint32_t realLen = sizeof(ParamSecruityNode) + PARAM_ALIGN(labelLen + 1);
    PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0,
        "Failed to allocate currOffset %u, dataSize %u datalen %u",
        workSpace->area->currOffset, workSpace->area->dataSize, realLen);

    ParamSecruityNode *node = (ParamSecruityNode *)(workSpace->area->data + workSpace->area->currOffset);
    node->uid = auditData->dacData.uid;
    node->gid = auditData->dacData.gid;
    node->mode = auditData->dacData.mode;
    node->length = 0;
    if (labelLen != 0) {
        int ret = memcpy_s(node->data, labelLen, auditData->label, labelLen);
        PARAM_CHECK(ret == EOK, return 0, "Failed to copy key");
        node->data[labelLen] = '\0';
        node->length = labelLen;
Z
zhong_ning 已提交
340
    }
S
sun_fan 已提交
341 342 343 344
    uint32_t offset = workSpace->area->currOffset;
    workSpace->area->currOffset += realLen;
    workSpace->area->securityNodeCount++;
    return offset;
Z
zhong_ning 已提交
345 346
}

S
sun_fan 已提交
347
uint32_t AddParamNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, const char *value, uint32_t valueLen)
Z
zhong_ning 已提交
348
{
4
411148299@qq.com 已提交
349
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid param");
Z
zhong_ning 已提交
350
    PARAM_CHECK(key != NULL && value != NULL, return 0, "Invalid param");
S
sun_fan 已提交
351 352

    uint32_t realLen = sizeof(ParamNode) + 1 + 1;
Z
zhong_ning 已提交
353 354
    if (valueLen > PARAM_VALUE_LEN_MAX) {
        realLen += keyLen + valueLen;
Z
zhong_ning 已提交
355
    } else {
Z
zhong_ning 已提交
356
        realLen += keyLen + PARAM_VALUE_LEN_MAX;
Z
zhong_ning 已提交
357
    }
S
sun_fan 已提交
358
    realLen = PARAM_ALIGN(realLen);
Z
zhong_ning 已提交
359
    PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0,
S
sun_fan 已提交
360 361 362 363 364
        "Failed to allocate currOffset %u, dataSize %u datalen %u",
        workSpace->area->currOffset, workSpace->area->dataSize, realLen);

    ParamNode *node = (ParamNode *)(workSpace->area->data + workSpace->area->currOffset);
    atomic_init(&node->commitId, 0);
Z
zhong_ning 已提交
365

S
sun_fan 已提交
366 367 368 369 370
    node->keyLength = keyLen;
    node->valueLength = valueLen;
    int ret = sprintf_s(node->data, realLen - 1, "%s=%s", key, value);
    PARAM_CHECK(ret > EOK, return 0, "Failed to sprint key and value");
    uint32_t offset = workSpace->area->currOffset;
Z
zhong_ning 已提交
371
    workSpace->area->currOffset += realLen;
S
sun_fan 已提交
372
    workSpace->area->paramNodeCount++;
Z
zhong_ning 已提交
373 374 375
    return offset;
}

4
411148299@qq.com 已提交
376
ParamTrieNode *GetTrieNode(const WorkSpace *workSpace, uint32_t offset)
Z
zhong_ning 已提交
377
{
4
411148299@qq.com 已提交
378
    PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return NULL, "Invalid param");
S
sun_fan 已提交
379 380
    if (offset == 0 || offset > workSpace->area->dataSize) {
        return NULL;
Z
zhong_ning 已提交
381
    }
S
sun_fan 已提交
382
    return (ParamTrieNode *)(workSpace->area->data + offset);
Z
zhong_ning 已提交
383 384
}

S
sun_fan 已提交
385
void SaveIndex(uint32_t *index, uint32_t offset)
Z
zhong_ning 已提交
386
{
4
411148299@qq.com 已提交
387
    PARAM_CHECK(index != NULL, return, "Invalid index");
S
sun_fan 已提交
388
    *index = offset;
Z
zhong_ning 已提交
389
}