class library: Volume - use ServerBoot to send synthdef
[supercollider.git] / server / supernova / utilities / named_hash_entry.hpp
blob7278db7b151a2d7de86a97e0a4f993229f7fe3e2
1 // Copyright (C) 2011 Tim Blechmann
2 //
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.
7 //
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
21 #include <string>
23 #include <boost/intrusive/unordered_set_hook.hpp>
24 #include <boost/unordered_set.hpp>
26 #include "utils.hpp"
27 #include "nova-tt/nova-tt/rw_mutex.hpp"
29 namespace nova {
30 namespace bi = boost::intrusive;
32 PURE inline bool strequal(const char * lhs, const char * rhs)
34 for(;;++lhs, ++rhs) {
35 if (*lhs == 0) {
36 if (*rhs == 0)
37 return true;
38 else
39 return false;
41 if (*rhs == 0)
42 return false;
43 if (*lhs != *rhs)
44 return false;
48 struct c_string
50 private:
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);
59 return string;
62 static const char * duplicate_string(const char * str)
64 return duplicate_string(str, strlen(str));
67 struct symbol_data
69 explicit symbol_data(const char * str):
70 str(str), hash(string_hash(str))
73 explicit symbol_data(const char * str, size_t hash):
74 str(str), hash(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)
83 return value.hash;
86 bool operator==(symbol_data const & rhs) const
88 return str == rhs.str;
91 const char * str;
92 size_t hash;
95 struct hash_by_string
97 size_t operator()(const char * str) const
99 return string_hash(str);
101 size_t operator()(symbol_data const & data) const
103 return data.hash;
107 struct equal_by_string
109 static const char * get_string(const char * arg)
111 return arg;
114 static const char * get_string(symbol_data const & arg)
116 return arg.str;
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));
126 class symbol_table
128 typedef boost::unordered_set<symbol_data> table_type;
129 typedef std::pair<table_type::const_iterator, bool> lookup_result_type;
131 public:
132 symbol_table(void):
133 table(16384)
136 symbol_data const & find(const char * str, size_t strlen)
138 mutex.lock_shared();
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;
154 private:
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());
161 table_type table;
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));
176 public:
177 c_string ():
178 data(NULL, 0)
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):
194 data(rhs.data)
197 const char * c_str(void) const
199 return data.str;
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;
221 symbol_data data;
224 class named_hash_entry:
225 public bi::unordered_set_base_hook<>
227 const c_string name_;
229 public:
230 named_hash_entry(const char * name):
231 name_(name)
234 named_hash_entry(c_string const & name):
235 name_(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)
249 return that.hash();
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());
333 #undef PURE
334 #endif /* UTILITIES_NAMED_HASH_ENTRY_HPP */