Horizon Official Technical Documentation
LockedLookupTable.hpp
Go to the documentation of this file.
1/***************************************************
2 * _ _ _ *
3 * | | | | (_) *
4 * | |_| | ___ _ __ _ _______ _ __ *
5 * | _ |/ _ \| '__| |_ / _ \| '_ \ *
6 * | | | | (_) | | | |/ / (_) | | | | *
7 * \_| |_/\___/|_| |_/___\___/|_| |_| *
8 ***************************************************
9 * This file is part of Horizon (c).
10 *
11 * Copyright (c) 2019 Sagun K. (sagunxp@gmail.com).
12 * Copyright (c) 2019 Horizon Dev Team.
13 *
14 * Base Author - Sagun K. (sagunxp@gmail.com)
15 *
16 * This library is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this library. If not, see <http://www.gnu.org/licenses/>.
28 **************************************************/
29
30#ifndef HORIZON_CORE_MULTITHREADING_LOCKEDLOOKUPTABLE_HPP
31#define HORIZON_CORE_MULTITHREADING_LOCKEDLOOKUPTABLE_HPP
32
33#include <iostream>
34#include <string>
35#include <boost/thread/shared_mutex.hpp>
36#include <boost/thread.hpp>
37#include <memory>
38#include <list>
39#include <vector>
40
41
42template <typename Key, typename Value, typename Hash = std::hash<Key>>
44{
45 class bucket_type;
46public:
47 typedef Key key_type;
48 typedef Value mapped_type;
49 typedef Hash hash_type;
50
51 LockedLookupTable(unsigned num_buckets = 19, const Hash &hasher_ = Hash())
52 : _buckets(num_buckets), hasher(hasher_)
53 {
54 for (unsigned i = 0; i < num_buckets; ++i)
55 _buckets[i].reset(new bucket_type);
56 }
57
58 LockedLookupTable(const LockedLookupTable &other) = delete;
60
61 Value const &operator[] (Key &k) { at(k); }
62
63 Value at(Key const &key, Value const &default_value = Value()) const
64 {
65 return get_bucket(key).at(key, default_value);
66 }
67
68 void insert(const Key &key, const Value &value)
69 {
70 get_bucket(key).insert(key, value);
71 }
72
73 void erase(const Key &key)
74 {
75 get_bucket(key).erase(key);
76 }
77
78 std::map<Key, Value> get_map() const
79 {
80 std::map<Key, Value> res;
81
82 for (unsigned i = 0; i < _buckets.size(); ++i) {
83 boost::unique_lock<boost::shared_mutex> lock(_buckets[i]->_mutex);
84 for (typename bucket_type::bucket_iterator it = _buckets[i]->data.begin();
85 it != _buckets[i]->data.end();
86 ++it) {
87 res.insert(*it);
88 }
89 }
90
91 return res;
92 }
93
94 int max_collisions() { return _buckets[0]->data.size() ? _buckets[0]->data.size() - 1 : 0; }
95
96 std::size_t size()
97 {
98 std::size_t count = 0;
99
100 for (unsigned i = 0; i < _buckets.size(); ++i) {
101 boost::unique_lock<boost::shared_mutex> lock(_buckets[i]->_mutex);
102 for (typename bucket_type::bucket_iterator it = _buckets[i]->data.begin();
103 it != _buckets[i]->data.end();
104 ++it) {
105 count++;
106 }
107 }
108
109 return count;
110 }
111
112 void clear()
113 {
114 for (unsigned i = 0; i < _buckets.size(); ++i) {
115 boost::unique_lock<boost::shared_mutex> lock(_buckets[i]->_mutex);
116 _buckets[i]->data.clear();
117 }
118 }
119
120private:
121 std::vector<std::unique_ptr<bucket_type>> _buckets;
122 Hash hasher;
123
124 bucket_type &get_bucket(Key const &key) const
125 {
126 const std::size_t bucket_index = hasher(key) % _buckets.size();
127 return *_buckets[bucket_index];
128 }
129
131 {
132 typedef std::pair<Key, Value> bucket_value;
133 typedef std::vector<bucket_value> bucket_data;
134
135 public:
136 typedef typename bucket_data::iterator bucket_iterator;
137
138 Value at(Key const &key, Value const &default_value)
139 {
140 boost::shared_lock<boost::shared_mutex> lock(_mutex);
141 bucket_iterator const found_entry = find_entry_for(key);
142 return (found_entry == data.end()) ? default_value : found_entry->second;
143 }
144
145 void insert(Key const &key, Value const &value)
146 {
147 boost::unique_lock<boost::shared_mutex> lock(_mutex);
148 bucket_iterator found_entry = find_entry_for(key);
149
150 if (found_entry != data.end())
151 data.erase(found_entry);
152
153 data.push_back(bucket_value(key, value));
154 }
155
156 void erase(Key const &key)
157 {
158 boost::unique_lock<boost::shared_mutex> lock(_mutex);
159 bucket_iterator const found_entry = find_entry_for(key);
160 if (found_entry != data.end())
161 data.erase(found_entry);
162 }
163
165 mutable boost::shared_mutex _mutex;
166
167 private:
169 {
170 return std::find_if(data.begin(), data.end(),
171 [&](bucket_value const &item)
172 {
173 return item.first == key;
174 });
175 }
176 };
177};
178
179#endif /* HORIZON_CORE_MULTITHREADING_LOCKEDLOOKUPTABLE_HPP */
Definition: LockedLookupTable.hpp:131
bucket_data data
Definition: LockedLookupTable.hpp:164
void erase(Key const &key)
Definition: LockedLookupTable.hpp:156
void insert(Key const &key, Value const &value)
Definition: LockedLookupTable.hpp:145
Value at(Key const &key, Value const &default_value)
Definition: LockedLookupTable.hpp:138
bucket_data::iterator bucket_iterator
Definition: LockedLookupTable.hpp:136
bucket_iterator find_entry_for(Key const &key)
Definition: LockedLookupTable.hpp:168
std::vector< bucket_value > bucket_data
Definition: LockedLookupTable.hpp:133
boost::shared_mutex _mutex
Definition: LockedLookupTable.hpp:165
std::pair< Key, Value > bucket_value
Definition: LockedLookupTable.hpp:132
Definition: LockedLookupTable.hpp:44
void clear()
Definition: LockedLookupTable.hpp:112
Value const & operator[](Key &k)
Definition: LockedLookupTable.hpp:61
int max_collisions()
Definition: LockedLookupTable.hpp:94
void insert(const Key &key, const Value &value)
Definition: LockedLookupTable.hpp:68
Key key_type
Definition: LockedLookupTable.hpp:47
LockedLookupTable(unsigned num_buckets=19, const Hash &hasher_=Hash())
Definition: LockedLookupTable.hpp:51
Hash hash_type
Definition: LockedLookupTable.hpp:49
Hash hasher
Definition: LockedLookupTable.hpp:122
Value mapped_type
Definition: LockedLookupTable.hpp:48
Value at(Key const &key, Value const &default_value=Value()) const
Definition: LockedLookupTable.hpp:63
LockedLookupTable & operator=(const LockedLookupTable &other)=delete
std::size_t size()
Definition: LockedLookupTable.hpp:96
LockedLookupTable(const LockedLookupTable &other)=delete
bucket_type & get_bucket(Key const &key) const
Definition: LockedLookupTable.hpp:124
std::vector< std::unique_ptr< bucket_type > > _buckets
Definition: LockedLookupTable.hpp:121
void erase(const Key &key)
Definition: LockedLookupTable.hpp:73
std::map< Key, Value > get_map() const
Definition: LockedLookupTable.hpp:78
size_t count(GridTypeListContainer< SPECIFIC_TYPE > const &elements, SPECIFIC_TYPE *)
Definition: GridReferenceContainer.hpp:100