bd6f1cdc0c00df82bfb2e422eb9c1512820b1b36
[junction.git] / junction / extra / impl / MapAdapter_CDS_Michael.h
1 /*------------------------------------------------------------------------
2   Junction: Concurrent data structures in C++
3   Copyright (c) 2016 Jeff Preshing
4
5   Distributed under the Simplified BSD License.
6   Original location: https://github.com/preshing/junction
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the LICENSE file for more information.
11 ------------------------------------------------------------------------*/
12
13 #ifndef JUNCTION_EXTRA_IMPL_MAPADAPTER_CDS_MICHAEL_H
14 #define JUNCTION_EXTRA_IMPL_MAPADAPTER_CDS_MICHAEL_H
15
16 #include <junction/Core.h>
17
18 #if !JUNCTION_WITH_CDS
19 #error "You must configure with JUNCTION_WITH_CDS=1!"
20 #endif
21
22 #include <junction/MapTraits.h>
23 #include <cds/init.h>
24 #include <cds/gc/hp.h>
25 #include <cds/container/michael_kvlist_hp.h>
26 #include <cds/container/michael_map.h>
27
28 namespace junction {
29 namespace extra {
30
31 class MapAdapter {
32 public:
33     static TURF_CONSTEXPR const char* MapName = "CDS MichaelKVList";
34
35     cds::gc::HP* m_hpGC;
36
37     MapAdapter(ureg) {
38         cds::Initialize();
39         m_hpGC = new cds::gc::HP;
40     }
41
42     ~MapAdapter() {
43         delete m_hpGC;
44         cds::Terminate();
45     }
46
47     class ThreadContext {
48     public:
49         ThreadContext(MapAdapter&, ureg) {
50         }
51
52         void registerThread() {
53             cds::threading::Manager::attachThread();
54         }
55
56         void unregisterThread() {
57             cds::threading::Manager::detachThread();
58         }
59
60         void update() {
61         }
62     };
63
64     class Map {
65     private:
66         // List traits based on std::less predicate
67         struct ListTraits : public cds::container::michael_list::traits {
68             typedef std::less<u32> less;
69         };
70
71         // Ordered list
72         typedef cds::container::MichaelKVList<cds::gc::HP, u32, void*, ListTraits> OrderedList;
73
74         // Map traits
75         struct MapTraits : public cds::container::michael_map::traits {
76             struct hash {
77                 size_t operator()(u32 i) const {
78                     return cds::opt::v::hash<u32>()(i);
79                 }
80             };
81         };
82
83         cds::container::MichaelHashMap<cds::gc::HP, OrderedList, MapTraits> m_map;
84
85     public:
86         Map(ureg capacity) : m_map(capacity, 1) {
87         }
88
89         void set(u32 key, void* value) {
90             m_map.insert(key, value);
91         }
92
93         void* get(u32 key) {
94             void* result = NULL;
95             m_map.find(key, [&result](std::pair<const u32, void*>& item) { result = item.second; });
96             return result;
97         }
98
99         void erase(u32 key) {
100             m_map.erase(key);
101         }
102     };
103
104     static ureg getInitialCapacity(ureg maxPopulation) {
105         return maxPopulation / 4;
106     }
107 };
108
109 } // namespace extra
110 } // namespace junction
111
112 #endif // JUNCTION_EXTRA_IMPL_MAPADAPTER_CDS_MICHAEL_H