Coverage Report

Created: 2025-04-27 02:50

/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