Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:33:22

0001 #ifndef __OOUC_HASH__
0002 #define __OOUC_HASH__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                         X r d O u c H a s h . h h                          */
0006 /*                                                                            */
0007 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0009 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0010 /*                                                                            */
0011 /* This file is part of the XRootD software suite.                            */
0012 /*                                                                            */
0013 /* XRootD is free software: you can redistribute it and/or modify it under    */
0014 /* the terms of the GNU Lesser General Public License as published by the     */
0015 /* Free Software Foundation, either version 3 of the License, or (at your     */
0016 /* option) any later version.                                                 */
0017 /*                                                                            */
0018 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0019 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0020 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0021 /* License for more details.                                                  */
0022 /*                                                                            */
0023 /* You should have received a copy of the GNU Lesser General Public License   */
0024 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0025 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0026 /*                                                                            */
0027 /* The copyright holder's institutional names and contributor's names may not */
0028 /* be used to endorse or promote products derived from this software without  */
0029 /* specific prior written permission of the institution or contributor.       */
0030 /******************************************************************************/
0031 
0032 #include <cstdlib>
0033 #include <sys/types.h>
0034 #include <cstring>
0035 #include <ctime>
0036 
0037 /*
0038 Hash_data_is_key - The key and data are the same so when an item is added
0039                    the data pointer is set to the key address.
0040 Hash_replace     - When adding an item, any existing item is replaced.
0041 Hash_count       - The number of deletion requests must equal the number of
0042                    additions before the item is actually deleted.
0043 Hash_keep        - When the item is added, the key is not duplicated and
0044                    when the item is deleted, the key *and* data are not deleted.
0045 Hash_dofree      - When an item is deleted the data is released using free()
0046                    instead of delete().
0047 Hash_keepdata    - Works like Hash_keep but only applies to the data object.
0048                    When adding the entry, the key is strdup'd and when deleting
0049                    an entry, the key is freed.
0050 */
0051 enum XrdOucHash_Options {Hash_default     = 0x0000,
0052                         Hash_data_is_key = 0x0001,
0053                         Hash_replace     = 0x0002,
0054                         Hash_count       = 0x0004,
0055                         Hash_keep        = 0x0008,
0056                         Hash_dofree      = 0x0010,
0057                         Hash_keepdata    = 0x0020
0058                        };
0059   
0060 template<class T>
0061 class XrdOucHash_Item
0062 {
0063 public:
0064 int                 Count() {return keycount;}
0065 
0066 T                   *Data() {return keydata;}
0067 
0068       unsigned long  Hash() {return keyhash;}
0069 
0070 const char          *Key()  {return keyval;}
0071 
0072 XrdOucHash_Item<T>   *Next() {return next;}
0073 
0074 time_t               Time() {return keytime;}
0075 
0076 void                 Update(int newcount, time_t newtime)
0077                             {keycount = newcount; 
0078                              if (newtime) keytime = newtime;
0079                             }
0080 
0081 int                  Same(const unsigned long KeyHash, const char *KeyVal)
0082                          {return keyhash == KeyHash && !strcmp(keyval, KeyVal);}
0083 
0084 void                 SetNext(XrdOucHash_Item<T> *item) {next = item;}
0085 
0086      XrdOucHash_Item(unsigned long      KeyHash,
0087                     const char        *KeyVal,
0088                     T                 *KeyData,
0089                     time_t             KeyTime,
0090                     XrdOucHash_Item<T> *KeyNext,
0091                     XrdOucHash_Options  KeyOpts)
0092           {keyhash = KeyHash; 
0093            if (KeyOpts & Hash_keep) keyval = KeyVal;
0094               else keyval  = strdup(KeyVal);
0095            if (KeyOpts & Hash_data_is_key) keydata = (T *)keyval;
0096               else keydata = KeyData;
0097            keytime = KeyTime;
0098            entopts = KeyOpts;
0099            next    = KeyNext;
0100            keycount= 0;
0101           }
0102 
0103     ~XrdOucHash_Item()
0104           {if (!(entopts & Hash_keep))
0105               {if (keydata && keydata != (T *)keyval 
0106                && !(entopts & Hash_keepdata))
0107                   {if (entopts & Hash_dofree) free(keydata);
0108                       else delete keydata;
0109                   }
0110                if (keyval)  free((void *)keyval);
0111               }
0112            keydata = 0; keyval = 0; keycount = 0;
0113           }
0114 
0115 private:
0116 
0117 XrdOucHash_Item<T> *next;
0118 const char        *keyval;
0119 unsigned long      keyhash;
0120 T                 *keydata;
0121 time_t             keytime;
0122 int                keycount;
0123 XrdOucHash_Options  entopts;
0124 };
0125 
0126 template<class T>
0127 class XrdOucHash
0128 {
0129 public:
0130 
0131 // Add() adds a new item to the hash. If it exists and repl = 0 then the old
0132 //       entry is returned and the new data is not added. Otherwise the current
0133 //       entry is replaced (see Rep()) and 0 is returned. If we have no memory
0134 //       to add the new entry, an ENOMEM exception is thrown. The
0135 //       LifeTime value is the number of seconds this entry is to be considered
0136 //       valid. When the time has passed, the entry may be deleted. A value
0137 //       of zero, keeps the entry until explicitly deleted. A special feature
0138 //       allows the data to be associated with the key to be the actual key
0139 //       using the Hash_data_is_key option. In this case, KeyData is ignored.
0140 //       The Hash_count option keeps track of duplicate key entries for Del.
0141 //
0142 T           *Add(const char *KeyVal, T *KeyData, const int LifeTime=0, 
0143                  XrdOucHash_Options opt=Hash_default);
0144 
0145 // Del() deletes the item from the hash. If it doesn't exist, it returns
0146 //       -ENOENT. Otherwise 0 is returned. If the Hash_count option is specified
0147 //       tyhen the entry is only deleted when the entry count is below 0.
0148 //
0149 int          Del(const char *KeyVal, XrdOucHash_Options opt = Hash_default);
0150 
0151 // Find() simply looks up an entry in the cache. It can optionally return the
0152 //        lifetime associated with the entry. If the
0153 //
0154 T           *Find(const char *KeyVal, time_t *KeyTime=0);
0155 
0156 // Num() returns the number of items in the hash table
0157 //
0158 int          Num() {return hashnum;}
0159 
0160 // Purge() simply deletes all of the appendages to the table.
0161 //
0162 void         Purge();
0163 
0164 // Rep() is simply Add() that allows replacement.
0165 //
0166 T           *Rep(const char *KeyVal, T *KeyData, const int LifeTime=0,
0167                  XrdOucHash_Options opt=Hash_default)
0168                 {return Add(KeyVal, KeyData, LifeTime, 
0169                             (XrdOucHash_Options)(opt | Hash_replace));}
0170 
0171 // Apply() applies the specified function to every item in the hash. The
0172 //         first argument is the key value, the second is the associated data,
0173 //         the third argument is whatever is the passed in void *variable, The
0174 //         following actions occur for values returned by the applied function:
0175 //         <0 - The hash table item is deleted.
0176 //         =0 - The next hash table item is processed.
0177 //         >0 - Processing stops and the hash table item is returned.
0178 //
0179 T           *Apply(int (*func)(const char *, T *, void *), void *Arg);
0180 
0181 // When allocateing a new hash, specify the required starting size. Make
0182 // sure that the previous number is the correct Fibonocci antecedent. The
0183 // series is simply n[j] = n[j-1] + n[j-2].
0184 //
0185     XrdOucHash(int psize = 89, int size=144, int load=80);
0186    ~XrdOucHash() {if (hashtable) {Purge(); free(hashtable); hashtable = 0;}}
0187 
0188 private:
0189 void Remove(int kent, XrdOucHash_Item<T> *hip, XrdOucHash_Item<T> *phip);
0190 
0191 XrdOucHash_Item<T> *Search(XrdOucHash_Item<T> *hip, 
0192                           const unsigned long khash,
0193                           const char *kval, 
0194                           XrdOucHash_Item<T> **phip=0);
0195 
0196 unsigned long HashVal(const char *KeyVal);
0197 
0198 void Expand();
0199 
0200 XrdOucHash_Item<T> **hashtable;
0201 int                 prevtablesize;
0202 int                 hashtablesize;
0203 int                 hashnum;
0204 int                 hashmax;
0205 int                 hashload;
0206 };
0207 
0208 /******************************************************************************/
0209 /*                 A c t u a l   I m p l e m e n t a t i o n                  */
0210 /******************************************************************************/
0211   
0212 #include "XrdOuc/XrdOucHash.icc"
0213 #endif