libStatGen Software  1
StringHash.h
1 /*
2  * Copyright (C) 2010-2012 Regents of the University of Michigan
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __STRINGHASH_H__
19 #define __STRINGHASH_H__
20 
21 #include "StringBasics.h"
22 #include "Constant.h"
23 #include "Hash.h"
24 
25 
27 {
28 public:
29  inline void setCaseSensitive(bool caseSensitive) {myCaseSensitive = caseSensitive;}
31  : myCaseSensitive(false)
32  {}
33 
34  virtual ~StringHashBase() {}
35 
36  // Make pure virtual
37  virtual void SetSize(int newsize) = 0;
38 
39 protected:
40  inline bool stringsEqual(const String& string1, const String& string2) const
41  {
42  if(myCaseSensitive)
43  {
44  // Case sensitive is faster.
45  return(string1.FastCompare(string2) == 0);
46  }
47  // Case insensitive - slow compare - convert to same case.
48  return(string1.SlowCompare(string2) == 0);
49  }
50 
51  inline unsigned int getKey(const String& string) const
52  {
53  if(myCaseSensitive)
54  {
55  return(hash(string.uchar(), string.Length(), 0));
56  }
57  // Case insensitive.
58  return(hash_no_case(string.uchar(), string.Length(), 0));
59  }
60 
61  bool myCaseSensitive;
62 };
63 
64 
65 class StringHash : public StringHashBase
66 {
67 protected:
68  String ** strings;
69  void ** objects;
70  unsigned int * keys;
71  unsigned int count, size;
72  unsigned int mask;
73 
74 public:
75  StringHash(int startsize = 32);
76  virtual ~StringHash();
77 
78  void Grow()
79  {
80  SetSize(size * 2);
81  }
82  void Shrink()
83  {
84  SetSize(size / 2);
85  }
86 
87  void SetSize(int newsize);
88 
89  void Clear();
90 
91  int Capacity() const
92  {
93  return size;
94  }
95  int Entries() const
96  {
97  return count;
98  }
99 
100  void * Object(int i) const
101  {
102  return objects[i];
103  }
104  void * Object(const String & key) const
105  {
106  int index = Find(key);
107 
108  return index >= 0 ? objects[index] : NULL;
109  }
110  void * Object(const String & key, void *(*create_object)())
111  {
112  int index = Find(key, create_object);
113 
114  return objects[index];
115  }
116 
117  void SetObject(int i, void * object)
118  {
119  objects[i] = object;
120  }
121  void SetObject(const String & key, void * object)
122  {
123  Add(key, object);
124  }
125 
126  int Add(const String & s, void * object = NULL);
127  int Find(const String & s, void *(*create_object)() = NULL);
128  int Find(const String & s) const;
129 
130  StringHash & operator = (const StringHash & rhs);
131 
132  const String & operator [](int i) const
133  {
134  return *(strings[i]);
135  }
136  String & operator [](int i)
137  {
138  return *(strings[i]);
139  }
140 // String & String(int i) { return *(strings[i]); }
141 
142  static void * CreateHash();
143 
144  void Delete(unsigned int index);
145  void Delete(const String & key)
146  {
147  Delete(Find(key));
148  }
149 
150  bool SlotInUse(int index) const
151  {
152  return strings[index] != NULL;
153  }
154 
155  void Print();
156  void Print(FILE * file);
157  void Print(const char * filename);
158 
159  String StringList(char separator = ',');
160 
161  // Initialize hash with the contents of a file
162  void ReadLinesFromFile(FILE * file);
163  void ReadLinesFromFile(const char * filename);
164 
165  void ReadLinesFromFile(IFILE & file);
166 
167  void Swap(StringHash & s);
168 
169 private:
170 
171  unsigned int Iterate(unsigned int key, const String & string) const
172  {
173  unsigned int h = key & mask;
174 
175  while (strings[h] != NULL &&
176  (keys[h] != key ||
177  (!stringsEqual(*(strings[h]), string))))
178  h = (h + 1) & mask;
179 
180  return h;
181  }
182 
183  void Insert(unsigned int where, unsigned int key, const String & string)
184  {
185  strings[where] = new String;
186  *(strings[where]) = string;
187  keys[where] = key;
188 
189  count++;
190  }
191 };
192 
194 {
195 protected:
196  String ** strings;
197  int * integers;
198  unsigned int * keys;
199  unsigned int count, size;
200  unsigned int mask;
201 
202 public:
203  StringIntHash(int startsize = 32);
204  virtual ~StringIntHash();
205 
206  void Grow()
207  {
208  SetSize(size * 2);
209  }
210  void Shrink()
211  {
212  SetSize(size / 2);
213  }
214 
215  void SetSize(int newsize);
216 
217  void Clear();
218 
219  int Capacity() const
220  {
221  return size;
222  }
223  int Entries() const
224  {
225  return count;
226  }
227 
228  int Integer(int i) const
229  {
230  return integers[i];
231  }
232  int Integer(const String & key) const
233  {
234  int index = Find(key);
235 
236  return index >= 0 ? integers[index] : -1;
237  }
238 
239  void SetInteger(int i, int value)
240  {
241  integers[i] = value;
242  }
243  void SetInteger(const String & key, int value)
244  {
245  Add(key, value);
246  }
247 
248  int IncrementCount(const String & key);
249  int IncrementCount(const String & key, int amount);
250  int DecrementCount(const String & key);
251  int GetCount(const String & key) const;
252  int GetCount(int index) const
253  {
254  return integers[index];
255  }
256 
257  int Add(const String & s, int integer);
258  int Find(const String & s, int defaultValue);
259  int Find(const String & s) const;
260 
261  StringIntHash & operator = (const StringIntHash & rhs);
262  bool operator == (const StringIntHash & rhs) const;
263 
264  const String & operator [](int i) const
265  {
266  return *(strings[i]);
267  }
268  String & operator [](int i)
269  {
270  return *(strings[i]);
271  }
272 // String & String(int i) { return *(strings[i]); }
273 
274  void Delete(unsigned int index);
275  void Delete(const String & key)
276  {
277  Delete(Find(key));
278  }
279 
280  bool SlotInUse(int index) const
281  {
282  return strings[index] != NULL;
283  }
284 
285 private:
286 
287  unsigned int Iterate(unsigned int key, const String & string) const
288  {
289  unsigned int h = key & mask;
290 
291  while (strings[h] != NULL &&
292  (keys[h] != key ||
293  (!stringsEqual(*(strings[h]), string))))
294  h = (h + 1) & mask;
295 
296  return h;
297  }
298 
299  void Insert(unsigned int where, unsigned int key, const String & string)
300  {
301  strings[where] = new String;
302  *(strings[where]) = string;
303  keys[where] = key;
304 
305  count++;
306  }
307 };
308 
310 {
311 protected:
312  String ** strings;
313  double * doubles;
314  unsigned int * keys;
315  unsigned int count, size;
316  unsigned int mask;
317 
318 public:
319  StringDoubleHash(int startsize = 32);
320  virtual ~StringDoubleHash();
321 
322  void Grow()
323  {
324  SetSize(size * 2);
325  }
326  void Shrink()
327  {
328  SetSize(size / 2);
329  }
330 
331  void SetSize(int newsize);
332 
333  void Clear();
334 
335  int Capacity() const
336  {
337  return size;
338  }
339  int Entries() const
340  {
341  return count;
342  }
343 
344  double Double(int i) const
345  {
346  return doubles[i];
347  }
348  double Double(const String & key) const
349  {
350  int index = Find(key);
351 
352  return index >= 0 ? doubles[index] : _NAN_;
353  }
354 
355  void SetDouble(int i, double value)
356  {
357  doubles[i] = value;
358  }
359  void SetDouble(const String & key, double value)
360  {
361  Add(key, value);
362  }
363 
364  int Add(const String & s, double value);
365  int Find(const String & s, double defaultValue);
366  int Find(const String & s) const;
367 
368  StringDoubleHash & operator = (const StringDoubleHash & rhs);
369 
370  const String & operator [](int i) const
371  {
372  return *(strings[i]);
373  }
374  String & operator [](int i)
375  {
376  return *(strings[i]);
377  }
378 // String & String(int i) { return *(strings[i]); }
379 
380  void Delete(unsigned int index);
381  void Delete(const String & key)
382  {
383  Delete(Find(key));
384  }
385 
386  bool SlotInUse(int index) const
387  {
388  return strings[index] != NULL;
389  }
390 
391 private:
392 
393  unsigned int Iterate(unsigned int key, const String & string) const
394  {
395  unsigned int h = key & mask;
396 
397  while (strings[h] != NULL &&
398  (keys[h] != key ||
399  (!stringsEqual(*(strings[h]), string))))
400  h = (h + 1) & mask;
401 
402  return h;
403  }
404 
405  void Insert(unsigned int where, unsigned int key, const String & string)
406  {
407  strings[where] = new String;
408  *(strings[where]) = string;
409  keys[where] = key;
410 
411  count++;
412  }
413 };
414 
415 
416 #endif
StringDoubleHash
Definition: StringHash.h:310
String
Definition: StringBasics.h:39
StringIntHash
Definition: StringHash.h:194
InputFile
Class for easily reading/writing files without having to worry about file type (uncompressed,...
Definition: InputFile.h:37
StringHash
Definition: StringHash.h:66
StringHashBase
Definition: StringHash.h:27