1 // Copyright (C) 2011 Tim Blechmann
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; see the file COPYING. If not, write to
15 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 // Boston, MA 02111-1307, USA.
18 #ifndef UTILITIES_NAMED_HASH_ENTRY_HPP
19 #define UTILITIES_NAMED_HASH_ENTRY_HPP
23 #include <boost/intrusive/unordered_set_hook.hpp>
24 #include <boost/unordered_set.hpp>
27 #include "nova-tt/nova-tt/rw_mutex.hpp"
30 namespace bi
= boost::intrusive
;
32 PURE
inline bool strequal(const char * lhs
, const char * rhs
)
51 static const char * duplicate_string(const char * str
, std::size_t length
)
53 assert(strlen(str
) == length
);
55 length
+= 1; // for terminating \0
56 char * string
= malloc_aligned
<char>(length
);
58 strncpy(string
, str
, length
);
62 static const char * duplicate_string(const char * str
)
64 return duplicate_string(str
, strlen(str
));
69 explicit symbol_data(const char * str
):
70 str(str
), hash(string_hash(str
))
73 explicit symbol_data(const char * str
, size_t hash
):
77 symbol_data(symbol_data
const & rhs
):
78 str(rhs
.str
), hash(rhs
.hash
)
81 friend size_t hash_value(symbol_data
const & value
)
86 bool operator==(symbol_data
const & rhs
) const
88 return str
== rhs
.str
;
97 size_t operator()(const char * str
) const
99 return string_hash(str
);
101 size_t operator()(symbol_data
const & data
) const
107 struct equal_by_string
109 static const char * get_string(const char * arg
)
114 static const char * get_string(symbol_data
const & arg
)
119 template <typename T1
, typename T2
>
120 bool operator()(T1
const & lhs
, T2
const & rhs
) const
122 return strequal(get_string(lhs
), get_string(rhs
));
128 typedef boost::unordered_set
<symbol_data
> table_type
;
129 typedef std::pair
<table_type::const_iterator
, bool> lookup_result_type
;
136 symbol_data
const & find(const char * str
, size_t strlen
)
139 lookup_result_type lookup_result
= symbol_lookup(str
);
140 mutex
.unlock_shared();
141 if (lookup_result
.second
)
142 return *lookup_result
.first
;
144 boost::unique_lock
<nova::nonrecursive_rw_mutex
> lock(mutex
);
145 lookup_result
= symbol_lookup(str
);
146 if (lookup_result
.second
)
147 return *lookup_result
.first
;
149 std::pair
<table_type::iterator
, bool> inserted
= table
.insert(symbol_data(duplicate_string(str
, strlen
)));
150 assert(inserted
.second
);
151 return *inserted
.first
;
155 lookup_result_type
symbol_lookup(const char * str
) const
157 table_type::iterator it
= table
.find(str
, hash_by_string(), equal_by_string());
158 return std::make_pair(it
, it
!= table
.end());
162 nova::nonrecursive_rw_mutex mutex
;
165 symbol_data
lookup_string(const char * str
, std::size_t length
)
167 static symbol_table table
;
168 return table
.find(str
, length
);
171 symbol_data
lookup_string(const char * str
)
173 return lookup_string(str
, strlen(str
));
181 explicit c_string (const char * str
):
182 data(lookup_string(str
))
185 c_string (std::string
const & str
):
186 data(lookup_string(str
.c_str(), str
.size()))
189 c_string (const char * str
, std::size_t length
):
190 data(lookup_string(str
, length
))
193 c_string (c_string
const & rhs
):
197 const char * c_str(void) const
202 friend std::size_t hash_value(c_string
const & value
)
204 return value
.data
.hash
;
207 friend bool operator== (c_string
const & lhs
,
208 c_string
const & rhs
)
210 return lhs
.data
== rhs
.data
;
213 friend bool operator< (c_string
const & lhs
,
214 c_string
const & rhs
)
216 return lhs
.data
.str
< rhs
.data
.str
;
224 class named_hash_entry
:
225 public bi::unordered_set_base_hook
<>
227 const c_string name_
;
230 named_hash_entry(const char * name
):
234 named_hash_entry(c_string
const & name
):
238 named_hash_entry(std::string
const & name
):
239 name_(name
.c_str(), name
.size())
242 const char * name(void) const
244 return name_
.c_str();
247 friend std::size_t hash_value(named_hash_entry
const & that
)
252 std::size_t hash(void) const
254 return name_
.data
.hash
;
257 friend bool operator== (named_hash_entry
const & a
,
258 named_hash_entry
const & b
)
260 return a
.name_
== b
.name_
;
264 struct named_hash_equal
266 template<typename def
>
267 bool operator()(def
const & lhs
,
268 std::string
const & rhs
) const
270 return operator()(lhs
.name(), rhs
.c_str());
273 template<typename def
>
274 bool operator()(std::string
const & lhs
,
275 def
const & rhs
) const
277 return operator()(lhs
.c_str(), rhs
.name());
280 template<typename def
>
281 bool operator()(def
const & lhs
,
282 c_string
const & rhs
) const
284 return operator()(lhs
.name(), rhs
.c_str());
287 template<typename def
>
288 bool operator()(c_string
const & lhs
,
289 def
const & rhs
) const
291 return operator()(lhs
.c_str(), rhs
.name());
294 template<typename def
>
295 bool operator()(const char * lhs
, def
const & rhs
) const
297 return operator()(lhs
, rhs
.name());
300 template<typename def
>
301 bool operator()(def
const & lhs
, const char * rhs
) const
303 return operator()(lhs
.name(), rhs
);
306 bool operator()(const char * lhs
, const char * rhs
) const
308 return strequal(rhs
, lhs
);
312 struct named_hash_hash
314 template<typename def
>
315 std::size_t operator()(def
const & arg
)
317 return hash_value(arg
);
320 std::size_t operator()(const char * str
)
322 return string_hash(str
);
325 std::size_t operator()(std::string
const & str
)
327 return string_hash(str
.c_str());
334 #endif /* UTILITIES_NAMED_HASH_ENTRY_HPP */