XrdOucRash.hh

Go to the documentation of this file.
00001 #ifndef __OUC_RASH__
00002 #define __OUC_RASH__
00003 /******************************************************************************/
00004 /*                                                                            */
00005 /*                         X r d O u c R a s h . h h                          */
00006 /*                                                                            */
00007 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University  */
00008 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00010 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00011 /******************************************************************************/
00012 
00013 //          $Id: XrdOucRash.hh 22437 2008-03-04 14:35:16Z rdm $
00014 
00015 // This templated class implements a radix tree to remap binary quantities using
00016 // a hash-like <key,Value> interface. Define the object as:
00017 
00018 // XrdOucRash<key_type, value_type> myobject;
00019 
00020 // Where: key_type   is the binary type of the key (short, int, long, long long)
00021 //        value_type is the binary type of the value (one of the types above).
00022 
00023 // The binary types may be signed or unsigned. Use the methods defined in
00024 // class XrdOucRash to Add(), Del(), Find(), and Rep() items in the table.
00025 // Use Apply() to scan through all of the items in the table and Purge() to
00026 // remove all items in the table (indices are not removed). Several options
00027 // exist to manage the items (see individual methods and XrdOucRash_Options).
00028 
00029 // Warning! This class is not MT-safe and should be protected by an external
00030 //          mutex when used in a multi-threaded environment.
00031  
00032 #include <sys/types.h>
00033 #include <time.h>
00034 
00035 enum XrdOucRash_Options {Rash_default     = 0x0000,
00036                          Rash_replace     = 0x0002,
00037                          Rash_count       = 0x0004
00038                        };
00039 
00040 template<typename K, typename V>
00041 class XrdOucRash_Item
00042 {
00043 public:
00044 int                  Count() {return keycount;}
00045 
00046 V                   *Data() {return &keydata;}
00047 
00048 K                    Key()  {return keyval;}
00049 
00050 time_t               Time() {return keytime;}
00051 
00052 void                 Update(int newcount, time_t newtime)
00053                             {keycount = newcount; 
00054                              if (newtime) keytime = newtime;
00055                             }
00056 
00057 void                 Set(V &keyData, time_t newtime)
00058                             {keydata = keyData;
00059                              keytime = newtime;
00060                             }
00061 
00062      XrdOucRash_Item(K                  &KeyVal,
00063                      V                  &KeyData,
00064                      time_t             KeyTime)
00065           {keyval  = KeyVal;
00066            keydata = KeyData;
00067            keytime = KeyTime;
00068            keycount= 0;
00069           }
00070 
00071     ~XrdOucRash_Item() {}
00072 
00073 private:
00074 
00075 K                  keyval;
00076 V                  keydata;
00077 time_t             keytime;
00078 int                keycount;
00079 };
00080 
00081 template<typename K, typename V>
00082 class XrdOucRash_Tent
00083 {
00084 public:
00085 XrdOucRash_Tent<K,V> *Table;
00086 XrdOucRash_Item<K,V> *Item;
00087 
00088       XrdOucRash_Tent() {Table = 0; Item = 0;}
00089      ~XrdOucRash_Tent() {if (Table) delete[] Table;
00090                          if (Item)  delete(Item);
00091                          }
00092 };
00093 
00094 template<typename K, typename V>
00095 class XrdOucRash
00096 {
00097 public:
00098 
00099 // Add() adds a new item to the table. If it exists and repl = 0 then the old
00100 //       entry is returned and the new data is not added. Otherwise the current
00101 //       entry is replaced (see Rep()) and 0 is returned. If we have no memory
00102 //       to add the new entry, an ENOMEM exception is thrown. The
00103 //       LifeTime value is the number of seconds this entry is to be considered
00104 //       valid. When the time has passed, the entry may be deleted. A value
00105 //       of zero, keeps the entry until explicitly deleted. The Hash_count 
00106 //       option keeps track of duplicate key entries for Del. Thus the key must
00107 //       be deleted as many times as it is added before it is physically deleted.
00108 //
00109 V           *Add(K KeyVal, V &KeyData, time_t LifeTime=0,
00110                  XrdOucRash_Options opt=Rash_default);
00111 
00112 // Del() deletes the item from the table. If it doesn't exist, it returns
00113 //       -ENOENT. If it was deleted it returns 0. If it was created with
00114 //       Rash_Count then the count is decremented and count+1 is returned.
00115 //
00116 int          Del(K KeyVal);
00117 
00118 // Find() simply looks up an entry in the cache. It can optionally return the
00119 //        lifetime associated with the entry. If the
00120 //
00121 V           *Find(K KeyVal, time_t *KeyTime=0);
00122 
00123 // Num() returns the number of items in the table
00124 //
00125 int          Num() {return rashnum;}
00126 
00127 // Purge() simply deletes all of the appendages to the table.
00128 //
00129 void         Purge();
00130 
00131 // Rep() is simply Add() that allows replacement.
00132 //
00133 V           *Rep(K KeyVal, V &KeyData, const int LifeTime=0,
00134                  XrdOucRash_Options opt=Rash_default)
00135                 {return Add(KeyVal, KeyData, LifeTime, 
00136                            (XrdOucRash_Options)(opt | Rash_replace));}
00137 
00138 // Apply() applies the specified function to every item in the table. The
00139 //         first argument is the key value, the second is the associated data,
00140 //         the third argument is whatever is the passed in void *variable, The
00141 //         following actions occur for values returned by the applied function:
00142 //         <0 - The table item is deleted.
00143 //         =0 - The next table item is processed.
00144 //         >0 - Processing stops and the address of item is returned.
00145 //
00146 V           *Apply(int (*func)(K, V, void *), void *Arg)
00147                   {return Apply(rashTable, func, Arg);}
00148 
00149     XrdOucRash() {rashnum = 0;}
00150    ~XrdOucRash() {Purge();}
00151 
00152 private:
00153 V                    *Apply(XrdOucRash_Tent<K,V> *tab,
00154                             int (*func)(K, V, void *), void *Arg);
00155 XrdOucRash_Item<K,V> *Lookup(K theKey, XrdOucRash_Tent<K,V> **tloc);
00156 void                  Insert(K theKey, XrdOucRash_Item<K,V> *theItem);
00157 unsigned long long    key2ull(K theKey);
00158 
00159 XrdOucRash_Tent<K,V> rashTable[16];
00160 int                  rashnum;
00161 };
00162 
00163 /******************************************************************************/
00164 /*                 A c t u a l   I m p l e m e n t a t i o n                  */
00165 /******************************************************************************/
00166   
00167 #include "XrdOuc/XrdOucRash.icc"
00168 #endif

Generated on Tue Jul 5 14:46:50 2011 for ROOT_528-00b_version by  doxygen 1.5.1