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 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */
9 /* Produced by Andrew Hanushevsky for Stanford University under contract */
10 /* DE-AC03-76-SFO0515 with the Department of Energy */
11 /******************************************************************************/
12 
13 // $Id$
14 
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <string.h>
18 #include <time.h>
19 
20 /*
21 Hash_data_is_key - The key and data are the same so when an item is added
22  the data pointer is set to the key address.
23 Hash_replace - When adding an item, any existing item is replaced.
24 Hash_count - The number of deletion requests must equal the number of
25  additions before the item is actually deleted.
26 Hash_keep - When the item is added, the key is not duplicated and
27  when the item is deleted, the key *and* data are not deleted.
28 Hash_dofree - When an item is deleted the data is released using free()
29  instead of delete().
30 Hash_keepdata - Works like Hash_keep but only applies to the data object.
31  When adding the entry, the key is strdup'd and when deleting
32  an entry, the key is freed.
33 */
35  Hash_data_is_key = 0x0001,
36  Hash_replace = 0x0002,
37  Hash_count = 0x0004,
38  Hash_keep = 0x0008,
39  Hash_dofree = 0x0010,
40  Hash_keepdata = 0x0020
41  };
42 
43 template<class T>
45 {
46 public:
47 int Count() {return keycount;}
48 
49 T *Data() {return keydata;}
50 
51  unsigned long Hash() {return keyhash;}
52 
53 const char *Key() {return keyval;}
54 
56 
57 time_t Time() {return keytime;}
58 
59 void Update(int newcount, time_t newtime)
60  {keycount = newcount;
61  if (newtime) keytime = newtime;
62  }
63 
64 int Same(const unsigned long KeyHash, const char *KeyVal)
65  {return keyhash == KeyHash && !strcmp(keyval, KeyVal);}
66 
67 void SetNext(XrdOucHash_Item<T> *item) {next = item;}
68 
69  XrdOucHash_Item(unsigned long KeyHash,
70  const char *KeyVal,
71  T *KeyData,
72  time_t KeyTime,
73  XrdOucHash_Item<T> *KeyNext,
74  XrdOucHash_Options KeyOpts)
75  {keyhash = KeyHash;
76  if (KeyOpts & Hash_keep) keyval = KeyVal;
77  else keyval = strdup(KeyVal);
78  if (KeyOpts & Hash_data_is_key) keydata = (T *)keyval;
79  else keydata = KeyData;
80  keytime = KeyTime;
81  entopts = KeyOpts;
82  next = KeyNext;
83  keycount= 0;
84  }
85 
87  {if (!(entopts & Hash_keep))
88  {if (keydata && keydata != (T *)keyval
89  && !(entopts & Hash_keepdata))
90  {if (entopts & Hash_dofree) free(keydata);
91  else delete keydata;
92  }
93  if (keyval) free((void *)keyval);
94  }
95  keydata = 0; keyval = 0; keycount = 0;
96  }
97 
98 private:
99 
101 const char *keyval;
102 unsigned long keyhash;
104 time_t keytime;
107 };
108 
109 template<class T>
111 {
112 public:
113 
114 // Add() adds a new item to the hash. If it exists and repl = 0 then the old
115 // entry is returned and the new data is not added. Otherwise the current
116 // entry is replaced (see Rep()) and 0 is returned. If we have no memory
117 // to add the new entry, an ENOMEM exception is thrown. The
118 // LifeTime value is the number of seconds this entry is to be considered
119 // valid. When the time has passed, the entry may be deleted. A value
120 // of zero, keeps the entry until explicitly deleted. A special feature
121 // allows the data to be associated with the key to be the actual key
122 // using the Hash_data_is_key option. In this case, KeyData is ignored.
123 // The Hash_count option keeps track of duplicate key entries for Del.
124 //
125 T *Add(const char *KeyVal, T *KeyData, const int LifeTime=0,
127 
128 // Del() deletes the item from the hash. If it doesn't exist, it returns
129 // -ENOENT. Otherwise 0 is returned. If the Hash_count option is specified
130 // tyhen the entry is only deleted when the entry count is below 0.
131 //
132 int Del(const char *KeyVal, XrdOucHash_Options opt = Hash_default);
133 
134 // Find() simply looks up an entry in the cache. It can optionally return the
135 // lifetime associated with the entry. If the
136 //
137 T *Find(const char *KeyVal, time_t *KeyTime=0);
138 
139 // Num() returns the number of items in the hash table
140 //
141 int Num() {return hashnum;}
142 
143 // Purge() simply deletes all of the appendages to the table.
144 //
145 void Purge();
146 
147 // Rep() is simply Add() that allows replacement.
148 //
149 T *Rep(const char *KeyVal, T *KeyData, const int LifeTime=0,
151  {return Add(KeyVal, KeyData, LifeTime,
152  (XrdOucHash_Options)(opt | Hash_replace));}
153 
154 // Apply() applies the specified function to every item in the hash. The
155 // first argument is the key value, the second is the associated data,
156 // the third argument is whatever is the passed in void *variable, The
157 // following actions occur for values returned by the applied function:
158 // <0 - The hash table item is deleted.
159 // =0 - The next hash table item is processed.
160 // >0 - Processing stops and the hash table item is returned.
161 //
162 T *Apply(int (*func)(const char *, T *, void *), void *Arg);
163 
164 // When allocateing a new hash, specify the required starting size. Make
165 // sure that the previous number is the correct Fibonocci antecedent. The
166 // series is simply n[j] = n[j-1] + n[j-2].
167 //
168  XrdOucHash(int psize = 89, int size=144, int load=80);
169  ~XrdOucHash() {if (hashtable) {Purge(); free(hashtable); hashtable = 0;}}
170 
171 private:
172 void Remove(int kent, XrdOucHash_Item<T> *hip, XrdOucHash_Item<T> *phip);
173 
175  const unsigned long khash,
176  const char *kval,
177  XrdOucHash_Item<T> **phip=0);
178 
179 unsigned long HashVal(const char *KeyVal);
180 
181 void Expand();
182 
189 };
190 
191 /******************************************************************************/
192 /* A c t u a l I m p l e m e n t a t i o n */
193 /******************************************************************************/
194 
195 #include "XrdOuc/XrdOucHash.icc"
196 #endif