• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (C) 2011 Tim Blechmann
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See
4 //  accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_LOCKFREE_TEST_HELPERS
8 #define BOOST_LOCKFREE_TEST_HELPERS
9 
10 #include <set>
11 #include <boost/array.hpp>
12 #include <boost/lockfree/detail/atomic.hpp>
13 #include <boost/thread.hpp>
14 
15 #include <boost/cstdint.hpp>
16 
17 template <typename int_type>
generate_id(void)18 int_type generate_id(void)
19 {
20     static boost::lockfree::detail::atomic<int_type> generator(0);
21     return ++generator;
22 }
23 
24 template <typename int_type, size_t buckets>
25 class static_hashed_set
26 {
27 
28 public:
calc_index(int_type id)29     int calc_index(int_type id)
30     {
31         // knuth hash ... does not need to be good, but has to be portable
32         size_t factor = size_t((float)buckets * 1.616f);
33 
34         return ((size_t)id * factor) % buckets;
35     }
36 
insert(int_type const & id)37     bool insert(int_type const & id)
38     {
39         std::size_t index = calc_index(id);
40 
41         boost::lock_guard<boost::mutex> lock (ref_mutex[index]);
42 
43         std::pair<typename std::set<int_type>::iterator, bool> p;
44         p = data[index].insert(id);
45 
46         return p.second;
47     }
48 
find(int_type const & id)49     bool find (int_type const & id)
50     {
51         std::size_t index = calc_index(id);
52 
53         boost::lock_guard<boost::mutex> lock (ref_mutex[index]);
54 
55         return data[index].find(id) != data[index].end();
56     }
57 
erase(int_type const & id)58     bool erase(int_type const & id)
59     {
60         std::size_t index = calc_index(id);
61 
62         boost::lock_guard<boost::mutex> lock (ref_mutex[index]);
63 
64         if (data[index].find(id) != data[index].end()) {
65             data[index].erase(id);
66             assert(data[index].find(id) == data[index].end());
67             return true;
68         }
69         else
70             return false;
71     }
72 
count_nodes(void) const73     std::size_t count_nodes(void) const
74     {
75         std::size_t ret = 0;
76         for (int i = 0; i != buckets; ++i) {
77             boost::lock_guard<boost::mutex> lock (ref_mutex[i]);
78             ret += data[i].size();
79         }
80         return ret;
81     }
82 
83 private:
84     boost::array<std::set<int_type>, buckets> data;
85     mutable boost::array<boost::mutex, buckets> ref_mutex;
86 };
87 
88 struct test_equal
89 {
test_equaltest_equal90     test_equal(int i):
91         i(i)
92     {}
93 
operator ()test_equal94     void operator()(int arg) const
95     {
96         BOOST_REQUIRE_EQUAL(arg, i);
97     }
98 
99     int i;
100 };
101 
102 struct dummy_functor
103 {
operator ()dummy_functor104     void operator()(int /* arg */) const
105     {
106     }
107 };
108 
109 
110 #endif
111