#ifndef __OUC_RASH__ #define __OUC_RASH__ /******************************************************************************/ /* */ /* X r d O u c R a s h . h h */ /* */ /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ // This templated class implements a radix tree to remap binary quantities using // a hash-like interface. Define the object as: // XrdOucRash myobject; // Where: key_type is the binary type of the key (short, int, long, long long) // value_type is the binary type of the value (one of the types above). // The binary types may be signed or unsigned. Use the methods defined in // class XrdOucRash to Add(), Del(), Find(), and Rep() items in the table. // Use Apply() to scan through all of the items in the table and Purge() to // remove all items in the table (indices are not removed). Several options // exist to manage the items (see individual methods and XrdOucRash_Options). // Warning! This class is not MT-safe and should be protected by an external // mutex when used in a multi-threaded environment. #include #include enum XrdOucRash_Options {Rash_default = 0x0000, Rash_replace = 0x0002, Rash_count = 0x0004 }; template class XrdOucRash_Item { public: int Count() {return keycount;} V *Data() {return &keydata;} K Key() {return keyval;} time_t Time() {return keytime;} void Update(int newcount, time_t newtime) {keycount = newcount; if (newtime) keytime = newtime; } void Set(V &keyData, time_t newtime) {keydata = keyData; keytime = newtime; } XrdOucRash_Item(K &KeyVal, V &KeyData, time_t KeyTime) {keyval = KeyVal; keydata = KeyData; keytime = KeyTime; keycount= 0; } ~XrdOucRash_Item() {} private: K keyval; V keydata; time_t keytime; int keycount; }; template class XrdOucRash_Tent { public: XrdOucRash_Tent *Table; XrdOucRash_Item *Item; XrdOucRash_Tent() {Table = 0; Item = 0;} ~XrdOucRash_Tent() {if (Table) delete[] Table; if (Item) delete(Item); } }; template class XrdOucRash { public: // Add() adds a new item to the table. If it exists and repl = 0 then the old // entry is returned and the new data is not added. Otherwise the current // entry is replaced (see Rep()) and 0 is returned. If we have no memory // to add the new entry, an ENOMEM exception is thrown. The // LifeTime value is the number of seconds this entry is to be considered // valid. When the time has passed, the entry may be deleted. A value // of zero, keeps the entry until explicitly deleted. The Hash_count // option keeps track of duplicate key entries for Del. Thus the key must // be deleted as many times as it is added before it is physically deleted. // V *Add(K KeyVal, V &KeyData, time_t LifeTime=0, XrdOucRash_Options opt=Rash_default); // Del() deletes the item from the table. If it doesn't exist, it returns // -ENOENT. If it was deleted it returns 0. If it was created with // Rash_Count then the count is decremented and count+1 is returned. // int Del(K KeyVal); // Find() simply looks up an entry in the cache. It can optionally return the // lifetime associated with the entry. If the // V *Find(K KeyVal, time_t *KeyTime=0); // Num() returns the number of items in the table // int Num() {return rashnum;} // Purge() simply deletes all of the appendages to the table. // void Purge(); // Rep() is simply Add() that allows replacement. // V *Rep(K KeyVal, V &KeyData, const int LifeTime=0, XrdOucRash_Options opt=Rash_default) {return Add(KeyVal, KeyData, LifeTime, (XrdOucRash_Options)(opt | Rash_replace));} // Apply() applies the specified function to every item in the table. The // first argument is the key value, the second is the associated data, // the third argument is whatever is the passed in void *variable, The // following actions occur for values returned by the applied function: // <0 - The table item is deleted. // =0 - The next table item is processed. // >0 - Processing stops and the address of item is returned. // V *Apply(int (*func)(K, V, void *), void *Arg) {return Apply(rashTable, func, Arg);} XrdOucRash() {rashnum = 0;} ~XrdOucRash() {Purge();} private: V *Apply(XrdOucRash_Tent *tab, int (*func)(K, V, void *), void *Arg); XrdOucRash_Item *Lookup(K theKey, XrdOucRash_Tent **tloc); void Insert(K theKey, XrdOucRash_Item *theItem); unsigned long long key2ull(K theKey); XrdOucRash_Tent rashTable[16]; int rashnum; }; /******************************************************************************/ /* A c t u a l I m p l e m e n t a t i o n */ /******************************************************************************/ #include "XrdOuc/XrdOucRash.icc" #endif