Line data Source code
1 : //**************************************************************************
2 : //* This file is property of and copyright by the *
3 : //* ALICE Experiment at CERN, All rights reserved. *
4 : //* *
5 : //* Primary Authors: Matthias Richter <Matthias.Richter@scieq.net> *
6 : //* for The ALICE HLT Project. *
7 : //* *
8 : //* Permission to use, copy, modify and distribute this software and its *
9 : //* documentation strictly for non-commercial purposes is hereby granted *
10 : //* without fee, provided that the above copyright notice appears in all *
11 : //* copies and that both the copyright notice and this permission notice *
12 : //* appear in the supporting documentation. The authors make no claims *
13 : //* about the suitability of this software for any purpose. It is *
14 : //* provided "as is" without express or implied warranty. *
15 : //**************************************************************************
16 :
17 : /// @file AliHLTTPCDataCompressionUnpackerComponent.cxx
18 : /// @author Matthias Richter
19 : /// @date 2016-03-08
20 : /// @brief Unpacker component for compressed TPC cluster data
21 : ///
22 :
23 : #include "AliHLTTPCDataCompressionUnpackerComponent.h"
24 : #include "AliHLTTPCDataCompressionDecoder.h"
25 : #include "AliHLTTPCDefinitions.h"
26 : #include "AliHLTErrorGuard.h"
27 : #include <stdexcept>
28 : #include <cerrno>
29 :
30 6 : ClassImp(AliHLTTPCDataCompressionUnpackerComponent)
31 :
32 : AliHLTTPCDataCompressionUnpackerComponent::AliHLTTPCDataCompressionUnpackerComponent()
33 3 : : AliHLTProcessor()
34 3 : , fpDecoder(NULL)
35 3 : , fClusterWriter(NULL)
36 3 : , fRequiredSpace(216*sizeof(AliHLTTPCRawClusterData))
37 3 : , fInputMultiplier(5.)
38 15 : {
39 : /// constructor
40 6 : }
41 :
42 : AliHLTTPCDataCompressionUnpackerComponent::~AliHLTTPCDataCompressionUnpackerComponent()
43 12 : {
44 : /// destructor
45 12 : }
46 :
47 : const char* AliHLTTPCDataCompressionUnpackerComponent::GetComponentID()
48 : {
49 : /// inherited from AliHLTComponent: id of the component
50 414 : return "TPCDataCompressorUnpacker";
51 : }
52 :
53 : void AliHLTTPCDataCompressionUnpackerComponent::GetInputDataTypes( AliHLTComponentDataTypeList& list)
54 : {
55 : /// inherited from AliHLTComponent: list of data types in the vector reference
56 0 : list.push_back(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
57 0 : list.push_back(AliHLTTPCDefinitions::RemainingClusterIdsDataType());
58 0 : list.push_back(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());
59 0 : list.push_back(AliHLTTPCDefinitions::ClusterIdTracksDataType());
60 0 : list.push_back(AliHLTTPCDefinitions::DataCompressionDescriptorDataType());
61 0 : list.push_back(AliHLTTPCDefinitions::ClustersFlagsDataType());
62 0 : }
63 :
64 : AliHLTComponentDataType AliHLTTPCDataCompressionUnpackerComponent::GetOutputDataType()
65 : {
66 : /// inherited from AliHLTComponent: output data type of the component.
67 0 : return kAliHLTMultipleDataType;
68 : }
69 :
70 : int AliHLTTPCDataCompressionUnpackerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
71 : {
72 : /// inherited from AliHLTComponent: multiple output data types of the component.
73 0 : list.push_back(AliHLTTPCDefinitions::RawClustersDataType());
74 0 : return list.size();
75 : }
76 :
77 : void AliHLTTPCDataCompressionUnpackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
78 : {
79 : /// inherited from AliHLTComponent: output data size estimator
80 0 : constBase=fRequiredSpace;
81 0 : inputMultiplier=fInputMultiplier;
82 0 : }
83 :
84 : AliHLTComponent* AliHLTTPCDataCompressionUnpackerComponent::Spawn()
85 : {
86 : /// inherited from AliHLTComponent: spawn function.
87 0 : return new AliHLTTPCDataCompressionUnpackerComponent;
88 0 : }
89 :
90 : int AliHLTTPCDataCompressionUnpackerComponent::DoEvent( const AliHLTComponentEventData& evtData,
91 : const AliHLTComponentBlockData* blocks,
92 : AliHLTComponentTriggerData& trigData,
93 : AliHLTUInt8_t* outputPtr,
94 : AliHLTUInt32_t& size,
95 : AliHLTComponentBlockDataList& outputBlocks )
96 : {
97 : /// inherited from AliHLTProcessor: data processing
98 : int iResult=0;
99 0 : AliHLTUInt32_t capacity=size;
100 0 : size=0;
101 :
102 0 : AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
103 0 : if (!IsDataEvent(&eventType)) {
104 0 : return iResult;
105 : }
106 :
107 : const AliHLTComponentBlockData* pDesc=NULL;
108 :
109 0 : if (fClusterWriter && fpDecoder) {
110 0 : fClusterWriter->Init(outputPtr, capacity);
111 0 : for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RemainingClusterIdsDataType());
112 0 : pDesc!=NULL; pDesc=GetNextInputBlock()) {
113 0 : fClusterWriter->AddClusterIds(pDesc);
114 : }
115 :
116 0 : for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::ClusterIdTracksDataType());
117 0 : pDesc!=NULL; pDesc=GetNextInputBlock()) {
118 0 : fClusterWriter->AddClusterIds(pDesc);
119 : }
120 :
121 : // read data
122 0 : AliHLTTPCDataCompressionDecoder& decoder=*fpDecoder;
123 0 : decoder.Clear();
124 :
125 0 : for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::ClustersFlagsDataType());
126 0 : pDesc!=NULL; pDesc=GetNextInputBlock()) {
127 0 : decoder.AddClusterFlags(pDesc);
128 : }
129 :
130 0 : if (pDesc = GetFirstInputBlock(AliHLTTPCDefinitions::DataCompressionDescriptorDataType())) {
131 0 : decoder.AddCompressionDescriptor(pDesc);
132 0 : }
133 :
134 : // first unpack track model clusters into temporary map and count clusters per
135 : // partition.
136 0 : for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());
137 0 : pDesc!=NULL && iResult>=0; pDesc=GetNextInputBlock()) {
138 0 : AliClusterWriter::iterator tmit=fClusterWriter->BeginTrackModelClusterBlock(0);
139 0 : iResult=decoder.ReadTrackModelClustersCompressed(tmit,
140 0 : reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr),
141 0 : pDesc->fSize,
142 0 : pDesc->fSpecification);
143 0 : }
144 : // count track model clusters in the individual partitions to allow correct
145 : // memory allocation of the partition cluster blocks
146 0 : int tmClusterCount=fClusterWriter->ProcessTrackModelClusterCount();
147 0 : HLTInfo("extracted %d cluster(s) from track model compressed data", tmClusterCount);
148 :
149 : // now unpack partition cluster blocks
150 0 : for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
151 0 : pDesc!=NULL && iResult>=0; pDesc=GetNextInputBlock()) {
152 0 : if (pDesc->fSize<=sizeof(AliHLTTPCRawClusterData)) {
153 0 : ALIHLTERRORGUARD(5, "inconsistent size of cluster data block");
154 0 : continue;
155 : }
156 0 : AliHLTTPCRawClusterData* clusterData=reinterpret_cast<AliHLTTPCRawClusterData*>(pDesc->fPtr);
157 0 : AliClusterWriter::iterator pcit=fClusterWriter->BeginPartitionClusterBlock(clusterData->fCount, pDesc->fSpecification);
158 0 : iResult=decoder.ReadClustersPartition(pcit,
159 0 : reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr),
160 0 : pDesc->fSize,
161 0 : pDesc->fSpecification);
162 0 : }
163 :
164 : // merge track model clusters into partition cluster blocks and copy output block
165 : // descriptors to list
166 0 : if (iResult>=0) {
167 0 : iResult=fClusterWriter->Finish(outputBlocks);
168 0 : if (iResult==-ENOSPC) {
169 0 : fRequiredSpace=fClusterWriter->GetRequiredSpace();
170 0 : fInputMultiplier=1.;
171 0 : } else if (iResult>=0) {
172 0 : size=iResult;
173 0 : }
174 : }
175 0 : fClusterWriter->Clear();
176 0 : }
177 :
178 : return iResult;
179 0 : }
180 :
181 : int AliHLTTPCDataCompressionUnpackerComponent::DoInit(int argc, const char** argv )
182 : {
183 : /// inherited from AliHLTComponent: component initialization
184 0 : auto_ptr<AliHLTTPCDataCompressionDecoder> decoder(new AliHLTTPCDataCompressionDecoder);
185 0 : if (!decoder.get()) {
186 0 : return -ENOMEM;
187 : }
188 0 : decoder->SetPadrowModeLocal();
189 :
190 0 : auto_ptr<AliClusterWriter> clw(new AliClusterWriter);
191 0 : if (!clw.get())
192 0 : return -ENOMEM;
193 :
194 0 : fpDecoder=decoder.release();
195 0 : fClusterWriter=clw.release();
196 :
197 0 : return 0;
198 0 : }
199 :
200 : int AliHLTTPCDataCompressionUnpackerComponent::DoDeinit()
201 : {
202 : /// inherited from AliHLTComponent: component cleanup
203 0 : if (fpDecoder) {
204 0 : fpDecoder->Clear();
205 0 : delete fpDecoder;
206 0 : fpDecoder=NULL;
207 0 : }
208 0 : if (fClusterWriter) {
209 0 : fClusterWriter->Clear();
210 0 : delete fClusterWriter;
211 0 : fClusterWriter=NULL;
212 0 : }
213 0 : return 0;
214 : }
215 :
216 : int AliHLTTPCDataCompressionUnpackerComponent::ScanConfigurationArgument(int argc, const char** argv)
217 : {
218 : /// inherited from AliHLTComponent: argument scan
219 0 : return 0;
220 : }
221 :
222 0 : AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::AliClusterWriter()
223 0 : : AliHLTLogging()
224 0 : , fOutputBuffer(NULL)
225 0 : , fBufferSize(0)
226 0 : , fBufferFilled(0)
227 0 : , fRequiredSpace(0)
228 0 : , fTrackModelClusters()
229 0 : , fTrackModelClusterCounts()
230 0 : , fPartitionClusterTargets()
231 0 : , fPartitionClusterIds()
232 0 : , fTrackModelClusterIds()
233 0 : {
234 0 : }
235 :
236 0 : AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::AliClusterWriter(AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size)
237 0 : : AliHLTLogging()
238 0 : , fOutputBuffer(pBuffer)
239 0 : , fBufferSize(size)
240 0 : , fBufferFilled(0)
241 0 : , fRequiredSpace(0)
242 0 : , fTrackModelClusters()
243 0 : , fTrackModelClusterCounts()
244 0 : , fPartitionClusterTargets()
245 0 : , fPartitionClusterIds()
246 0 : , fTrackModelClusterIds()
247 0 : {
248 0 : }
249 :
250 : AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::~AliClusterWriter()
251 0 : {
252 0 : }
253 :
254 : AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::iterator AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::BeginTrackModelClusterBlock(int /*count*/)
255 : {
256 : /// iterator of track model clusters
257 : /// the iterator is placed BEFORE the position of the first cluster, this is a bit
258 : /// counter intuitive, but for the sake of the implementation of the decoder class
259 : /// AliHLTTPCDataCompressionDecoder. To provide the slice and partition parameters
260 : /// for every cluster it calls Next with these parameters before every cluster
261 :
262 : /// The count parameter can later be used to optimize the memory allocation, for the
263 : /// moment however it looks like the total cluster count of the track model block
264 : /// has not been set in AliHLTTPCDataCompressionComponent.
265 : AliClusterIdBlock* clusterIds=NULL;
266 0 : clusterIds=&fTrackModelClusterIds;
267 :
268 0 : AliHLTTPCRawClusterMapRef ref(fTrackModelClusters);
269 0 : return iterator(ref, -1, -1, clusterIds);
270 0 : }
271 :
272 : AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::iterator AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::BeginPartitionClusterBlock(int count, AliHLTUInt32_t specification)
273 : {
274 : /// iterator of partition clusters block of specification
275 : /// see note above concerning initial position of the iterator
276 0 : AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetSingleSliceNr(specification);
277 0 : assert(slice>=0);
278 0 : AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetSinglePatchNr(specification);
279 0 : assert(partition>=0);
280 :
281 0 : if (fTrackModelClusterCounts.find(specification)!=fTrackModelClusterCounts.end()) {
282 : // add clusters from track model format
283 0 : count+=fTrackModelClusterCounts[specification];
284 0 : }
285 :
286 0 : if (fPartitionBlockDescriptors.find(specification)==fPartitionBlockDescriptors.end()) {
287 : // reserve a new block
288 0 : AliHLTComponentBlockData bd=ReservePartitionClusterBlock(count, specification);
289 0 : if (bd.fSize>0) {
290 0 : fPartitionBlockDescriptors[specification]=bd;
291 0 : }
292 0 : } else {
293 0 : AliHLTComponentBlockData bd=fPartitionBlockDescriptors[specification];
294 0 : assert(bd.fSize>=sizeof(AliHLTTPCRawClusterData));
295 0 : AliHLTTPCRawClusterData* clusterData=reinterpret_cast<AliHLTTPCRawClusterData*>(fOutputBuffer+bd.fOffset);
296 0 : assert(clusterData->fCount>=count);
297 0 : if (count>=0 && clusterData->fCount<(unsigned)count) {
298 : // not clear yet how to handle
299 0 : throw std::runtime_error("extension of pre-allocated cluster buffer not implemented");
300 : }
301 0 : }
302 :
303 : AliClusterIdBlock* clusterIds=NULL;
304 0 : if (fPartitionClusterIds.find(specification)!=fPartitionClusterIds.end())
305 0 : clusterIds=&fPartitionClusterIds[specification];
306 :
307 0 : if (fPartitionClusterTargets.find(specification)==fPartitionClusterTargets.end()) {
308 0 : throw std::runtime_error("allocation of target buffer failed");
309 : }
310 0 : AliHLTTPCRawClusterArrayRef ref(fPartitionClusterTargets[specification], count>0?count:0);
311 0 : return iterator(ref, slice, partition, clusterIds);
312 0 : }
313 :
314 : AliHLTComponentBlockData AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::ReservePartitionClusterBlock(int count, AliHLTUInt32_t specification)
315 : {
316 : AliHLTComponentBlockData bd;
317 0 : memset (&bd, 0, sizeof(AliHLTComponentBlockData));
318 0 : bd.fStructSize=sizeof(AliHLTComponentBlockData);
319 0 : bd.fDataType=AliHLTTPCDefinitions::fgkRawClustersDataType;
320 0 : bd.fSpecification=specification;
321 0 : bd.fOffset=fBufferFilled;
322 :
323 0 : assert(count>0);
324 0 : if (count<=0) return bd;
325 :
326 : // check if a block of the same partition has already been reserved
327 0 : assert(fPartitionClusterTargets.find(specification)==fPartitionClusterTargets.end());
328 0 : if (fPartitionClusterTargets.find(specification)!=fPartitionClusterTargets.end()) {
329 : return bd;
330 : }
331 :
332 0 : int requiredSpace=sizeof(AliHLTTPCRawClusterData) + count*sizeof(AliHLTTPCRawCluster);
333 0 : fRequiredSpace+=requiredSpace;
334 0 : if (requiredSpace + fBufferFilled > fBufferSize) {
335 : // not enough space for cluster block, accumulate the required space and
336 : // return an empty block descriptor
337 0 : return bd;
338 : }
339 :
340 0 : bd.fSize=requiredSpace;
341 :
342 : // init the cluster data header and array
343 0 : AliHLTTPCRawClusterData* clusterData=reinterpret_cast<AliHLTTPCRawClusterData*>(fOutputBuffer+fBufferFilled);
344 0 : clusterData->fVersion=0;
345 0 : clusterData->fCount=count;
346 0 : AliHLTTPCRawCluster* firstCluster=reinterpret_cast<AliHLTTPCRawCluster*>(clusterData+1);
347 0 : memset(firstCluster, 0, count*sizeof(AliHLTTPCRawCluster));
348 0 : fPartitionClusterTargets[specification]=firstCluster;
349 :
350 0 : fBufferFilled+=requiredSpace;
351 :
352 : return bd;
353 0 : }
354 :
355 : int AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::ProcessTrackModelClusterCount()
356 : {
357 : // count track model clusters in the individual partitions
358 0 : for (std::map<AliHLTUInt32_t, AliHLTTPCRawCluster>::const_iterator mapit=fTrackModelClusters.begin();
359 0 : mapit!=fTrackModelClusters.end(); ++mapit) {
360 0 : unsigned slice=AliHLTTPCSpacePointData::GetSlice(mapit->first);
361 0 : unsigned partition=AliHLTTPCSpacePointData::GetPatch(mapit->first);
362 0 : AliHLTUInt32_t specification=AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, partition, partition);
363 0 : if (fTrackModelClusterCounts.find(specification)==fTrackModelClusterCounts.end()) {
364 0 : fTrackModelClusterCounts[specification]=0;
365 0 : }
366 0 : fTrackModelClusterCounts[specification]+=1;
367 0 : }
368 :
369 0 : return fTrackModelClusters.size();
370 : }
371 :
372 : void AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::Init(AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size)
373 : {
374 : /// set output buffer and init for writing
375 0 : fOutputBuffer=pBuffer;
376 0 : fBufferSize=size;
377 0 : fBufferFilled=0;
378 0 : fRequiredSpace=0;
379 0 : }
380 :
381 : void AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::Clear(Option_t * /*option*/)
382 : {
383 0 : fOutputBuffer=NULL;
384 0 : fBufferSize=0;
385 0 : fBufferFilled=0;
386 0 : fRequiredSpace=0;
387 :
388 0 : fTrackModelClusters.clear();
389 0 : fTrackModelClusterCounts.clear();
390 0 : fPartitionClusterTargets.clear();
391 0 : fPartitionClusterIds.clear();
392 0 : fPartitionBlockDescriptors.clear();
393 0 : new (&fTrackModelClusterIds) AliClusterIdBlock;
394 0 : }
395 :
396 : int AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::AddClusterIds(const AliHLTComponentBlockData* pDesc)
397 : {
398 : /// add cluster id block for partition or track model clusters
399 0 : if (!pDesc) return -EINVAL;
400 0 : if (pDesc->fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
401 0 : fTrackModelClusterIds.fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
402 0 : fTrackModelClusterIds.fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
403 0 : return 0;
404 : }
405 0 : if (pDesc->fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
406 0 : fPartitionClusterIds[pDesc->fSpecification].fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
407 0 : fPartitionClusterIds[pDesc->fSpecification].fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
408 0 : return 0;
409 : }
410 0 : return -ENODATA;
411 0 : }
412 :
413 : int AliHLTTPCDataCompressionUnpackerComponent::AliClusterWriter::Finish(AliHLTComponentBlockDataList& outputBlocks)
414 : {
415 : /// finish unpacking of clusters: merge track model clusters, copy block descriptors
416 0 : std::map<AliHLTUInt32_t, int> writtenPartitionClusters;
417 0 : for (std::map<AliHLTUInt32_t, AliHLTTPCRawCluster>::const_iterator mapit=fTrackModelClusters.begin();
418 0 : mapit!=fTrackModelClusters.end(); ++mapit) {
419 0 : unsigned slice=AliHLTTPCSpacePointData::GetSlice(mapit->first);
420 0 : unsigned partition=AliHLTTPCSpacePointData::GetPatch(mapit->first);
421 0 : AliHLTUInt32_t specification=AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, partition, partition);
422 0 : if (writtenPartitionClusters.find(specification)==writtenPartitionClusters.end()) {
423 : // init map for counting of written clusters
424 0 : if (fTrackModelClusterIds.fIds!=NULL) {
425 0 : writtenPartitionClusters[specification]=-1;
426 0 : } else if (fPartitionBlockDescriptors.find(specification)!=fPartitionBlockDescriptors.end()) {
427 : // this is a bit awkward to determine the first location for the track
428 : // model clusters after all partition clusters have been written
429 0 : unsigned nTotalClusters=(fPartitionBlockDescriptors[specification].fSize-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster);
430 0 : writtenPartitionClusters[specification]=nTotalClusters-fTrackModelClusterCounts[specification];
431 0 : } else {
432 0 : writtenPartitionClusters[specification]=0;
433 : }
434 : }
435 0 : if (fPartitionClusterTargets.find(specification)==fPartitionClusterTargets.end()) {
436 : // partition cluster block not yet allocated
437 0 : AliHLTComponentBlockData bd=ReservePartitionClusterBlock(fTrackModelClusterCounts[specification], specification);
438 0 : if (bd.fSize>0) fPartitionBlockDescriptors[specification]=bd;
439 : else {
440 0 : ALIHLTERRORGUARD(5, "allocation of partition cluster buffer for writing of track model clusters failed, specification 0x%08x", specification);
441 0 : continue;
442 : }
443 : // indicate that track model clusters are copied into a flat partition buffer
444 : // contiguously, ignoring the clusters ids
445 0 : writtenPartitionClusters[specification]=0;
446 0 : }
447 0 : unsigned clusterNo=AliHLTTPCSpacePointData::GetNumber(mapit->first);
448 0 : if (fTrackModelClusterIds.fIds!=NULL && (writtenPartitionClusters[specification]<0)) {
449 0 : clusterNo=AliHLTTPCSpacePointData::GetNumber(fTrackModelClusterIds.fIds[clusterNo]);
450 0 : } else {
451 0 : clusterNo=writtenPartitionClusters[specification]++;
452 : }
453 0 : if ((fPartitionClusterTargets[specification])[clusterNo].GetCharge()!=0) {
454 0 : throw std::runtime_error(" cluster position has already been filled");
455 : }
456 0 : (fPartitionClusterTargets[specification])[clusterNo]=mapit->second;
457 0 : }
458 :
459 : unsigned totalSize=0;
460 0 : AliHLTComponentBlockDataList ol;
461 0 : for( std::map<AliHLTUInt32_t, AliHLTComponentBlockData>::iterator it = fPartitionBlockDescriptors.begin();
462 0 : it != fPartitionBlockDescriptors.end();
463 0 : ++it ) {
464 0 : ol.push_back( it->second );
465 0 : totalSize+=it->second.fSize;
466 : }
467 0 : if (totalSize!=fBufferFilled) {
468 0 : throw std::runtime_error("inconsistent output size");
469 : }
470 :
471 0 : if (fRequiredSpace>totalSize) {
472 0 : return -ENOSPC;
473 : }
474 :
475 0 : outputBlocks.insert(outputBlocks.begin(), ol.begin(), ol.end());
476 0 : return totalSize;
477 0 : }
|