-
-
Save facontidavide/95f20c28df8ec91729f9d8ab01e7d2df to your computer and use it in GitHub Desktop.
#include <iostream> | |
#include <cstring> | |
#include <unordered_map> | |
// https://github.com/martinmoene/string-view-lite | |
#include "string_view.hpp" | |
template <typename Value> | |
class StringMap: public std::unordered_map<std::string, Value> | |
{ | |
public: | |
typename std::unordered_map<string,Value>::iterator find(const nonstd::string_view& v ) | |
{ | |
tmp_.reserve( v.size() ); | |
tmp_.assign( v.data(), v.size() ); | |
return std::unordered_map<string, Value>::find(tmp_); | |
} | |
typename std::unordered_map<std::string,Value>::iterator find(const std::string& v ) | |
{ | |
return std::unordered_map<std::string, Value>::find(v); | |
} | |
typename std::unordered_map<std::string,Value>::iterator find(const char* v ) | |
{ | |
tmp_.assign(v); | |
return std::unordered_map<std::string, Value>::find(v); | |
} | |
private: | |
thread_local static std::string tmp_; | |
}; | |
template <typename T> thread_local std::string StringMap<T>::tmp_ = {}; | |
int main() | |
{ | |
std::string key_A("Hello"); | |
nonstd::string_view key_B("Hello"); | |
nonstd::string_view key_C(key_A); | |
StringMap<std::string> smap; | |
smap["Hello"] = "World"; | |
for (auto& it: smap) | |
{ | |
std::cout << it.first << ":" << it.second << std::endl; | |
} | |
std::cout << smap.find(key_A)->second << std::endl; | |
std::cout << smap.find(key_B)->second << std::endl; | |
std::cout << smap.find(key_C)->second << std::endl; | |
std::cout << smap.find("Hello")->second << std::endl; | |
return 0; | |
} |
std::unordered_map::find is originally thread safe against itself and other readonly methods. But your solution is not.
If I implement shared_mutex pattern with multiple simultaneous readers your implementation may corrupt memory.
I'm writing here to notify others since this code is easily found via google, I saw people citing this solution in stackOverflow. But this solution is broken and may corrupt memory in multi threaded environment.
@kolomenkin Are you confusing hardware threads and execution threads?
If the OS schedules another execution thread on the hardware thread the previous code was running on, the thread_local variable will not be the same.
@Vizepi , you are right. It was a silly mistake on my side.
@facontidavide , your solution does not have the problems I mentioned above. It is thread safe for reading.
unordered_map itself is not thread safe ;)