-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfastmap.h
119 lines (98 loc) · 2.57 KB
/
fastmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef _FASTMAP_H_INCLUDED
#define _FASTMAP_H_INCLUDED
#include <mutex>
#include <shared_mutex>
#include <vector>
#include <memory>
#include <iterator>
#include <algorithm>
#include <atomic>
#include <map>
class MutexPool final
{
public:
explicit MutexPool(size_t size)
:mutexs_()
,index_(0)
{
std::generate_n(std::back_inserter(mutexs_), size, std::make_shared<std::mutex>);
}
~MutexPool() = default;
MutexPool(const MutexPool&) = delete;
MutexPool& operator =(const MutexPool&) = delete;
std::shared_ptr<std::mutex> getMutex() const
{
return mutexs_[index_++ % mutexs_.size()];
}
private:
std::vector<std::shared_ptr<std::mutex>> mutexs_;
mutable std::atomic_size_t index_;
};
template<typename T>
class MutexSharedPtr : public std::shared_ptr<T>
{
public:
MutexSharedPtr() = default;
MutexSharedPtr(const std::shared_ptr<T>& v, const MutexPool& mutex_pool)
:std::shared_ptr<T>(v)
,mu_(mutex_pool.getMutex())
{}
protected:
std::shared_ptr<std::mutex> mu_;
};
template<typename T>
class LockPtr : public MutexSharedPtr<T>
{
public:
LockPtr() = default;
LockPtr(LockPtr<T>&&) = default;
LockPtr(const LockPtr<T>&) = delete;
LockPtr& operator= (const LockPtr<T>&) = delete;
LockPtr(MutexSharedPtr<T>& ptr)
:MutexSharedPtr<T>(ptr)
{
mu_->lock();
}
~LockPtr()
{
if (mu_)
{
mu_->unlock();
}
}
};
template<typename K, typename V>
class FastMap : private std::map<K, MutexSharedPtr<V>>
{
public:
using Base = std::map<K, MutexSharedPtr<V>>;
explicit FastMap(size_t size)
:Base()
,mutex_pool_(size)
{}
LockPtr<V> find(const K& key)
{
std::shared_lock<std::shared_mutex> guard(mu_);
auto it = Base::find(key);
if (Base::end() == it)
{
return {};
}
return LockPtr<V>(it->second);
}
template<typename...Args>
bool insert(const K& key, Args&&...args)
{
std::unique_lock<std::shared_mutex> guard(mu_);
return Base::insert(Base::value_type(key, MutexSharedPtr<V>(std::make_shared<V>(std::forward<Args>(args)...), mutex_pool_))).second;
}
bool erase(const K& key)
{
std::unique_lock<std::shared_mutex> guard(mu_);
return 0 != Base::erase(key);
}
private:
mutable std::shared_mutex mu_;
MutexPool mutex_pool_;
};
#endif //_FASTMAP_H_INCLUDED