/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 | 50 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} _ZN5doris8PathTrieIiEC2Ev Line | Count | Source | 31 | 14 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} |
_ZN5doris8PathTrieIPNS_11HttpHandlerEEC2Ev Line | Count | Source | 31 | 36 | PathTrie() : _root("/", "*"), _root_value(nullptr), _separator('/') {} |
|
32 | | |
33 | 50 | ~PathTrie() { |
34 | 50 | if (_root_value != nullptr) { |
35 | 4 | _allocator.destroy(_root_value); |
36 | 4 | _allocator.deallocate(_root_value, 1); |
37 | 4 | } |
38 | 50 | } _ZN5doris8PathTrieIiED2Ev Line | Count | Source | 33 | 14 | ~PathTrie() { | 34 | 14 | if (_root_value != nullptr) { | 35 | 2 | _allocator.destroy(_root_value); | 36 | 2 | _allocator.deallocate(_root_value, 1); | 37 | 2 | } | 38 | 14 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEED2Ev Line | Count | Source | 33 | 36 | ~PathTrie() { | 34 | 36 | if (_root_value != nullptr) { | 35 | 2 | _allocator.destroy(_root_value); | 36 | 2 | _allocator.deallocate(_root_value, 1); | 37 | 2 | } | 38 | 36 | } |
|
39 | | |
40 | | class Allocator { |
41 | | public: |
42 | | using value_type = T; |
43 | | |
44 | 146 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } _ZN5doris8PathTrieIiE9Allocator8allocateEm Line | Count | Source | 44 | 22 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator8allocateEm Line | Count | Source | 44 | 124 | T* allocate(size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); } |
|
45 | | |
46 | | template <typename... Args> |
47 | 276 | void construct(T* p, Args&&... args) { |
48 | 276 | new (p) T(std::forward<Args>(args)...); |
49 | 276 | } _ZN5doris8PathTrieIiE9Allocator9constructIJRKiEEEvPiDpOT_ Line | Count | Source | 47 | 22 | void construct(T* p, Args&&... args) { | 48 | 22 | new (p) T(std::forward<Args>(args)...); | 49 | 22 | } |
_ZN5doris8PathTrieIiE9Allocator9constructIJRiEEEvPiDpOT_ Line | Count | Source | 47 | 24 | void construct(T* p, Args&&... args) { | 48 | 24 | new (p) T(std::forward<Args>(args)...); | 49 | 24 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator9constructIJRKS2_EEEvPS2_DpOT_ Line | Count | Source | 47 | 124 | void construct(T* p, Args&&... args) { | 48 | 124 | new (p) T(std::forward<Args>(args)...); | 49 | 124 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator9constructIJRS2_EEEvPS2_DpOT_ Line | Count | Source | 47 | 106 | void construct(T* p, Args&&... args) { | 48 | 106 | new (p) T(std::forward<Args>(args)...); | 49 | 106 | } |
|
50 | | |
51 | 146 | void destroy(T* p) { p->~T(); } _ZN5doris8PathTrieIiE9Allocator7destroyEPi Line | Count | Source | 51 | 22 | void destroy(T* p) { p->~T(); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator7destroyEPS2_ Line | Count | Source | 51 | 124 | void destroy(T* p) { p->~T(); } |
|
52 | | |
53 | 146 | void deallocate(T* p, size_t n) { ::operator delete(p); } _ZN5doris8PathTrieIiE9Allocator10deallocateEPim Line | Count | Source | 53 | 22 | void deallocate(T* p, size_t n) { ::operator delete(p); } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE9Allocator10deallocateEPS2_m Line | Count | Source | 53 | 124 | 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 | 140 | : _value(nullptr), _wildcard(wildcard) { |
60 | 140 | if (is_named_wildcard(key)) { |
61 | 14 | _named_wildcard = extract_template(key); |
62 | 14 | } |
63 | 140 | } _ZN5doris8PathTrieIiE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ Line | Count | Source | 59 | 30 | : _value(nullptr), _wildcard(wildcard) { | 60 | 30 | if (is_named_wildcard(key)) { | 61 | 4 | _named_wildcard = extract_template(key); | 62 | 4 | } | 63 | 30 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_ Line | Count | Source | 59 | 110 | : _value(nullptr), _wildcard(wildcard) { | 60 | 110 | if (is_named_wildcard(key)) { | 61 | 10 | _named_wildcard = extract_template(key); | 62 | 10 | } | 63 | 110 | } |
|
64 | | |
65 | | TrieNode(const std::string& key, const T& value, const std::string& wildcard) |
66 | 140 | : _value(nullptr), _wildcard(wildcard) { |
67 | 140 | _value = _allocator.allocate(1); |
68 | 140 | _allocator.construct(_value, value); |
69 | 140 | if (is_named_wildcard(key)) { |
70 | 22 | _named_wildcard = extract_template(key); |
71 | 22 | } |
72 | 140 | } _ZN5doris8PathTrieIiE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiSA_ Line | Count | Source | 66 | 18 | : _value(nullptr), _wildcard(wildcard) { | 67 | 18 | _value = _allocator.allocate(1); | 68 | 18 | _allocator.construct(_value, value); | 69 | 18 | if (is_named_wildcard(key)) { | 70 | 4 | _named_wildcard = extract_template(key); | 71 | 4 | } | 72 | 18 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS2_SC_ Line | Count | Source | 66 | 122 | : _value(nullptr), _wildcard(wildcard) { | 67 | 122 | _value = _allocator.allocate(1); | 68 | 122 | _allocator.construct(_value, value); | 69 | 122 | if (is_named_wildcard(key)) { | 70 | 18 | _named_wildcard = extract_template(key); | 71 | 18 | } | 72 | 122 | } |
|
73 | | |
74 | 280 | ~TrieNode() { |
75 | 280 | for (auto& iter : _children) { |
76 | 230 | delete iter.second; |
77 | 230 | iter.second = nullptr; |
78 | 230 | } |
79 | 280 | if (_value != nullptr) { |
80 | 142 | _allocator.destroy(_value); |
81 | 142 | _allocator.deallocate(_value, 1); |
82 | 142 | } |
83 | 280 | } _ZN5doris8PathTrieIiE8TrieNodeD2Ev Line | Count | Source | 74 | 48 | ~TrieNode() { | 75 | 48 | for (auto& iter : _children) { | 76 | 34 | delete iter.second; | 77 | 34 | iter.second = nullptr; | 78 | 34 | } | 79 | 48 | if (_value != nullptr) { | 80 | 20 | _allocator.destroy(_value); | 81 | 20 | _allocator.deallocate(_value, 1); | 82 | 20 | } | 83 | 48 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNodeD2Ev Line | Count | Source | 74 | 232 | ~TrieNode() { | 75 | 232 | for (auto& iter : _children) { | 76 | 196 | delete iter.second; | 77 | 196 | iter.second = nullptr; | 78 | 196 | } | 79 | 232 | if (_value != nullptr) { | 80 | 122 | _allocator.destroy(_value); | 81 | 122 | _allocator.deallocate(_value, 1); | 82 | 122 | } | 83 | 232 | } |
|
84 | | |
85 | | // Return true if insert success. |
86 | 336 | bool insert(const std::vector<std::string> path, int index, const T& value) { |
87 | 336 | if (index >= path.size()) { |
88 | 0 | return false; |
89 | 0 | } |
90 | 336 | const std::string& token = path[index]; |
91 | 336 | std::string key = token; |
92 | | |
93 | 336 | if (is_named_wildcard(token)) { |
94 | 50 | key = _wildcard; |
95 | 50 | } |
96 | | |
97 | 336 | TrieNode* node = get_child(key); |
98 | | |
99 | 336 | if (node == nullptr) { |
100 | | // no exist child for this key |
101 | 230 | if (index == path.size() - 1) { |
102 | 140 | node = new TrieNode(token, value, _wildcard); |
103 | 140 | _children.insert(std::make_pair(key, node)); |
104 | 140 | return true; |
105 | 140 | } else { |
106 | 90 | node = new TrieNode(token, _wildcard); |
107 | 90 | _children.insert(std::make_pair(key, node)); |
108 | 90 | } |
109 | 230 | } else { |
110 | | // If this is a template, set this to the node |
111 | 106 | if (is_named_wildcard(token)) { |
112 | 14 | std::string temp = extract_template(token); |
113 | 14 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { |
114 | 12 | node->_named_wildcard = temp; |
115 | 12 | } else { |
116 | | // Duplicated |
117 | 2 | return false; |
118 | 2 | } |
119 | 14 | } |
120 | 104 | if (index == path.size() - 1) { |
121 | 4 | if (node->_value == nullptr) { |
122 | 2 | node->_value = _allocator.allocate(1); |
123 | 2 | _allocator.construct(node->_value, value); |
124 | 2 | return true; |
125 | 2 | } |
126 | | // Already register by other path |
127 | 2 | return false; |
128 | 4 | } |
129 | 104 | } |
130 | 190 | return node->insert(path, index + 1, value); |
131 | 336 | } _ZN5doris8PathTrieIiE8TrieNode6insertESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEiRKi Line | Count | Source | 86 | 60 | bool insert(const std::vector<std::string> path, int index, const T& value) { | 87 | 60 | if (index >= path.size()) { | 88 | 0 | return false; | 89 | 0 | } | 90 | 60 | const std::string& token = path[index]; | 91 | 60 | std::string key = token; | 92 | | | 93 | 60 | if (is_named_wildcard(token)) { | 94 | 12 | key = _wildcard; | 95 | 12 | } | 96 | | | 97 | 60 | TrieNode* node = get_child(key); | 98 | | | 99 | 60 | if (node == nullptr) { | 100 | | // no exist child for this key | 101 | 34 | if (index == path.size() - 1) { | 102 | 18 | node = new TrieNode(token, value, _wildcard); | 103 | 18 | _children.insert(std::make_pair(key, node)); | 104 | 18 | return true; | 105 | 18 | } else { | 106 | 16 | node = new TrieNode(token, _wildcard); | 107 | 16 | _children.insert(std::make_pair(key, node)); | 108 | 16 | } | 109 | 34 | } else { | 110 | | // If this is a template, set this to the node | 111 | 26 | if (is_named_wildcard(token)) { | 112 | 4 | std::string temp = extract_template(token); | 113 | 4 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { | 114 | 2 | node->_named_wildcard = temp; | 115 | 2 | } else { | 116 | | // Duplicated | 117 | 2 | return false; | 118 | 2 | } | 119 | 4 | } | 120 | 24 | if (index == path.size() - 1) { | 121 | 4 | if (node->_value == nullptr) { | 122 | 2 | node->_value = _allocator.allocate(1); | 123 | 2 | _allocator.construct(node->_value, value); | 124 | 2 | return true; | 125 | 2 | } | 126 | | // Already register by other path | 127 | 2 | return false; | 128 | 4 | } | 129 | 24 | } | 130 | 36 | return node->insert(path, index + 1, value); | 131 | 60 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode6insertESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EEiRKS2_ Line | Count | Source | 86 | 276 | bool insert(const std::vector<std::string> path, int index, const T& value) { | 87 | 276 | if (index >= path.size()) { | 88 | 0 | return false; | 89 | 0 | } | 90 | 276 | const std::string& token = path[index]; | 91 | 276 | std::string key = token; | 92 | | | 93 | 276 | if (is_named_wildcard(token)) { | 94 | 38 | key = _wildcard; | 95 | 38 | } | 96 | | | 97 | 276 | TrieNode* node = get_child(key); | 98 | | | 99 | 276 | if (node == nullptr) { | 100 | | // no exist child for this key | 101 | 196 | if (index == path.size() - 1) { | 102 | 122 | node = new TrieNode(token, value, _wildcard); | 103 | 122 | _children.insert(std::make_pair(key, node)); | 104 | 122 | return true; | 105 | 122 | } else { | 106 | 74 | node = new TrieNode(token, _wildcard); | 107 | 74 | _children.insert(std::make_pair(key, node)); | 108 | 74 | } | 109 | 196 | } else { | 110 | | // If this is a template, set this to the node | 111 | 80 | if (is_named_wildcard(token)) { | 112 | 10 | std::string temp = extract_template(token); | 113 | 10 | if (node->_named_wildcard.empty() || node->_named_wildcard.compare(temp) == 0) { | 114 | 10 | node->_named_wildcard = temp; | 115 | 10 | } else { | 116 | | // Duplicated | 117 | 0 | return false; | 118 | 0 | } | 119 | 10 | } | 120 | 80 | 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 | 80 | } | 130 | 154 | return node->insert(path, index + 1, value); | 131 | 276 | } |
|
132 | | |
133 | | bool retrieve(const std::vector<std::string> path, int index, T* value, |
134 | 296 | std::map<std::string, std::string>* params) { |
135 | | // check max index |
136 | 296 | if (index >= path.size()) { |
137 | 0 | return false; |
138 | 0 | } |
139 | 296 | bool use_wildcard = false; |
140 | 296 | const std::string& token = path[index]; |
141 | 296 | TrieNode* node = get_child(token); |
142 | 296 | if (node == nullptr) { |
143 | 46 | node = get_child(_wildcard); |
144 | 46 | if (node == nullptr) { |
145 | 6 | return false; |
146 | 6 | } |
147 | 40 | use_wildcard = true; |
148 | 250 | } else { |
149 | | // If we the last one, but we have no value, check wildcard |
150 | 250 | if (index == path.size() - 1 && node->_value == nullptr && |
151 | 250 | get_child(_wildcard) != nullptr) { |
152 | 0 | node = get_child(_wildcard); |
153 | 0 | use_wildcard = true; |
154 | 250 | } else { |
155 | 250 | use_wildcard = (token.compare(_wildcard) == 0); |
156 | 250 | } |
157 | 250 | } |
158 | | |
159 | 290 | put(params, node, token); |
160 | | |
161 | 290 | if (index == path.size() - 1) { |
162 | 126 | if (node->_value == nullptr) { |
163 | 0 | return false; |
164 | 0 | } |
165 | 126 | _allocator.construct(value, *node->_value); |
166 | 126 | return true; |
167 | 126 | } |
168 | | |
169 | | // find exact |
170 | 164 | if (node->retrieve(path, index + 1, value, params)) { |
171 | 160 | return true; |
172 | 160 | } |
173 | | |
174 | | // backtrace to test if wildcard can match |
175 | 4 | if (!use_wildcard) { |
176 | 4 | node = get_child(_wildcard); |
177 | 4 | if (node != nullptr) { |
178 | 0 | put(params, node, token); |
179 | 0 | return node->retrieve(path, index + 1, value, params); |
180 | 0 | } |
181 | 4 | } |
182 | 4 | return false; |
183 | 4 | } _ZN5doris8PathTrieIiE8TrieNode8retrieveESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEiPiPSt3mapIS9_S9_St4lessIS9_ESaISt4pairIKS9_S9_EEE Line | Count | Source | 134 | 58 | std::map<std::string, std::string>* params) { | 135 | | // check max index | 136 | 58 | if (index >= path.size()) { | 137 | 0 | return false; | 138 | 0 | } | 139 | 58 | bool use_wildcard = false; | 140 | 58 | const std::string& token = path[index]; | 141 | 58 | TrieNode* node = get_child(token); | 142 | 58 | if (node == nullptr) { | 143 | 18 | node = get_child(_wildcard); | 144 | 18 | if (node == nullptr) { | 145 | 4 | return false; | 146 | 4 | } | 147 | 14 | use_wildcard = true; | 148 | 40 | } else { | 149 | | // If we the last one, but we have no value, check wildcard | 150 | 40 | if (index == path.size() - 1 && node->_value == nullptr && | 151 | 40 | get_child(_wildcard) != nullptr) { | 152 | 0 | node = get_child(_wildcard); | 153 | 0 | use_wildcard = true; | 154 | 40 | } else { | 155 | 40 | use_wildcard = (token.compare(_wildcard) == 0); | 156 | 40 | } | 157 | 40 | } | 158 | | | 159 | 54 | put(params, node, token); | 160 | | | 161 | 54 | if (index == path.size() - 1) { | 162 | 20 | if (node->_value == nullptr) { | 163 | 0 | return false; | 164 | 0 | } | 165 | 20 | _allocator.construct(value, *node->_value); | 166 | 20 | return true; | 167 | 20 | } | 168 | | | 169 | | // find exact | 170 | 34 | if (node->retrieve(path, index + 1, value, params)) { | 171 | 30 | return true; | 172 | 30 | } | 173 | | | 174 | | // backtrace to test if wildcard can match | 175 | 4 | if (!use_wildcard) { | 176 | 4 | node = get_child(_wildcard); | 177 | 4 | if (node != nullptr) { | 178 | 0 | put(params, node, token); | 179 | 0 | return node->retrieve(path, index + 1, value, params); | 180 | 0 | } | 181 | 4 | } | 182 | 4 | return false; | 183 | 4 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode8retrieveESt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EEiPS2_PSt3mapISB_SB_St4lessISB_ESaISt4pairIKSB_SB_EEE Line | Count | Source | 134 | 238 | std::map<std::string, std::string>* params) { | 135 | | // check max index | 136 | 238 | if (index >= path.size()) { | 137 | 0 | return false; | 138 | 0 | } | 139 | 238 | bool use_wildcard = false; | 140 | 238 | const std::string& token = path[index]; | 141 | 238 | TrieNode* node = get_child(token); | 142 | 238 | if (node == nullptr) { | 143 | 28 | node = get_child(_wildcard); | 144 | 28 | if (node == nullptr) { | 145 | 2 | return false; | 146 | 2 | } | 147 | 26 | use_wildcard = true; | 148 | 210 | } else { | 149 | | // If we the last one, but we have no value, check wildcard | 150 | 210 | if (index == path.size() - 1 && node->_value == nullptr && | 151 | 210 | get_child(_wildcard) != nullptr) { | 152 | 0 | node = get_child(_wildcard); | 153 | 0 | use_wildcard = true; | 154 | 210 | } else { | 155 | 210 | use_wildcard = (token.compare(_wildcard) == 0); | 156 | 210 | } | 157 | 210 | } | 158 | | | 159 | 236 | put(params, node, token); | 160 | | | 161 | 236 | if (index == path.size() - 1) { | 162 | 106 | if (node->_value == nullptr) { | 163 | 0 | return false; | 164 | 0 | } | 165 | 106 | _allocator.construct(value, *node->_value); | 166 | 106 | return true; | 167 | 106 | } | 168 | | | 169 | | // find exact | 170 | 130 | if (node->retrieve(path, index + 1, value, params)) { | 171 | 130 | return true; | 172 | 130 | } | 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 | 722 | bool is_named_wildcard(const std::string& key) { |
187 | 722 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { |
188 | 100 | return true; |
189 | 100 | } |
190 | 622 | return false; |
191 | 722 | } _ZN5doris8PathTrieIiE8TrieNode17is_named_wildcardERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 186 | 134 | bool is_named_wildcard(const std::string& key) { | 187 | 134 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { | 188 | 24 | return true; | 189 | 24 | } | 190 | 110 | return false; | 191 | 134 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode17is_named_wildcardERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 186 | 588 | bool is_named_wildcard(const std::string& key) { | 187 | 588 | if (key.find('{') != std::string::npos && key.find('}') != std::string::npos) { | 188 | 76 | return true; | 189 | 76 | } | 190 | 512 | return false; | 191 | 588 | } |
|
192 | | |
193 | 50 | std::string extract_template(const std::string& key) { |
194 | 50 | std::size_t left = key.find_first_of('{') + 1; |
195 | 50 | std::size_t right = key.find_last_of('}'); |
196 | 50 | return key.substr(left, right - left); |
197 | 50 | } _ZN5doris8PathTrieIiE8TrieNode16extract_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 193 | 12 | std::string extract_template(const std::string& key) { | 194 | 12 | std::size_t left = key.find_first_of('{') + 1; | 195 | 12 | std::size_t right = key.find_last_of('}'); | 196 | 12 | return key.substr(left, right - left); | 197 | 12 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode16extract_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 193 | 38 | std::string extract_template(const std::string& key) { | 194 | 38 | std::size_t left = key.find_first_of('{') + 1; | 195 | 38 | std::size_t right = key.find_last_of('}'); | 196 | 38 | return key.substr(left, right - left); | 197 | 38 | } |
|
198 | | |
199 | 682 | TrieNode* get_child(const std::string& key) { |
200 | 682 | auto pair = _children.find(key); |
201 | 682 | if (pair == _children.end()) { |
202 | 286 | return nullptr; |
203 | 286 | } |
204 | 396 | return pair->second; |
205 | 682 | } _ZN5doris8PathTrieIiE8TrieNode9get_childERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 199 | 140 | TrieNode* get_child(const std::string& key) { | 200 | 140 | auto pair = _children.find(key); | 201 | 140 | if (pair == _children.end()) { | 202 | 60 | return nullptr; | 203 | 60 | } | 204 | 80 | return pair->second; | 205 | 140 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode9get_childERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE Line | Count | Source | 199 | 542 | TrieNode* get_child(const std::string& key) { | 200 | 542 | auto pair = _children.find(key); | 201 | 542 | if (pair == _children.end()) { | 202 | 226 | return nullptr; | 203 | 226 | } | 204 | 316 | return pair->second; | 205 | 542 | } |
|
206 | | |
207 | | void put(std::map<std::string, std::string>* params, TrieNode* node, |
208 | 290 | const std::string& token) { |
209 | 290 | if (params != nullptr && !node->_named_wildcard.empty()) { |
210 | 34 | params->insert(std::make_pair(node->_named_wildcard, token)); |
211 | 34 | } |
212 | 290 | } _ZN5doris8PathTrieIiE8TrieNode3putEPSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEEPS2_RSD_ Line | Count | Source | 208 | 54 | const std::string& token) { | 209 | 54 | if (params != nullptr && !node->_named_wildcard.empty()) { | 210 | 8 | params->insert(std::make_pair(node->_named_wildcard, token)); | 211 | 8 | } | 212 | 54 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8TrieNode3putEPSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEEPS4_RSF_ Line | Count | Source | 208 | 236 | const std::string& token) { | 209 | 236 | if (params != nullptr && !node->_named_wildcard.empty()) { | 210 | 26 | params->insert(std::make_pair(node->_named_wildcard, token)); | 211 | 26 | } | 212 | 236 | } |
|
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 | 152 | bool insert(const std::string& path, const T& value) { |
222 | 152 | std::vector<std::string> path_array; |
223 | 152 | split(path, &path_array); |
224 | 152 | if (path_array.empty()) { |
225 | 6 | if (_root_value == nullptr) { |
226 | 4 | _root_value = _allocator.allocate(1); |
227 | 4 | _allocator.construct(_root_value, value); |
228 | 4 | return true; |
229 | 4 | } else { |
230 | 2 | return false; |
231 | 2 | } |
232 | 6 | } |
233 | 146 | int index = 0; |
234 | 146 | if (path_array[0].empty()) { |
235 | 0 | index = 1; |
236 | 0 | } |
237 | 146 | return _root.insert(path_array, index, value); |
238 | 152 | } _ZN5doris8PathTrieIiE6insertERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKi Line | Count | Source | 221 | 28 | bool insert(const std::string& path, const T& value) { | 222 | 28 | std::vector<std::string> path_array; | 223 | 28 | split(path, &path_array); | 224 | 28 | if (path_array.empty()) { | 225 | 4 | 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 | 2 | return false; | 231 | 2 | } | 232 | 4 | } | 233 | 24 | int index = 0; | 234 | 24 | if (path_array[0].empty()) { | 235 | 0 | index = 1; | 236 | 0 | } | 237 | 24 | return _root.insert(path_array, index, value); | 238 | 28 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE6insertERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS2_ Line | Count | Source | 221 | 124 | bool insert(const std::string& path, const T& value) { | 222 | 124 | std::vector<std::string> path_array; | 223 | 124 | split(path, &path_array); | 224 | 124 | if (path_array.empty()) { | 225 | 2 | 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 | 0 | return false; | 231 | 0 | } | 232 | 2 | } | 233 | 122 | int index = 0; | 234 | 122 | if (path_array[0].empty()) { | 235 | 0 | index = 1; | 236 | 0 | } | 237 | 122 | return _root.insert(path_array, index, value); | 238 | 124 | } |
|
239 | | |
240 | 18 | bool retrieve(const std::string& path, T* value) { return retrieve(path, value, nullptr); } |
241 | | |
242 | 136 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { |
243 | 136 | if (path.empty()) { |
244 | 2 | if (_root_value == nullptr) { |
245 | 0 | return false; |
246 | 2 | } else { |
247 | 2 | _allocator.construct(value, *_root_value); |
248 | 2 | return true; |
249 | 2 | } |
250 | 2 | } |
251 | 134 | std::vector<std::string> path_array; |
252 | 134 | split(path, &path_array); |
253 | 134 | if (path_array.empty()) { |
254 | 2 | if (_root_value == nullptr) { |
255 | 0 | return false; |
256 | 2 | } else { |
257 | 2 | _allocator.construct(value, *_root_value); |
258 | 2 | return true; |
259 | 2 | } |
260 | 2 | } |
261 | 132 | int index = 0; |
262 | 132 | if (path_array[0].empty()) { |
263 | 0 | index = 1; |
264 | 0 | } |
265 | 132 | return _root.retrieve(path_array, index, value, params); |
266 | 134 | } _ZN5doris8PathTrieIiE8retrieveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPiPSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEE Line | Count | Source | 242 | 28 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { | 243 | 28 | if (path.empty()) { | 244 | 2 | if (_root_value == nullptr) { | 245 | 0 | return false; | 246 | 2 | } else { | 247 | 2 | _allocator.construct(value, *_root_value); | 248 | 2 | return true; | 249 | 2 | } | 250 | 2 | } | 251 | 26 | std::vector<std::string> path_array; | 252 | 26 | split(path, &path_array); | 253 | 26 | if (path_array.empty()) { | 254 | 2 | if (_root_value == nullptr) { | 255 | 0 | return false; | 256 | 2 | } else { | 257 | 2 | _allocator.construct(value, *_root_value); | 258 | 2 | return true; | 259 | 2 | } | 260 | 2 | } | 261 | 24 | int index = 0; | 262 | 24 | if (path_array[0].empty()) { | 263 | 0 | index = 1; | 264 | 0 | } | 265 | 24 | return _root.retrieve(path_array, index, value, params); | 266 | 26 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE8retrieveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS2_PSt3mapIS9_S9_St4lessIS9_ESaISt4pairISA_S9_EEE Line | Count | Source | 242 | 108 | bool retrieve(const std::string& path, T* value, std::map<std::string, std::string>* params) { | 243 | 108 | 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 | 108 | std::vector<std::string> path_array; | 252 | 108 | split(path, &path_array); | 253 | 108 | 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 | 108 | int index = 0; | 262 | 108 | if (path_array[0].empty()) { | 263 | 0 | index = 1; | 264 | 0 | } | 265 | 108 | return _root.retrieve(path_array, index, value, params); | 266 | 108 | } |
|
267 | | |
268 | | private: |
269 | 294 | void split(const std::string& path, std::vector<std::string>* array) { |
270 | 294 | const char* path_str = path.c_str(); |
271 | 294 | std::size_t start = 0; |
272 | 294 | std::size_t pos = 0; |
273 | 5.25k | for (; pos < path.length(); ++pos) { |
274 | 4.95k | if (path_str[pos] == _separator) { |
275 | 660 | if (pos - start > 0) { |
276 | 368 | array->push_back(path.substr(start, pos - start)); |
277 | 368 | } |
278 | 660 | start = pos + 1; |
279 | 660 | } |
280 | 4.95k | } |
281 | 294 | if (pos - start > 0) { |
282 | 282 | array->push_back(path.substr(start, pos - start)); |
283 | 282 | } |
284 | 294 | } _ZN5doris8PathTrieIiE5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPSt6vectorIS7_SaIS7_EE Line | Count | Source | 269 | 62 | void split(const std::string& path, std::vector<std::string>* array) { | 270 | 62 | const char* path_str = path.c_str(); | 271 | 62 | std::size_t start = 0; | 272 | 62 | std::size_t pos = 0; | 273 | 686 | for (; pos < path.length(); ++pos) { | 274 | 624 | if (path_str[pos] == _separator) { | 275 | 148 | if (pos - start > 0) { | 276 | 84 | array->push_back(path.substr(start, pos - start)); | 277 | 84 | } | 278 | 148 | start = pos + 1; | 279 | 148 | } | 280 | 624 | } | 281 | 62 | if (pos - start > 0) { | 282 | 52 | array->push_back(path.substr(start, pos - start)); | 283 | 52 | } | 284 | 62 | } |
_ZN5doris8PathTrieIPNS_11HttpHandlerEE5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPSt6vectorIS9_SaIS9_EE Line | Count | Source | 269 | 232 | void split(const std::string& path, std::vector<std::string>* array) { | 270 | 232 | const char* path_str = path.c_str(); | 271 | 232 | std::size_t start = 0; | 272 | 232 | std::size_t pos = 0; | 273 | 4.56k | for (; pos < path.length(); ++pos) { | 274 | 4.33k | if (path_str[pos] == _separator) { | 275 | 512 | if (pos - start > 0) { | 276 | 284 | array->push_back(path.substr(start, pos - start)); | 277 | 284 | } | 278 | 512 | start = pos + 1; | 279 | 512 | } | 280 | 4.33k | } | 281 | 232 | if (pos - start > 0) { | 282 | 230 | array->push_back(path.substr(start, pos - start)); | 283 | 230 | } | 284 | 232 | } |
|
285 | | |
286 | | TrieNode _root; |
287 | | T* _root_value; |
288 | | char _separator; |
289 | | Allocator _allocator; |
290 | | }; |
291 | | |
292 | | } // namespace doris |