xrootd
XrdOucTable.hh
Go to the documentation of this file.
1 #ifndef __OUC_TABLE__
2 #define __OUC_TABLE__
3 /******************************************************************************/
4 /* */
5 /* X r d O u c T a b l e . h h */
6 /* */
7 /* (c) 2006 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* All Rights Reserved */
9 /* Produced by Andrew Hanushevsky for Stanford University under contract */
10 /* DE-AC02-76-SFO0515 with the Department of Energy */
11 /******************************************************************************/
12 
13 // $Id$
14 
15 #include <stdlib.h>
16 #include <string.h>
17 
18 template<class T>
20 {
21 public:
22 
23  XrdOucTable(int maxe)
24  {int i;
25  Table = new OucTable[maxe];
26  maxnum = maxe; curnum = 0; avlnum = 0;
27  for (i = 1; i < maxe; i++) Table[i-1].Fnum = i;
28  Table[maxe-1].Fnum = -1;
29  }
30 
31  ~XrdOucTable() {delete [] Table;}
32 
33 // Alloc() returns the next free slot number in the table. A negative value
34 // indicates that no free slots are left.
35 //
36 int Alloc() {int i = avlnum;
37  if (i >= 0) {avlnum = Table[i].Fnum;
38  if (i >= curnum) curnum = i+1;
39  }
40  return i;
41  }
42 
43 // Apply() applies the specified function to every item in the list.
44 // An argument may be passed to the function. A null pointer is
45 // returned if the list was completely traversed. Otherwise, the
46 // pointer to the node on which the applied function returned a
47 // non-zero value is returned. An optional starting point may be passed.
48 //
49 T *Apply(int (*func)(T *, void *), void *Arg, int Start=0)
50  {int i;
51  for (i = Start; i < curnum; i++)
52  if (Table[i].Item && (*func)(Table[i].Item, Arg))
53  return Table[i].Item;
54  return (T *)0;
55  }
56 
57 // Delete() entry at Tnum and destroy it. The key is destroyed and the slot
58 // is placed on the free list. The second variation of Remove, deletes by key.
59 //
60 void Delete(int Tnum)
61  {T *temp;
62  if ((temp = Remove(Tnum))) delete temp;
63  }
64 
65 void Delete(const char *key)
66  {T *temp;
67  if ((temp = Remove(key))) delete temp;
68  }
69 
70 // Find() finds a table entry matching the specified key. It returns the
71 // Item associated with the key or zero if it is not found. If the
72 // address of an integer is passed, the associated entry number is
73 // also returned (it is unchanged if a null is returned).
74 //
75 T *Find(const char *key, int *Tnum=0)
76  {int i;
77  for (i = 0; i < curnum; i++)
78  if (Table[i].Item && Table[i].Key && !strcmp(Table[i].Key, key))
79  {if (Tnum) *Tnum = i; return Table[i].Item;}
80  return 0;
81  }
82 
83 // Insert() inserts the specified node at entry Tnum. If Tnum is negative, a free
84 // slot is allocated and the item is inserted there. The slot number is
85 // returned. A negative slot number indicates the table is full.
86 //
87 int Insert(T *Item, const char *key=0, int Tnum=-1)
88  {if ((Tnum < 0 && ((Tnum = Alloc()) < 0)) || Tnum >= maxnum) return -1;
89  Table[Tnum].Item = Item; Table[Tnum].Key = strdup(key);
90  return Tnum;
91  }
92 
93 // Item() supplies the item value associated with entry Tnum; If the address
94 // if ikey is not zero, the associated key value is returned.
95 //
96 T *Item(int Tnum, char **ikey=0)
97  {if (Tnum < 0 || Tnum >= curnum || !Table[Tnum].Item) return (T *)0;
98  if (ikey) *ikey = Table[Tnum].Key;
99  return Table[Tnum].Item;
100  }
101 
102 // Next() iterates through the table using a cursor. This function is
103 // useful for unlocked scanning of the table.
104 //
105 int Next(int &Tnum) {int i;
106  for (i = Tnum; i < curnum; i++)
107  if (Table[i].Item) {Tnum = i+1; return i;}
108  return -1;
109  }
110 
111 // Remove() entry at Tnum and returns it. The key is destroyed and the slot
112 // is placed on the free list. The second variation of Remove, removes by key.
113 //
114 T *Remove(int Tnum)
115  {T *temp;
116  if (Tnum < 0 || Tnum >= curnum || !Table[Tnum].Item) return (T *)0;
117  if (Table[Tnum].Key) free(Table[Tnum].Key);
118  temp = Table[Tnum].Item; Table[Tnum].Item = 0;
119  Table[Tnum].Fnum = avlnum;
120  avlnum = Tnum;
121  if (Tnum == (curnum-1))
122  while(curnum && Table[curnum].Item == 0) curnum--;
123  return temp;
124  }
125 
126 T *Remove(const char *key) {int i;
127  if (Find(key, &i)) return Remove(i);
128  return (T *)0;
129  }
130 
131 private:
132 struct OucTable {T *Item;
133  union {char *Key;
134  int Fnum;};
135  OucTable() {Item = 0; Key = 0;}
136  ~OucTable() {if (Key) free(Key);
137  if (Item) delete Item;
138  }
139  };
140 
141 OucTable *Table;
142 int avlnum;
143 int maxnum;
144 int curnum;
145 };
146 #endif