/root/doris/be/src/util/path_trie.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <map> |
21 | | #include <memory> |
22 | | #include <string> |
23 | | #include <vector> |
24 | | |
25 | | namespace doris { |
26 | | |
27 | | // This tree is usd for manage restful api path. |
28 | | template <class T> |
29 | | class PathTrie { |
30 | | public: |
31 | 19 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} _ZN5doris8PathTrieIiEC2Ev Line | Count | Source | 31 | 7 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} |
_ZN5doris8PathTrieIPNS_11HttpHandlerEEC2Ev Line | Count | Source | 31 | 12 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} |
|
32 | | |
33 | 19 | ~PathTrie() { |
34 | 19 | if (_root_value != nullptr) { |
35 | 2 | _allocator.destroy(_root_value); |
36 | 2 | _allocator.deallocate(_root_value, 1); |
37 | 2 | } |
38 | 19 | } _ZN5doris8PathTrieIiED2Ev Line | Count | Source | 33 | 7 | ~PathTrie() { | 34 | 7 | if (_root_value != nullptr) { | 35 | 1 | _allocator.destroy(_root_value); | 36 | 1 | _allocator.deallocate(_root_value, 1); | 37 | 1 | } | 38 | 7 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEED2Ev Line | Count | Source | 33 | 12 | ~PathTrie() { | 34 | 12 | if (_root_value != nullptr) { | 35 | 1 | _allocator.destroy(_root_value); | 36 | 1 | _allocator.deallocate(_root_value, 1); | 37 | 1 | } | 38 | 12 | } |
|
39 | | |
40 | | class Allocator { |
41 | | public: |
42 | | using value_type = T; |
43 | | |
44 | 67 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } _ZN5doris8PathTrieIiE9Allocator8allocateEm Line | Count | Source | 44 | 11 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator8allocateEm Line | Count | Source | 44 | 56 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } |
|
45 | | |
46 | | template <typename... Args> |
47 | 125 | void construct(T* p, Args&&... args) { |
48 | 125 | new (p) T(std::forward<Args>(args)...); |
49 | 125 | } _ZN5doris8PathTrieIiE9Allocator9constructIJRKiEEEvPiDpOT_ Line | Count | Source | 47 | 11 | void construct(T* p, Args&&... args) { | 48 | 11 | new (p) T(std::forward<Args>(args)...); | 49 | 11 | } |
_ZN5doris8PathTrieIiE9Allocator9constructIJRiEEEvPiDpOT_ Line | Count | Source | 47 | 12 | void construct(T* p, Args&&... args) { | 48 | 12 | new (p) T(std::forward<Args>(args)...); | 49 | 12 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator9constructIJRKS2_EEEvPS2_DpOT_ Line | Count | Source | 47 | 56 | void construct(T* p, Args&&... args) { | 48 | 56 | new (p) T(std::forward<Args>(args)...); | 49 | 56 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator9constructIJRS2_EEEvPS2_DpOT_ Line | Count | Source | 47 | 46 | void construct(T* p, Args&&... args) { | 48 | 46 | new (p) T(std::forward<Args>(args)...); | 49 | 46 | } |
|
50 | | |
51 | 67 | void destroy(T* p) { p->~T(); } _ZN5doris8PathTrieIiE9Allocator7destroyEPi Line | Count | Source | 51 | 11 | void destroy(T* p) { p->~T(); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator7destroyEPS2_ Line | Count | Source | 51 | 56 | void destroy(T* p) { p->~T(); } |
|
52 | | |
53 | 67 | void deallocate(T* p, size_t n) { ::operator delete(p); } _ZN5doris8PathTrieIiE9Allocator10deallocateEPim Line | Count | Source | 53 | 11 | void deallocate(T* p, size_t n) { ::operator delete(p); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator10deallocateEPS2_m Line | Count | Source | 53 | 56 | void deallocate(T* p, size_t n) { ::operator delete(p); } |
|
54 | | }; |
55 | | |
56 | | class TrieNode { |
57 | | public: |
58 | | TrieNode(const std::string& key, const std::string& wildcard) |
59 | 52 | : _value(nullptr), _wildcard(wildcard) { |
60 | 52 | if (is_named_wildcard(key)) { |
61 | 7 | _named_wildcard = extract_template(key); |
62 | 7 | } |
63 | 52 | } _ZN5doris8PathTrieIiE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ Line | Count | Source | 59 | 15 | : _value(nullptr), _wildcard(wildcard) { | 60 | 15 | if (is_named_wildcard(key)) { | 61 | 2 | _named_wildcard = extract_template(key); | 62 | 2 | } | 63 | 15 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_ Line | Count | Source | 59 | 37 | : _value(nullptr), _wildcard(wildcard) { | 60 | 37 | if (is_named_wildcard(key)) { | 61 | 5 | _named_wildcard = extract_template(key); | 62 | 5 | } | 63 | 37 | } |
|
64 | | |
65 | | TrieNode(const std::string& key, const T& value, const std::string& wildcard) |
66 | 64 | : _value(nullptr), _wildcard(wildcard) { |
67 | 64 | _value = _allocator.allocate(1); |
68 | 64 | _allocator.construct(_value, value); |
69 | 64 | if (is_named_wildcard(key)) { |
70 | 11 | _named_wildcard = extract_template(key); |
71 | 11 | } |
72 | 64 | } _ZN5doris8PathTrieIiE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiSA_ Line | Count | Source | 66 | 9 | : _value(nullptr), _wildcard(wildcard) { | 67 | 9 | _value = _allocator.allocate(1); | 68 | 9 | _allocator.construct(_value, value); | 69 | 9 | if (is_named_wildcard(key)) { | 70 | 2 | _named_wildcard = extract_template(key); | 71 | 2 | } | 72 | 9 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS2_SC_ Line | Count | Source | 66 | 55 | : _value(nullptr), _wildcard(wildcard) { | 67 | 55 | _value = _allocator.allocate(1); | 68 | 55 | _allocator.construct(_value, value); | 69 | 55 | if (is_named_wildcard(key)) { | 70 | 9 | _named_wildcard = extract_template(key); | 71 | 9 | } | 72 | 55 | } |
|
73 | | |
74 | 116 | ~TrieNode() { |
75 | 116 | for (auto& iter : _children) { |
76 | 97 | delete iter.second; |
77 | 97 | iter.second = nullptr; |
78 | 97 | } |
79 | 116 | if (_value != nullptr) { |
80 | 65 | _allocator.destroy(_value); |
81 | 65 | _allocator.deallocate(_value, 1); |
82 | 65 | } |
83 | 116 | } _ZN5doris8PathTrieIiE8TrieNodeD2Ev Line | Count | Source | 74 | 24 | ~TrieNode() { | 75 | 24 | for (auto& iter : _children) { | 76 | 17 | delete iter.second; | 77 | 17 | iter.second = nullptr; | 78 | 17 | } | 79 | 24 | if (_value != nullptr) { | 80 | 10 | _allocator.destroy(_value); | 81 | 10 | _allocator.deallocate(_value, 1); | 82 | 10 | } | 83 | 24 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeD2Ev Line | Count | Source | 74 | 92 | ~TrieNode() { | 75 | 92 | for (auto& iter : _children) { | 76 | 80 | delete iter.second; | 77 | 80 | iter.second = nullptr; | 78 | 80 | } | 79 | 92 | if (_value != nullptr) { | 80 | 55 | _allocator.destroy(_value); | 81 | 55 | _allocator.deallocate(_value, 1); | 82 | 55 | } | 83 | 92 | } |
|
84 | | |
85 | | // Return true if insert success. |
86 | 150 | bool insert(const std::vector<std::string> path, int index, const T& value) { |
87 | 150 | if (index >= path.size()) { |
88 | 0 | return false; |
89 | 0 | } |
90 | 150 | const std::string& token = path[index]; |
91 | 150 | std::string key = token; |
92 | | |
93 | 150 | if (is_named_wildcard(token)) { |
94 | 25 | key = _wildcard; |
95 | 25 | } |
96 | | |
97 | 150 | TrieNode* node = get_child(key); |
98 | | |
99 | 150 | if (node == nullptr) { |
100 | | // no exist child for this key |
101 | 97 | if (index == path.size() - 1) { |
102 | 64 | node = new TrieNode(token, value, _wildcard); |
103 | 64 | _children.insert(std::make_pair(key, node)); |
104 | 64 | return true; |
105 | 64 | } else { |
106 | 33 | node = new TrieNode(token, _wildcard); |
107 | 33 | _children.insert(std::make_pair(key, node)); |
108 | 33 | } |
109 | 97 | } else { |
110 | | // If this is a template, set this to the node |
111 | 53 | if (is_named_wildcard(token)) { |
112 | 7 | std::string temp = extract_template(token); |
113 | 7 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { |
114 | 6 | node->_named_wildcard = temp; |
115 | 6 | } else { |
116 | | // Duplicated |
117 | 1 | return false; |
118 | 1 | } |
119 | 7 | } |
120 | 52 | if (index == path.size() - 1) { |
121 | 2 | if (node->_value == nullptr) { |
122 | 1 | node->_value = _allocator.allocate(1); |
123 | 1 | _allocator.construct(node->_value, value); |
124 | 1 | return true; |
125 | 1 | } |
126 | | // Already register by other path |
127 | 1 | return false; |
128 | 2 | } |
129 | 52 | } |
130 | 83 | return node->insert(path, index + 1, value); |
131 | 150 | } _ZN5doris8PathTrieIiE8TrieNode6insertESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEiRKi Line | Count | Source | 86 | 30 | bool insert(const std::vector<std::string> path, int index, const T& value) { | 87 | 30 | if (index >= path.size()) { | 88 | 0 | return false; | 89 | 0 | } | 90 | 30 | const std::string& token = path[index]; | 91 | 30 | std::string key = token; | 92 | | | 93 | 30 | if (is_named_wildcard(token)) { | 94 | 6 | key = _wildcard; | 95 | 6 | } | 96 | | | 97 | 30 | TrieNode* node = get_child(key); | 98 | | | 99 | 30 | if (node == nullptr) { | 100 | | // no exist child for this key | 101 | 17 | if (index == path.size() - 1) { | 102 | 9 | node = new TrieNode(token, value, _wildcard); | 103 | 9 | _children.insert(std::make_pair(key, node)); | 104 | 9 | return true; | 105 | 9 | } else { | 106 | 8 | node = new TrieNode(token, _wildcard); | 107 | 8 | _children.insert(std::make_pair(key, node)); | 108 | 8 | } | 109 | 17 | } else { | 110 | | // If this is a template, set this to the node | 111 | 13 | if (is_named_wildcard(token)) { | 112 | 2 | std::string temp = extract_template(token); | 113 | 2 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { | 114 | 1 | node->_named_wildcard = temp; | 115 | 1 | } else { | 116 | | // Duplicated | 117 | 1 | return false; | 118 | 1 | } | 119 | 2 | } | 120 | 12 | if (index == path.size() - 1) { | 121 | 2 | if (node->_value == nullptr) { | 122 | 1 | node->_value = _allocator.allocate(1); | 123 | 1 | _allocator.construct(node->_value, value); | 124 | 1 | return true; | 125 | 1 | } | 126 | | // Already register by other path | 127 | 1 | return false; | 128 | 2 | } | 129 | 12 | } | 130 | 18 | return node->insert(path, index + 1, value); | 131 | 30 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode6insertESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EEiRKS2_ Line | Count | Source | 86 | 120 | bool insert(const std::vector<std::string> path, int index, const T& value) { | 87 | 120 | if (index >= path.size()) { | 88 | 0 | return false; | 89 | 0 | } | 90 | 120 | const std::string& token = path[index]; | 91 | 120 | std::string key = token; | 92 | | | 93 | 120 | if (is_named_wildcard(token)) { | 94 | 19 | key = _wildcard; | 95 | 19 | } | 96 | | | 97 | 120 | TrieNode* node = get_child(key); | 98 | | | 99 | 120 | if (node == nullptr) { | 100 | | // no exist child for this key | 101 | 80 | if (index == path.size() - 1) { | 102 | 55 | node = new TrieNode(token, value, _wildcard); | 103 | 55 | _children.insert(std::make_pair(key, node)); | 104 | 55 | return true; | 105 | 55 | } else { | 106 | 25 | node = new TrieNode(token, _wildcard); | 107 | 25 | _children.insert(std::make_pair(key, node)); | 108 | 25 | } | 109 | 80 | } else { | 110 | | // If this is a template, set this to the node | 111 | 40 | if (is_named_wildcard(token)) { | 112 | 5 | std::string temp = extract_template(token); | 113 | 5 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { | 114 | 5 | node->_named_wildcard = temp; | 115 | 5 | } else { | 116 | | // Duplicated | 117 | 0 | return false; | 118 | 0 | } | 119 | 5 | } | 120 | 40 | if (index == path.size() - 1) { | 121 | 0 | if (node->_value == nullptr) { | 122 | 0 | node->_value = _allocator.allocate(1); | 123 | 0 | _allocator.construct(node->_value, value); | 124 | 0 | return true; | 125 | 0 | } | 126 | | // Already register by other path | 127 | 0 | return false; | 128 | 0 | } | 129 | 40 | } | 130 | 65 | return node->insert(path, index + 1, value); | 131 | 120 | } |
|
132 | | |
133 | | bool retrieve(const std::vector<std::string> path, int index, T* value, |
134 | 127 | std::map<std::string, std::string>* params) { |
135 | | // check max index |
136 | 127 | if (index >= path.size()) { |
137 | 0 | return false; |
138 | 0 | } |
139 | 127 | bool use_wildcard = false; |
140 | 127 | const std::string& token = path[index]; |
141 | 127 | TrieNode* node = get_child(token); |
142 | 127 | if (node == nullptr) { |
143 | 23 | node = get_child(_wildcard); |
144 | 23 | if (node == nullptr) { |
145 | 3 | return false; |
146 | 3 | } |
147 | 20 | use_wildcard = true; |
148 | 104 | } else { |
149 | | // If we the last one, but we have no value, check wildcard |
150 | 104 | if (index == path.size() - 1 && node->_value == nullptr && |
151 | 104 | get_child(_wildcard) != nullptr) { |
152 | 0 | node = get_child(_wildcard); |
153 | 0 | use_wildcard = true; |
154 | 104 | } else { |
155 | 104 | use_wildcard = (token.compare(_wildcard) == 0); |
156 | 104 | } |
157 | 104 | } |
158 | | |
159 | 124 | put(params, node, token); |
160 | | |
161 | 124 | if (index == path.size() - 1) { |
162 | 56 | if (node->_value == nullptr) { |
163 | 0 | return false; |
164 | 0 | } |
165 | 56 | _allocator.construct(value, *node->_value); |
166 | 56 | return true; |
167 | 56 | } |
168 | | |
169 | | // find exact |
170 | 68 | if (node->retrieve(path, index + 1, value, params)) { |
171 | 66 | return true; |
172 | 66 | } |
173 | | |
174 | | // backtrace to test if wildcard can match |
175 | 2 | if (!use_wildcard) { |
176 | 2 | node = get_child(_wildcard); |
177 | 2 | if (node != nullptr) { |
178 | 0 | put(params, node, token); |
179 | 0 | return node->retrieve(path, index + 1, value, params); |
180 | 0 | } |
181 | 2 | } |
182 | 2 | return false; |
183 | 2 | } _ZN5doris8PathTrieIiE8TrieNode8retrieveESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEiPiPSt3mapIS9_S9_St4lessIS9_ESaISt4pairIKS9_S9_EEE Line | Count | Source | 134 | 29 | std::map<std::string, std::string>* params) { | 135 | | // check max index | 136 | 29 | if (index >= path.size()) { | 137 | 0 | return false; | 138 | 0 | } | 139 | 29 | bool use_wildcard = false; | 140 | 29 | const std::string& token = path[index]; | 141 | 29 | TrieNode* node = get_child(token); | 142 | 29 | if (node == nullptr) { | 143 | 9 | node = get_child(_wildcard); | 144 | 9 | if (node == nullptr) { | 145 | 2 | return false; | 146 | 2 | } | 147 | 7 | use_wildcard = true; | 148 | 20 | } else { | 149 | | // If we the last one, but we have no value, check wildcard | 150 | 20 | if (index == path.size() - 1 && node->_value == nullptr && | 151 | 20 | get_child(_wildcard) != nullptr) { | 152 | 0 | node = get_child(_wildcard); | 153 | 0 | use_wildcard = true; | 154 | 20 | } else { | 155 | 20 | use_wildcard = (token.compare(_wildcard) == 0); | 156 | 20 | } | 157 | 20 | } | 158 | | | 159 | 27 | put(params, node, token); | 160 | | | 161 | 27 | if (index == path.size() - 1) { | 162 | 10 | if (node->_value == nullptr) { | 163 | 0 | return false; | 164 | 0 | } | 165 | 10 | _allocator.construct(value, *node->_value); | 166 | 10 | return true; | 167 | 10 | } | 168 | | | 169 | | // find exact | 170 | 17 | if (node->retrieve(path, index + 1, value, params)) { | 171 | 15 | return true; | 172 | 15 | } | 173 | | | 174 | | // backtrace to test if wildcard can match | 175 | 2 | if (!use_wildcard) { | 176 | 2 | node = get_child(_wildcard); | 177 | 2 | if (node != nullptr) { | 178 | 0 | put(params, node, token); | 179 | 0 | return node->retrieve(path, index + 1, value, params); | 180 | 0 | } | 181 | 2 | } | 182 | 2 | return false; | 183 | 2 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode8retrieveESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EEiPS2_PSt3mapISB_SB_St4lessISB_ESaISt4pairIKSB_SB_EEE Line | Count | Source | 134 | 98 | std::map<std::string, std::string>* params) { | 135 | | // check max index | 136 | 98 | if (index >= path.size()) { | 137 | 0 | return false; | 138 | 0 | } | 139 | 98 | bool use_wildcard = false; | 140 | 98 | const std::string& token = path[index]; | 141 | 98 | TrieNode* node = get_child(token); | 142 | 98 | if (node == nullptr) { | 143 | 14 | node = get_child(_wildcard); | 144 | 14 | if (node == nullptr) { | 145 | 1 | return false; | 146 | 1 | } | 147 | 13 | use_wildcard = true; | 148 | 84 | } else { | 149 | | // If we the last one, but we have no value, check wildcard | 150 | 84 | if (index == path.size() - 1 && node->_value == nullptr && | 151 | 84 | get_child(_wildcard) != nullptr) { | 152 | 0 | node = get_child(_wildcard); | 153 | 0 | use_wildcard = true; | 154 | 84 | } else { | 155 | 84 | use_wildcard = (token.compare(_wildcard) == 0); | 156 | 84 | } | 157 | 84 | } | 158 | | | 159 | 97 | put(params, node, token); | 160 | | | 161 | 97 | if (index == path.size() - 1) { | 162 | 46 | if (node->_value == nullptr) { | 163 | 0 | return false; | 164 | 0 | } | 165 | 46 | _allocator.construct(value, *node->_value); | 166 | 46 | return true; | 167 | 46 | } | 168 | | | 169 | | // find exact | 170 | 51 | if (node->retrieve(path, index + 1, value, params)) { | 171 | 51 | return true; | 172 | 51 | } | 173 | | | 174 | | // backtrace to test if wildcard can match | 175 | 0 | if (!use_wildcard) { | 176 | 0 | node = get_child(_wildcard); | 177 | 0 | if (node != nullptr) { | 178 | 0 | put(params, node, token); | 179 | 0 | return node->retrieve(path, index + 1, value, params); | 180 | 0 | } | 181 | 0 | } | 182 | 0 | return false; | 183 | 0 | } |
|
184 | | |
185 | | private: |
186 | 319 | bool is_named_wildcard(const std::string& key) { |
187 | 319 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { |
188 | 50 | return true; |
189 | 50 | } |
190 | 269 | return false; |
191 | 319 | } _ZN5doris8PathTrieIiE8TrieNode17is_named_wildcardERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 186 | 67 | bool is_named_wildcard(const std::string& key) { | 187 | 67 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { | 188 | 12 | return true; | 189 | 12 | } | 190 | 55 | return false; | 191 | 67 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode17is_named_wildcardERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 186 | 252 | bool is_named_wildcard(const std::string& key) { | 187 | 252 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { | 188 | 38 | return true; | 189 | 38 | } | 190 | 214 | return false; | 191 | 252 | } |
|
192 | | |
193 | 25 | std::string extract_template(const std::string& key) { |
194 | 25 | std::size_t left = key.find_first_of('{') + 1; |
195 | 25 | std::size_t right = key.find_last_of('}'); |
196 | 25 | return key.substr(left, right - left); |
197 | 25 | } _ZN5doris8PathTrieIiE8TrieNode16extract_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 193 | 6 | std::string extract_template(const std::string& key) { | 194 | 6 | std::size_t left = key.find_first_of('{') + 1; | 195 | 6 | std::size_t right = key.find_last_of('}'); | 196 | 6 | return key.substr(left, right - left); | 197 | 6 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode16extract_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 193 | 19 | std::string extract_template(const std::string& key) { | 194 | 19 | std::size_t left = key.find_first_of('{') + 1; | 195 | 19 | std::size_t right = key.find_last_of('}'); | 196 | 19 | return key.substr(left, right - left); | 197 | 19 | } |
|
198 | | |
199 | 302 | TrieNode* get_child(const std::string& key) { |
200 | 302 | auto pair = _children.find(key); |
201 | 302 | if (pair == _children.end()) { |
202 | 125 | return nullptr; |
203 | 125 | } |
204 | 177 | return pair->second; |
205 | 302 | } _ZN5doris8PathTrieIiE8TrieNode9get_childERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 199 | 70 | TrieNode* get_child(const std::string& key) { | 200 | 70 | auto pair = _children.find(key); | 201 | 70 | if (pair == _children.end()) { | 202 | 30 | return nullptr; | 203 | 30 | } | 204 | 40 | return pair->second; | 205 | 70 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode9get_childERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 199 | 232 | TrieNode* get_child(const std::string& key) { | 200 | 232 | auto pair = _children.find(key); | 201 | 232 | if (pair == _children.end()) { | 202 | 95 | return nullptr; | 203 | 95 | } | 204 | 137 | return pair->second; | 205 | 232 | } |
|
206 | | |
207 | | void put(std::map<std::string, std::string>* params, TrieNode* node, |
208 | 124 | const std::string& token) { |
209 | 124 | if (params != nullptr && !node->_named_wildcard.empty()) { |
210 | 17 | params->insert(std::make_pair(node->_named_wildcard, token)); |
211 | 17 | } |
212 | 124 | } _ZN5doris8PathTrieIiE8TrieNode3putEPSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEEPS2_RSD_ Line | Count | Source | 208 | 27 | const std::string& token) { | 209 | 27 | if (params != nullptr && !node->_named_wildcard.empty()) { | 210 | 4 | params->insert(std::make_pair(node->_named_wildcard, token)); | 211 | 4 | } | 212 | 27 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode3putEPSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEEPS4_RSF_ Line | Count | Source | 208 | 97 | const std::string& token) { | 209 | 97 | if (params != nullptr && !node->_named_wildcard.empty()) { | 210 | 13 | params->insert(std::make_pair(node->_named_wildcard, token)); | 211 | 13 | } | 212 | 97 | } |
|
213 | | |
214 | | T* _value; |
215 | | std::string _wildcard; |
216 | | std::string _named_wildcard; |
217 | | std::map<std::string, TrieNode*> _children; |
218 | | Allocator _allocator; |
219 | | }; |
220 | | |
221 | 70 | bool insert(const std::string& path, const T& value) { |
222 | 70 | std::vector<std::string> path_array; |
223 | 70 | split(path, &path_array); |
224 | 70 | if (path_array.empty()) { |
225 | 3 | if (_root_value == nullptr) { |
226 | 2 | _root_value = _allocator.allocate(1); |
227 | 2 | _allocator.construct(_root_value, value); |
228 | 2 | return true; |
229 | 2 | } else { |
230 | 1 | return false; |
231 | 1 | } |
232 | 3 | } |
233 | 67 | int index = 0; |
234 | 67 | if (path_array[0].empty()) { |
235 | 0 | index = 1; |
236 | 0 | } |
237 | 67 | return _root.insert(path_array, index, value); |
238 | 70 | } _ZN5doris8PathTrieIiE6insertERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKi Line | Count | Source | 221 | 14 | bool insert(const std::string& path, const T& value) { | 222 | 14 | std::vector<std::string> path_array; | 223 | 14 | split(path, &path_array); | 224 | 14 | if (path_array.empty()) { | 225 | 2 | if (_root_value == nullptr) { | 226 | 1 | _root_value = _allocator.allocate(1); | 227 | 1 | _allocator.construct(_root_value, value); | 228 | 1 | return true; | 229 | 1 | } else { | 230 | 1 | return false; | 231 | 1 | } | 232 | 2 | } | 233 | 12 | int index = 0; | 234 | 12 | if (path_array[0].empty()) { | 235 | 0 | index = 1; | 236 | 0 | } | 237 | 12 | return _root.insert(path_array, index, value); | 238 | 14 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE6insertERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS2_ Line | Count | Source | 221 | 56 | bool insert(const std::string& path, const T& value) { | 222 | 56 | std::vector<std::string> path_array; | 223 | 56 | split(path, &path_array); | 224 | 56 | if (path_array.empty()) { | 225 | 1 | if (_root_value == nullptr) { | 226 | 1 | _root_value = _allocator.allocate(1); | 227 | 1 | _allocator.construct(_root_value, value); | 228 | 1 | return true; | 229 | 1 | } else { | 230 | 0 | return false; | 231 | 0 | } | 232 | 1 | } | 233 | 55 | int index = 0; | 234 | 55 | if (path_array[0].empty()) { | 235 | 0 | index = 1; | 236 | 0 | } | 237 | 55 | return _root.insert(path_array, index, value); | 238 | 56 | } |
|
239 | | |
240 | 9 | bool retrieve(const std::string& path, T* value) { return retrieve(path, value, nullptr); } |
241 | | |
242 | 61 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { |
243 | 61 | if (path.empty()) { |
244 | 1 | if (_root_value == nullptr) { |
245 | 0 | return false; |
246 | 1 | } else { |
247 | 1 | _allocator.construct(value, *_root_value); |
248 | 1 | return true; |
249 | 1 | } |
250 | 1 | } |
251 | 60 | std::vector<std::string> path_array; |
252 | 60 | split(path, &path_array); |
253 | 60 | if (path_array.empty()) { |
254 | 1 | if (_root_value == nullptr) { |
255 | 0 | return false; |
256 | 1 | } else { |
257 | 1 | _allocator.construct(value, *_root_value); |
258 | 1 | return true; |
259 | 1 | } |
260 | 1 | } |
261 | 59 | int index = 0; |
262 | 59 | if (path_array[0].empty()) { |
263 | 0 | index = 1; |
264 | 0 | } |
265 | 59 | return _root.retrieve(path_array, index, value, params); |
266 | 60 | } _ZN5doris8PathTrieIiE8retrieveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPiPSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEE Line | Count | Source | 242 | 14 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { | 243 | 14 | if (path.empty()) { | 244 | 1 | if (_root_value == nullptr) { | 245 | 0 | return false; | 246 | 1 | } else { | 247 | 1 | _allocator.construct(value, *_root_value); | 248 | 1 | return true; | 249 | 1 | } | 250 | 1 | } | 251 | 13 | std::vector<std::string> path_array; | 252 | 13 | split(path, &path_array); | 253 | 13 | if (path_array.empty()) { | 254 | 1 | if (_root_value == nullptr) { | 255 | 0 | return false; | 256 | 1 | } else { | 257 | 1 | _allocator.construct(value, *_root_value); | 258 | 1 | return true; | 259 | 1 | } | 260 | 1 | } | 261 | 12 | int index = 0; | 262 | 12 | if (path_array[0].empty()) { | 263 | 0 | index = 1; | 264 | 0 | } | 265 | 12 | return _root.retrieve(path_array, index, value, params); | 266 | 13 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8retrieveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS2_PSt3mapIS9_S9_St4lessIS9_ESaISt4pairISA_S9_EEE Line | Count | Source | 242 | 47 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { | 243 | 47 | if (path.empty()) { | 244 | 0 | if (_root_value == nullptr) { | 245 | 0 | return false; | 246 | 0 | } else { | 247 | 0 | _allocator.construct(value, *_root_value); | 248 | 0 | return true; | 249 | 0 | } | 250 | 0 | } | 251 | 47 | std::vector<std::string> path_array; | 252 | 47 | split(path, &path_array); | 253 | 47 | if (path_array.empty()) { | 254 | 0 | if (_root_value == nullptr) { | 255 | 0 | return false; | 256 | 0 | } else { | 257 | 0 | _allocator.construct(value, *_root_value); | 258 | 0 | return true; | 259 | 0 | } | 260 | 0 | } | 261 | 47 | int index = 0; | 262 | 47 | if (path_array[0].empty()) { | 263 | 0 | index = 1; | 264 | 0 | } | 265 | 47 | return _root.retrieve(path_array, index, value, params); | 266 | 47 | } |
|
267 | | |
268 | | private: |
269 | 134 | void split(const std::string& path, std::vector<std::string>* array) { |
270 | 134 | const char* path_str = path.c_str(); |
271 | 134 | std::size_t start = 0; |
272 | 134 | std::size_t pos = 0; |
273 | 2.29k | for (; pos < path.length(); ++pos) { |
274 | 2.15k | if (path_str[pos] == _separator) { |
275 | 291 | if (pos - start > 0) { |
276 | 158 | array->push_back(path.substr(start, pos - start)); |
277 | 158 | } |
278 | 291 | start = pos + 1; |
279 | 291 | } |
280 | 2.15k | } |
281 | 134 | if (pos - start > 0) { |
282 | 128 | array->push_back(path.substr(start, pos - start)); |
283 | 128 | } |
284 | 134 | } _ZN5doris8PathTrieIiE5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPSt6vectorIS7_SaIS7_EE Line | Count | Source | 269 | 31 | void split(const std::string& path, std::vector<std::string>* array) { | 270 | 31 | const char* path_str = path.c_str(); | 271 | 31 | std::size_t start = 0; | 272 | 31 | std::size_t pos = 0; | 273 | 343 | for (; pos < path.length(); ++pos) { | 274 | 312 | if (path_str[pos] == _separator) { | 275 | 74 | if (pos - start > 0) { | 276 | 42 | array->push_back(path.substr(start, pos - start)); | 277 | 42 | } | 278 | 74 | start = pos + 1; | 279 | 74 | } | 280 | 312 | } | 281 | 31 | if (pos - start > 0) { | 282 | 26 | array->push_back(path.substr(start, pos - start)); | 283 | 26 | } | 284 | 31 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPSt6vectorIS9_SaIS9_EE Line | Count | Source | 269 | 103 | void split(const std::string& path, std::vector<std::string>* array) { | 270 | 103 | const char* path_str = path.c_str(); | 271 | 103 | std::size_t start = 0; | 272 | 103 | std::size_t pos = 0; | 273 | 1.94k | for (; pos < path.length(); ++pos) { | 274 | 1.84k | if (path_str[pos] == _separator) { | 275 | 217 | if (pos - start > 0) { | 276 | 116 | array->push_back(path.substr(start, pos - start)); | 277 | 116 | } | 278 | 217 | start = pos + 1; | 279 | 217 | } | 280 | 1.84k | } | 281 | 103 | if (pos - start > 0) { | 282 | 102 | array->push_back(path.substr(start, pos - start)); | 283 | 102 | } | 284 | 103 | } |
|
285 | | |
286 | | TrieNode _root; |
287 | | T* _root_value; |
288 | | char _separator; |
289 | | Allocator _allocator; |
290 | | }; |
291 | | |
292 | | } // namespace doris |