00001 #ifndef __OOUC_HASH__
00002 #define __OOUC_HASH__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdlib.h>
00016 #include <sys/types.h>
00017 #include <string.h>
00018 #include <time.h>
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 enum XrdOucHash_Options {Hash_default = 0x0000,
00035 Hash_data_is_key = 0x0001,
00036 Hash_replace = 0x0002,
00037 Hash_count = 0x0004,
00038 Hash_keep = 0x0008,
00039 Hash_dofree = 0x0010,
00040 Hash_keepdata = 0x0020
00041 };
00042
00043 template<class T>
00044 class XrdOucHash_Item
00045 {
00046 public:
00047 int Count() {return keycount;}
00048
00049 T *Data() {return keydata;}
00050
00051 unsigned long Hash() {return keyhash;}
00052
00053 const char *Key() {return keyval;}
00054
00055 XrdOucHash_Item<T> *Next() {return next;}
00056
00057 time_t Time() {return keytime;}
00058
00059 void Update(int newcount, time_t newtime)
00060 {keycount = newcount;
00061 if (newtime) keytime = newtime;
00062 }
00063
00064 int Same(const unsigned long KeyHash, const char *KeyVal)
00065 {return keyhash == KeyHash && !strcmp(keyval, KeyVal);}
00066
00067 void SetNext(XrdOucHash_Item<T> *item) {next = item;}
00068
00069 XrdOucHash_Item(unsigned long KeyHash,
00070 const char *KeyVal,
00071 T *KeyData,
00072 time_t KeyTime,
00073 XrdOucHash_Item<T> *KeyNext,
00074 XrdOucHash_Options KeyOpts)
00075 {keyhash = KeyHash;
00076 if (KeyOpts & Hash_keep) keyval = KeyVal;
00077 else keyval = strdup(KeyVal);
00078 if (KeyOpts & Hash_data_is_key) keydata = (T *)keyval;
00079 else keydata = KeyData;
00080 keytime = KeyTime;
00081 entopts = KeyOpts;
00082 next = KeyNext;
00083 keycount= 0;
00084 }
00085
00086 ~XrdOucHash_Item()
00087 {if (!(entopts & Hash_keep))
00088 {if (keydata && keydata != (T *)keyval
00089 && !(entopts & Hash_keepdata))
00090 {if (entopts & Hash_dofree) free(keydata);
00091 else delete keydata;
00092 }
00093 if (keyval) free((void *)keyval);
00094 }
00095 keydata = 0; keyval = 0; keycount = 0;
00096 }
00097
00098 private:
00099
00100 XrdOucHash_Item<T> *next;
00101 const char *keyval;
00102 unsigned long keyhash;
00103 T *keydata;
00104 time_t keytime;
00105 int keycount;
00106 XrdOucHash_Options entopts;
00107 };
00108
00109 template<class T>
00110 class XrdOucHash
00111 {
00112 public:
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 T *Add(const char *KeyVal, T *KeyData, const int LifeTime=0,
00126 XrdOucHash_Options opt=Hash_default);
00127
00128
00129
00130
00131
00132 int Del(const char *KeyVal, XrdOucHash_Options opt = Hash_default);
00133
00134
00135
00136
00137 T *Find(const char *KeyVal, time_t *KeyTime=0);
00138
00139
00140
00141 int Num() {return hashnum;}
00142
00143
00144
00145 void Purge();
00146
00147
00148
00149 T *Rep(const char *KeyVal, T *KeyData, const int LifeTime=0,
00150 XrdOucHash_Options opt=Hash_default)
00151 {return Add(KeyVal, KeyData, LifeTime,
00152 (XrdOucHash_Options)(opt | Hash_replace));}
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 T *Apply(int (*func)(const char *, T *, void *), void *Arg);
00163
00164
00165
00166
00167
00168 XrdOucHash(int psize = 89, int size=144, int load=80);
00169 ~XrdOucHash() {if (hashtable) {Purge(); free(hashtable); hashtable = 0;}}
00170
00171 private:
00172 void Remove(int kent, XrdOucHash_Item<T> *hip, XrdOucHash_Item<T> *phip);
00173
00174 XrdOucHash_Item<T> *Search(XrdOucHash_Item<T> *hip,
00175 const unsigned long khash,
00176 const char *kval,
00177 XrdOucHash_Item<T> **phip=0);
00178
00179 unsigned long HashVal(const char *KeyVal);
00180
00181 void Expand();
00182
00183 XrdOucHash_Item<T> **hashtable;
00184 int prevtablesize;
00185 int hashtablesize;
00186 int hashnum;
00187 int hashmax;
00188 int hashload;
00189 };
00190
00191
00192
00193
00194
00195 #include "XrdOuc/XrdOucHash.icc"
00196 #endif