Edinburgh Speech Tools  2.1-release
EST_THash.h
Go to the documentation of this file.
1  /************************************************************************/
2  /* */
3  /* Centre for Speech Technology Research */
4  /* University of Edinburgh, UK */
5  /* Copyright (c) 1996,1997 */
6  /* All Rights Reserved. */
7  /* */
8  /* Permission is hereby granted, free of charge, to use and distribute */
9  /* this software and its documentation without restriction, including */
10  /* without limitation the rights to use, copy, modify, merge, publish, */
11  /* distribute, sublicense, and/or sell copies of this work, and to */
12  /* permit persons to whom this work is furnished to do so, subject to */
13  /* the following conditions: */
14  /* 1. The code must retain the above copyright notice, this list of */
15  /* conditions and the following disclaimer. */
16  /* 2. Any modifications must be clearly marked as such. */
17  /* 3. Original authors' names are not deleted. */
18  /* 4. The authors' names are not used to endorse or promote products */
19  /* derived from this software without specific prior written */
20  /* permission. */
21  /* */
22  /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23  /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24  /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25  /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26  /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27  /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28  /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29  /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30  /* THIS SOFTWARE. */
31  /* */
32  /************************************************************************/
33  /* Author: Richard Caley (rjc@cstr.ed.ac.uk) */
34  /************************************************************************/
35 
36 #ifndef __EST_THASH_H__
37 #define __EST_THASH_H__
38 
39 #include <iostream>
40 
41 #include "EST_String.h"
42 #include "EST_system.h"
43 #include "EST_bool.h"
44 #include "EST_TIterator.h"
45 
46 #include "instantiate/EST_THashI.h"
48 
49 /**@defgroup HashTables Hash Tables
50  * @ingroup containerclasses
51  *
52  * @author Richard Caley <rjc@cstr.ed.ac.uk>
53  * @version $Id: EST_THash.h,v 1.6 2004/09/29 08:24:17 robert Exp $
54  */
55 ///@{
56 
57 /** \class EST_HashFunctions
58  * \brief This is just a convenient place to put some useful hash functions.
59  */
61 public:
62  /// A generally useful hash function.
63  static unsigned int DefaultHash(const void *data, ssize_t size, unsigned int n);
64 
65  /// A hash function for strings.
66  static unsigned int StringHash(const EST_String &key, unsigned int size);
67 };
68 
69 template<class K, class V> class EST_THash;
70 
71 /** \class EST_Hash_Pair
72  * \brief This class is used in hash tables to hold a key value pair.
73  * Not much to say beyond that.
74  */
75 template<class K, class V>
77 public:
78  /// The key
79  K k;
80  /// The value
81  V v;
82 
83  /// A constructor:
85  k=K();
86  v=V();
87  next=0;
88  }
89 private:
90  /// Pointer used to chain entries into buckets.
91  EST_Hash_Pair<K,V> *next;
92 
93  /// The hash table must be a friend so it can see the pointer.
94  friend class EST_THash<K, V>;
95 };
96 
97 /** \class EST_THash
98  * \brief An open hash table. The number of buckets should be set to allow
99  * enough space that there are relatively few entries per bucket on
100  * average.
101  */
102 template<class K, class V>
103 class EST_THash : protected EST_HashFunctions {
104 
105 private:
106  /// Something to return when there is no entry in the table.
107  static V Dummy_Value;
108  static K Dummy_Key;
109 
110  /// Total number of entries.
111  unsigned int p_num_entries;
112 
113  /// Number of buckets.
114  unsigned int p_num_buckets;
115 
116  /// Pointer to an array of <variable>p_num_buckets</variable>buckets.
117  EST_Hash_Pair<K,V> **p_buckets;
118 
119  /// The hash function to use on this table.
120  unsigned int (*p_hash_function)(const K &key, unsigned int size);
121 
122 public:
123  /** Create a table with the given number of buckets. Optionally setting
124  * a custom hash function.
125  */
126  EST_THash(int size,
127  unsigned int (*hash_function)(const K &key, unsigned int size)= NULL);
128 
129  /// Create a copy
130  EST_THash(const EST_THash<K,V> &from);
131 
132  /// Destroy the table.
133  ~EST_THash(void);
134 
135  /// Empty the table.
136  void clear(void);
137 
138  /// Return the total number of entries in the table.
139  unsigned int num_entries(void) const
140  { return p_num_entries; };
141 
142  /// Does the key have an entry?
143  int present(const K &key) const;
144 
145  /** Return the value associated with the key.
146  * `found` is set to whether such an entry was found.
147  */
148  V &val(const K &key, int &found) const;
149 
150  /// Return the value associated with the key.
151  V &val(const K &key) const {int x; return val(key, x); }
152 
153  const K &key(const V &val, int &found) const;
154  const K &key(const V &val) const {int x; return key(val, x); }
155 
156  /// Copy all entries
157  void copy(const EST_THash<K,V> &from);
158 
159  /// Apply `func` to each entry in the table.
160  void map(void (*func)(K&, V&));
161 
162  /// Add an entry to the table.
163  int add_item(const K &key, const V &value, int no_search = 0);
164 
165  /// Remove an entry from the table.
166  int remove_item(const K &rkey, int quiet = 0);
167 
168  /// Assignment is a copy operation
169  EST_THash<K,V> &operator = (const EST_THash<K,V> &from);
170 
171  /// Print the table to `stream` in a human readable format.
172  void dump(ostream &stream, int all=0);
173 
174  /**@name Pair Iteration
175  *
176  * This iterator steps through the table returning key-value pairs.
177  */
178  ///@{
179 protected:
180  /** A position in the table is given by a bucket number and a
181  * pointer into the bucket.
182  */
183  // struct IPointer{ unsigned int b; EST_Hash_Pair<K, V> *p; };
184  class IPointer{
185  public:
186  unsigned int b;
189  b = 0;
190  p = 0;
191  };
192  };
193 
194  //typedef class IPointer_s IPointer;
195 
196  /// Shift to point at something.
197  void skip_blank(IPointer &ip) const
198  {
199  while (ip.p==NULL && ip.b<p_num_buckets)
200  {ip.b++; ip.p = ip.b<p_num_buckets?p_buckets[ip.b]:0; }
201  }
202 
203  /// Go to start of the table.
204  void point_to_first(IPointer &ip) const
205  { ip.b=0; ip.p = ip.b<p_num_buckets?p_buckets[ip.b]:0;
206  skip_blank(ip);}
207 
208  /// Move pointer forwards, at the end of the bucket, move down.
209  void move_pointer_forwards(IPointer &ip) const
210  {
211  ip.p = ip.p->next;
212  skip_blank(ip);
213  }
214 
215  /// We are at the end if the pointer ever becomes NULL
216  bool points_to_something(const IPointer &ip) const { return ip.b<p_num_buckets; }
217 
218  /// Return the contents of this entry.
219  EST_Hash_Pair<K, V> &points_at(const IPointer &ip) { return *(ip.p); }
220 
221  /// The iterator must be a friend to access this private interface.
222  friend class EST_TStructIterator< EST_THash<K, V>, IPointer, EST_Hash_Pair<K, V> >;
223  friend class EST_TRwStructIterator< EST_THash<K, V>, IPointer, EST_Hash_Pair<K, V> >;
224  friend class EST_TIterator< EST_THash<K, V>, IPointer, EST_Hash_Pair<K, V> >;
225  friend class EST_TRwIterator< EST_THash<K, V>, IPointer, EST_Hash_Pair<K, V> >;
226 
227 public:
228  /// An entry returned by the iterator is a key value pair.
230 
231  /// Give the iterator a sensible name.
234  ///@}
235 
236  /**@name Key Iteration
237  *
238  * This iterator steps through the table returning just keys.
239  */
240  ///@{
241 protected:
242  /** A position in the table is given by a bucket number and a
243  * pointer into the bucket.
244  */
245  class IPointer_k {
246  public:
247  unsigned int b;
250  b=0;
251  p=0;
252  };
253  };
254 
255  //typedef struct IPointer_k_s IPointer_k;
256 
257  /// Shift to point at something.
258  void skip_blank(IPointer_k &ip) const
259  {
260  while (ip.p==NULL && ip.b<p_num_buckets)
261  {ip.b++; ip.p = ip.b<p_num_buckets?p_buckets[ip.b]:0; }
262  }
263 
264  /// Go to start of the table.
265  void point_to_first(IPointer_k &ip) const
266  { ip.b=0; ip.p = ip.b<p_num_buckets?p_buckets[ip.b]:0;
267  skip_blank(ip);}
268 
269  /// Move pointer forwards, at the end of the bucket, move down.
270  void move_pointer_forwards(IPointer_k &ip) const
271  {
272  ip.p = ip.p->next;
273  skip_blank(ip);
274  }
275 
276  /// We are at the end if the pointer ever becomes NULL
277  bool points_to_something(const IPointer_k &ip) const { return ip.b<p_num_buckets; }
278 
279  /// Return the key of this entry.
280  K &points_at(const IPointer_k &ip) { return (ip.p)->k; }
281 
282  /// The iterator must be a friend to access this private interface.
283  friend class EST_TIterator< EST_THash<K, V>, IPointer_k, K >;
284  friend class EST_TRwIterator< EST_THash<K, V>, IPointer_k, K >;
285 
286 public:
287  /// An entry returned by this iterator is just a key.
288  typedef K KeyEntry;
289 
290  /// Give the iterator a sensible name.
291  typedef EST_TIterator< EST_THash<K, V>, IPointer_k, K > KeyEntries;
293  ///@}
294 
295 };
296 
297 /** \class EST_TStringHash
298  * \brief A specialised hash table for when the key is an EST_String.
299  *
300  * This is just a version of EST_THash which
301  * has a different default hash function.
302  */
303 template<class V>
304 class EST_TStringHash : public EST_THash<EST_String, V> {
305 public:
306 
307  /// Create a string hash table of `size` buckets.
309 
310  /// An entry returned by the iterator is a key value pair.
312 
313 /* struct IPointer_s{ unsigned int b; Entry *p; };
314  typedef struct IPointer_s IPointer; */
315 
316  // Convince GCC that the IPointer we're going to use is a typename
318 
319  /// Give the iterator a sensible name.
322 
323  typedef EST_TRwStructIterator< EST_THash<EST_String, V>, typename EST_THash<EST_String, V>::IPointer,
325 
327 
328 /* struct IPointer_k_s { unsigned int b; EST_Hash_Pair<EST_String, V> *p; };
329  typedef struct IPointer_k_s IPointer_k; */
330 
331  /// Give the iterator a sensible name.
332 
333  // Convince GCC that the IPointer_k we're going to use is a typename
335 
338  typedef EST_TRwIterator< EST_THash<EST_String, V>, typename EST_THash<EST_String, V>::IPointer_k,
340 };
341 
342  ///@}
343 
344 /** \brief The default hash function used by EST_THash
345  */
346 inline static unsigned int DefaultHashFunction(const void *data, ssize_t size, unsigned int n)
347 {
348  unsigned int x=0;
349  const char *p = (const char *)data;
350  for(; size>0 ; p++, size--)
351  x = ((x+*p)*33) % n;
352  return x;
353 }
354 
355 #endif
static unsigned int DefaultHash(const void *data, ssize_t size, unsigned int n)
A generally useful hash function.
Definition: THash_aux.cc:45
EST_Hash_Pair< K, V > * p
Definition: EST_THash.h:248
EST_Hash_Pair()
A constructor:
Definition: EST_THash.h:84
EST_TIterator< EST_THash< K, V >, IPointer_k, K > KeyEntries
Give the iterator a sensible name.
Definition: EST_THash.h:291
EST_TRwStructIterator< EST_THash< K, V >, IPointer, EST_Hash_Pair< K, V > > RwEntries
Definition: EST_THash.h:233
EST_TStructIterator< EST_THash< K, V >, IPointer, EST_Hash_Pair< K, V > > Entries
Give the iterator a sensible name.
Definition: EST_THash.h:232
unsigned int num_entries(void) const
Return the total number of entries in the table.
Definition: EST_THash.h:139
EST_TStructIterator< EST_THash< EST_String, V >, typename EST_THash< EST_String, V >::IPointer, EST_Hash_Pair< EST_String, V > > Entries
Give the iterator a sensible name.
Definition: EST_THash.h:321
A specialised hash table for when the key is an EST_String.
Definition: EST_THash.h:304
EST_TRwIterator< EST_THash< K, V >, IPointer_k, K > KeyRwEntries
Definition: EST_THash.h:292
int ssize_t
void skip_blank(IPointer_k &ip) const
Shift to point at something.
Definition: EST_THash.h:258
EST_String KeyEntry
Definition: EST_THash.h:326
EST_TStringHash(int size)
Create a string hash table of size buckets.
Definition: EST_THash.h:308
void point_to_first(IPointer_k &ip) const
Go to start of the table.
Definition: EST_THash.h:265
unsigned int b
Definition: EST_THash.h:186
bool points_to_something(const IPointer_k &ip) const
We are at the end if the pointer ever becomes NULL.
Definition: EST_THash.h:277
EST_THash< EST_String, V >::IPointer_k TN_IPointer_k
Give the iterator a sensible name.
Definition: EST_THash.h:334
V v
The value.
Definition: EST_THash.h:81
K k
The key.
Definition: EST_THash.h:79
K KeyEntry
An entry returned by this iterator is just a key.
Definition: EST_THash.h:288
void point_to_first(IPointer &ip) const
Go to start of the table.
Definition: EST_THash.h:204
void move_pointer_forwards(IPointer_k &ip) const
Move pointer forwards, at the end of the bucket, move down.
Definition: EST_THash.h:270
void move_pointer_forwards(IPointer &ip) const
Move pointer forwards, at the end of the bucket, move down.
Definition: EST_THash.h:209
K & points_at(const IPointer_k &ip)
Return the key of this entry.
Definition: EST_THash.h:280
EST_TVector< T > & copy(EST_TVector< T > a, const EST_TList< T > &in)
NULL
Definition: EST_WFST.cc:55
This is just a convenient place to put some useful hash functions.
Definition: EST_THash.h:60
V & val(const K &key) const
Return the value associated with the key.
Definition: EST_THash.h:151
static unsigned int StringHash(const EST_String &key, unsigned int size)
A hash function for strings.
Definition: THash_aux.cc:50
getString int
Definition: EST_item_aux.cc:50
void skip_blank(IPointer &ip) const
Shift to point at something.
Definition: EST_THash.h:197
const K & key(const V &val) const
Definition: EST_THash.h:154
EST_Hash_Pair< K, V > * p
Definition: EST_THash.h:187
EST_TIterator< EST_THash< EST_String, V >, typename EST_THash< EST_String, V >::IPointer_k, EST_String > KeyEntries
Definition: EST_THash.h:337
An open hash table. The number of buckets should be set to allow enough space that there are relative...
Definition: EST_THash.h:69
EST_TRwIterator< EST_THash< EST_String, V >, typename EST_THash< EST_String, V >::IPointer_k, EST_String > KeyRwEntries
Definition: EST_THash.h:339
EST_THash< EST_String, V >::IPointer TN_IPointer
Definition: EST_THash.h:317
EST_Hash_Pair< K, V > Entry
An entry returned by the iterator is a key value pair.
Definition: EST_THash.h:229
void remove_item(EST_Item *l, const char *relname)
Definition: EST_Item.cc:614
EST_Hash_Pair< K, V > & points_at(const IPointer &ip)
Return the contents of this entry.
Definition: EST_THash.h:219
This class is used in hash tables to hold a key value pair. Not much to say beyond that...
Definition: EST_THash.h:76
bool points_to_something(const IPointer &ip) const
We are at the end if the pointer ever becomes NULL.
Definition: EST_THash.h:216
EST_TRwStructIterator< EST_THash< EST_String, V >, typename EST_THash< EST_String, V >::IPointer, EST_Hash_Pair< EST_String, V > > RwEntries
Definition: EST_THash.h:324
unsigned int b
Definition: EST_THash.h:247