]>
Commit | Line | Data |
---|---|---|
c801d85f | 1 | ///////////////////////////////////////////////////////////////////////////// |
bcaa23de | 2 | // Name: wx/hash.h |
c801d85f KB |
3 | // Purpose: wxHashTable class |
4 | // Author: Julian Smart | |
bcaa23de | 5 | // Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH() |
c801d85f KB |
6 | // Created: 01/02/97 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) | |
bcaa23de | 9 | // Licence: wxWindows licence |
c801d85f KB |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
bcaa23de VZ |
12 | #ifndef _WX_HASH_H__ |
13 | #define _WX_HASH_H__ | |
c801d85f KB |
14 | |
15 | #ifdef __GNUG__ | |
16 | #pragma interface "hash.h" | |
17 | #endif | |
18 | ||
c801d85f | 19 | #include "wx/list.h" |
c2bb85e9 | 20 | #include "wx/dynarray.h" |
c801d85f | 21 | |
bcaa23de VZ |
22 | // the default size of the hash |
23 | #define wxHASH_SIZE_DEFAULT (1000) | |
24 | ||
c801d85f KB |
25 | /* |
26 | * A hash table is an array of user-definable size with lists | |
27 | * of data items hanging off the array positions. Usually there'll | |
28 | * be a hit, so no search is required; otherwise we'll have to run down | |
29 | * the list to find the desired item. | |
30 | */ | |
31 | ||
bcaa23de VZ |
32 | // ---------------------------------------------------------------------------- |
33 | // this is the base class for object hashes: hash tables which contain | |
34 | // pointers to objects | |
35 | // ---------------------------------------------------------------------------- | |
36 | ||
37 | class WXDLLEXPORT wxHashTableBase : public wxObject | |
c801d85f | 38 | { |
bcaa23de VZ |
39 | public: |
40 | wxHashTableBase(); | |
41 | ||
42 | void Create(wxKeyType keyType = wxKEY_INTEGER, | |
43 | size_t size = wxHASH_SIZE_DEFAULT); | |
44 | void Destroy(); | |
45 | ||
46 | size_t GetSize() const { return m_hashSize; } | |
47 | size_t GetCount() const { return m_count; } | |
48 | ||
49 | void DeleteContents(bool flag); | |
50 | ||
51 | protected: | |
52 | // find the node for (key, value) | |
53 | wxNodeBase *GetNode(long key, long value) const; | |
54 | ||
55 | // the array of lists in which we store the values for given key hash | |
56 | wxListBase **m_hashTable; | |
57 | ||
58 | // the size of m_lists array | |
59 | size_t m_hashSize; | |
60 | ||
61 | // the type of indexing we use | |
62 | wxKeyType m_keyType; | |
63 | ||
64 | // the total number of elements in the hash | |
65 | size_t m_count; | |
66 | ||
67 | // should we delete our data? | |
68 | bool m_deleteContents; | |
69 | ||
70 | private: | |
71 | // no copy ctor/assignment operator (yet) | |
72 | DECLARE_NO_COPY_CLASS(wxHashTableBase); | |
c801d85f KB |
73 | }; |
74 | ||
c2bb85e9 VZ |
75 | // ---------------------------------------------------------------------------- |
76 | // a hash table which stores longs | |
77 | // ---------------------------------------------------------------------------- | |
78 | ||
79 | class WXDLLEXPORT wxHashTableLong : public wxObject | |
80 | { | |
81 | public: | |
82 | wxHashTableLong(size_t size = wxHASH_SIZE_DEFAULT) { Init(size); } | |
83 | ||
84 | void Create(size_t size = wxHASH_SIZE_DEFAULT); | |
85 | void Destroy(); | |
86 | ||
87 | size_t GetSize() const { return m_hashSize; } | |
88 | size_t GetCount() const { return m_count; } | |
89 | ||
90 | void Put(long key, long value); | |
91 | long Get(long key) const; | |
92 | long Delete(long key); | |
93 | ||
94 | protected: | |
95 | void Init(size_t size); | |
96 | ||
97 | private: | |
98 | wxArrayLong **m_values, | |
99 | **m_keys; | |
100 | ||
101 | // the size of array above | |
102 | size_t m_hashSize; | |
103 | ||
104 | // the total number of elements in the hash | |
105 | size_t m_count; | |
106 | ||
107 | // not implemented yet | |
108 | DECLARE_NO_COPY_CLASS(wxHashTableLong); | |
109 | }; | |
110 | ||
bcaa23de VZ |
111 | // ---------------------------------------------------------------------------- |
112 | // for compatibility only | |
113 | // ---------------------------------------------------------------------------- | |
114 | ||
115 | class WXDLLEXPORT wxHashTable : public wxObject | |
116 | { | |
117 | public: | |
118 | int n; | |
119 | int current_position; | |
120 | wxNode *current_node; | |
121 | ||
122 | unsigned int key_type; | |
123 | wxList **hash_table; | |
124 | ||
125 | wxHashTable(int the_key_type = wxKEY_INTEGER, | |
126 | int size = wxHASH_SIZE_DEFAULT); | |
127 | ~wxHashTable(); | |
128 | ||
129 | // copy ctor and assignment operator | |
130 | wxHashTable(const wxHashTable& table) { DoCopy(table); } | |
131 | wxHashTable& operator=(const wxHashTable& table) | |
132 | { Clear(); DoCopy(table); return *this; } | |
133 | ||
134 | void DoCopy(const wxHashTable& table); | |
135 | ||
136 | void Destroy(); | |
137 | ||
138 | bool Create(int the_key_type = wxKEY_INTEGER, | |
139 | int size = wxHASH_SIZE_DEFAULT); | |
140 | ||
141 | // Note that there are 2 forms of Put, Get. | |
142 | // With a key and a value, the *value* will be checked | |
143 | // when a collision is detected. Otherwise, if there are | |
144 | // 2 items with a different value but the same key, | |
145 | // we'll retrieve the WRONG ONE. So where possible, | |
146 | // supply the required value along with the key. | |
147 | // In fact, the value-only versions make a key, and still store | |
148 | // the value. The use of an explicit key might be required | |
149 | // e.g. when combining several values into one key. | |
150 | // When doing that, it's highly likely we'll get a collision, | |
151 | // e.g. 1 + 2 = 3, 2 + 1 = 3. | |
152 | ||
153 | // key and value are NOT necessarily the same | |
154 | void Put(long key, long value, wxObject *object); | |
155 | void Put(long key, const wxChar *value, wxObject *object); | |
156 | ||
157 | // key and value are the same | |
158 | void Put(long value, wxObject *object); | |
159 | void Put(const wxChar *value, wxObject *object); | |
160 | ||
161 | // key and value not the same | |
162 | wxObject *Get(long key, long value) const; | |
163 | wxObject *Get(long key, const wxChar *value) const; | |
164 | ||
165 | // key and value are the same | |
166 | wxObject *Get(long value) const; | |
167 | wxObject *Get(const wxChar *value) const; | |
168 | ||
169 | // Deletes entry and returns data if found | |
170 | wxObject *Delete(long key); | |
171 | wxObject *Delete(const wxChar *key); | |
172 | ||
173 | wxObject *Delete(long key, int value); | |
174 | wxObject *Delete(long key, const wxChar *value); | |
175 | ||
176 | // Construct your own integer key from a string, e.g. in case | |
177 | // you need to combine it with something | |
178 | long MakeKey(const wxChar *string) const; | |
179 | ||
180 | // Way of iterating through whole hash table (e.g. to delete everything) | |
181 | // Not necessary, of course, if you're only storing pointers to | |
182 | // objects maintained separately | |
183 | ||
184 | void BeginFind(); | |
185 | wxNode *Next(); | |
186 | ||
187 | void DeleteContents(bool flag); | |
188 | void Clear(); | |
189 | ||
190 | // Returns number of nodes | |
191 | size_t GetCount() const { return m_count; } | |
192 | ||
193 | private: | |
194 | size_t m_count; // number of elements in the hashtable | |
195 | bool m_deleteContents; | |
196 | ||
197 | DECLARE_DYNAMIC_CLASS(wxHashTable) | |
198 | }; | |
199 | ||
200 | // defines a new type safe hash table which stores the elements of type eltype | |
201 | // in lists of class listclass | |
202 | #define WX_DECLARE_HASH(eltype, listclass, hashclass) \ | |
203 | class WXDLLEXPORT hashclass : public wxHashTableBase \ | |
204 | { \ | |
205 | public: \ | |
206 | hashclass(wxKeyType keyType = wxKEY_INTEGER, \ | |
207 | size_t size = wxHASH_SIZE_DEFAULT) \ | |
208 | { Create(keyType, size); } \ | |
209 | \ | |
210 | ~hashclass() { Destroy(); } \ | |
211 | \ | |
212 | void Put(long key, long val, eltype *data) { DoPut(key, val, data); } \ | |
213 | void Put(long key, eltype *data) { DoPut(key, key, data); } \ | |
214 | \ | |
215 | eltype *Get(long key, long value) const \ | |
216 | { \ | |
217 | wxNodeBase *node = GetNode(key, value); \ | |
218 | return node ? ((listclass::Node *)node)->GetData() : (eltype *)0; \ | |
219 | } \ | |
220 | eltype *Get(long key) const { return Get(key, key); } \ | |
221 | \ | |
222 | eltype *Delete(long key, long value) \ | |
223 | { \ | |
224 | eltype *data; \ | |
225 | \ | |
226 | wxNodeBase *node = GetNode(key, value); \ | |
227 | if ( node ) \ | |
228 | { \ | |
229 | data = ((listclass::Node *)node)->GetData(); \ | |
230 | \ | |
231 | delete node; \ | |
232 | m_count--; \ | |
233 | } \ | |
234 | else \ | |
235 | { \ | |
236 | data = (eltype *)0; \ | |
237 | } \ | |
238 | \ | |
239 | return data; \ | |
240 | } \ | |
241 | eltype *Delete(long key) { return Delete(key, key); } \ | |
242 | \ | |
243 | protected: \ | |
244 | void DoPut(long key, long value, eltype *data) \ | |
245 | { \ | |
246 | size_t slot = (size_t)abs(key % m_hashSize); \ | |
247 | \ | |
248 | if ( !m_hashTable[slot] ) \ | |
249 | { \ | |
250 | m_hashTable[slot] = new listclass(m_keyType); \ | |
251 | if ( m_deleteContents ) \ | |
252 | m_hashTable[slot]->DeleteContents(TRUE); \ | |
253 | } \ | |
254 | \ | |
255 | ((listclass *)m_hashTable[slot])->Append(value, data); \ | |
256 | m_count++; \ | |
257 | } \ | |
258 | } | |
259 | ||
c801d85f | 260 | #endif |
bcaa23de | 261 | // _WX_HASH_H__ |