libStatGen Software  1
StringHash.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends