00001 /* 00002 File: Hash.h 00003 00004 Function: Defines a string-based hash table 00005 00006 Author: Andrew Willmott 00007 00008 Copyright: 00009 */ 00010 00011 #ifndef __Hash__ 00012 #define __Hash__ 00013 00014 #include "cl/String.h" 00015 #include "cl/Array.h" 00016 00017 class HashEntry 00018 { 00019 public: 00020 Char *key; 00021 ULong hash; 00022 Void *data; 00023 }; 00024 00025 class HashIter 00026 { 00027 public: 00028 virtual Void ProcessVoidItem(StrConst s, Void *data) = 0; 00029 }; 00030 00031 class Hash 00032 { 00033 public: 00034 Hash(Int n = 0); 00035 00036 Void SetVoidItem(StrConst s, Void *data); 00037 Void *GetVoidItem(StrConst s) 00038 { 00039 HashEntry *he = Find(s); 00040 if (he && he->key) 00041 return(he->data); 00042 else 00043 return(0); 00044 }; 00045 Bool ItemExists(StrConst s) 00046 { 00047 HashEntry *he = Find(s); 00048 return(he && he->data); 00049 }; 00050 00051 Void DeleteItem(StrConst s); 00052 // delete item s 00053 Void Iterate(HashIter &iter); 00054 // iterate over all keys 00055 00056 // low-level functions 00057 00058 HashEntry *Find(StrConst s); 00059 // returns the entry corresponding to the key if it exists, 00060 // or a new entry if not. if the latter, you must set the 00061 // key field to indicate it's being used. 00062 // returns 0 if we ran out of memory. 00063 Int Init(Int n); 00064 // (re)initialises table, assuming max of n entries 00065 // returns the number of entries in the new table 00066 00067 // delete s's entry 00068 virtual Void FreeData(Void *data); 00069 00070 Void FreeKey(Char *key); 00071 Void FreeTable(); 00072 00073 ULong CalcHash(StrConst s); 00074 00075 protected: 00076 00077 Array<HashEntry> table; 00078 Int numDeleted; 00079 Bool copyKey; 00080 }; 00081 00082 // This is here both as an example, and the most commonly used hash. 00083 // For any data-specific hash, you will need to override FreeData() to 00084 // correctly dispose of the data (if necessary), and will probably 00085 // want to create your own SetItem/GetItem methods as below. 00086 00087 class IntHash : public Hash 00088 { 00089 public: 00090 Void SetItem(StrConst s, Int a) 00091 { SetVoidItem(s, (Void *) (a + 1)); }; 00092 00093 Int GetItem(StrConst s) 00094 { return(((SAddrInt) GetVoidItem(s)) - 1); }; 00095 00096 Void FreeData(Void *data) 00097 {}; 00098 }; 00099 00100 class IntHashIter : public HashIter 00101 { 00102 public: 00103 virtual Void ProcessItem(StrConst s, Int a) = 0; 00104 virtual Void ProcessVoidItem(StrConst s, Void *data) 00105 { ProcessItem(s, ((SAddrInt) data) - 1); }; 00106 }; 00107 00108 #endif