github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/util/thread_safe_map.h (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or // (at your 9 // option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #pragma once 21 #include "common/common.h" 22 23 namespace neb { 24 template <typename Key, typename Val, typename Lock = boost::shared_mutex> 25 class thread_safe_map { 26 public: 27 typedef std::map<Key, Val> map_t; 28 typedef Lock lock_t; 29 using r_guard_t = boost::shared_lock<lock_t>; 30 using w_guard_t = std::unique_lock<lock_t>; 31 32 thread_safe_map() = default; 33 34 void insert(const typename map_t::key_type &k, 35 const typename map_t::mapped_type &v) { 36 w_guard_t _l(m_mutex); 37 if (m_map.find(k) != m_map.end()) { 38 m_map[k] = v; 39 return; 40 } 41 m_map.insert(std::make_pair(k, v)); 42 } 43 44 bool insert_if_not_exist(const typename map_t::key_type &k, 45 const typename map_t::mapped_type &v) { 46 w_guard_t _l(m_mutex); 47 if (m_map.find(k) != m_map.end()) { 48 m_map[k] = v; 49 return false; 50 } 51 m_map.insert(std::make_pair(k, v)); 52 return true; 53 } 54 55 void erase(const typename map_t::key_type &k) { 56 w_guard_t _l(m_mutex); 57 auto it = m_map.find(k); 58 if (it != m_map.end()) { 59 m_map.erase(it); 60 } 61 } 62 63 std::pair<bool, typename map_t::mapped_type> 64 try_get_and_update_val(const typename map_t::key_type &k, 65 const typename map_t::mapped_type &v) { 66 w_guard_t _l(m_mutex); 67 auto ret = try_get_val(k); 68 insert(k, v); 69 return ret; 70 } 71 72 std::pair<bool, typename map_t::mapped_type> 73 try_get_val(const typename map_t::key_type &k) { 74 r_guard_t _l(m_mutex); 75 if (m_map.find(k) == m_map.end()) { 76 return std::make_pair(false, typename map_t::mapped_type()); 77 } 78 auto ret = m_map.find(k)->second; 79 return std::make_pair(true, ret); 80 } 81 82 std::pair<bool, typename map_t::value_type> 83 try_lower_than(const typename map_t::key_type &k) { 84 r_guard_t _l(m_mutex); 85 if (m_map.empty() || k < m_map.begin()->first) { 86 return std::make_pair(false, typename map_t::value_type()); 87 } 88 auto it = m_map.upper_bound(k); 89 it--; 90 auto ret = *it; 91 return std::make_pair(true, ret); 92 } 93 94 typename map_t::value_type begin() { 95 r_guard_t _l(m_mutex); 96 auto ret = m_map.begin(); 97 return *ret; 98 } 99 100 typename map_t::value_type end() { 101 r_guard_t _l(m_mutex); 102 auto ret = m_map.end(); 103 return *ret; 104 } 105 106 bool exist(const typename map_t::key_type &k) { 107 r_guard_t _l(m_mutex); 108 return m_map.find(k) != m_map.end(); 109 } 110 111 size_t size() const { 112 r_guard_t _l(m_mutex); 113 return m_map.size(); 114 } 115 116 bool empty() const { 117 r_guard_t _l(m_mutex); 118 return m_map.empty(); 119 } 120 121 void clear() { 122 w_guard_t _l(m_mutex); 123 m_map.clear(); 124 } 125 126 private: 127 map_t m_map; 128 mutable lock_t m_mutex; 129 }; 130 } // namespace neb