ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.9
Committed: Wed Dec 3 11:36:02 2008 UTC (16 years, 5 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.8: +5 -5 lines
Log Message:
Add (const *)

File Contents

# User Rev Content
1 loizides 1.1 //--------------------------------------------------------------------------------------------------
2 loizides 1.9 // $Id: RefArray.h,v 1.8 2008/11/20 17:49:15 loizides Exp $
3 loizides 1.1 //
4     // RefArray
5     //
6     // Implementation of a TRefArray using stack (and not heap) memory.
7 bendavid 1.7 // The maximum number of references is left as a template parameter.
8     // Since all of the stack allocation is handled by the StackArrays
9     // the RefArray itself can now actually be split.
10     //
11     // RefArray now supports objects from multiple PIDs, but only a single PID will be stored as long
12     // as only objects from a single PID are added.
13 loizides 1.1 //
14     // Authors: C.Loizides, J.Bendavid
15     //--------------------------------------------------------------------------------------------------
16    
17 loizides 1.2 #ifndef MITANA_DATACONT_REFARRAY
18     #define MITANA_DATACONT_REFARRAY
19 loizides 1.1
20     #include <TObject.h>
21     #include <TRefArray.h>
22     #include <TRefTable.h>
23     #include <TProcessID.h>
24     #include <TError.h>
25     #include "MitAna/DataCont/interface/Collection.h"
26 bendavid 1.7 #include "MitAna/DataCont/interface/StackArray.h"
27     #include "MitAna/DataCont/interface/StackArrayBasic.h"
28     #include "MitAna/DataCont/interface/ProcIDRef.h"
29 loizides 1.1
30     namespace mithep
31     {
32 bendavid 1.7 template<class ArrayElement, UInt_t N>
33 loizides 1.8 class RefArray /*: public Collection<ArrayElement>*/
34 loizides 1.1 {
35     public:
36     RefArray();
37 bendavid 1.7 virtual ~RefArray() {}
38 loizides 1.1
39 loizides 1.9 void Add(const ArrayElement *ae);
40 loizides 1.1 ArrayElement *At(UInt_t idx);
41 loizides 1.8 const ArrayElement *At(UInt_t idx) const;
42     void Clear(Option_t */*opt*/="") {}
43     UInt_t Entries() const { return GetEntries(); }
44     UInt_t GetEntries() const { return fUIDs.GetEntries(); }
45     UInt_t GetSize() const { return N; }
46     Bool_t IsOwner() const { return kTRUE; }
47 bendavid 1.7 void Reset();
48 loizides 1.8 void Trim() {}
49 loizides 1.1 ArrayElement *UncheckedAt(UInt_t idx);
50 loizides 1.8 const ArrayElement *UncheckedAt(UInt_t idx) const;
51 loizides 1.1 ArrayElement *operator[](UInt_t idx);
52 loizides 1.8 const ArrayElement *operator[](UInt_t idx) const;
53 loizides 1.1
54     protected:
55 loizides 1.8 TObject *GetObject(UInt_t idx) const;
56     UInt_t GetUID(UInt_t idx) const;
57 loizides 1.1
58 bendavid 1.7 StackArray<ProcIDRef,N> fPIDs;//|| process ids of referenced objects
59     StackArrayBasic<UInt_t,N> fUIDs;//|| unique ids of referenced objects
60 loizides 1.1
61 bendavid 1.7 ClassDef(RefArray,2) // Implementation of our own TRefArray
62 loizides 1.1 };
63     }
64    
65     //--------------------------------------------------------------------------------------------------
66 bendavid 1.7 template<class ArrayElement, UInt_t N>
67     inline mithep::RefArray<ArrayElement,N>::RefArray()
68 loizides 1.1 {
69 loizides 1.8 // Default constructor.
70    
71     // Unfortunately the following only would make sense if TObject was our direct ancestor:
72     // this->Class()->IgnoreTObjectStreamer(1);
73 loizides 1.1 }
74    
75     //--------------------------------------------------------------------------------------------------
76 bendavid 1.7 template<class ArrayElement, UInt_t N>
77 loizides 1.9 void mithep::RefArray<ArrayElement,N>::Add(const ArrayElement *ae)
78 loizides 1.1 {
79     // Add new reference to object.
80    
81 bendavid 1.7 if(GetEntries()>=N) {
82 loizides 1.8 Fatal("Add", "Maximum number of slots reached (%d>=%d): "
83     "To support more requires a different template!", GetEntries(), N);
84 loizides 1.1 return;
85     }
86    
87     // check if the object can belong here and assign or get its uid
88     if (ae->TestBit(kHasUUID)) {
89 loizides 1.8 Fatal("Add", "Object can not be added as it has not UUID!");
90 loizides 1.1 return;
91     }
92    
93 bendavid 1.7 UInt_t uid = 0;
94     TProcessID *pid = 0;
95 loizides 1.1 if (ae->TestBit(kIsReferenced)) {
96     uid = ae->GetUniqueID();
97 loizides 1.9 pid = TProcessID::GetProcessWithUID(uid, const_cast<ArrayElement*>(ae));
98 loizides 1.1 } else {
99 bendavid 1.7 pid = TProcessID::GetSessionProcessID();
100 loizides 1.9 uid = TProcessID::AssignID(const_cast<ArrayElement*>(ae));
101 loizides 1.1 }
102    
103 loizides 1.8 // If RefArray contains one and only one PID reference, then only add another if the added object
104     // has a different PID. When this occurs all of the extra spaces which had been left empty get
105     // filled in with the original PID
106 bendavid 1.7 if (fPIDs.GetEntries()==1) {
107     if (pid != fPIDs.At(0)->Pid() ) {
108     while (fPIDs.GetEntries()<GetEntries())
109     fPIDs.Allocate()->SetPid(fPIDs.At(0)->Pid());
110    
111     fPIDs.Allocate()->SetPid(pid);
112     }
113     }
114     else
115     fPIDs.Allocate()->SetPid(pid);
116    
117     fUIDs.Add(uid);
118 loizides 1.1 }
119    
120     //--------------------------------------------------------------------------------------------------
121 bendavid 1.7 template<class ArrayElement, UInt_t N>
122     inline ArrayElement *mithep::RefArray<ArrayElement,N>::At(UInt_t idx)
123 loizides 1.1 {
124     // Return entry at given index.
125    
126 bendavid 1.7 if(idx<GetEntries())
127 loizides 1.1 return static_cast<ArrayElement*>(GetObject(idx));
128    
129 loizides 1.8 Fatal("At", "Given index (%ud) is larger than array size (%ud)", idx, GetEntries());
130 loizides 1.1 return 0;
131     }
132    
133     //--------------------------------------------------------------------------------------------------
134 bendavid 1.7 template<class ArrayElement, UInt_t N>
135     inline const ArrayElement *mithep::RefArray<ArrayElement,N>::At(UInt_t idx) const
136 loizides 1.1 {
137     // Return entry at given index.
138    
139 bendavid 1.7 if(idx<GetEntries())
140 loizides 1.1 return static_cast<const ArrayElement*>(GetObject(idx));
141    
142 loizides 1.8 Fatal("At", "Given index (%ud) is larger than array size (%ud)", idx, GetEntries());
143 loizides 1.1 return 0;
144     }
145    
146     //--------------------------------------------------------------------------------------------------
147 bendavid 1.7 template<class ArrayElement, UInt_t N>
148     TObject *mithep::RefArray<ArrayElement,N>::GetObject(UInt_t idx) const
149 loizides 1.1 {
150     // Return entry at given index. Code adapted from TRef::GetObject().
151 loizides 1.8
152 bendavid 1.7 TProcessID *pid=0;
153     if (fPIDs.GetEntries()>1)
154     pid = fPIDs.At(idx)->Pid();
155     else
156     pid = fPIDs.At(0)->Pid();
157 loizides 1.1
158 bendavid 1.7 if (!pid) {
159 loizides 1.8 Fatal("GetObject","Process id pointer is null!");
160 loizides 1.1 return 0;
161     }
162    
163 bendavid 1.7 if (!TProcessID::IsValid(pid)) {
164 loizides 1.8 Fatal("GetObject","Process id is invalid!");
165 loizides 1.1 return 0;
166     }
167 loizides 1.8
168 loizides 1.1 UInt_t uid = GetUID(idx);
169    
170     //the reference may be in the TRefTable
171     TRefTable *table = TRefTable::GetRefTable();
172     if (table) {
173 bendavid 1.7 table->SetUID(uid, pid);
174 loizides 1.1 table->Notify();
175     }
176    
177     //try to find the object from the table of the corresponding PID
178 bendavid 1.7 TObject *obj = pid->GetObjectWithID(uid);
179 loizides 1.1 return obj;
180     }
181    
182     //--------------------------------------------------------------------------------------------------
183 bendavid 1.7 template<class ArrayElement, UInt_t N>
184     inline UInt_t mithep::RefArray<ArrayElement,N>::GetUID(UInt_t idx) const
185 loizides 1.1 {
186     // Return uid corresponding to idx.
187    
188 bendavid 1.7 return fUIDs.At(idx);
189 loizides 1.1 }
190    
191     //--------------------------------------------------------------------------------------------------
192 bendavid 1.7 template<class ArrayElement, UInt_t N>
193 loizides 1.8 inline void mithep::RefArray<ArrayElement,N>::Reset()
194 loizides 1.1 {
195 loizides 1.8 fUIDs.Reset();
196     fPIDs.Reset();
197 loizides 1.1 }
198    
199     //--------------------------------------------------------------------------------------------------
200 bendavid 1.7 template<class ArrayElement, UInt_t N>
201 loizides 1.8 inline ArrayElement *mithep::RefArray<ArrayElement,N>::UncheckedAt(UInt_t idx)
202 loizides 1.1 {
203     // Return entry at given index.
204    
205 loizides 1.8 return static_cast<ArrayElement*>(GetObject(idx));
206 loizides 1.1 }
207    
208 bendavid 1.7 //--------------------------------------------------------------------------------------------------
209     template<class ArrayElement, UInt_t N>
210 loizides 1.8 inline const ArrayElement *mithep::RefArray<ArrayElement,N>::UncheckedAt(UInt_t idx) const
211 bendavid 1.7 {
212 loizides 1.8 // Return entry at given index.
213    
214     return static_cast<const ArrayElement*>(GetObject(idx));
215 loizides 1.1 }
216    
217     //--------------------------------------------------------------------------------------------------
218 bendavid 1.7 template<class ArrayElement, UInt_t N>
219 loizides 1.8 inline const ArrayElement *mithep::RefArray<ArrayElement,N>::operator[](UInt_t idx) const
220 loizides 1.1 {
221     // Return entry at given index.
222    
223 loizides 1.8 return At(idx);
224 loizides 1.1 }
225    
226     //--------------------------------------------------------------------------------------------------
227 bendavid 1.7 template<class ArrayElement, UInt_t N>
228 loizides 1.8 inline ArrayElement *mithep::RefArray<ArrayElement,N>::operator[](UInt_t idx)
229 loizides 1.1 {
230     // Return entry at given index.
231    
232 loizides 1.8 return At(idx);
233 loizides 1.1 }
234     #endif