xrootd
XrdOucHash.hh
Go to the documentation of this file.
1 #ifndef __OOUC_HASH__
2 #define __OOUC_HASH__
3 /******************************************************************************/
4 /* */
5 /* X r d O u c H a s h . h h */
6 /* */
7 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Department of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /******************************************************************************/
31 
32 #include <stdlib.h>
33 #include <sys/types.h>
34 #include <string.h>
35 #include <time.h>
36 
37 /*
38 Hash_data_is_key - The key and data are the same so when an item is added
39  the data pointer is set to the key address.
40 Hash_replace - When adding an item, any existing item is replaced.
41 Hash_count - The number of deletion requests must equal the number of
42  additions before the item is actually deleted.
43 Hash_keep - When the item is added, the key is not duplicated and
44  when the item is deleted, the key *and* data are not deleted.
45 Hash_dofree - When an item is deleted the data is released using free()
46  instead of delete().
47 Hash_keepdata - Works like Hash_keep but only applies to the data object.
48  When adding the entry, the key is strdup'd and when deleting
49  an entry, the key is freed.
50 */
52  Hash_data_is_key = 0x0001,
53  Hash_replace = 0x0002,
54  Hash_count = 0x0004,
55  Hash_keep = 0x0008,
56  Hash_dofree = 0x0010,
57  Hash_keepdata = 0x0020
58  };
59 
60 template<class T>
62 {
63 public:
64 int Count() {return keycount;}
65 
66 T *Data() {return keydata;}
67 
68  unsigned long Hash() {return keyhash;}
69 
70 const char *Key() {return keyval;}
71 
73 
74 time_t Time() {return keytime;}
75 
76 void Update(int newcount, time_t newtime)
77  {keycount = newcount;
78  if (newtime) keytime = newtime;
79  }
80 
81 int Same(const unsigned long KeyHash, const char *KeyVal)
82  {return keyhash == KeyHash && !strcmp(keyval, KeyVal);}
83 
84 void SetNext(XrdOucHash_Item<T> *item) {next = item;}
85 
86  XrdOucHash_Item(unsigned long KeyHash,
87  const char *KeyVal,
88  T *KeyData,
89  time_t KeyTime,
90  XrdOucHash_Item<T> *KeyNext,
91  XrdOucHash_Options KeyOpts)
92  {keyhash = KeyHash;
93  if (KeyOpts & Hash_keep) keyval = KeyVal;
94  else keyval = strdup(KeyVal);
95  if (KeyOpts & Hash_data_is_key) keydata = (T *)keyval;
96  else keydata = KeyData;
97  keytime = KeyTime;
98  entopts = KeyOpts;
99  next = KeyNext;
100  keycount= 0;
101  }
102 
104  {if (!(entopts & Hash_keep))
105  {if (keydata && keydata != (T *)keyval
106  && !(entopts & Hash_keepdata))
107  {if (entopts & Hash_dofree) free(keydata);
108  else delete keydata;
109  }
110  if (keyval) free((void *)keyval);
111  }
112  keydata = 0; keyval = 0; keycount = 0;
113  }
114 
115 private:
116 
118 const char *keyval;
119 unsigned long keyhash;
121 time_t keytime;
124 };
125 
126 template<class T>
128 {
129 public:
130 
131 // Add() adds a new item to the hash. If it exists and repl = 0 then the old
132 // entry is returned and the new data is not added. Otherwise the current
133 // entry is replaced (see Rep()) and 0 is returned. If we have no memory
134 // to add the new entry, an ENOMEM exception is thrown. The
135 // LifeTime value is the number of seconds this entry is to be considered
136 // valid. When the time has passed, the entry may be deleted. A value
137 // of zero, keeps the entry until explicitly deleted. A special feature
138 // allows the data to be associated with the key to be the actual key
139 // using the Hash_data_is_key option. In this case, KeyData is ignored.
140 // The Hash_count option keeps track of duplicate key entries for Del.
141 //
142 T *Add(const char *KeyVal, T *KeyData, const int LifeTime=0,
144 
145 // Del() deletes the item from the hash. If it doesn't exist, it returns
146 // -ENOENT. Otherwise 0 is returned. If the Hash_count option is specified
147 // tyhen the entry is only deleted when the entry count is below 0.
148 //
149 int Del(const char *KeyVal, XrdOucHash_Options opt = Hash_default);
150 
151 // Find() simply looks up an entry in the cache. It can optionally return the
152 // lifetime associated with the entry. If the
153 //
154 T *Find(const char *KeyVal, time_t *KeyTime=0);
155 
156 // Num() returns the number of items in the hash table
157 //
158 int Num() {return hashnum;}
159 
160 // Purge() simply deletes all of the appendages to the table.
161 //
162 void Purge();
163 
164 // Rep() is simply Add() that allows replacement.
165 //
166 T *Rep(const char *KeyVal, T *KeyData, const int LifeTime=0,
168  {return Add(KeyVal, KeyData, LifeTime,
169  (XrdOucHash_Options)(opt | Hash_replace));}
170 
171 // Apply() applies the specified function to every item in the hash. The
172 // first argument is the key value, the second is the associated data,
173 // the third argument is whatever is the passed in void *variable, The
174 // following actions occur for values returned by the applied function:
175 // <0 - The hash table item is deleted.
176 // =0 - The next hash table item is processed.
177 // >0 - Processing stops and the hash table item is returned.
178 //
179 T *Apply(int (*func)(const char *, T *, void *), void *Arg);
180 
181 // When allocateing a new hash, specify the required starting size. Make
182 // sure that the previous number is the correct Fibonocci antecedent. The
183 // series is simply n[j] = n[j-1] + n[j-2].
184 //
185  XrdOucHash(int psize = 89, int size=144, int load=80);
186  ~XrdOucHash() {if (hashtable) {Purge(); free(hashtable); hashtable = 0;}}
187 
188 private:
189 void Remove(int kent, XrdOucHash_Item<T> *hip, XrdOucHash_Item<T> *phip);
190 
192  const unsigned long khash,
193  const char *kval,
194  XrdOucHash_Item<T> **phip=0);
195 
196 unsigned long HashVal(const char *KeyVal);
197 
198 void Expand();
199 
206 };
207 
208 /******************************************************************************/
209 /* A c t u a l I m p l e m e n t a t i o n */
210 /******************************************************************************/
211 
212 #include "XrdOuc/XrdOucHash.icc"
213 #endif
int hashload
Definition: XrdOucHash.hh:205
XrdOucHash_Item< T > * Next()
Definition: XrdOucHash.hh:72
T * Rep(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.hh:166
XrdOucHash_Options entopts
Definition: XrdOucHash.hh:123
~XrdOucHash()
Definition: XrdOucHash.hh:186
XrdOucHash_Item< T > * Search(XrdOucHash_Item< T > *hip, const unsigned long khash, const char *kval, XrdOucHash_Item< T > **phip=0)
XrdOucHash_Item(unsigned long KeyHash, const char *KeyVal, T *KeyData, time_t KeyTime, XrdOucHash_Item< T > *KeyNext, XrdOucHash_Options KeyOpts)
Definition: XrdOucHash.hh:86
int hashtablesize
Definition: XrdOucHash.hh:202
~XrdOucHash_Item()
Definition: XrdOucHash.hh:103
int prevtablesize
Definition: XrdOucHash.hh:201
time_t Time()
Definition: XrdOucHash.hh:74
Definition: XrdOucHash.hh:55
T * Data()
Definition: XrdOucHash.hh:66
void Remove(int kent, XrdOucHash_Item< T > *hip, XrdOucHash_Item< T > *phip)
XrdOucHash_Item< T > * next
Definition: XrdOucHash.hh:117
Definition: XrdOucHash.hh:57
Definition: XrdOucHash.hh:53
Definition: XrdOucHash.hh:56
Definition: XrdOucHash.hh:52
void SetNext(XrdOucHash_Item< T > *item)
Definition: XrdOucHash.hh:84
XrdOucHash_Item< T > ** hashtable
Definition: XrdOucHash.hh:200
int Num()
Definition: XrdOucHash.hh:158
Definition: XrdOucHash.hh:51
XrdOucHash_Options
Definition: XrdOucHash.hh:51
T * Apply(int(*func)(const char *, T *, void *), void *Arg)
int Count()
Definition: XrdOucHash.hh:64
int Same(const unsigned long KeyHash, const char *KeyVal)
Definition: XrdOucHash.hh:81
void Purge()
int hashnum
Definition: XrdOucHash.hh:203
int Del(const char *KeyVal, XrdOucHash_Options opt=Hash_default)
unsigned long Hash()
Definition: XrdOucHash.hh:68
T * keydata
Definition: XrdOucHash.hh:120
const char * Key()
Definition: XrdOucHash.hh:70
unsigned long HashVal(const char *KeyVal)
const char * keyval
Definition: XrdOucHash.hh:118
T * Find(const char *KeyVal, time_t *KeyTime=0)
void Expand()
time_t keytime
Definition: XrdOucHash.hh:121
Definition: XrdOucHash.hh:61
Definition: XrdOucHash.hh:127
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.hh:54
void Update(int newcount, time_t newtime)
Definition: XrdOucHash.hh:76
int keycount
Definition: XrdOucHash.hh:122
XrdOucHash(int psize=89, int size=144, int load=80)
unsigned long keyhash
Definition: XrdOucHash.hh:119
int hashmax
Definition: XrdOucHash.hh:204