]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - HLT/BASE/AliHLTDataBuffer.h
bugfix: static member was not implemented
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.h
... / ...
CommitLineData
1// @(#) $Id$
2
3#ifndef ALIHLTDATABUFFER_H
4#define ALIHLTDATABUFFER_H
5/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * See cxx source for full Copyright notice */
7
8/** @file AliHLTDataBuffer.h
9 @author Matthias Richter
10 @date
11 @brief Handling of Data Buffers for HLT components.
12 @note The class is used in Offline (AliRoot) context
13*/
14
15#include <cerrno>
16#include <vector>
17#include "AliHLTLogging.h"
18#include "AliHLTDataTypes.h"
19#include "AliHLTDefinitions.h"
20#include "TObject.h"
21//#include "TList.h"
22
23class AliHLTComponent;
24/* @name internal data structures
25 */
26
27/**
28 * @struct AliHLTDataSegment
29 * @brief Descriptor of a data segment within the buffer.
30 * @ingroup alihlt_system
31 */
32struct AliHLTDataSegment {
33 AliHLTDataSegment()
34 :
35 fDataType(),
36 fSegmentOffset(0),
37 fSegmentSize(0),
38 fSpecification(0)
39 {
40 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
41 }
42 AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
43 :
44 fDataType(),
45 fSegmentOffset(offset),
46 fSegmentSize(size),
47 fSpecification(0)
48 {
49 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
50 }
51 /** the data type of this segment */
52 AliHLTComponentDataType fDataType; // see above
53 /** offset in byte within the data buffer */
54 AliHLTUInt32_t fSegmentOffset; // see above
55 /** size of the actual content */
56 AliHLTUInt32_t fSegmentSize; // see above
57 /** data specification */
58 AliHLTUInt32_t fSpecification; // see above
59};
60
61/**
62 * @struct AliHLTRawBuffer
63 * @brief Descriptor of the raw data buffer which can host several segments.
64 * @ingroup alihlt_system
65 */
66struct AliHLTRawBuffer {
67 /** size of the currently occupied partition of the buffer */
68 AliHLTUInt32_t fSize; // see above
69 /** total size of the buffer, including safety margin */
70 AliHLTUInt32_t fTotalSize; // see above
71 /** the buffer */
72 void* fPtr; //! transient
73};
74
75/**
76 * @class AliHLTConsumerDescriptor
77 * @brief Helper class to describe a consumer component.
78 *
79 * There is unfortunately no unique determination of the data type from the
80 * component itself possible, thats why both component and data type have to
81 * be initialized and are stored in a compound. The class is intended to make
82 * bookkeeping easier.
83 *
84 * @note This class is only used for the @ref alihlt_system.
85 *
86 * @ingroup alihlt_system
87 */
88class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
89 public:
90 /** standard constructur */
91 AliHLTConsumerDescriptor();
92 /** constructur
93 * @param pConsumer pointer to the consumer component
94 */
95 AliHLTConsumerDescriptor(AliHLTComponent* pConsumer);
96 /** not a valid copy constructor, defined according to effective C++ style */
97 AliHLTConsumerDescriptor(const AliHLTConsumerDescriptor&);
98 /** not a valid assignment op, but defined according to effective C++ style */
99 AliHLTConsumerDescriptor& operator=(const AliHLTConsumerDescriptor&);
100 /** destructor */
101 ~AliHLTConsumerDescriptor();
102
103 /**
104 * Get the component of this descriptor.
105 * @return pointer to the component
106 */
107 AliHLTComponent* GetComponent() {return fpConsumer;}
108
109 /**
110 * Set an active data segment.
111 * the pointer will be handled in a container, no allocation, copy or
112 * cleanup.
113 * @param offset offset of the segment in the buffer
114 * @param size size of the segment in the buffer
115 * @return >=0 if succeeded
116 */
117 int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
118
119 /**
120 * Check whether there is an active data segment of certain size with
121 * certain offset.
122 * @param offset offset of the data segment in the data buffer
123 * @param size size of the data segment in the data buffer
124 * @return > if existend, 0 if not
125 */
126 int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
127
128 /** find an active data segment of certain size with certain offset
129 * will see if this is necessary
130 * @param offset offset of the data segment in the data buffer
131 * @param size size of the data segment in the data buffer
132 * @return offset of the data segment
133 */
134 //AliHLTUInt32_t FindActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
135
136 /** get the number of active segments for this consumer
137 * @return number of active segments
138 */
139 int GetNofActiveSegments() {return fSegments.size();};
140
141 /**
142 */
143 int ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
144
145 private:
146 /** consumer object */
147 AliHLTComponent* fpConsumer; //! transient
148
149 /** list of data segments */
150 vector<AliHLTDataSegment> fSegments; // see above
151
152 //ClassDef(AliHLTConsumerDescriptor, 0)
153};
154
155/**
156 * @class AliHLTDataBuffer
157 * @brief Handling of data buffers for the HLT.
158 *
159 * The class provides handling of data buffers for HLT tasks. Each task gets
160 * its own Data Buffer instance. The buffer is grouped into different data
161 * segments according to the output of the component.<br>
162 * The Data Buffer keeps control over the data requests of the 'child'
163 * components. Each component can subscribe to a certain segment of the data
164 * buffer. It's state is then changed from 'reserved' to 'active'. After the
165 * data processing, the component has to release the segment and it's state is
166 * set to 'processed'. If all components have requested and released their data,
167 * the Raw Buffer is released and pushed back in the list of available buffers.
168 *
169 * @note This class is only used for the @ref alihlt_system.
170 *
171 * @ingroup alihlt_system
172 */
173class AliHLTDataBuffer : public TObject, public AliHLTLogging {
174 public:
175 //////////////////////////////////////////////////////////////////////////////
176 // condtructors and destructors
177
178 /* standard constructor
179 */
180 AliHLTDataBuffer();
181 /** not a valid copy constructor, defined according to effective C++ style */
182 AliHLTDataBuffer(const AliHLTDataBuffer&);
183 /** not a valid assignment op, but defined according to effective C++ style */
184 AliHLTDataBuffer& operator=(const AliHLTDataBuffer&);
185 /** destructor */
186 virtual ~AliHLTDataBuffer();
187
188 //////////////////////////////////////////////////////////////////////////////
189 // initialization
190
191 /**
192 * Add component to the list of consumers
193 * @param pConsumer - a consumer of type AliHLTComponent
194 */
195 int SetConsumer(AliHLTComponent* pConsumer);
196
197 //////////////////////////////////////////////////////////////////////////////
198 // component to component communication
199
200 /**
201 * Determine the number of matching data blocks for the component and a
202 * consumer component. <br>
203 * The first approach will support only one output data type for processing
204 * components.
205 * @param pConsumer the component which subscribes to the buffer
206 * @param tgtList (optional) the list to receive the data types
207 * @return: number of data blocks which match the input data types
208 * of the consumer, neg. error code if failed <br>
209 * -EINVAL invalid parameter <br>
210 */
211 int FindMatchingDataBlocks(const AliHLTComponent* pConsumer,
212 vector<AliHLTComponentDataType>* tgtList=NULL);
213
214 /**
215 * Subscribe to a segment of the data buffer.
216 * The function prepares the block descriptor for subsequent use with the
217 * AliHLTComponent::ProcessEvent method, the method can prepare several block
218 * descriptors up to the array size specified by iArraySize. The return value
219 * is independent from the array size the number of block descriptors which
220 * would have been prepared if there was enough space in the array<br>
221 * The method is used by the consumer component.
222 * @param pConsumer the component which subscribes to the buffer
223 * @param arrayBlockDesc pointer to block descriptor to be filled
224 * @param iArraySize size of the block descriptor array
225 * @return: number of matching data blocks, neg. error code if failed<br>
226 * -EACCESS the consumer state can't be changed (activated)
227 * -EBADF unresolved data segments <br>
228 * -ENOENT consumer component not found <br>
229 * -ENODATA data buffer does not have raw data <br>
230 * -EINVAL invalid parameter <br>
231 */
232 int Subscribe(const AliHLTComponent* pConsumer,
233 AliHLTComponentBlockData* arrayBlockDesc,
234 int iArraySize);
235
236 /**
237 * Release an instance of the data buffer.
238 * Resets the variables of the block descriptor.
239 * If all buffer segments are released, the Data Buffer is reseted
240 * and the Raw Buffer released.<br>
241 * The method is used by the consumer component.
242 * @param pBlockDesc descriptor of the data segment
243 * @param pConsumer the component which subscribes to the buffer
244 * @return: >0 if success, negative error code if failed <br>
245 * -EACCESS the consumer state can not be changed (de-activated)
246 * -ENOENT consumer has not subscribed to the buffer <br>
247 * -EINVAL invalid parameter <br>
248 */
249 int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer);
250
251 /**
252 * Get a target buffer of minimum size iMinSize.
253 * The method is used by the component which owns the Data Buffer to
254 * allocate a buffer for the data it is going to produce.
255 * @param iMinSize minumum size of the requested buffer
256 * @return: pointer to target buffer if
257 */
258 AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
259
260 /**
261 * Set the segments for the data buffer.
262 * This is usually done after the component has written the data to the buffer,
263 * which was requested by the @ref GetTargetBuffer method. The component might
264 * produce different types of data, for each type a segment has to be defined
265 * which describes the data inside the buffer.<br>
266 * The @ref AliHLTComponentBlockData segment descriptor comes directly from
267 * the @ref AliHLTComponent::ProcessEvent method.
268 * @param pTgt the target buffer which the segments refer to
269 * @param arraySegments the output block descriptors of the component
270 * @param iSize size of the array
271 */
272 int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arraySegments, int iSize);
273
274 /**
275 * Check if the data buffer is empty.
276 * @return 1 if empty, 0 if not
277 */
278 int IsEmpty();
279
280 /**
281 * Get the total and maximum size of the buffer.
282 * Lets see if this is needed later
283 */
284 //int GetTotalSize();
285
286 /**
287 * Get the number of segments
288 * @return number of segments
289 */
290 int GetNofSegments();
291
292 /**
293 * Get the number of consumers
294 * @return number of consumers
295 */
296 int GetNofConsumers();
297
298 /**
299 * Get the number of active consumers
300 * @return number of active consumers
301 */
302 int GetNofActiveConsumers();
303
304 /**
305 * Check if a consumer is already in the list
306 * @param pConsumer pointer to consumer component
307 * @param bAllLists search in all lists if 1
308 * search only in fConsumer list if 0
309 * @return 1 if found, 0 if not
310 */
311 int FindConsumer(AliHLTComponent* pConsumer, int bAllLists=1);
312
313 /**
314 * Public method to reset the buffer.
315 * Eventually with some additional checks. In normal operation,
316 * an external reset should not be necessary.
317 */
318 int Reset();
319
320 private:
321 /* lets see if this is needed
322 AliHLTDataSegment* FindDataSegment(AliHLTComponentDataType datatype);
323 */
324
325 /**
326 * Find those data segments which match the input types of a component.
327 * @param pConsumer the component which subscribes to the buffer
328 * @param tgtList the list to receive the data segment descriptors
329 * @return: number of data blocks which match the input data types
330 * of the consumer, neg. error code if failed <br>
331 * -EINVAL invalid parameter <br>
332 */
333 int FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList);
334
335 /**
336 * Reset the data buffer.
337 * Removes all consumers back to the @ref fConsumers list, deletes
338 * segments and releases the Raw Buffer.
339 */
340 int ResetDataBuffer();
341
342 //////////////////////////////////////////////////////////////////////////////
343
344 // the data description
345
346 // the data segments within this buffer
347 vector<AliHLTDataSegment> fSegments; // see above
348
349 // the list of all consumers which are going to subscribe to the buffer
350 vector<AliHLTConsumerDescriptor*> fConsumers; // see above
351 // the list of all consumers which are currently subscribed to the buffer
352 vector<AliHLTConsumerDescriptor*> fActiveConsumers; // see above
353 // the list of all consumers which are already released for the current event
354 vector<AliHLTConsumerDescriptor*> fReleasedConsumers; // see above
355
356 // the buffer instance
357 AliHLTRawBuffer* fpBuffer; //! transient
358
359 // flags indicating the state of the buffer
360 AliHLTUInt32_t fFlags; // see above
361
362 //////////////////////////////////////////////////////////////////////////////
363 // global buffer handling, internal use only
364
365 /**
366 * Create a raw buffer of a certain size.
367 * The function tries to find a buffer of the given size (or a bit bigger by a
368 * certain margin @ref fgMargin) from the list of free buffers.
369 * If no buffer is available, a new one is created and added to the buffer handling.
370 * @param size min. size of the requested buffer
371 * @return pointer to raw buffer
372 */
373 static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
374
375 /**
376 * Mark a buffer as free.
377 * After the Data Buffer has finnished using the raw buffer, it is released
378 * and added to the list of available buffers.
379 * @param pBuffer the raw buffer to release
380 * @return >=0 if succeeded, neg. error code if failed
381 */
382 static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
383
384 /**
385 * Deletes all the raw buffers.
386 * When the last Data Buffer object is destructed, all raw data buffers are
387 * relesed.
388 */
389 static int DeleteRawBuffers();
390
391 /**
392 * Number of instances of AliHLTDataBuffer.
393 * The statice variable is incremented and decremented in the constructor/
394 * destructor. All internal data structures are cleaned up when the last
395 * instance is exiting.
396 */
397 static int fgNofInstances; // see above
398 /** global list of free raw buffers */
399 static vector<AliHLTRawBuffer*> fgFreeBuffers; // see above
400 /** global list of currently active raw buffers */
401 static vector<AliHLTRawBuffer*> fgActiveBuffers; // see above
402 /** determines the raw buffer size margin at buffer requests */
403 static AliHLTUInt32_t fgMargin; // see above
404
405 /** global instance to HLT logging class for static methods */
406 static AliHLTLogging fgLogging; // see above
407
408 //////////////////////////////////////////////////////////////////////////////
409 // internal helper functions
410
411 /**
412 * Find the consumer descriptor for a certain component and data type in
413 * a list of consumers.<br>
414 * <b>Note:</b> There are three lists which contain the consumers in the
415 * different states.
416 * @param pConsumer pointer to consumer component
417 * @param list list where to search for the consumer
418 */
419 AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer,
420 vector<AliHLTConsumerDescriptor*> &list) const;
421
422 /**
423 * Change the state of a consumer.
424 * The state of a consumer is determined by the list it is strored in, the
425 * method moves a consumer from the source to the target list.
426 * @param pDesc pointer to consumer descriptor
427 * @param srcList list where the consumer is currently to be found
428 * @param tgtList list where to move the consumer
429 */
430 int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc,
431 vector<AliHLTConsumerDescriptor*> &srcList,
432 vector<AliHLTConsumerDescriptor*> &tgtList);
433
434 /**
435 * Cleanup a consumer list.
436 * Release all allocated data structures. <b>Note:</b> Not the component itself!
437 */
438 int CleanupConsumerList();
439
440 ClassDef(AliHLTDataBuffer, 0)
441};
442#endif // ALIHLTDATABUFFER_H