1 /*
2 * Copyright (c) 2023 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 "projection_tree.h"
16 
17 namespace DocumentDB {
18 constexpr int JSON_DEEP_MAX = 4;
19 
ParseSinglePathToTree(ProjectionNode * node,std::vector<std::string> & singlePath)20 static int ParseSinglePathToTree(ProjectionNode *node, std::vector<std::string> &singlePath)
21 {
22     for (size_t j = 0; j < singlePath.size(); j++) {
23         if (node->sonNode[singlePath[j]] != nullptr) {
24             node = node->sonNode[singlePath[j]];
25             if (j < singlePath.size() - 1 && node->isDeepest) {
26                 return -E_INVALID_ARGS;
27             }
28             if (j == singlePath.size() - 1 && !node->isDeepest) {
29                 return -E_INVALID_ARGS;
30             }
31         } else {
32             auto tempNode = new (std::nothrow) ProjectionNode;
33             if (tempNode == nullptr) {
34                 GLOGE("Memory allocation failed!");
35                 return -E_FAILED_MEMORY_ALLOCATE;
36             }
37             tempNode->Deep = node->Deep + 1;
38             if (tempNode->Deep > JSON_DEEP_MAX) {
39                 delete tempNode;
40                 return -E_INVALID_ARGS;
41             }
42             node->isDeepest = false;
43             node->sonNode[singlePath[j]] = tempNode;
44             node = node->sonNode[singlePath[j]];
45         }
46     }
47     return E_OK;
48 }
49 
ParseTree(std::vector<std::vector<std::string>> & path)50 int ProjectionTree::ParseTree(std::vector<std::vector<std::string>> &path)
51 {
52     ProjectionNode *node = &node_;
53     if (node == nullptr) {
54         return E_OK;
55     }
56     for (auto singlePath : path) {
57         node = &node_;
58         int errCode = ParseSinglePathToTree(node, singlePath);
59         if (errCode != E_OK) {
60             return errCode;
61         }
62     }
63     return E_OK;
64 }
65 
SearchTree(std::vector<std::string> & singlePath,size_t & index)66 bool ProjectionTree::SearchTree(std::vector<std::string> &singlePath, size_t &index)
67 {
68     ProjectionNode *node = &node_;
69     for (size_t i = 0; i < singlePath.size(); i++) {
70         if (node->sonNode[singlePath[i]] != nullptr) {
71             node = node->sonNode[singlePath[i]];
72             if (node->isDeepest) {
73                 index = i + 1;
74             }
75         } else {
76             return false;
77         }
78     }
79     return true;
80 }
81 
DeleteProjectionNode()82 int ProjectionNode::DeleteProjectionNode()
83 {
84     for (auto item : sonNode) {
85         if (item.second != nullptr) {
86             delete item.second;
87             item.second = nullptr;
88         }
89     }
90     return E_OK;
91 }
92 } // namespace DocumentDB