- extended high-level component interface: header buffer before TObjects,
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 17 Jul 2007 11:01:07 +0000 (11:01 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 17 Jul 2007 11:01:07 +0000 (11:01 +0000)
  ROOT memory file added, ROOT file streamer added
- workaround for ROOT garbage collection causing crashes when
  cleaning up input objects
- documentation
- eff C++ cleanup

21 files changed:
HLT/BASE/AliHLTComponent.cxx
HLT/BASE/AliHLTComponent.h
HLT/BASE/AliHLTMemoryFile.cxx [new file with mode: 0644]
HLT/BASE/AliHLTMemoryFile.h [new file with mode: 0644]
HLT/BASE/AliHLTModuleAgent.cxx
HLT/BASE/AliHLTModuleAgent.h
HLT/BASE/AliHLTOfflineDataSink.h
HLT/BASE/AliHLTOfflineDataSource.h
HLT/BASE/AliHLTOfflineInterface.cxx
HLT/BASE/AliHLTOfflineInterface.h
HLT/BASE/util/AliHLTFileWriter.h
HLT/BASE/util/AliHLTLoaderPublisherComponent.cxx
HLT/BASE/util/AliHLTLoaderPublisherComponent.h
HLT/BASE/util/AliHLTRootFilePublisherComponent.h
HLT/BASE/util/AliHLTRootFileStreamerComponent.cxx [new file with mode: 0644]
HLT/BASE/util/AliHLTRootFileStreamerComponent.h [new file with mode: 0644]
HLT/BASE/util/AliHLTRootFileWriterComponent.cxx
HLT/BASE/util/AliHLTRootFileWriterComponent.h
HLT/ChangeLog
HLT/libAliHLTUtil.pkg
HLT/libHLTbase.pkg

index ae39006..782b803 100644 (file)
@@ -32,8 +32,10 @@ using namespace std;
 #include "AliHLTMessage.h"
 #include "TString.h"
 #include "TObjArray.h"
+#include "TObjectTable.h"
 #include "TClass.h"
 #include "TStopwatch.h"
+#include "AliHLTMemoryFile.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTComponent);
@@ -63,7 +65,8 @@ AliHLTComponent::AliHLTComponent()
   fOutputBufferSize(0),
   fOutputBufferFilled(0),
   fOutputBlocks(),
-  fpStopwatches(new TObjArray(kSWTypeCount))
+  fpStopwatches(new TObjArray(kSWTypeCount)),
+  fMemFiles()
 {
   // see header file for class documentation
   // or
@@ -93,16 +96,15 @@ AliHLTComponent::AliHLTComponent(const AliHLTComponent&)
   fOutputBufferSize(0),
   fOutputBufferFilled(0),
   fOutputBlocks(),
-  fpStopwatches(NULL)
+  fpStopwatches(NULL),
+  fMemFiles()
 {
   // see header file for class documentation
-  HLTFatal("copy constructor untested");
 }
 
 AliHLTComponent& AliHLTComponent::operator=(const AliHLTComponent&)
 { 
   // see header file for class documentation
-  HLTFatal("assignment operator untested");
   return *this;
 }
 
@@ -112,6 +114,19 @@ AliHLTComponent::~AliHLTComponent()
   CleanupInputObjects();
   if (fpStopwatches!=NULL) delete fpStopwatches;
   fpStopwatches=NULL;
+  vector<AliHLTMemoryFile*>::iterator element=fMemFiles.begin();
+  while (element!=fMemFiles.end()) {
+    if (*element) {
+      if ((*element)->IsClosed()==0) {
+       HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
+       // close but do not flush as we dont know whether the buffer is still valid
+       (*element)->Close(0);
+      }
+      delete *element;
+      *element=NULL;
+    }
+    element++;
+  }
 }
 
 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
@@ -454,9 +469,9 @@ const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataTyp
   if (classname) fClassName=classname;
   else fClassName.clear();
   int idx=FindInputBlock(fSearchDataType, 0, 1);
-  HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
   TObject* pObj=NULL;
   if (idx>=0) {
+    HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
       fCurrentInputBlock=idx;
     } else {
@@ -575,7 +590,11 @@ int AliHLTComponent::CleanupInputObjects()
   fpInputObjects=NULL;
   for (int i=0; i<array->GetEntries(); i++) {
     TObject* pObj=array->At(i);
-    if (pObj) delete pObj;
+    // grrr, garbage collection strikes back: When read via AliHLTMessage
+    // (CreateInputObject), and written to a TFile afterwards, the
+    // TFile::Close calls ROOOT's garbage collection. No clue why the
+    // object ended up in the key list and needs to be deleted
+    if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
   }
   delete array;
   return 0;
@@ -700,7 +719,8 @@ AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData*
   return iSpec;
 }
 
-int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
+int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, 
+                             void* pHeader, int headerSize)
 {
   // see header file for function documentation
   ALIHLTCOMPONENT_BASE_STOPWATCH();
@@ -711,7 +731,7 @@ int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& d
     Int_t iMsgLength=msg.Length();
     if (iMsgLength>0) {
       msg.SetLength(); // sets the length to the first (reserved) word
-      iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec);
+      iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
       if (iResult>=0) {
        HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
       }
@@ -725,13 +745,14 @@ int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& d
   return iResult;
 }
 
-int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
+int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
+                             void* pHeader, int headerSize)
 {
   // see header file for function documentation
   ALIHLTCOMPONENT_BASE_STOPWATCH();
   AliHLTComponentDataType dt;
   SetDataType(dt, dtID, dtOrigin);
-  return PushBack(pObject, dt, spec);
+  return PushBack(pObject, dt, spec, pHeader, headerSize);
 }
 
 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
@@ -750,31 +771,40 @@ int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const
   return PushBack(pBuffer, iSize, dt, spec);
 }
 
-int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
+int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
+                             void* pHeader, int iHeaderSize)
 {
   // see header file for function documentation
   int iResult=0;
+  int iBlkSize = iBufferSize + iHeaderSize;
   if (pBuffer) {
-    if (fpOutputBuffer && iSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
+    if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
       AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
       AliHLTComponentBlockData bd;
       FillBlockData( bd );
       bd.fOffset        = fOutputBufferFilled;
       bd.fPtr           = pTgt;
-      bd.fSize          = iSize;
+      bd.fSize          = iBlkSize;
       bd.fDataType      = dt;
       bd.fSpecification = spec;
+      if (pHeader!=NULL && pHeader!=pTgt) {
+       memcpy(pTgt, pHeader, iHeaderSize);
+      }
+
+      pTgt += (AliHLTUInt8_t) iHeaderSize;
+
       if (pBuffer!=NULL && pBuffer!=pTgt) {
-       memcpy(pTgt, pBuffer, iSize);
+       memcpy(pTgt, pBuffer, iBufferSize);
+       
        //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); 
-       //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iSize, pBuffer, pTgt, firstWord);
+       //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
       }
       fOutputBufferFilled+=bd.fSize;
       fOutputBlocks.push_back( bd );
-      //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iSize, DataType2Text(dt).c_str(), spec);
+      //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
     } else {
       if (fpOutputBuffer) {
-       HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iSize);
+       HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
       } else {
        HLTError("output buffer not available");
       }
@@ -795,6 +825,138 @@ int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
     return msg.Length();  
 }
 
+AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
+                                                   const char* dtOrigin,
+                                                   AliHLTUInt32_t spec)
+{
+  // see header file for function documentation
+  ALIHLTCOMPONENT_BASE_STOPWATCH();
+  AliHLTComponentDataType dt;
+  SetDataType(dt, dtID, dtOrigin);
+  return CreateMemoryFile(capacity, dt, spec);
+}
+
+AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
+                                                   const AliHLTComponentDataType& dt,
+                                                   AliHLTUInt32_t spec)
+{
+  // see header file for function documentation
+  ALIHLTCOMPONENT_BASE_STOPWATCH();
+  AliHLTMemoryFile* pFile=NULL;
+  if (capacity>=0 && capacity<=fOutputBufferSize-fOutputBufferFilled){
+    AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
+    pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
+    if (pFile) {
+      int nofBlocks=fOutputBlocks.size();
+      if (nofBlocks+1>fMemFiles.size()) {
+       fMemFiles.resize(nofBlocks+1, NULL);
+      }
+      if (nofBlocks<fMemFiles.size()) {
+       fMemFiles[nofBlocks]=pFile;
+       AliHLTComponentBlockData bd;
+       FillBlockData( bd );
+       bd.fOffset        = fOutputBufferFilled;
+       bd.fPtr           = pTgt;
+       bd.fSize          = capacity;
+       bd.fDataType      = dt;
+       bd.fSpecification = spec;
+       fOutputBufferFilled+=bd.fSize;
+       fOutputBlocks.push_back( bd );
+      } else {
+       HLTError("can not allocate/grow object array");
+       pFile->Close(0);
+       delete pFile;
+       pFile=NULL;
+      }
+    }
+  } else {
+    HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
+  }
+  return pFile;
+}
+
+AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
+                                                   const char* dtOrigin,
+                                                   AliHLTUInt32_t spec,
+                                                   float capacity)
+{
+  // see header file for function documentation
+  ALIHLTCOMPONENT_BASE_STOPWATCH();
+  AliHLTComponentDataType dt;
+  SetDataType(dt, dtID, dtOrigin);
+  int size=fOutputBufferSize-fOutputBufferFilled;
+  if (capacity<0 || capacity>1.0) {
+    HLTError("invalid parameter: capacity %f", capacity);
+    return NULL;
+  }
+  size=(int)(size*capacity);
+  return CreateMemoryFile(size, dt, spec);
+}
+
+AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
+                                                   AliHLTUInt32_t spec,
+                                                   float capacity)
+{
+  // see header file for function documentation
+  ALIHLTCOMPONENT_BASE_STOPWATCH();
+  int size=fOutputBufferSize-fOutputBufferFilled;
+  if (capacity<0 || capacity>1.0) {
+    HLTError("invalid parameter: capacity %f", capacity);
+    return NULL;
+  }
+  size=(int)(size*capacity);
+  return CreateMemoryFile(size, dt, spec);
+}
+
+int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
+                          const char* key, int option)
+{
+  int iResult=0;
+  if (pFile && pObject) {
+    pFile->cd();
+    iResult=pObject->Write(key, option);
+    if (iResult>0) {
+      // success
+    } else {
+      iResult=-pFile->GetErrno();
+      if (iResult==-ENOSPC) {
+       HLTError("error writing memory file, buffer too small");
+      }
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
+{
+  int iResult=0;
+  if (pFile) {
+    vector<AliHLTMemoryFile*>::iterator element=fMemFiles.begin();
+    int i=0;
+    while (element!=fMemFiles.end() && iResult>=0) {
+      if (*element && *element==pFile) {
+       iResult=pFile->Close();
+       
+       // sync memory files and descriptors
+       if (iResult>=0) {
+         fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
+       }
+       delete *element;
+       *element=NULL;
+       return iResult;
+      }
+      element++; i++;
+    }
+    HLTError("can not find memory file %p", pFile);
+    iResult=-ENOENT;
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
 {
   // see header file for function documentation
@@ -834,12 +996,29 @@ int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
   if (iResult>=0) {
     if (fOutputBlocks.size()>0) {
       //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
-      if (blockData.size()>0) {
-       HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
-       iResult=-EFAULT;
-      } else {
-       iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
-       size=fOutputBufferFilled;
+      
+      // sync memory files and descriptors
+      vector<AliHLTMemoryFile*>::iterator element=fMemFiles.begin();
+      int i=0;
+      while (element!=fMemFiles.end() && iResult>=0) {
+       if (*element) {
+         if ((*element)->IsClosed()==0) {
+           HLTWarning("memory file has not been closed, force flush");
+           iResult=CloseMemoryFile(*element);
+         }
+       }
+       element++; i++;
+      }
+
+      if (iResult>=0) {
+       // create the descriptor list
+       if (blockData.size()>0) {
+         HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
+         iResult=-EFAULT;
+       } else {
+         iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
+         size=fOutputBufferFilled;
+       }
       }
     } else {
       iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
index 0141170..4917724 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTCOMPONENT_H
 #define ALIHLTCOMPONENT_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTComponent.h
@@ -46,6 +47,7 @@ typedef AliHLTComponentEventDoneData AliHLTComponent_EventDoneData;
 class AliHLTComponentHandler;
 class TObjArray;
 class TStopwatch;
+class AliHLTMemoryFile;
 
 /**
  * @class AliHLTComponent
@@ -147,8 +149,11 @@ class TStopwatch;
  *        add event information to the output
  * 
  * In addition, the processing methods are simplified a bit by cutting out most of
- * the parameters. The component implementation 
- * @see AliHLTProcessor AliHLTDataSource AliHLTDataSink
+ * the parameters.
+ * @see 
+ * - @ref AliHLTProcessor::DoEvent
+ * - @ref AliHLTDataSource::GetEvent
+ * - @ref AliHLTDataSink::DumpEvent
  *
  * \em IMPORTANT: objects and block descriptors provided by the high-level interface
  *  <b>MUST NOT BE DELETED</b> by the caller.
@@ -689,25 +694,35 @@ class AliHLTComponent : public AliHLTLogging {
 
   /**
    * Insert an object into the output.
+   * If header is specified, it will be inserted before the root object,
+   * default is no header.
    * @param pObject     pointer to root object
    * @param dt          data type of the object
    * @param spec        data specification
+   * @param pHeader     pointer to header
+   * @param headerSize  size of Header
    * @return neg. error code if failed 
    */
   int PushBack(TObject* pObject, const AliHLTComponentDataType& dt, 
-              AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
+              AliHLTUInt32_t spec=kAliHLTVoidDataSpec, 
+              void* pHeader=NULL, int headerSize=0);
 
   /**
    * Insert an object into the output.
+   * If header is specified, it will be inserted before the root object,
+   * default is no header.
    * @param pObject     pointer to root object
    * @param dtID        data type ID of the object
    * @param dtOrigin    data type origin of the object
    * @param spec        data specification
+   * @param pHeader     pointer to header
+   * @param headerSize  size of Header
    * @return neg. error code if failed 
    */
   int PushBack(TObject* pObject, const char* dtID, const char* dtOrigin,
-              AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
-
+              AliHLTUInt32_t spec=kAliHLTVoidDataSpec,
+              void* pHeader=NULL, int headerSize=0);
   /**
    * Insert an object into the output.
    * @param pBuffer     pointer to buffer
@@ -738,6 +753,98 @@ class AliHLTComponent : public AliHLTLogging {
    */
   int EstimateObjectSize(TObject* pObject) const;
 
+  /**
+   * Create a memory file in the output stream.
+   * This method creates a TFile object which stores all data in
+   * memory instead of disk. The TFile object is published as binary data.
+   * The instance can be used like a normal TFile object. The TFile::Close
+   * or @ref CloseMemoryFile method has to be called in order to flush the
+   * output stream.
+   *
+   * \b Note: The returned object is deleted by the framework.
+   * @param capacity    total size reserved for the memory file
+   * @param dtID        data type ID of the file
+   * @param dtOrigin    data type origin of the file
+   * @param spec        data specification
+   * @return file handle, NULL if failed 
+   */
+  AliHLTMemoryFile* CreateMemoryFile(int capacity, const char* dtID, const char* dtOrigin,
+                                    AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
+
+  /**
+   * Create a memory file in the output stream.
+   * This method creates a TFile object which stores all data in
+   * memory instead of disk. The TFile object is published as binary data.
+   * The instance can be used like a normal TFile object. The TFile::Close
+   * or @ref CloseMemoryFile method has to be called in order to flush the
+   * output stream.
+   *
+   * \b Note: The returned object is deleted by the framework.
+   * @param capacity    total size reserved for the memory file
+   * @param dt          data type of the file
+   * @param spec        data specification
+   * @return file handle, NULL if failed 
+   */
+  AliHLTMemoryFile* CreateMemoryFile(int capacity, 
+                                    const AliHLTComponentDataType& dt=kAliHLTAnyDataType,
+                                    AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
+
+  /**
+   * Create a memory file in the output stream.
+   * This method creates a TFile object which stores all data in
+   * memory instead of disk. The TFile object is published as binary data.
+   * The instance can be used like a normal TFile object. The TFile::Close
+   * or @ref CloseMemoryFile method has to be called in order to flush the
+   * output stream.
+   *
+   * \b Note: The returned object is deleted by the framework.
+   * @param dtID        data type ID of the file
+   * @param dtOrigin    data type origin of the file
+   * @param spec        data specification
+   * @param capacity    fraction of the available output buffer size
+   * @return file handle, NULL if failed 
+   */
+  AliHLTMemoryFile* CreateMemoryFile(const char* dtID, const char* dtOrigin,
+                                    AliHLTUInt32_t spec=kAliHLTVoidDataSpec,
+                                    float capacity=1.0);
+
+  /**
+   * Create a memory file in the output stream.
+   * This method creates a TFile object which stores all data in
+   * memory instead of disk. The TFile object is published as binary data.
+   * The instance can be used like a normal TFile object. The TFile::Close
+   * or @ref CloseMemoryFile method has to be called in order to flush the
+   * output stream.
+   *
+   * \b Note: The returned object is deleted by the framework.
+   * @param dt          data type of the file
+   * @param spec        data specification
+   * @param capacity    fraction of the available output buffer size
+   * @return file handle, NULL if failed 
+   */
+  AliHLTMemoryFile* CreateMemoryFile(const AliHLTComponentDataType& dt=kAliHLTAnyDataType,
+                                    AliHLTUInt32_t spec=kAliHLTVoidDataSpec,
+                                    float capacity=1.0);
+
+  /**
+   * Write an object to memory file in the output stream.
+   * @param pFile       file handle
+   * @param pObject     pointer to root object
+   * @param key         key in ROOT file
+   * @param option      options, see TObject::Write
+   * @return neg. error code if failed
+   *         - -ENOSPC    no space left
+   */
+  int Write(AliHLTMemoryFile* pFile, const TObject* pObject, const char* key=NULL, int option=TObject::kOverwrite);
+
+  /**
+   * Close object memory file.
+   * @param pFile       file handle
+   * @return neg. error code if failed
+   *         - -ENOSPC    buffer size too small
+   */
+  int CloseMemoryFile(AliHLTMemoryFile* pFile);
+
   /**
    * Insert event-done data information into the output.
    * @param edd          event-done data information
@@ -816,16 +923,19 @@ class AliHLTComponent : public AliHLTLogging {
    * This is the only method to insert blocks into the output stream, called
    * from all types of the Pushback method. The actual data might have been
    * written to the output buffer already. In that case NULL can be provided
-   * as buffer, only the block descriptor will be build.
+   * as buffer, only the block descriptor will be build. If a header is specified, 
+   * it will be inserted before the buffer, default is no header.
    * @param pBuffer     pointer to buffer
    * @param iSize       size of the buffer in byte
    * @param dt          data type
    * @param spec        data specification
+   * @param pHeader     pointer to header
+   * @param iHeaderSize size of Header
    */
-  int InsertOutputBlock(void* pBuffer, int iSize,
+  int InsertOutputBlock(void* pBuffer, int iBufferSize,
                        const AliHLTComponentDataType& dt,
-                       AliHLTUInt32_t spec);
-
+                       AliHLTUInt32_t spec,
+                       void* pHeader=NULL, int iHeaderSize=0);
 
   /** The global component handler instance */
   static AliHLTComponentHandler* fgpComponentHandler;              //! transient
@@ -875,6 +985,9 @@ class AliHLTComponent : public AliHLTLogging {
   /** stopwatch array */
   TObjArray* fpStopwatches;                                        //! transient
 
-  ClassDef(AliHLTComponent, 2)
+  /** array of memory files AliHLTMemoryFile */
+  vector<AliHLTMemoryFile*> fMemFiles;                             //! transient
+
+  ClassDef(AliHLTComponent, 3)
 };
 #endif
diff --git a/HLT/BASE/AliHLTMemoryFile.cxx b/HLT/BASE/AliHLTMemoryFile.cxx
new file mode 100644 (file)
index 0000000..9fd25ce
--- /dev/null
@@ -0,0 +1,243 @@
+// $Id$
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** @file   AliHLTMemoryFile.cxx
+    @author Matthias Richter
+    @date   
+    @brief  ROOT file in memory.                                          */
+
+#include "AliHLTMemoryFile.h"
+#include <cerrno>
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTMemoryFile);
+
+AliHLTMemoryFile::AliHLTMemoryFile()
+  :
+  fpBuffer(NULL),
+  fBufferSize(0),
+  fPosition(0),
+  fSize(0),
+  fErrno(0),
+  fbClosed(0),
+  fHeaderSize(0),
+  fTrailerSize(0)
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+}
+
+AliHLTMemoryFile::AliHLTMemoryFile(void* pBuffer, int iSize)
+  :
+  TFile("/dev/null", "CREATE"),
+  AliHLTLogging(),
+  fpBuffer((char*)pBuffer),
+  fBufferSize(iSize),
+  fPosition(0),
+  fSize(0),
+  fErrno(0),
+  fbClosed(0),
+  fHeaderSize(0),
+  fTrailerSize(0)
+{
+  // see header file for class documentation
+  //HLTDebug("created memory file %p, capacity %d, ROOT version %d", this, fBufferSize, fVersion);
+}
+
+AliHLTMemoryFile::AliHLTMemoryFile(const AliHLTMemoryFile&)
+  :
+  fpBuffer(NULL),
+  fBufferSize(0),
+  fPosition(0),
+  fSize(0),
+  fErrno(0),
+  fbClosed(0),
+  fHeaderSize(0),
+  fTrailerSize(0)
+{
+  // see header file for class documentation
+}
+
+AliHLTMemoryFile& AliHLTMemoryFile::operator=(const AliHLTMemoryFile&)
+{ 
+  // see header file for class documentation
+  return *this;
+}
+
+AliHLTMemoryFile::~AliHLTMemoryFile()
+{
+  // see header file for function documentation
+  //HLTDebug("deleting file %p size %d", this, fSize);
+  if (!fbClosed) {
+    HLTWarning("memory file not closed, possible data loss");
+  }
+}
+
+int AliHLTMemoryFile::Close(int bFlush)
+{
+  fErrno=0;
+  if (fbClosed) return 0;
+  if (bFlush) {
+    TFile::Close();
+  }
+  fpBuffer=NULL;
+  fBufferSize=fPosition=0;
+  fbClosed=1;
+  if (fErrno==ENOSPC) {
+    HLTError("error flushing memory file, buffer too small");
+  } else if (fErrno>0) {
+    HLTError("error flushing memory file");
+  }
+  return -fErrno;
+}
+
+Int_t    AliHLTMemoryFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
+{
+  // see header file for function documentation
+  if (fpBuffer==NULL || fSize==0) return 1;
+  //HLTDebug("opening file %p capacity %d", this, fSize);
+  fErrno=0;
+  errno=fErrno=ENOSPC;
+  return -1;
+}
+
+Int_t    AliHLTMemoryFile::SysClose(Int_t fd)
+{
+  // see header file for function documentation
+  //HLTDebug("closing file %p size %d", this, fSize);
+  return 0;
+}
+
+Int_t    AliHLTMemoryFile::SysRead(Int_t fd, void *buf, Int_t len)
+{
+  // see header file for function documentation
+  if (buf==NULL) return 0;
+  fErrno=0;
+  //HLTDebug("reading buffer of size %d at position %d", len, fPosition);
+  if (fpBuffer==NULL || fBufferSize==0) return 0;
+  int read=len<fSize-fPosition?len:fSize-fPosition;
+  memcpy(buf, fpBuffer+fPosition, read);
+  fPosition+=read;
+  if (fPosition>=fSize) fSize=fPosition+1;
+  return read;
+}
+
+Int_t    AliHLTMemoryFile::SysWrite(Int_t fd, const void *buf, Int_t len)
+{
+  // see header file for function documentation
+  if (buf==NULL) return 0;
+  fErrno=0;
+  //HLTDebug("writing buffer of size %d at position %d", len, fPosition);
+  if (len<fBufferSize-fPosition) {
+    memcpy(fpBuffer+fPosition, buf, len);
+    fPosition+=len;
+    if (fPosition>=fSize) fSize=fPosition+1;
+    return len;
+  }
+  errno=fErrno=ENOSPC;
+  return -1;
+}
+
+Long64_t AliHLTMemoryFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
+{
+  // see header file for function documentation
+  //HLTDebug("seek %d from %d", offset, whence);
+  fErrno=0;
+  int position=(int)offset;
+  switch (whence) {
+  case SEEK_SET:
+    // nothing to do
+    break;
+  case SEEK_CUR:
+    position+=fPosition;
+    break;
+  case SEEK_END:
+    position+=fSize;
+  default:
+    position=-1;
+    errno=EINVAL;
+  }
+  if (position>=0) {
+    if (position<fBufferSize) {
+      fPosition=position;
+    } else {
+      position=-1;
+      errno=fErrno=ENOSPC;
+    }
+  }
+  return position;
+}
+
+Int_t    AliHLTMemoryFile::SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
+{
+  // see header file for function documentation
+  if (size) *size=fSize;
+  return 0;
+}
+
+Int_t    AliHLTMemoryFile::SysSync(Int_t fd)
+{
+  // see header file for function documentation
+  return 0;
+}
+
+int AliHLTMemoryFile::WriteHeader(const char* pHeader, int size)
+{
+  // see header file for function documentation
+  fErrno=0;
+  if (fHeaderSize==0) {
+    if (fSize+size<fBufferSize) {
+      if (fSize>0) {
+       // move exiting data
+       memcpy(fpBuffer+size, fpBuffer, fSize);
+      }
+      memcpy(fpBuffer, pHeader, size);
+      fpBuffer+=size;
+      fPosition+=size;
+      fBufferSize-=size;
+      fHeaderSize=size;
+    } else {
+      HLTError("no space left in memory file");
+      fErrno=ENOSPC;
+    }
+  } else {
+    HLTError("header exists");
+    fErrno=EEXIST;
+  }
+  return -fErrno;
+}
+
+// int AliHLTMemoryFile::WriteTrailer(const char* pTrailer, int size)
+// {
+//   // see header file for function documentation
+//   fErrno=0;
+//   if (fD>0) {
+//     HLTError("file must be closed to write trailer");
+//     return EPERM;
+//   }
+//   if (fSize+size<fBufferSize) {
+//     memcpy(fpBuffer+fSize, pTrailer, size);
+//   } else {
+//     HLTError("no space left in memory file");
+//     fErrno=ENOSPC;
+//   }
+//   return fErrno;
+// }
diff --git a/HLT/BASE/AliHLTMemoryFile.h b/HLT/BASE/AliHLTMemoryFile.h
new file mode 100644 (file)
index 0000000..bceb0db
--- /dev/null
@@ -0,0 +1,133 @@
+//-*- Mode: C++ -*-
+// @(#) $Id$
+
+#ifndef ALIHLTMEMORYFILE_H
+#define ALIHLTMEMORYFILE_H
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/** @file   AliHLTMemoryFile.h
+    @author Matthias Richter
+    @date   
+    @brief  Serialization of complete ROOT files.
+
+// see below for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+                                                                          */
+#include "TFile.h"
+#include "AliHLTLogging.h"
+
+/**
+ * @class AliHLTMemoryFile
+ * Serialization of ROOT files for transport in the Alice HLT analysis
+ * chain.
+ *
+ * The file behaves like a normal ROOT file except that it is written to
+ * a memory buffer instead of disk.
+ */
+class AliHLTMemoryFile : public TFile, public AliHLTLogging {
+ public:
+  /** standard constructor */
+  AliHLTMemoryFile();
+
+  /** constructor */
+  AliHLTMemoryFile(void* pBuffer, int iSize);
+
+  /** standard destructor */
+  virtual ~AliHLTMemoryFile();
+
+  /**
+   * Write a header at the beginning of the file.
+   * The header is not part of the ROOT file. It should be written before any
+   * other object in order to avoid data to be moved.
+   * @param pHeader     buffer to write
+   * @param iSize       size of the buffer
+   * @return neg. error code if failed
+   *         - -ENOSPC    buffer size too small
+   */
+  int WriteHeader(const char* pHeader, int size);
+
+  /**
+   * Write a header at the beginning of the file.
+   * The trailer is not part of the ROOT file. It can only be written if the
+   * file already has been closed.
+   * @param pTrailer    buffer to write
+   * @param iSize       size of the buffer
+   * @return neg. error code if failed
+   *         - -ENOSPC    buffer size too small
+   */
+  // not yet stable
+  //int WriteTrailer(const char* pTrailer, int size);
+
+  /**
+   * Close file and flush output.
+   * @param bFlush       write remaining data
+   * @return neg. error code if failed
+   *         - -ENOSPC    buffer size too small
+   */
+  int Close(int bFlush=1);
+
+  /**
+   * Check if file has been closed.
+   * @return 1 if closed
+   */
+  int IsClosed() {return fbClosed;}
+
+  /**
+   * Get the last error code.
+   * @return error code
+   */
+  int GetErrno() {return fErrno;}
+
+  /**
+   * Get header size.
+   */
+  int GetHeaderSize() {return fHeaderSize;}
+
+ protected:
+  // Interface to basic system I/O routines
+  Int_t    SysOpen(const char *pathname, Int_t flags, UInt_t mode);
+  Int_t    SysClose(Int_t fd);
+  Int_t    SysRead(Int_t fd, void *buf, Int_t len);
+  Int_t    SysWrite(Int_t fd, const void *buf, Int_t len);
+  Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence);
+  Int_t    SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime);
+  Int_t    SysSync(Int_t fd);
+
+ private:
+  /** not a valid copy constructor, defined according to effective C++ style */
+  AliHLTMemoryFile(const AliHLTMemoryFile&);
+  /** not a valid assignment op, but defined according to effective C++ style */
+  AliHLTMemoryFile& operator=(const AliHLTMemoryFile&);
+
+  /** target buffer */
+  char* fpBuffer;                                                 //! transient
+
+  /** size of buffer */
+  int fBufferSize;                                                // see above
+
+  /** position */
+  int fPosition;                                                  // see above
+
+  /** filled posrtion of the buffer */
+  int fSize;                                                      // see above
+
+  /** result of last operation */
+  int fErrno;                                                     // see above
+
+  /** file closed */
+  int fbClosed;                                                   // see above
+
+  /** size of header */
+  int fHeaderSize;                                                // see above
+
+  /** size of trailer */
+  int fTrailerSize;                                               // see above
+
+  ClassDef(AliHLTMemoryFile, 1)
+};
+#endif // ALIHLTMEMORYFILE_H
index 613dfe5..27ea342 100644 (file)
@@ -29,6 +29,8 @@
 ClassImp(AliHLTModuleAgent)
 
 AliHLTModuleAgent::AliHLTModuleAgent()
+  :
+  fpNext(NULL)
 {
   // see header file for class documentation
   // or
@@ -41,7 +43,8 @@ AliHLTModuleAgent::AliHLTModuleAgent()
 AliHLTModuleAgent::AliHLTModuleAgent(const AliHLTModuleAgent&)
   :
   TObject(),
-  AliHLTLogging()
+  AliHLTLogging(),
+  fpNext(NULL)
 {
   // see header file for function documentation
 }
index fabc439..74bebf7 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTMODULEAGENT_H
 #define ALIHLTMODULEAGENT_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTModuleAgent.h
index 9050858..2375746 100644 (file)
@@ -3,8 +3,9 @@
 
 #ifndef ALIHLTOFFLINEDATASINK_H
 #define ALIHLTOFFLINEDATASINK_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx sink for full Copyright notice                               */
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTOfflineDataSink.h
     @author Matthias Richter
index 3e390ac..24dd5f6 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTOFFLINEDATASOURCE_H
 #define ALIHLTOFFLINEDATASOURCE_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTOfflineDataSource.h
index da07963..6f7632b 100644 (file)
@@ -32,7 +32,8 @@ AliHLTOfflineInterface::AliHLTOfflineInterface()
   :
   fpRunLoader(NULL),
   fpRawReader(NULL),
-  fpESD(NULL)
+  fpESD(NULL),
+  fpNext(NULL)
 {
   // see header file for class documentation
   // or
@@ -51,7 +52,8 @@ AliHLTOfflineInterface::AliHLTOfflineInterface(AliRunLoader* pRunLoader, AliRawR
   :
   fpRunLoader(pRunLoader),
   fpRawReader(pRawReader),
-  fpESD(NULL)
+  fpESD(NULL),
+  fpNext(NULL)
 {
 }
 
@@ -60,7 +62,8 @@ AliHLTOfflineInterface::AliHLTOfflineInterface(const AliHLTOfflineInterface&)
   TObject(),
   fpRunLoader(NULL),
   fpRawReader(NULL),
-  fpESD(NULL)
+  fpESD(NULL),
+  fpNext(NULL)
 {
   // see header file for class documentation
   //HLTFatal("copy constructor untested");
index 25c5aa1..a4fc280 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTOFFLINEINTERFACE_H
 #define ALIHLTOFFLINEINTERFACE_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTOfflineInterface.h
index b116baa..656f708 100644 (file)
@@ -2,7 +2,8 @@
 
 #ifndef ALIHLTFILEWRITER_H
 #define ALIHLTFILEWRITER_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTFileWriter.h
@@ -91,7 +92,7 @@ class AliHLTFileWriter : public AliHLTDataSink  {
   virtual int InitWriter();
 
   /**
-   * Init the writer.
+   * Close the writer.
    * The DoDeinit function is not available for child classes. CloseWriter is the
    * corresponding function for classes derived from AliHLTFileWriter.
    */
index b77a935..74dfbe2 100644 (file)
@@ -51,6 +51,25 @@ AliHLTLoaderPublisherComponent::AliHLTLoaderPublisherComponent()
   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
 }
 
+AliHLTLoaderPublisherComponent::AliHLTLoaderPublisherComponent(const AliHLTLoaderPublisherComponent&)
+  :
+  fMaxSize(0),
+  fLoaderType(),
+  fTreeType("digits"),
+  fVerbose(kFALSE),
+  fDataType(kAliHLTAnyDataType),
+  fSpecification(0),
+  fpLoader(NULL)
+{
+  // see header file for class documentation
+}
+
+AliHLTLoaderPublisherComponent& AliHLTLoaderPublisherComponent::operator=(const AliHLTLoaderPublisherComponent&)
+{
+  // see header file for class documentation
+  return *this;
+}
+
 AliHLTLoaderPublisherComponent::~AliHLTLoaderPublisherComponent()
 {
   // see header file for class documentation
index 72b041e..5debfb7 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTLOADERPUBLISHERCOMPONENT_H
 #define ALIHLTLOADERPUBLISHERCOMPONENT_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTLoaderPublisherComponent.h
@@ -103,6 +104,11 @@ class AliHLTLoaderPublisherComponent : public AliHLTOfflineDataSource {
               AliHLTComponentTriggerData& trigData);
 
  private:
+  /** not a valid copy constructor, defined according to effective C++ style */
+  AliHLTLoaderPublisherComponent(const AliHLTLoaderPublisherComponent&);
+  /** not a valid assignment op, but defined according to effective C++ style */
+  AliHLTLoaderPublisherComponent& operator=(const AliHLTLoaderPublisherComponent&);
+
   /**
    * Get tree of type specified in fTreeType from loader.
    */
index 66b2d5e..b6b5bad 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTROOTFILEPUBLISHERCOMPONENT_H
 #define ALIHLTROOTFILEPUBLISHERCOMPONENT_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTRootFilePublisherComponent.h
 
 /**
  * @class AliHLTRootFilePublisherComponent
- * An HLT data source component which publishes data from one or a sequence
- * of files.<br>
+ * \Note: This component is not what it pretends to be. So far it was just
+ * used for debugging purpose. If you need a component like this make a
+ * feature request at                                                  <br>
+ * https://savannah.cern.ch/projects/alicehlt/
+ * and assign it to richterm.                                          <br>
+ * Any contributions are of course welcome.
  *
  * Component ID: \b RootFilePublisherComponent <br>
  * Library: \b libHLTBase (in order to use the component from the external
diff --git a/HLT/BASE/util/AliHLTRootFileStreamerComponent.cxx b/HLT/BASE/util/AliHLTRootFileStreamerComponent.cxx
new file mode 100644 (file)
index 0000000..de39881
--- /dev/null
@@ -0,0 +1,156 @@
+// @(#) $Id$
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** @file   AliHLTRootFileStreamerComponent.cxx
+    @author Matthias Richter
+    @date   
+    @brief  Save objects in a ROOT memory file
+
+                                                                          */
+
+#include "AliHLTRootFileStreamerComponent.h"
+#include "TString.h"
+
+/** the global object for component registration */
+AliHLTRootFileStreamerComponent gAliHLTRootFileStreamerComponent;
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTRootFileStreamerComponent)
+
+AliHLTRootFileStreamerComponent::AliHLTRootFileStreamerComponent()
+  :
+  AliHLTProcessor(),
+  fDataType(kAliHLTVoidDataType),
+  fSpecification(~(AliHLTUInt32_t)0)
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+}
+
+AliHLTRootFileStreamerComponent::AliHLTRootFileStreamerComponent(const AliHLTRootFileStreamerComponent&)
+  :
+  AliHLTProcessor(),
+  fDataType(kAliHLTVoidDataType),
+  fSpecification(~(AliHLTUInt32_t)0)
+{
+  // see header file for class documentation
+}
+
+AliHLTRootFileStreamerComponent& AliHLTRootFileStreamerComponent::operator=(const AliHLTRootFileStreamerComponent&)
+{
+  // see header file for class documentation
+  return *this;
+}
+
+AliHLTRootFileStreamerComponent::~AliHLTRootFileStreamerComponent()
+{
+  // see header file for class documentation
+}
+
+void AliHLTRootFileStreamerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
+{
+  // see header file for class documentation
+  list.clear();
+  list.push_back(kAliHLTAnyDataType);
+}
+
+AliHLTComponentDataType AliHLTRootFileStreamerComponent::GetOutputDataType()
+{
+  // see header file for class documentation
+  return fDataType;
+}
+
+void AliHLTRootFileStreamerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
+{
+  // see header file for class documentation
+  constBase=500;
+  inputMultiplier=5.0;
+}
+
+int AliHLTRootFileStreamerComponent::DoInit( int argc, const char** argv )
+{
+  // see header file for class documentation
+
+  int iResult=0;
+  TString argument="";
+  int bMissingParam=0;
+  for (int i=0; i<argc && iResult>=0; i++) {
+    argument=argv[i];
+    if (argument.IsNull()) continue;
+
+    // -datatype
+    if (argument.CompareTo("-datatype")==0) {
+      if ((bMissingParam=(++i>=argc))) break;
+      memcpy(&fDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
+      if ((bMissingParam=(++i>=argc))) break;
+      memcpy(&fDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
+
+      // -dataspec
+    } else if (argument.CompareTo("-dataspec")==0) {
+      if ((bMissingParam=(++i>=argc))) break;
+      TString parameter(argv[i]);
+      parameter.Remove(TString::kLeading, ' '); // remove all blanks
+      if (parameter.IsDigit()) {
+       fSpecification=(AliHLTUInt32_t)parameter.Atoi();
+      } else if (parameter.BeginsWith("0x") &&
+                parameter.Replace(0,2,"",0).IsHex()) {
+       sscanf(parameter.Data(),"%x", &fSpecification);
+      } else {
+       HLTError("wrong parameter for argument %s, number expected", argument.Data());
+       iResult=-EINVAL;
+      }
+    } else {
+      HLTError("unknown argument %s", argument.Data());
+      break;
+    }
+  }
+  if (bMissingParam) {
+    HLTError("missing parameter for argument %s", argument.Data());
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTRootFileStreamerComponent::DoEvent( const AliHLTComponentEventData& evtData,
+                                           AliHLTComponentTriggerData& /*trigData*/ )
+{
+  // see header file for class documentation
+  int iResult=0;
+  AliHLTMemoryFile* pFile=CreateMemoryFile(fDataType,fSpecification);
+  if (pFile) {
+    const TObject* pObj=GetFirstInputObject(kAliHLTAnyDataType);
+    int count=0;
+    while (pObj && iResult>=0) {
+      iResult=Write(pFile, pObj);
+      if (iResult) {
+       count++;
+       HLTDebug("wrote object of class %s, data type %s", pObj->ClassName(), (DataType2Text(GetDataType(pObj)).c_str())); 
+      }
+      pObj=GetNextInputObject();
+    }
+    HLTInfo("wrote %d object(s) from %d input blocks to file", count, GetNumberOfInputBlocks());
+    iResult=CloseMemoryFile(pFile);
+  } else {
+    iResult=-ENOMEM;
+  }
+  return iResult;
+}
diff --git a/HLT/BASE/util/AliHLTRootFileStreamerComponent.h b/HLT/BASE/util/AliHLTRootFileStreamerComponent.h
new file mode 100644 (file)
index 0000000..0671fb4
--- /dev/null
@@ -0,0 +1,112 @@
+// -*- Mode: C++ -*-
+// @(#) $Id$
+
+#ifndef ALIHLTROOTFILESTREAMERCOMPONENT_H
+#define ALIHLTROOTFILESTREAMERCOMPONENT_H
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/** @file   AliHLTRootFileStreamerComponent.h
+    @author Matthias Richter
+    @date   
+    @brief  Save objects in a ROOT memory file
+
+                                                                          */
+#include "AliHLTProcessor.h"
+
+/**
+ * @class AliHLTRootFileStreamerComponent
+ * The RootFileStreamer provides a stand alone component to write incoming
+ * TObject like structures into a ROOT memory file. The memory file is
+ * published via the output stream.
+ *
+ * Component ID: \b ROOTFileStreamer <br>
+ * Library: \b libAliHLTUtil.
+ *
+ * Mandatory arguments: <br>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formating -->
+ *
+ * Optional arguments:<br>
+ * \li -datatype     <i> datatype   dataorigin </i> <br>
+ *      data type ID and origin, e.g. <tt>-datatype CLUSTERS TPC </tt>
+ * \li -dataspec     <i> specification </i> <br>
+ *      data specification treated as decimal number or hex number if
+ *      prepended by '0x'
+ *
+ * @ingroup alihlt_component
+ */
+class AliHLTRootFileStreamerComponent : public AliHLTProcessor
+{
+ public:
+  /** standard constructor */
+  AliHLTRootFileStreamerComponent();
+  /** destructor */
+  virtual ~AliHLTRootFileStreamerComponent();
+
+  /**
+   * The id of the component.
+   * @return component id (string)
+   */
+  const char* GetComponentID() {return "ROOTFileStreamer";};
+
+  /**
+   * Spawn function.
+   * @return new class instance
+   */
+  AliHLTComponent* Spawn() {return new AliHLTRootFileStreamerComponent;}
+
+  /**
+   * Get the input data types of the component.
+   * The function is pure virtual and must be implemented by the child class.
+   * @return list of data types in the vector reference
+   */
+  void GetInputDataTypes( vector<AliHLTComponentDataType>& );
+
+  /**
+   * Get the output data type of the component.
+   * The function is pure virtual and must be implemented by the child class.
+   * @return output data type
+   */
+  AliHLTComponentDataType GetOutputDataType();
+
+  /**
+   * Get a ratio by how much the data volume is shrinked or enhanced.
+   * The function is pure virtual and must be implemented by the child class.
+   * @param constBase        <i>return</i>: additive part, independent of the
+   *                                   input data volume  
+   * @param inputMultiplier  <i>return</i>: multiplication ratio
+   * @return values in the reference variables
+   */
+  void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
+
+ protected:
+  /**
+   * Internal initialization.
+   * @see @ref AliHLTComponent::DoInit for description and parameters
+   */
+  virtual int DoInit( int argc, const char** argv );
+
+  /**
+   * The high-level data processing method.
+   * All incoming objects are saved into a ROOT file in memory.
+   * @param evtData       event data structure
+   * @param trigData     trigger data structure
+   * @return neg. error code if failed
+   */
+  int DoEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
+
+ private:
+  /** not a valid copy constructor, defined according to effective C++ style */
+  AliHLTRootFileStreamerComponent(const AliHLTRootFileStreamerComponent&);
+  /** not a valid assignment op, but defined according to effective C++ style */
+  AliHLTRootFileStreamerComponent& operator=(const AliHLTRootFileStreamerComponent&);
+
+  /** data type */
+  AliHLTComponentDataType fDataType;                               // see above
+  /** data specification */
+  AliHLTUInt32_t          fSpecification;                          // see above
+
+  ClassDef(AliHLTRootFileStreamerComponent, 0)
+};
+#endif
index a285167..6a4ffc1 100644 (file)
@@ -71,6 +71,16 @@ AliHLTRootFileWriterComponent::~AliHLTRootFileWriterComponent()
   // see header file for class documentation
 }
 
+int AliHLTRootFileWriterComponent::CloseWriter()
+{
+  // see header file for class documentation
+  if (fCurrentFile!=NULL) {
+    HLTDebug("close root file");
+    TFile* pFile=fCurrentFile; fCurrentFile=NULL;
+    pFile->Close(); delete pFile;
+  }
+}
+
 int AliHLTRootFileWriterComponent::DumpEvent( const AliHLTComponentEventData& evtData,
                                            const AliHLTComponentBlockData* blocks, 
                                            AliHLTComponentTriggerData& trigData )
@@ -91,7 +101,7 @@ int AliHLTRootFileWriterComponent::DumpEvent( const AliHLTComponentEventData& ev
     }
     pObj=GetNextInputObject();
   }
-  HLTDebug("wrote %d of %d object(s) to file", count, GetNumberOfInputBlocks());
+  HLTDebug("wrote %d object(s) from %d input blocks to file", count, GetNumberOfInputBlocks());
   return iResult;
 }
 
index e02ea19..8c0fad3 100644 (file)
@@ -3,7 +3,8 @@
 
 #ifndef ALIHLTROOTFILEWRITERCOMPONENT_H
 #define ALIHLTROOTFILEWRITERCOMPONENT_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
 /** @file   AliHLTRootFileWriterComponent.h
@@ -49,6 +50,12 @@ class AliHLTRootFileWriterComponent : public AliHLTFileWriter
   virtual AliHLTComponent* Spawn() {return new AliHLTRootFileWriterComponent;}
 
  protected:
+  /**
+   * Close the writer.
+   * Cleanup and others.
+   */
+  int CloseWriter();
+
   /**
    * Data processing method for the component.
    * The function can be overloaded by specific ROOT file writer
index 77a5612..f39d458 100644 (file)
@@ -1,3 +1,11 @@
+2007-07-17 HLT base
+       - extended high-level component interface in order to allow header
+         buffer before TObjects
+       - ROOT memory file added
+       - ROOT file streamer added
+       - workaround for ROOT garbage collection causing crashes when
+         cleaning up input objects
+       
 2007-05-09 version HLT-v0-6 tagged
        Highlights
        BASE libHLTbase version 3.1.0
index 116adc0..d5adb13 100644 (file)
@@ -7,6 +7,7 @@ MODULE_SRCS=    AliHLTFilePublisher.cxx \
                AliHLTFileWriter.cxx \
                AliHLTRootFilePublisherComponent.cxx \
                AliHLTRootFileWriterComponent.cxx \
+               AliHLTRootFileStreamerComponent.cxx \
                AliHLTLoaderPublisherComponent.cxx \
                AliHLTDynamicAliLog.cxx \
                AliHLTAgentUtil.cxx
@@ -15,6 +16,7 @@ CLASS_HDRS:=          AliHLTFilePublisher.h \
                AliHLTFileWriter.h \
                AliHLTRootFilePublisherComponent.h \
                AliHLTRootFileWriterComponent.h \
+               AliHLTRootFileStreamerComponent.h \
                AliHLTLoaderPublisherComponent.h \
                AliHLTAgentUtil.h
 
index 55b146c..274c1b1 100644 (file)
@@ -18,6 +18,7 @@ MODULE_SRCS=  AliHLTComponent.cxx \
                AliHLTOfflineDataSource.cxx \
                AliHLTOfflineDataSink.cxx \
                AliHLTModuleAgent.cxx \
+               AliHLTMemoryFile.cxx \
                AliHLTMessage.cxx
 
 CLASS_HDRS:=   AliHLTComponent.h \
@@ -36,6 +37,7 @@ CLASS_HDRS:=          AliHLTComponent.h \
                AliHLTOfflineDataSource.h \
                AliHLTOfflineDataSink.h \
                AliHLTModuleAgent.h \
+               AliHLTMemoryFile.h \
                AliHLTMessage.h
 
 MODULE_HDRS:=  $(CLASS_HDRS) \