Coverage Report

Created: 2025-09-17 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/butil/find_cstr.h
Line
Count
Source
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
// Date: Tue Jun 23 15:03:24 CST 2015
19
20
#ifndef BUTIL_FIND_CSTR_H
21
#define BUTIL_FIND_CSTR_H
22
23
#include <string>
24
#include <map>
25
#include <algorithm>
26
#include "butil/thread_local.h"
27
28
// Find c-string in maps with std::string as keys without memory allocations.
29
// Example:
30
//   std::map<std::string, int> string_map;
31
//
32
//   string_map.find("hello");         // constructed a temporary std::string
33
//                                     // which needs memory allocation.
34
//
35
//   find_cstr(string_map, "hello");   // no allocation.
36
//
37
// You can specialize find_cstr for other maps.
38
// Possible prototypes are:
39
//   const_iterator find_cstr(const Map& map, const char* key);
40
//   iterator       find_cstr(Map& map, const char* key);
41
//   const_iterator find_cstr(const Map& map, const char* key, size_t length);
42
//   iterator       find_cstr(Map& map, const char* key, size_t length);
43
44
namespace butil {
45
46
struct StringMapThreadLocalTemp {
47
    bool initialized;
48
    char buf[sizeof(std::string)];
49
50
0
    static void delete_tls(void* buf) {
51
0
        StringMapThreadLocalTemp* temp = (StringMapThreadLocalTemp*)buf;
52
0
        if (temp->initialized) {
53
0
            temp->initialized = false;
54
0
            std::string* temp_string = (std::string*)temp->buf;
55
0
            temp_string->~basic_string();
56
0
        }
57
0
    }
58
59
0
    inline std::string* get_string(const char* key) {
60
0
        if (!initialized) {
61
0
            initialized = true;
62
0
            std::string* tmp = new (buf) std::string(key);
63
0
            thread_atexit(delete_tls, this);
64
0
            return tmp;
65
0
        } else {
66
0
            std::string* tmp = (std::string*)buf;
67
0
            tmp->assign(key);
68
0
            return tmp;
69
0
        }
70
0
    }
71
72
0
    inline std::string* get_string(const char* key, size_t length) {
73
0
        if (!initialized) {
74
0
            initialized = true;
75
0
            std::string* tmp = new (buf) std::string(key, length);
76
0
            thread_atexit(delete_tls, this);
77
0
            return tmp;
78
0
        } else {
79
0
            std::string* tmp = (std::string*)buf;
80
0
            tmp->assign(key, length);
81
0
            return tmp;
82
0
        }
83
0
    }
84
85
0
    inline std::string* get_lowered_string(const char* key) {
86
0
        std::string* tmp = get_string(key);
87
0
        std::transform(tmp->begin(), tmp->end(), tmp->begin(), ::tolower);
88
0
        return tmp;
89
0
    }
90
    
91
0
    inline std::string* get_lowered_string(const char* key, size_t length) {
92
0
        std::string* tmp = get_string(key, length);
93
0
        std::transform(tmp->begin(), tmp->end(), tmp->begin(), ::tolower);
94
0
        return tmp;
95
0
    }
96
};
97
98
extern thread_local StringMapThreadLocalTemp tls_stringmap_temp;
99
100
template <typename T, typename C, typename A>
101
typename std::map<std::string, T, C, A>::const_iterator
102
0
find_cstr(const std::map<std::string, T, C, A>& m, const char* key) {
103
0
    return m.find(*tls_stringmap_temp.get_string(key));
104
0
}
105
106
template <typename T, typename C, typename A>
107
typename std::map<std::string, T, C, A>::iterator
108
find_cstr(std::map<std::string, T, C, A>& m, const char* key) {
109
    return m.find(*tls_stringmap_temp.get_string(key));
110
}
111
112
template <typename T, typename C, typename A>
113
typename std::map<std::string, T, C, A>::const_iterator
114
find_cstr(const std::map<std::string, T, C, A>& m,
115
          const char* key, size_t length) {
116
    return m.find(*tls_stringmap_temp.get_string(key, length));
117
}
118
119
template <typename T, typename C, typename A>
120
typename std::map<std::string, T, C, A>::iterator
121
find_cstr(std::map<std::string, T, C, A>& m,
122
          const char* key, size_t length) {
123
    return m.find(*tls_stringmap_temp.get_string(key, length));
124
}
125
126
template <typename T, typename C, typename A>
127
typename std::map<std::string, T, C, A>::const_iterator
128
find_lowered_cstr(const std::map<std::string, T, C, A>& m, const char* key) {
129
    return m.find(*tls_stringmap_temp.get_lowered_string(key));
130
}
131
132
template <typename T, typename C, typename A>
133
typename std::map<std::string, T, C, A>::iterator
134
find_lowered_cstr(std::map<std::string, T, C, A>& m, const char* key) {
135
    return m.find(*tls_stringmap_temp.get_lowered_string(key));
136
}
137
138
template <typename T, typename C, typename A>
139
typename std::map<std::string, T, C, A>::const_iterator
140
find_lowered_cstr(const std::map<std::string, T, C, A>& m,
141
                  const char* key, size_t length) {
142
    return m.find(*tls_stringmap_temp.get_lowered_string(key, length));
143
}
144
145
template <typename T, typename C, typename A>
146
typename std::map<std::string, T, C, A>::iterator
147
find_lowered_cstr(std::map<std::string, T, C, A>& m,
148
                  const char* key, size_t length) {
149
    return m.find(*tls_stringmap_temp.get_lowered_string(key, length));
150
}
151
152
}  // namespace butil
153
154
#endif  // BUTIL_FIND_CSTR_H