xrootd
|
00001 #ifndef __OUC_TABLE__ 00002 #define __OUC_TABLE__ 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d O u c T a b l e . h h */ 00006 /* */ 00007 /* (c) 2006 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved */ 00009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC02-76-SFO0515 with the Department of Energy */ 00011 /******************************************************************************/ 00012 00013 // $Id$ 00014 00015 #include <stdlib.h> 00016 #include <string.h> 00017 00018 template<class T> 00019 class XrdOucTable 00020 { 00021 public: 00022 00023 XrdOucTable(int maxe) 00024 {int i; 00025 Table = new OucTable[maxe]; 00026 maxnum = maxe; curnum = 0; avlnum = 0; 00027 for (i = 1; i < maxe; i++) Table[i-1].Fnum = i; 00028 Table[maxe-1].Fnum = -1; 00029 } 00030 00031 ~XrdOucTable() {delete [] Table;} 00032 00033 // Alloc() returns the next free slot number in the table. A negative value 00034 // indicates that no free slots are left. 00035 // 00036 int Alloc() {int i = avlnum; 00037 if (i >= 0) {avlnum = Table[i].Fnum; 00038 if (i >= curnum) curnum = i+1; 00039 } 00040 return i; 00041 } 00042 00043 // Apply() applies the specified function to every item in the list. 00044 // An argument may be passed to the function. A null pointer is 00045 // returned if the list was completely traversed. Otherwise, the 00046 // pointer to the node on which the applied function returned a 00047 // non-zero value is returned. An optional starting point may be passed. 00048 // 00049 T *Apply(int (*func)(T *, void *), void *Arg, int Start=0) 00050 {int i; 00051 for (i = Start; i < curnum; i++) 00052 if (Table[i].Item && (*func)(Table[i].Item, Arg)) 00053 return Table[i].Item; 00054 return (T *)0; 00055 } 00056 00057 // Delete() entry at Tnum and destroy it. The key is destroyed and the slot 00058 // is placed on the free list. The second variation of Remove, deletes by key. 00059 // 00060 void Delete(int Tnum) 00061 {T *temp; 00062 if ((temp = Remove(Tnum))) delete temp; 00063 } 00064 00065 void Delete(const char *key) 00066 {T *temp; 00067 if ((temp = Remove(key))) delete temp; 00068 } 00069 00070 // Find() finds a table entry matching the specified key. It returns the 00071 // Item associated with the key or zero if it is not found. If the 00072 // address of an integer is passed, the associated entry number is 00073 // also returned (it is unchanged if a null is returned). 00074 // 00075 T *Find(const char *key, int *Tnum=0) 00076 {int i; 00077 for (i = 0; i < curnum; i++) 00078 if (Table[i].Item && Table[i].Key && !strcmp(Table[i].Key, key)) 00079 {if (Tnum) *Tnum = i; return Table[i].Item;} 00080 return 0; 00081 } 00082 00083 // Insert() inserts the specified node at entry Tnum. If Tnum is negative, a free 00084 // slot is allocated and the item is inserted there. The slot number is 00085 // returned. A negative slot number indicates the table is full. 00086 // 00087 int Insert(T *Item, const char *key=0, int Tnum=-1) 00088 {if ((Tnum < 0 && ((Tnum = Alloc()) < 0)) || Tnum >= maxnum) return -1; 00089 Table[Tnum].Item = Item; Table[Tnum].Key = strdup(key); 00090 return Tnum; 00091 } 00092 00093 // Item() supplies the item value associated with entry Tnum; If the address 00094 // if ikey is not zero, the associated key value is returned. 00095 // 00096 T *Item(int Tnum, char **ikey=0) 00097 {if (Tnum < 0 || Tnum >= curnum || !Table[Tnum].Item) return (T *)0; 00098 if (ikey) *ikey = Table[Tnum].Key; 00099 return Table[Tnum].Item; 00100 } 00101 00102 // Next() iterates through the table using a cursor. This function is 00103 // useful for unlocked scanning of the table. 00104 // 00105 int Next(int &Tnum) {int i; 00106 for (i = Tnum; i < curnum; i++) 00107 if (Table[i].Item) {Tnum = i+1; return i;} 00108 return -1; 00109 } 00110 00111 // Remove() entry at Tnum and returns it. The key is destroyed and the slot 00112 // is placed on the free list. The second variation of Remove, removes by key. 00113 // 00114 T *Remove(int Tnum) 00115 {T *temp; 00116 if (Tnum < 0 || Tnum >= curnum || !Table[Tnum].Item) return (T *)0; 00117 if (Table[Tnum].Key) free(Table[Tnum].Key); 00118 temp = Table[Tnum].Item; Table[Tnum].Item = 0; 00119 Table[Tnum].Fnum = avlnum; 00120 avlnum = Tnum; 00121 if (Tnum == (curnum-1)) 00122 while(curnum && Table[curnum].Item == 0) curnum--; 00123 return temp; 00124 } 00125 00126 T *Remove(const char *key) {int i; 00127 if (Find(key, &i)) return Remove(i); 00128 return (T *)0; 00129 } 00130 00131 private: 00132 struct OucTable {T *Item; 00133 union {char *Key; 00134 int Fnum;}; 00135 OucTable() {Item = 0; Key = 0;} 00136 ~OucTable() {if (Key) free(Key); 00137 if (Item) delete Item; 00138 } 00139 }; 00140 00141 OucTable *Table; 00142 int avlnum; 00143 int maxnum; 00144 int curnum; 00145 }; 00146 #endif