libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010-2012 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef __STRINGHASH_H__ 00019 #define __STRINGHASH_H__ 00020 00021 #include "StringBasics.h" 00022 #include "Constant.h" 00023 #include "Hash.h" 00024 00025 00026 class StringHashBase 00027 { 00028 public: 00029 inline void setCaseSensitive(bool caseSensitive) {myCaseSensitive = caseSensitive;} 00030 StringHashBase() 00031 : myCaseSensitive(false) 00032 {} 00033 00034 virtual ~StringHashBase() {} 00035 00036 // Make pure virtual 00037 virtual void SetSize(int newsize) = 0; 00038 00039 protected: 00040 inline bool stringsEqual(const String& string1, const String& string2) const 00041 { 00042 if(myCaseSensitive) 00043 { 00044 // Case sensitive is faster. 00045 return(string1.FastCompare(string2) == 0); 00046 } 00047 // Case insensitive - slow compare - convert to same case. 00048 return(string1.SlowCompare(string2) == 0); 00049 } 00050 00051 inline unsigned int getKey(const String& string) const 00052 { 00053 if(myCaseSensitive) 00054 { 00055 return(hash(string.uchar(), string.Length(), 0)); 00056 } 00057 // Case insensitive. 00058 return(hash_no_case(string.uchar(), string.Length(), 0)); 00059 } 00060 00061 bool myCaseSensitive; 00062 }; 00063 00064 00065 class StringHash : public StringHashBase 00066 { 00067 protected: 00068 String ** strings; 00069 void ** objects; 00070 unsigned int * keys; 00071 unsigned int count, size; 00072 unsigned int mask; 00073 00074 public: 00075 StringHash(int startsize = 32); 00076 virtual ~StringHash(); 00077 00078 void Grow() 00079 { 00080 SetSize(size * 2); 00081 } 00082 void Shrink() 00083 { 00084 SetSize(size / 2); 00085 } 00086 00087 void SetSize(int newsize); 00088 00089 void Clear(); 00090 00091 int Capacity() const 00092 { 00093 return size; 00094 } 00095 int Entries() const 00096 { 00097 return count; 00098 } 00099 00100 void * Object(int i) const 00101 { 00102 return objects[i]; 00103 } 00104 void * Object(const String & key) const 00105 { 00106 int index = Find(key); 00107 00108 return index >= 0 ? objects[index] : NULL; 00109 } 00110 void * Object(const String & key, void *(*create_object)()) 00111 { 00112 int index = Find(key, create_object); 00113 00114 return objects[index]; 00115 } 00116 00117 void SetObject(int i, void * object) 00118 { 00119 objects[i] = object; 00120 } 00121 void SetObject(const String & key, void * object) 00122 { 00123 Add(key, object); 00124 } 00125 00126 int Add(const String & s, void * object = NULL); 00127 int Find(const String & s, void *(*create_object)() = NULL); 00128 int Find(const String & s) const; 00129 00130 StringHash & operator = (const StringHash & rhs); 00131 00132 const String & operator [](int i) const 00133 { 00134 return *(strings[i]); 00135 } 00136 String & operator [](int i) 00137 { 00138 return *(strings[i]); 00139 } 00140 // String & String(int i) { return *(strings[i]); } 00141 00142 static void * CreateHash(); 00143 00144 void Delete(unsigned int index); 00145 void Delete(const String & key) 00146 { 00147 Delete(Find(key)); 00148 } 00149 00150 bool SlotInUse(int index) const 00151 { 00152 return strings[index] != NULL; 00153 } 00154 00155 void Print(); 00156 void Print(FILE * file); 00157 void Print(const char * filename); 00158 00159 String StringList(char separator = ','); 00160 00161 // Initialize hash with the contents of a file 00162 void ReadLinesFromFile(FILE * file); 00163 void ReadLinesFromFile(const char * filename); 00164 00165 void ReadLinesFromFile(IFILE & file); 00166 00167 void Swap(StringHash & s); 00168 00169 private: 00170 00171 unsigned int Iterate(unsigned int key, const String & string) const 00172 { 00173 unsigned int h = key & mask; 00174 00175 while (strings[h] != NULL && 00176 (keys[h] != key || 00177 (!stringsEqual(*(strings[h]), string)))) 00178 h = (h + 1) & mask; 00179 00180 return h; 00181 } 00182 00183 void Insert(unsigned int where, unsigned int key, const String & string) 00184 { 00185 strings[where] = new String; 00186 *(strings[where]) = string; 00187 keys[where] = key; 00188 00189 count++; 00190 } 00191 }; 00192 00193 class StringIntHash : public StringHashBase 00194 { 00195 protected: 00196 String ** strings; 00197 int * integers; 00198 unsigned int * keys; 00199 unsigned int count, size; 00200 unsigned int mask; 00201 00202 public: 00203 StringIntHash(int startsize = 32); 00204 virtual ~StringIntHash(); 00205 00206 void Grow() 00207 { 00208 SetSize(size * 2); 00209 } 00210 void Shrink() 00211 { 00212 SetSize(size / 2); 00213 } 00214 00215 void SetSize(int newsize); 00216 00217 void Clear(); 00218 00219 int Capacity() const 00220 { 00221 return size; 00222 } 00223 int Entries() const 00224 { 00225 return count; 00226 } 00227 00228 int Integer(int i) const 00229 { 00230 return integers[i]; 00231 } 00232 int Integer(const String & key) const 00233 { 00234 int index = Find(key); 00235 00236 return index >= 0 ? integers[index] : -1; 00237 } 00238 00239 void SetInteger(int i, int value) 00240 { 00241 integers[i] = value; 00242 } 00243 void SetInteger(const String & key, int value) 00244 { 00245 Add(key, value); 00246 } 00247 00248 int IncrementCount(const String & key); 00249 int IncrementCount(const String & key, int amount); 00250 int DecrementCount(const String & key); 00251 int GetCount(const String & key) const; 00252 int GetCount(int index) const 00253 { 00254 return integers[index]; 00255 } 00256 00257 int Add(const String & s, int integer); 00258 int Find(const String & s, int defaultValue); 00259 int Find(const String & s) const; 00260 00261 StringIntHash & operator = (const StringIntHash & rhs); 00262 bool operator == (const StringIntHash & rhs) const; 00263 00264 const String & operator [](int i) const 00265 { 00266 return *(strings[i]); 00267 } 00268 String & operator [](int i) 00269 { 00270 return *(strings[i]); 00271 } 00272 // String & String(int i) { return *(strings[i]); } 00273 00274 void Delete(unsigned int index); 00275 void Delete(const String & key) 00276 { 00277 Delete(Find(key)); 00278 } 00279 00280 bool SlotInUse(int index) const 00281 { 00282 return strings[index] != NULL; 00283 } 00284 00285 private: 00286 00287 unsigned int Iterate(unsigned int key, const String & string) const 00288 { 00289 unsigned int h = key & mask; 00290 00291 while (strings[h] != NULL && 00292 (keys[h] != key || 00293 (!stringsEqual(*(strings[h]), string)))) 00294 h = (h + 1) & mask; 00295 00296 return h; 00297 } 00298 00299 void Insert(unsigned int where, unsigned int key, const String & string) 00300 { 00301 strings[where] = new String; 00302 *(strings[where]) = string; 00303 keys[where] = key; 00304 00305 count++; 00306 } 00307 }; 00308 00309 class StringDoubleHash : public StringHashBase 00310 { 00311 protected: 00312 String ** strings; 00313 double * doubles; 00314 unsigned int * keys; 00315 unsigned int count, size; 00316 unsigned int mask; 00317 00318 public: 00319 StringDoubleHash(int startsize = 32); 00320 virtual ~StringDoubleHash(); 00321 00322 void Grow() 00323 { 00324 SetSize(size * 2); 00325 } 00326 void Shrink() 00327 { 00328 SetSize(size / 2); 00329 } 00330 00331 void SetSize(int newsize); 00332 00333 void Clear(); 00334 00335 int Capacity() const 00336 { 00337 return size; 00338 } 00339 int Entries() const 00340 { 00341 return count; 00342 } 00343 00344 double Double(int i) const 00345 { 00346 return doubles[i]; 00347 } 00348 double Double(const String & key) const 00349 { 00350 int index = Find(key); 00351 00352 return index >= 0 ? doubles[index] : _NAN_; 00353 } 00354 00355 void SetDouble(int i, double value) 00356 { 00357 doubles[i] = value; 00358 } 00359 void SetDouble(const String & key, double value) 00360 { 00361 Add(key, value); 00362 } 00363 00364 int Add(const String & s, double value); 00365 int Find(const String & s, double defaultValue); 00366 int Find(const String & s) const; 00367 00368 StringDoubleHash & operator = (const StringDoubleHash & rhs); 00369 00370 const String & operator [](int i) const 00371 { 00372 return *(strings[i]); 00373 } 00374 String & operator [](int i) 00375 { 00376 return *(strings[i]); 00377 } 00378 // String & String(int i) { return *(strings[i]); } 00379 00380 void Delete(unsigned int index); 00381 void Delete(const String & key) 00382 { 00383 Delete(Find(key)); 00384 } 00385 00386 bool SlotInUse(int index) const 00387 { 00388 return strings[index] != NULL; 00389 } 00390 00391 private: 00392 00393 unsigned int Iterate(unsigned int key, const String & string) const 00394 { 00395 unsigned int h = key & mask; 00396 00397 while (strings[h] != NULL && 00398 (keys[h] != key || 00399 (!stringsEqual(*(strings[h]), string)))) 00400 h = (h + 1) & mask; 00401 00402 return h; 00403 } 00404 00405 void Insert(unsigned int where, unsigned int key, const String & string) 00406 { 00407 strings[where] = new String; 00408 *(strings[where]) = string; 00409 keys[where] = key; 00410 00411 count++; 00412 } 00413 }; 00414 00415 00416 #endif