summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2013-02-26 04:54:45 +0000
committerMike Buland <eichlan@xagasoft.com>2013-02-26 04:54:45 +0000
commit772a6bef0de2dcf0b7d9d596ce86f1def4d1f03e (patch)
treea9e3be8f50309fe06c8c1d01092e6fc0d9c5b82d /src
parentf342b82c4bf125c7cb478160bf011e571c317726 (diff)
downloadlibbu++-772a6bef0de2dcf0b7d9d596ce86f1def4d1f03e.tar.gz
libbu++-772a6bef0de2dcf0b7d9d596ce86f1def4d1f03e.tar.bz2
libbu++-772a6bef0de2dcf0b7d9d596ce86f1def4d1f03e.tar.xz
libbu++-772a6bef0de2dcf0b7d9d596ce86f1def4d1f03e.zip
Added auto-lock classes to the Bu::ReadWriteMutex, I think I like that type of
encapsulation, at least for the read/write guy. Also started work on a thread-safe wrapper for the standard hash. There is a lot of functionality we just have to leave out in this, it's just too dangerous in a thread-safe class.
Diffstat (limited to 'src')
-rw-r--r--src/tests/synchrohash.cpp7
-rw-r--r--src/unstable/readwritemutex.h36
-rw-r--r--src/unstable/synchrohash.cpp0
-rw-r--r--src/unstable/synchrohash.h224
4 files changed, 267 insertions, 0 deletions
diff --git a/src/tests/synchrohash.cpp b/src/tests/synchrohash.cpp
new file mode 100644
index 0000000..7f6dbd1
--- /dev/null
+++ b/src/tests/synchrohash.cpp
@@ -0,0 +1,7 @@
1#include <bu/synchrohash.h>
2
3int main()
4{
5 Bu::SynchroHash<int, char *> Things;
6}
7
diff --git a/src/unstable/readwritemutex.h b/src/unstable/readwritemutex.h
index 8641e3f..eb159ca 100644
--- a/src/unstable/readwritemutex.h
+++ b/src/unstable/readwritemutex.h
@@ -69,6 +69,42 @@ namespace Bu
69 */ 69 */
70 void unlockWrite(); 70 void unlockWrite();
71 71
72 class ReadLocker
73 {
74 public:
75 ReadLocker( ReadWriteMutex &m ) :
76 m( m )
77 {
78 m.lockRead();
79 }
80
81 ~ReadLocker()
82 {
83 m.unlockRead();
84 }
85
86 private:
87 ReadWriteMutex &m;
88 };
89
90 class WriteLocker
91 {
92 public:
93 WriteLocker( ReadWriteMutex &m ) :
94 m( m )
95 {
96 m.lockWrite();
97 }
98
99 ~WriteLocker()
100 {
101 m.unlockWrite();
102 }
103
104 private:
105 ReadWriteMutex &m;
106 };
107
72 private: 108 private:
73 Bu::Mutex mRead; 109 Bu::Mutex mRead;
74 int iCounter; 110 int iCounter;
diff --git a/src/unstable/synchrohash.cpp b/src/unstable/synchrohash.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/unstable/synchrohash.cpp
diff --git a/src/unstable/synchrohash.h b/src/unstable/synchrohash.h
new file mode 100644
index 0000000..45572c2
--- /dev/null
+++ b/src/unstable/synchrohash.h
@@ -0,0 +1,224 @@
1/*
2 * Copyright (C) 2007-2013 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_SYNCHRO_HASH_H
9#define BU_SYNCHRO_HASH_H
10
11#include <memory>
12#include "bu/hash.h"
13#include "bu/readwritemutex.h"
14
15namespace Bu
16{
17 /**
18 * Libbu++ Thread Safe Template Hash Table. This is your average hash
19 * table, that uses
20 * template functions in order to do fast, efficient, generalized hashing.
21 * It's pretty easy to use, and works well with all other libbu++ types so
22 * far.
23 *
24 * In order to use it, I recommend the following for all basic usage:
25 *@code
26 // Define a Hash typedef with strings as keys and ints as values.
27 typedef Bu::SynchroHash<Bu::String, int> StrIntHash;
28
29 // Create one
30 StrIntHash hInts;
31
32 // Insert some integers
33 hInts["one"] = 1;
34 hInts["forty-two"] = 42;
35 hInts.insert("forty two", 42 );
36
37 // Get values out of the hash, the last two options are the most explicit,
38 // and must be used if the hash's value type does not match what you're
39 // comparing to exactly.
40 if( hInts["one"] == 1 ) doSomething();
41 if( hInts["forty-two"].value() == 42 ) doSomething();
42 if( hInts.get("forty two") == 42 ) doSomething();
43
44 // Iterate through the Hash
45 for( StrIntHash::iterator i = hInts.begin(); i != hInts.end(); i++ )
46 {
47 // i.getValue() works too
48 print("'%s' = %d\n", i.getKey().getStr(), (*i) );
49 }
50
51 @endcode
52 *@param key (typename) The datatype of the hashtable keys
53 *@param value (typename) The datatype of the hashtable data
54 *@param sizecalc (typename) Functor to compute new table size on rehash
55 *@param keyalloc (typename) Memory allocator for hashtable keys
56 *@param valuealloc (typename) Memory allocator for hashtable values
57 *@param challoc (typename) Byte allocator for bitflags
58 *@ingroup Containers
59 */
60 template<typename key, typename value,
61 typename sizecalc = __calcNextTSize_fast,
62 typename keyalloc = std::allocator<key>,
63 typename valuealloc = std::allocator<value>,
64 typename challoc = std::allocator<uint32_t>
65 >
66 class SynchroHash
67 {
68 private:
69 typedef class SynchroHash<key, value, sizecalc, keyalloc, valuealloc, challoc> MyType;
70 typedef class Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> HashType;
71
72 public:
73 SynchroHash()
74 {
75 }
76
77 virtual ~SynchroHash()
78 {
79 }
80
81 /**
82 * Get the current hash table capacity. (Changes at re-hash)
83 *@returns (uint32_t) The current capacity.
84 */
85 uint32_t getCapacity() const
86 {
87 ReadWriteMutex::ReadLocker rl( mCore );
88 return hCore.getCapacity();
89 }
90
91 /**
92 * Get the number of hash locations spoken for. (Including
93 * not-yet-cleaned-up deleted items.)
94 *@returns (uint32_t) The current fill state.
95 */
96 uint32_t getFill() const
97 {
98 ReadWriteMutex::ReadLocker rl( mCore );
99 return; hCore.getFill();
100 }
101
102 /**
103 * Get the number of items stored in the hash table.
104 *@returns (uint32_t) The number of items stored in the hash table.
105 */
106 uint32_t getSize() const
107 {
108 ReadWriteMutex::ReadLocker rl( mCore );
109 return hCore.getSize();
110 }
111
112 bool isEmpty() const
113 {
114 ReadWriteMutex::ReadLocker rl( mCore );
115 return hCore.isEmpty();
116 }
117
118 /**
119 * Get the number of items which have been deleted, but not yet
120 * cleaned up.
121 *@returns (uint32_t) The number of deleted items.
122 */
123 uint32_t getDeleted() const
124 {
125 ReadWriteMutex::ReadLocker rl( mCore );
126 return hCore.getDeleted();
127 }
128
129 /**
130 * Insert a value (v) under key (k) into the hash table
131 *@param k (key_type) Key to list the value under.
132 *@param v (value_type) Value to store in the hash table.
133 */
134 void insert( const key &k, const value &v )
135 {
136 ReadWriteMutex::WriteLocker wl( mCore );
137 hCore.insert( k, v );
138 }
139
140 /**
141 * Remove a value from the hash table.
142 *@param k (key_type) The data under this key will be erased.
143 */
144 void erase( const key &k )
145 {
146 ReadWriteMutex::WriteLocker wl( mCore );
147 hCore.erase( k );
148 }
149
150 /**
151 * Remove all data from the hash table.
152 */
153 virtual void clear()
154 {
155 ReadWriteMutex::WriteLocker wl( mCore );
156 hCore.clear();
157 }
158
159 /**
160 * Get a const item of data from the hash table.
161 *@param k (key_type) Key pointing to the data to be retrieved.
162 *@returns (const value_type &) A const version of the data pointed
163 * to by (k).
164 */
165 value get( const key &k ) const
166 {
167 ReadWriteMutex::WriteLocker wl( mCore );
168 return hCore.get( k );
169 }
170
171 /**
172 * Does the hash table contain an item under key (k).
173 *@param k (key_type) The key to check.
174 *@returns (bool) Whether there was an item in the hash under key (k).
175 */
176 bool has( const key &k ) const
177 {
178 ReadWriteMutex::ReadLocker rl( mCore );
179 return hCore.has( k );
180 }
181
182 /**
183 * Get a list of all the keys in the hash table.
184 *@returns (std::list<key_type>) The list of keys in the hash table.
185 */
186 Bu::List<key> getKeys() const
187 {
188 ReadWriteMutex::ReadLocker rl( mCore );
189 return hCore.getKeys();
190 }
191
192 Bu::List<value> getValues() const
193 {
194 ReadWriteMutex::ReadLocker rl( mCore );
195 return hCore.getValues();
196 }
197
198 bool operator==( const MyType &rhs ) const
199 {
200 ReadWriteMutex::ReadLocker rl( mCore );
201 ReadWriteMutex::ReadLocker rl2( rhs.mCore );
202 return hCore == rhs.hCore;
203 }
204
205 bool operator!=( const MyType &rhs ) const
206 {
207 return !(*this == rhs);
208 }
209
210 MyType &operator+=( const MyType &rhs )
211 {
212 ReadWriteMutex::WriteLocker wl( mCore );
213 ReadWriteMutex::ReadLocker rl( rhs.mCore );
214 hCore += rhs.hCore;
215 return *this;
216 }
217
218 private:
219 HashType hCore;
220 ReadWriteMutex mCore;
221 };
222}
223
224#endif