- break up of argument string into argument list: making static method of AliHLTConfi...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 13 Jan 2009 09:11:46 +0000 (09:11 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 13 Jan 2009 09:11:46 +0000 (09:11 +0000)
- make selection functionality and parsing of arguments from AliHLTBlockFilteirComponent commonly available: AliHLTBlockDataCollection
- AliHLTFileWriter: adding support for data block selection and postpone burst write

15 files changed:
HLT/BASE/AliHLTBlockDataCollection.cxx [new file with mode: 0644]
HLT/BASE/AliHLTBlockDataCollection.h [new file with mode: 0644]
HLT/BASE/AliHLTConfiguration.cxx
HLT/BASE/AliHLTConfiguration.h
HLT/BASE/test/Makefile.am
HLT/BASE/test/testAliHLTBlockDataCollection.C [new file with mode: 0644]
HLT/BASE/util/AliHLTBlockFilterComponent.cxx
HLT/BASE/util/AliHLTBlockFilterComponent.h
HLT/BASE/util/AliHLTFileWriter.cxx
HLT/BASE/util/AliHLTFileWriter.h
HLT/BASE/util/Makefile.am
HLT/BASE/util/test/Makefile.am [new file with mode: 0644]
HLT/BASE/util/test/testAliHLTFileWriter.C [new file with mode: 0644]
HLT/configure.ac
HLT/libHLTbase.pkg

diff --git a/HLT/BASE/AliHLTBlockDataCollection.cxx b/HLT/BASE/AliHLTBlockDataCollection.cxx
new file mode 100644 (file)
index 0000000..cf9df00
--- /dev/null
@@ -0,0 +1,181 @@
+// $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   AliHLTBlockDataCollection.cxx
+    @author Matthias Richter
+    @date   
+    @brief  A collection of AliHLTComponentBlockData descriptors providing
+            argument parsing and basic selection.
+*/
+
+#include <cstdlib>
+#include "AliHLTBlockDataCollection.h"
+#include "AliHLTComponent.h"
+#include "TString.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTBlockDataCollection)
+
+AliHLTBlockDataCollection::AliHLTBlockDataCollection()
+  : TObject()
+  , AliHLTLogging()
+  , fFilterRules()
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+}
+
+AliHLTBlockDataCollection::~AliHLTBlockDataCollection()
+{
+  // see header file for class documentation
+}
+
+int AliHLTBlockDataCollection::Add(const AliHLTComponentBlockData& block)
+{
+  // see header file for class documentation
+  fFilterRules.push_back(block);
+  return fFilterRules.size();
+}
+
+int AliHLTBlockDataCollection::ScanArgument( int argc, const char** argv )
+{
+  // see header file for class documentation
+  int iResult=0;
+  TString argument="";
+  int bMissingParam=0;
+  AliHLTComponentBlockData rule;
+  AliHLTComponent::FillBlockData(rule);
+  int i=0;
+  for (; i<argc && iResult>=0; i++) {
+    argument=argv[i];
+    if (argument.IsNull()) continue;
+
+    // -datatype
+    if (argument.CompareTo("-datatype")==0) {
+      if ((bMissingParam=(i+2>=argc))) break;
+
+      if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
+       // the data type has already been set, add to list
+       // and reset
+       fFilterRules.push_back(rule);
+       AliHLTComponent::FillBlockData(rule);
+      }
+
+      AliHLTComponent::SetDataType(rule.fDataType, argv[i+1], argv[i+2]);
+      i+=2;
+
+      // -origin
+    } else if (argument.CompareTo("-origin")==0) {
+      if ((bMissingParam=(i+1>=argc))) break;
+
+      if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
+       // the data type has already been set, add to list
+       // and reset
+       fFilterRules.push_back(rule);
+       AliHLTComponent::FillBlockData(rule);
+      }
+
+      AliHLTComponent::SetDataType(rule.fDataType, NULL, argv[i+1]);
+      i+=1;
+
+      // -typeid
+    } else if (argument.CompareTo("-typeid")==0) {
+      if ((bMissingParam=(i+1>=argc))) break;
+
+      if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
+       // the data type has already been set, add to list
+       // and reset
+       fFilterRules.push_back(rule);
+       AliHLTComponent::FillBlockData(rule);
+      }
+
+      AliHLTComponent::SetDataType(rule.fDataType, argv[i+1], NULL);
+      i+=1;
+
+      // -dataspec
+    } else if (argument.CompareTo("-dataspec")==0) {
+      if ((bMissingParam=(++i>=argc))) break;
+
+      if (rule.fSpecification!=kAliHLTVoidDataSpec) {
+       // the specification has already been set, add to list
+       // and reset
+       fFilterRules.push_back(rule);
+       AliHLTComponent::FillBlockData(rule);
+      }
+
+      TString parameter(argv[i]);
+      parameter.Remove(TString::kLeading, ' '); // remove all blanks
+      char* pRemnant=NULL;
+      rule.fSpecification=strtoul(parameter.Data(), &pRemnant, 0);
+      if (pRemnant!=NULL && pRemnant[0]!=0) {
+       HLTError("invalid parameter/remnant (%s) for argument %s, number expected", pRemnant, argument.Data());
+       iResult=-EINVAL;
+      }
+    } else {
+      // terminate at the first unknown argument
+      break;
+    }
+  }
+
+  if (bMissingParam) {
+    HLTError("missing parameter for argument %s", argument.Data());
+    iResult=-EPROTO;
+  }
+  if (iResult>=0) {
+    if (rule.fSpecification!=kAliHLTVoidDataSpec || !MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
+      // add the pending rule
+      fFilterRules.push_back(rule);
+      AliHLTComponent::FillBlockData(rule);
+    }
+    iResult=i;
+  }
+
+  return iResult;
+}
+
+int AliHLTBlockDataCollection::IsSelected(const AliHLTComponentBlockData& block)
+{
+  // see header file for class documentation
+  AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
+  //HLTDebug("check block: %s spec %#x", DataType2Text(block.fDataType, 1).c_str(), block.fSpecification);
+  if (desc==fFilterRules.end()) return 1; // no filter rules
+  do {
+    // match if
+    // 1. data types match or filter data type not set
+    // 2. data spec match or filter data wpec not set
+    // 3. either filter data type or spec is set
+    //HLTDebug("check rule : %s spec %#x", DataType2Text((*desc).fDataType, 2).c_str(), block.fSpecification);
+    if (((*desc).fDataType==block.fDataType) &&
+       ((*desc).fSpecification==block.fSpecification || (*desc).fSpecification==kAliHLTVoidDataSpec) &&
+       (!MatchExactly((*desc).fDataType,kAliHLTAnyDataType) || (*desc).fSpecification!=kAliHLTVoidDataSpec)) {
+      return 1;
+    }
+  } while (++desc!=fFilterRules.end());
+  
+  return 0;
+}
+
+int AliHLTBlockDataCollection::IsEmpty()
+{
+  // see header file for class documentation
+  if (fFilterRules.size()==0) return 1;
+  return 0;
+}
diff --git a/HLT/BASE/AliHLTBlockDataCollection.h b/HLT/BASE/AliHLTBlockDataCollection.h
new file mode 100644 (file)
index 0000000..d0d0b7b
--- /dev/null
@@ -0,0 +1,100 @@
+// -*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTBLOCKDATACOLLECTION_H
+#define ALIHLTBLOCKDATACOLLECTION_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   AliHLTBlockDataCollection.h
+    @author Matthias Richter
+    @date   
+    @brief  A collection of AliHLTComponentBlockData descriptors providing
+            argument parsing and basic selection.
+*/
+
+#include "AliHLTLogging.h"
+#include "vector"
+#include "TObject.h"
+
+/**
+ * @class AliHLTBlockDataCollection
+ * Class handles a list of AliHLTComponentBlockData entries and parsing of
+ * argument list to fill it. Originally taken from AliHLTBlickFilterComponent,
+ * but decided to be commonly of benefit.
+ *
+ * See ScanArgument() function for description of available arguments
+ * <pre>
+ * -datatype ID ORIGIN
+ * -typeid ID
+ * -origin ORIGIN
+ * -dataspec SPEC
+ * </pre>
+ *
+ * @ingroup alihlt_base
+ */
+class AliHLTBlockDataCollection : public TObject, public AliHLTLogging
+{
+ public:
+  /** standard constructor */
+  AliHLTBlockDataCollection();
+  /** destructor */
+  virtual ~AliHLTBlockDataCollection();
+
+  /**
+   * Add data block descriptor.
+   */
+  int Add(const AliHLTComponentBlockData& block);
+
+  /**
+   * Check if the data block is selected by the filter rules.
+   * @return 1 if selected
+   */
+  int IsSelected(const AliHLTComponentBlockData& block);
+
+  /**
+   * Scan argument and read block descriptor data.
+   * The function is invoked by components in the course of argument
+   * scan.
+   *
+   * Scan the list for known arguments, terminates at the first unknown argument.
+   * Recognized arguments:
+   * \li -datatype     <i> id origin      </i>                            <br>
+   *      e.g. <tt> -datatype 'ESD_TREE' 'TPC ' </tt>                     <br>
+   *      \b Note: due to the 4-character data origin it might be necessary to
+   *      append a blank to the detectorname, e.g. <tt>TPC -> 'TPC '</tt>
+   *
+   * \li -origin  <i> origin  </i>                                        <br>
+   *      e.g. -origin 'TPC ', \b Note:  the filter rule has type id 'ANY'
+   *
+   * \li -typeid  <i> id      </i>                                        <br>
+   *      e.g. -typeid ESD_TREE, \b Note: the filter rule has origin 'ANY'
+   *
+   * \li -dataspec     <i> specification </i>                             <br>
+   *      data specification treated as decimal number or hex number if
+   *      prepended by '0x'
+   * 
+   * @return number of arguments which have been treated.
+   */
+  int ScanArgument(int argc, const char** argv );
+
+  /**
+   * Check collection for content.
+   * @return 1 if empty, 0 if content available
+   */
+  int IsEmpty();
+ protected:
+
+ private:
+  /** copy constructor prohibited */
+  AliHLTBlockDataCollection(const AliHLTBlockDataCollection&);
+  /** assignment operator prohibited */
+  AliHLTBlockDataCollection& operator=(const AliHLTBlockDataCollection&);
+
+  /** filtering rules, only the data type and specification members are use */
+  vector<AliHLTComponentBlockData> fFilterRules;                       //! transient
+
+  ClassDef(AliHLTBlockDataCollection, 0)
+};
+#endif
index 60670d50166ada3ce4f4c5a1c61a2653b7c96090..438020efb80dbc81cd30b75864caf0e6cc3771c1 100644 (file)
@@ -372,7 +372,7 @@ int AliHLTConfiguration::ExtractArguments()
   return iResult;
 }
 
-int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList) const
+int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
 {
   // see header file for function documentation
   int iResult=0;
index d7922e0681785359b761f3c3ff31cc68742e5b77..88ed254a3b0ff548b944a6bb2d1b3235bd37d961 100644 (file)
@@ -206,6 +206,15 @@ class AliHLTConfiguration : public TObject, public AliHLTLogging {
     return !(*this==c);
   }
 
+  /**
+   * Helper function to build a vector from an argument string.
+   * The function allocates memory for each token. The caller is responsible
+   * for cleaning the strings recursively.
+   * @param arg       pointer to argument string
+   * @param argList   target to receive the argument list
+   */
+  static int InterpreteString(const char* arg, vector<char*>& argList);
+
  protected:
   
 
@@ -218,13 +227,6 @@ class AliHLTConfiguration : public TObject, public AliHLTLogging {
    */
   int ExtractArguments();
 
-  /**
-   * Helper function to build a vector from an argument string
-   * @param arg       pointer to argument string
-   * @param argList   target to receive the argument list
-   */
-  int InterpreteString(const char* arg, vector<char*>& argList) const;
-
   /**
    * Convert buffer size string to number
    */
index 6db56c998131e5f9137992cd26759333a3aeea3f..8a51fe0ea4a353a8af4e901f9dd97511fc7d2da4 100644 (file)
@@ -5,11 +5,15 @@ AM_CPPFLAGS                   = -I$(top_srcdir)/BASE
 
 EXTRA_DIST     = 
 
-check_PROGRAMS = dtOperators \
+check_PROGRAMS = testAliHLTBlockDataCollection \
+                 dtOperators \
                  testDefaultDataTypes
 
 #                testAliHLT_C_Component_WrapperInterface
 
+testAliHLTBlockDataCollection_SOURCES = testAliHLTBlockDataCollection.cxx
+testAliHLTBlockDataCollection_LDADD = $(top_builddir)/BASE/libHLTbase.la
+
 dtOperators_SOURCES = dtOperators.cxx
 dtOperators_LDADD = $(top_builddir)/BASE/libHLTbase.la
 
@@ -19,4 +23,4 @@ dtOperators_LDADD = $(top_builddir)/BASE/libHLTbase.la
 testDefaultDataTypes_SOURCES = testDefaultDataTypes.C
 testDefaultDataTypes_LDADD = $(top_builddir)/BASE/libHLTbase.la
 
-TESTS          = $(check_PROGRAMS)
\ No newline at end of file
+TESTS          = $(check_PROGRAMS)
diff --git a/HLT/BASE/test/testAliHLTBlockDataCollection.C b/HLT/BASE/test/testAliHLTBlockDataCollection.C
new file mode 100644 (file)
index 0000000..896525a
--- /dev/null
@@ -0,0 +1,164 @@
+// $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   testAliHLTBlockDataCollection.C
+    @author Matthias Richter
+    @date   
+    @brief  Test macro/program for the AliHLTBlockDataCollection
+ */
+
+#ifndef __CINT__
+#include <ostream>
+#include <vector>
+#include "AliHLTBlockDataCollection.h"
+#include "AliHLTComponent.h"
+#else
+#define EINVAL 22
+#define EPROTO 71
+#endif //__CINT__
+
+typedef struct init_t {
+  const char* arguments;
+  int result;
+} init_t;
+
+typedef struct select_t {
+  const char* id;
+  const char* origin;
+  UInt_t specification;
+  int result;
+} select_t;
+
+init_t gInits[]={
+  {"-datatype 'ESD_TREE' 'TPC ' ", 3},
+  {"-datatype 'ESD_TREE' 'TPC ' "
+   "-origin PHOS "
+   "-verbosity "
+   "-origin 'TRD ' "
+   "-dataspec 0xdeadbeef ", 9},
+  {"-datatype 'ESD_TREE'", -EPROTO},
+  {NULL, 0}
+};
+
+select_t gSelections[]={
+  {"ESD_TREE", "TPC ", 0, 1},
+  {"DDL_RAW ", "TPC ", 0xaffe, 0},
+  {"ESD_TREE", "TRD ", 0xaffe, 0},
+  {"ESD_TREE", "TRD ", 0xdeadbeef, 1},
+  {NULL, NULL, 0, 0}
+};
+
+int gVerbosity=0;
+
+int InitCollection(AliHLTBlockDataCollection& collection, const char* init)
+{
+  // build argument vector
+  int iResult=0;
+  char* arguments=new char[strlen(init)+1];
+  strcpy(arguments, init);
+  vector<int> positions;
+  bool bQuote=false;
+  int i=0;
+  int iStart=0;
+  for (;arguments[i]!=0; i++) {
+    if (arguments[i]=='\'') {
+      if (bQuote=!bQuote) {
+       // opening quote, set start
+      } else {
+       // closing quote, add argument
+       arguments[i]=0;
+       if (i-iStart>0) positions.push_back(iStart);
+      }
+      iStart=i+1;
+    } else if ((arguments[i]==' ' && !bQuote) ||
+              arguments[i]==0) {
+      arguments[i]=0;
+      if (i-iStart>0) positions.push_back(iStart);
+      iStart=i+1;
+    }
+  }
+  if (i-iStart>0) positions.push_back(iStart);
+
+  int argc=positions.size();
+  const char** argv=new const char*[argc];
+  for (int j=0; j<argc ; j++) {
+    argv[j]=&arguments[positions[j]];
+  }
+
+  // test argument scan
+  for (i=0; i<argc; i++) {
+    if (gVerbosity>1) cout << "scanning " << argc-i << " arguments: " << argv[i] << endl;
+    int result=collection.ScanArgument(argc-i, &argv[i]);
+    if (result>0) {
+      iResult+=result;
+      i+=result-1;
+    } else if (result<0) {
+      iResult=result;
+      break;
+    }
+  }
+
+  // cleanup
+  delete [] argv;
+  delete [] arguments;
+
+  return iResult;
+}
+
+int testAliHLTBlockDataCollection(int verbosity=0)
+{
+  gVerbosity=verbosity;
+  AliHLTBlockDataCollection collection;
+  for (int initNo=0; gInits[initNo].arguments!=NULL; initNo++) {
+    if (gVerbosity>0) cout << "checking: " << gInits[initNo].arguments << endl;
+    int result=InitCollection(collection, gInits[initNo].arguments);
+    if (result!=gInits[initNo].result) {
+      cerr << "failed: " << initNo << " (" << gInits[initNo].arguments << ") " << ": result " << result << ", expected " << gInits[initNo].result << endl;
+      return -1;
+    } else {
+      if (gVerbosity>1) cout << "init " << initNo << " (" << gInits[initNo].arguments << ") " << "succeeded: result " << result << endl;
+    }
+  }
+
+  AliHLTComponentBlockData bd;
+  AliHLTComponent::FillBlockData(bd);
+
+  for (int selectNo=0; gSelections[selectNo].id!=NULL; selectNo++) {
+    AliHLTComponent::SetDataType(bd.fDataType, gSelections[selectNo].id, gSelections[selectNo].origin );
+    bd.fSpecification=gSelections[selectNo].specification;
+    int result=collection.IsSelected(bd);
+    if (result!=gSelections[selectNo].result) {
+      cerr << "failed: block " << gSelections[selectNo].id << ":" << gSelections[selectNo].origin << " 0x" << hex << gSelections[selectNo].specification << ": result " << result << ", expected " << gSelections[selectNo].result << endl;
+      return -1;
+    } else {
+      if (gVerbosity>0) cout << "checking: block " << gSelections[selectNo].id << ":" << gSelections[selectNo].origin << " 0x" << hex << gSelections[selectNo].specification << (result==1?" selected":" not selected") << " (correctly)" << endl;
+    }
+  }
+
+  return 0;
+}
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+  int iResult=0;
+  if ((iResult=testAliHLTBlockDataCollection(1))<0) {
+    cerr << "<<<<< re-run with higher verbosity >>>>>>>" << endl;
+    testAliHLTBlockDataCollection(2);
+  }
+  return iResult;
+}
index 2c7c1314d92066501c17d5d3d6a4df181fca7ea9..2a9ea708c7b404a6a1efa555c56aee5835f5889d 100644 (file)
@@ -1,4 +1,4 @@
-// @(#) $Id$
+// $Id$
 
 //**************************************************************************
 //* This file is property of and copyright by the ALICE HLT Project        * 
index e23c857eb4c23fe71122f103371cc523aa3ca8e4..b940fbc3c7e54c227dd7d09c20e94f60a740ff23 100644 (file)
@@ -1,5 +1,5 @@
 // -*- Mode: C++ -*-
-// @(#) $Id$
+// $Id$
 
 #ifndef ALIHLTBLOCKFILTERCOMPONENT_H
 #define ALIHLTBLOCKFILTERCOMPONENT_H
index b7424203044acd74316ca8eb20696b07af51bc63..73d3e38a086262cdc41aa75314727e2d6b2d563b 100644 (file)
@@ -26,11 +26,13 @@ using namespace std;
 #endif
 
 #include "AliHLTFileWriter.h"
+#include "AliHLTBlockDataCollection.h"
 #include <TObjArray.h>
 #include <TObjString.h>
 #include <TSystem.h>
 //#include <TMath.h>
 //#include <TFile.h>
+#include <cassert>
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTFileWriter)
@@ -38,6 +40,7 @@ ClassImp(AliHLTFileWriter)
 AliHLTFileWriter::AliHLTFileWriter()
   :
   AliHLTDataSink(),
+  fpBlockDataCollection(NULL),
   fBaseName(""),
   fExtension(""),
   fDirectory(""),
@@ -47,6 +50,10 @@ AliHLTFileWriter::AliHLTFileWriter()
   fBlcknoFormat("_0x%02x"),
   fCurrentFileName(""),
   fMode(0)
+  , fpBurstBuffer(NULL)
+  , fBurstBufferSize(0)
+  , fBurstBlocks()
+  , fBurstBlockEvents()
 {
   // see header file for class documentation
   // or
@@ -63,6 +70,25 @@ AliHLTFileWriter::~AliHLTFileWriter()
   // delete all the objects
 }
 
+int AliHLTFileWriter::SetDefaults()
+{
+  // see header file for class documentation
+  fBaseName="";
+  fExtension="";
+  fDirectory="";
+  fSubDirFormat="";
+  fIdFormat="_0x%08x";
+  fSpecFormat="";
+  fBlcknoFormat="_0x%02x";
+  fCurrentFileName="";
+  fMode=0;
+  fpBurstBuffer=NULL;
+  fBurstBufferSize=0;
+  fBurstBlocks.clear();
+  fBurstBlockEvents.clear();
+  return 0;
+}
+
 const char* AliHLTFileWriter::GetComponentID()
 {
   // see header file for class documentation
@@ -86,9 +112,13 @@ int AliHLTFileWriter::DoInit( int argc, const char** argv )
 {
   // see header file for class documentation
   int iResult=0;
+  fpBlockDataCollection=new AliHLTBlockDataCollection;
   TString argument="";
   int bMissingParam=0;
-  for (int i=0; i<argc && iResult>=0; i++) {
+  char* cpErr=NULL;
+  int i=0;
+  for (; i<argc && iResult>=0; i++) {
+    cpErr=NULL;
     argument=argv[i];
     if (argument.IsNull()) continue;
 
@@ -184,10 +214,21 @@ int AliHLTFileWriter::DoInit( int argc, const char** argv )
       SetMode(kWriteAllEvents);
       SetMode(kWriteAllBlocks);
 
+      // -burst-buffer
+    } else if (argument.CompareTo("-burst-buffer")==0) {
+      if ((bMissingParam=(++i>=argc))) break;
+      fBurstBufferSize = strtoul( argv[i], &cpErr ,0);
+      if ( *cpErr ) break;
+
       // -skip-datatype
     } else if(argument.CompareTo("-skip-datatype")==0){
       SetMode(kSkipDataType);
 
+      // check for selection arguments (AliHLTBlockDataCollection)
+    } else if (fpBlockDataCollection && 
+              (iResult=fpBlockDataCollection->ScanArgument(argc-i, &argv[i]))>0) {
+       i+=iResult-1;
+       iResult=0;
     } else {
       if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
        HLTError("unknown argument %s", argument.Data());
@@ -201,10 +242,32 @@ int AliHLTFileWriter::DoInit( int argc, const char** argv )
       }
     }
   }
-  if (bMissingParam) {
+
+  if (cpErr && *cpErr) {
+    HLTError("Cannot convert specifier '%s' for argument '%s'", argv[i], argument.Data());
+    iResult=-EINVAL;
+  } else if (bMissingParam) {
     HLTError("missing parameter for argument %s", argument.Data());
     iResult=-EINVAL;
   }
+  if (fpBlockDataCollection &&
+      (iResult<0 || fpBlockDataCollection->IsEmpty())) {
+    delete fpBlockDataCollection;
+    fpBlockDataCollection=NULL;
+  }
+  if (iResult>=0 && fBurstBufferSize>0) {
+    if (!CheckMode(kConcatenateBlocks) || !CheckMode(kConcatenateEvents)) {
+      HLTError("burst write currently only supported for mode kConcatenateBlocks AND kConcatenateEvents");
+      iResult=-EINVAL;
+    } else {
+    fpBurstBuffer=new AliHLTUInt8_t[fBurstBufferSize];
+    if (!fpBurstBuffer) {
+      iResult=-ENOMEM;
+      fBurstBufferSize=0;
+    }
+    }
+  }
+
   if (iResult>=0) {
     iResult=InitWriter();
     if (!fDirectory.IsNull()) {
@@ -243,8 +306,25 @@ int AliHLTFileWriter::ScanArgument(int /*argc*/, const char** /*argv*/)
 int AliHLTFileWriter::DoDeinit()
 {
   // see header file for class documentation
-  int iResult=CloseWriter();
+  int iResult=0;
+  if (fpBurstBuffer) {
+    if ((iResult=BurstWrite())<0) {
+      HLTError("failed BurstWrite");
+    }
+    delete [] fpBurstBuffer;
+    fpBurstBuffer=NULL;
+    fBurstBufferSize=0;
+    fBurstBlocks.clear();
+    fBurstBlockEvents.clear();
+  }
+
+  iResult=CloseWriter();
   ClearMode(kEnumerate);
+
+  if (fpBlockDataCollection) delete fpBlockDataCollection;
+  fpBlockDataCollection=NULL;
+
+  SetDefaults();
   return iResult;
 }
 
@@ -277,31 +357,12 @@ int AliHLTFileWriter::DumpEvent( const AliHLTComponentEventData& evtData,
 
   int blockno=0;
   for (pDesc=GetFirstInputBlock(); pDesc!=NULL; pDesc=GetNextInputBlock(), blockno++) {
-    if (pDesc->fDataType==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate) && !CheckMode(kWriteAllBlocks))
+    if (fpBlockDataCollection) {
+      if (!fpBlockDataCollection->IsSelected(*pDesc)) continue;
+    } else if (pDesc->fDataType==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate) && !CheckMode(kWriteAllBlocks))
       continue;
     HLTDebug("block %d out of %d", blockno, evtData.fBlockCnt);
-    TString filename;
-    HLTDebug("dataspec 0x%x", pDesc->fSpecification);
-    iResult=BuildFileName(evtData.fEventID, blockno, pDesc->fDataType, pDesc->fSpecification, filename);
-    ios::openmode filemode=(ios::openmode)0;
-    if (fCurrentFileName.CompareTo(filename)==0) {
-      // append to the file
-      filemode=ios::app;
-    } else {
-      // store the file for the next block
-      fCurrentFileName=filename;
-    }
-    if (iResult>=0) {
-      ofstream dump(filename.Data(), filemode);
-      if (dump.good()) {
-       dump.write((static_cast<const char*>(pDesc->fPtr)), pDesc->fSize);
-       HLTDebug("wrote %d byte(s) to file %s", pDesc->fSize, filename.Data());
-      } else {
-       HLTError("can not open file %s for writing", filename.Data());
-       iResult=-EBADF;
-      }
-      dump.close();
-    }
+    iResult=ScheduleBlock(blockno, evtData.fEventID, pDesc);
   }
   return iResult;
 }
@@ -389,3 +450,110 @@ int AliHLTFileWriter::CheckMode(Short_t mode) const
   //HLTDebug("check mode 0x%x for flag 0x%x: %d", fMode, mode, (fMode&mode)!=0);
   return (fMode&mode)!=0;
 }
+
+int AliHLTFileWriter::ScheduleBlock(int blockno, const AliHLTEventID_t& eventID,
+                                   const AliHLTComponentBlockData* pDesc)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (fpBurstBuffer==NULL ||
+      fBurstBlocks.size()==0 && pDesc->fSize>fBurstBufferSize) {
+    return WriteBlock(blockno, eventID, pDesc);
+  }
+  AliHLTComponentBlockData bd=*pDesc;
+  bd.fPtr=NULL;
+  if (fBurstBlocks.size()>0) {
+    bd.fOffset=fBurstBlocks.back().fOffset+fBurstBlocks.back().fSize;
+  } else {
+    bd.fOffset=0;
+  }
+  if (bd.fOffset+bd.fSize>fBurstBufferSize) {
+    if ((iResult=BurstWrite())>=0) {
+      iResult=WriteBlock(blockno, eventID, pDesc);
+    }
+  } else {
+    memcpy(fpBurstBuffer+bd.fOffset, pDesc->fPtr, bd.fSize);
+    fBurstBlocks.push_back(bd);
+    fBurstBlockEvents.push_back(eventID);
+  }
+
+  return iResult;
+}
+
+int AliHLTFileWriter::BurstWrite()
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (fBurstBlocks.size()==0) return 0;
+  assert(fBurstBlocks.size()==fBurstBlockEvents.size());
+  HLTDebug("writing %d postponed blocks", fBurstBlocks.size());
+  int blockno=0;
+  AliHLTComponentBlockDataList::iterator block=fBurstBlocks.begin();
+  AliHLTComponentBlockDataList::iterator firstBlock=block;
+  vector<AliHLTEventID_t>::iterator event=fBurstBlockEvents.begin();
+  if (CheckMode(kConcatenateEvents)) {
+    block=fBurstBlocks.end()-1;
+    event=fBurstBlockEvents.end()-1;
+  }
+  for (; block!=fBurstBlocks.end() && iResult>=0; block++, event++, blockno++) {
+    if (event!=fBurstBlockEvents.begin() && *event!=*(event-1)) {
+      blockno=0;
+    }
+    if (CheckMode(kConcatenateEvents)) {
+      // all blocks in the burst buffer are written in one go
+      // just the block descriptor is updated appropriately
+      (*block).fSize+=(*block).fOffset;
+      (*block).fPtr=fpBurstBuffer;
+    } else if (CheckMode(kConcatenateBlocks)) {
+      // all blocks of the same event are written in one go
+      // just the block descriptor is updated appropriately
+      if (event+1==fBurstBlockEvents.end() ||
+         *event!=*(event+1)) {
+       (*block).fSize+=(*block).fOffset-(*firstBlock).fOffset;
+       (*block).fPtr=fpBurstBuffer+(*firstBlock).fOffset;
+       firstBlock=block+1;
+      } else {
+       // coninue if it wasn't the last block of this event
+       continue;
+      }
+    } else {
+      (*block).fPtr=fpBurstBuffer+(*block).fOffset;
+    }
+    (*block).fOffset=0;
+    iResult=WriteBlock(blockno, *event, &(*block));
+  }
+  fBurstBlocks.clear();
+  fBurstBlockEvents.clear();
+
+  return iResult;
+}
+
+int AliHLTFileWriter::WriteBlock(int blockno, const AliHLTEventID_t& eventID,
+                                const AliHLTComponentBlockData* pDesc)
+{
+  // see header file for class documentation
+  int iResult=0;
+  TString filename;
+  HLTDebug("dataspec 0x%x", pDesc->fSpecification);
+  iResult=BuildFileName(eventID, blockno, pDesc->fDataType, pDesc->fSpecification, filename);
+  ios::openmode filemode=(ios::openmode)0;
+  if (fCurrentFileName.CompareTo(filename)==0) {
+    // append to the file
+    filemode=ios::app;
+  } else {
+    // store the file for the next block
+    fCurrentFileName=filename;
+  }
+  if (iResult>=0) {
+    ofstream dump(filename.Data(), filemode);
+    if (dump.good()) {
+      dump.write((static_cast<const char*>(pDesc->fPtr)), pDesc->fSize);
+      HLTDebug("wrote %d byte(s) to file %s", pDesc->fSize, filename.Data());
+    } else {
+      HLTError("can not open file %s for writing", filename.Data());
+      iResult=-EBADF;
+    }
+    dump.close();
+  }
+  return iResult;
+}
index 0524626bcb8f777f1742cbae3f7896f009876c21..9046a59b678ee62bbacf06ae043855c6ed2d048c 100644 (file)
@@ -1,4 +1,4 @@
-// @(#) $Id$
+// $Id$
 
 #ifndef ALIHLTFILEWRITER_H
 #define ALIHLTFILEWRITER_H
@@ -15,6 +15,8 @@
 #include "AliHLTDataSink.h"
 #include <TString.h>
 
+class AliHLTBlockDataCollection;
+
 /**
  * @class AliHLTFileWriter
  * An HLT data sink component which writes data to file(s).
  *      the beginning.
  * \li -write-all <br>
  *      combines both -write-all-events and -write-all-blocks
+ * \li -burst-buffer <size> <br>
+ *      size of burst buffer, blocks are written to buffer until it is filled
+ *      and written in one burst (though to different files according to conf)<br>
+ *      \b Note: burst write is currently only supported for mode
+ *      -concatenate-events AND -concatenate-blocks (both enabled).
+ * \li -datatype     <i> id origin      </i>                            <br>
+ *     data block selection by AliHLTBlockDataCollection
+ * \li -origin  <i> origin  </i>                                        <br>
+ *     data block selection by AliHLTBlockDataCollection
+ * \li -typeid  <i> id      </i>                                        <br>
+ *     data block selection by AliHLTBlockDataCollection
+ * \li -dataspec     <i> specification </i>                             <br>
+ *     data block selection by AliHLTBlockDataCollection
  *
  * <h2>Configuration:</h2>
  * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
@@ -259,12 +274,45 @@ class AliHLTFileWriter : public AliHLTDataSink  {
     kSkipDataType = 0x20
   };
 
+  /** argument scan concerning block descriptor selections */
+  AliHLTBlockDataCollection* fpBlockDataCollection;                //!transient
+
  private:
   /** copy constructor prohibited */
   AliHLTFileWriter(const AliHLTFileWriter&);
   /** assignment operator prohibited */
   AliHLTFileWriter& operator=(const AliHLTFileWriter&);
 
+  /**
+   * Set defaults for all internal properties
+   */
+  int SetDefaults();
+
+  /**
+   * Schedule block for writing.
+   * The block is written immediately unless burst mode is activated.
+   * In burst mode, the block is buffered in the burst buffer until it is filled.
+   * Content of the burst buffer is then written in one burst.
+   *
+   * In the first implementation, burst write is only foreseen for the base
+   * file writer.
+   */
+  int ScheduleBlock(int blockno, const AliHLTEventID_t& eventID,
+                   const AliHLTComponentBlockData* pDesc);
+
+  /**
+   * Flush burst buffer.
+   */
+  int BurstWrite();
+
+  /**
+   * Write data block;
+   * Build file name from the block attributes and compare with the
+   * lat file name in order to correctly append data or not.
+   */
+  int WriteBlock(int blockno, const AliHLTEventID_t& eventID,
+                const AliHLTComponentBlockData* pDesc);
+
   /** the basename of the output file */
   TString    fBaseName;                                            // see above
   /** the extension of the output file */
@@ -287,6 +335,18 @@ class AliHLTFileWriter : public AliHLTDataSink  {
   /** mode specifier, see @ref TWriterMode */
   Short_t    fMode;                                                // see above
 
-  ClassDef(AliHLTFileWriter, 2)
+  /** burst buffer for postponed data write */
+  AliHLTUInt8_t* fpBurstBuffer;                                    //!transient
+
+  /** size of burst buffer */
+  AliHLTUInt32_t fBurstBufferSize;                                 //!transient
+
+  /** block descriptor list for postponed burst write*/
+  AliHLTComponentBlockDataList fBurstBlocks;                       //!transient
+
+  /** event ids for the burst blocks */
+  vector<AliHLTEventID_t> fBurstBlockEvents;                       //!transient
+  
+  ClassDef(AliHLTFileWriter, 3)
 };
 #endif
index 6affcbead273445c070952afcd507b73cf64db74..af7022a817401b971a9215bd9f15a88c1c45b236 100644 (file)
@@ -8,6 +8,8 @@
 #    e.g. for libAliHLTUtil, MODULE=AliHLTUtil
 MODULE                         = AliHLTUtil
 
+SUBDIRS                        = . test
+
 EXTRA_DIST                     =
 
 # library definition
diff --git a/HLT/BASE/util/test/Makefile.am b/HLT/BASE/util/test/Makefile.am
new file mode 100644 (file)
index 0000000..6281cfc
--- /dev/null
@@ -0,0 +1,14 @@
+# $Id$
+# Makefile template for Alice HLT libAliHLTUtil test programs
+
+AM_CPPFLAGS                    = -I$(top_srcdir)/BASE \
+                                 -I$(top_srcdir)/BASE/util
+
+EXTRA_DIST     = 
+
+check_PROGRAMS = testAliHLTFileWriter
+
+testAliHLTFileWriter_SOURCES = testAliHLTFileWriter.C
+testAliHLTFileWriter_LDADD = $(top_builddir)/BASE/libHLTbase.la
+
+TESTS          = $(check_PROGRAMS)
diff --git a/HLT/BASE/util/test/testAliHLTFileWriter.C b/HLT/BASE/util/test/testAliHLTFileWriter.C
new file mode 100644 (file)
index 0000000..ca1afac
--- /dev/null
@@ -0,0 +1,275 @@
+// $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   testAliHLTFileWriter.C
+    @author Matthias Richter
+    @date   
+    @brief  Test macro/program for the AliHLTFileWriter
+ */
+
+#ifndef __CINT__
+#include <ostream>
+#include <vector>
+#include "AliHLTComponent.h"
+#include "AliHLTComponentHandler.h"
+#include "AliHLTConfiguration.h"
+#include "TString.h"
+#include "TFile.h"
+#include "TSystem.h"
+#else
+#define EINVAL 22
+#define EPROTO 71
+#endif //__CINT__
+
+typedef AliHLTUInt32_t TestElement_t;
+const char* testDirectory="/tmp/testAliHLTFileWriter";
+
+int SetEvent(unsigned eventNo, vector<TestElement_t>& testData)
+{
+  unsigned shift=(sizeof(TestElement_t)-1)*8;
+  AliHLTUInt32_t mask=0xf<<shift;
+  for (unsigned i=0; i<testData.size(); i++) {
+    testData[i]&=~mask;
+    testData[i]|=eventNo<<shift;
+  }
+  return 0;
+}
+
+int TestCycle(AliHLTComponent* pComponent, const char* arguments, AliHLTComponentBlockDataList blocks,
+             vector<TestElement_t>& testData, unsigned int nofEvents=1)
+{
+  int iResult=0;
+  vector<char*> argList;
+  if ((iResult=AliHLTConfiguration::InterpreteString(arguments, argList))<0) {
+    cerr << "failed: chopping arguments \"" << arguments << "\"" << endl;
+  }
+
+  // notepad for generalized unit test class
+  // - test component for outputsize==0 if no blocks are added
+
+  // init FileWriter component
+  if ((iResult=pComponent->Init(NULL, NULL, argList.size(), const_cast<const char**>(&(argList[0]))))!=0) {
+    cerr << "failed: initializing component" << endl;
+    return iResult;
+  }
+
+  // process event
+  AliHLTComponentBlockData eventTypeBlock;
+  AliHLTComponent::FillBlockData(eventTypeBlock);
+  eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
+  eventTypeBlock.fSpecification=gkAliEventTypeData;
+  blocks.push_back(eventTypeBlock);
+
+  AliHLTComponentEventData evtData;
+  memset(&evtData, 0, sizeof(AliHLTComponentEventData));
+  evtData.fStructSize=sizeof(AliHLTComponentEventData);
+  evtData.fEventID=0;
+  evtData.fBlockCnt=blocks.size();
+  
+  AliHLTComponentTriggerData trigData;
+  memset(&trigData, 0, sizeof(AliHLTComponentTriggerData));
+  trigData.fStructSize=sizeof(AliHLTComponentTriggerData);
+
+  AliHLTUInt32_t size=0;
+  AliHLTUInt32_t outputBlockCnt=0;
+  AliHLTComponentBlockData* outputBlocks=NULL;
+  AliHLTComponentEventDoneData* edd=NULL;
+
+  for (unsigned eventNo=0; eventNo<nofEvents; eventNo++) {
+    SetEvent(eventNo, testData);
+    evtData.fEventID=eventNo;
+    if ((iResult=pComponent->ProcessEvent(evtData, &(blocks[0]), trigData, NULL, size, outputBlockCnt, outputBlocks, edd))!=0) {
+      cerr << "failed: event processing" << endl;
+      break;
+    }
+  }
+  blocks.pop_back();
+
+  // cleanup FileWriter component
+  if ((iResult=pComponent->Deinit())!=0) {
+    cerr << "failed: deinit component" << endl;
+  }
+
+  // cleanup argument vector
+  for (vector<char*>::iterator element=argList.begin();
+       element!=argList.end(); element++) {
+    delete *element;
+  }
+  argList.clear();
+
+  return iResult;
+}
+
+int BuildFileName(unsigned eventNo, unsigned blockID,
+                 const AliHLTComponentDataType& dataType,
+                 const AliHLTUInt32_t /*specification*/,
+                 bool bConcatenateEvents, bool bConcatenateBlocks,
+                 TString& filename)
+{
+  int iResult=0;
+  filename="";
+
+  filename+=testDirectory;
+  if (!filename.EndsWith("/")) {
+    filename+="/";
+  }
+
+  filename+="event";
+  if (!bConcatenateEvents) {
+    filename+=Form("_0x%08x", eventNo);
+  }
+  if (!bConcatenateBlocks && !bConcatenateEvents) {
+    filename+=Form("_0x%02x", blockID);
+    if (dataType!=kAliHLTVoidDataType) {
+      filename+="_";
+      filename+=AliHLTComponent::DataType2Text(dataType).data();
+    }
+    //filename+=Form("", specification);
+  }
+  return iResult;
+}
+
+int CheckOutputFiles(AliHLTComponentBlockDataList blocks, vector<TestElement_t>& testData, 
+                    bool bConcatenateEvents, bool bConcatenateBlocks,
+                    unsigned int nofEvents=1)
+{
+  int iResult=0;
+  AliHLTUInt32_t fileOffset=0;
+  TString lastFileName;
+  TFile* pFile=NULL;
+  TArrayC buffer;
+  for (unsigned eventNo=0; eventNo<nofEvents && iResult>=0; eventNo++) {
+    SetEvent(eventNo, testData);
+    for (unsigned blockNo=0; blockNo<blocks.size(); blockNo++) {
+      TString fileName;
+      BuildFileName(eventNo, blockNo, blocks[blockNo].fDataType, blocks[blockNo].fSpecification, bConcatenateEvents, bConcatenateBlocks, fileName);
+      if (pFile && !fileName.IsNull() && fileName!=lastFileName) {
+       pFile->Close();
+       delete pFile;
+       pFile=NULL;
+       fileOffset=0;
+      }
+      lastFileName=fileName;
+      fileName+="?filetype=raw";
+      if (!pFile) pFile=new TFile(fileName);
+      if (!pFile || pFile->IsZombie()) {
+       cerr << "failed: can not open file " << fileName.ReplaceAll("?filetype=raw", "") << endl;
+       iResult=-ENOENT;
+       break;
+      }
+      if (buffer.GetSize()<(int)blocks[blockNo].fSize) {
+       buffer.Set(blocks[blockNo].fSize);
+      }
+      if ((pFile->ReadBuffer((char*)buffer.GetArray(), blocks[blockNo].fSize))!=0) {
+       cerr << "failed: reading " << blocks[blockNo].fSize << " at offset " << fileOffset << " from file " << fileName.ReplaceAll("?filetype=raw", "") << endl;
+       iResult=-EIO;
+       break;
+      }
+      AliHLTUInt8_t* origin=(AliHLTUInt8_t*)blocks[blockNo].fPtr;
+      AliHLTUInt8_t* processed=(AliHLTUInt8_t*)buffer.GetArray();
+      if (memcmp(origin, processed, blocks[blockNo].fSize)!=0) {
+       cerr << "failed: data missmatch in event " << eventNo << " block " << blockNo << endl;
+       iResult=-EFAULT;
+       break;
+      }
+      cout << "checked: file " << fileName.ReplaceAll("?filetype=raw", "") << " offset " << fileOffset << endl;
+      fileOffset+=blocks[blockNo].fSize;
+    }
+  }
+  if (pFile) {
+    pFile->Close();
+    delete pFile;
+    pFile=NULL;
+  }
+  return iResult;
+}
+
+int testAliHLTFileWriter()
+{
+  int iResult=0;
+  AliHLTComponentHandler chandler;
+  if ((iResult=chandler.LoadLibrary("../.libs/libAliHLTUtil.so"))<0) {
+    cerr << "failed: loading libAliHLTUtil" << endl;
+    return iResult;
+  }
+
+  // create FileWriter component
+  AliHLTComponent* pComponent=NULL;
+  if ((iResult=chandler.CreateComponent("FileWriter", pComponent))<0) {
+    cerr << "failed: can not create component \"FileWriter\"" << endl;
+    return iResult;
+  }
+
+  AliHLTComponentBlockDataList blocks;
+  const unsigned testDataSize=500;
+  vector<TestElement_t> testData;
+  testData.assign(testDataSize, 0);
+  unsigned int i=0;
+  for (; i<testDataSize; i++) testData[i]=i;
+
+  const unsigned elementsPerBlock=100;
+  AliHLTComponentBlockData bd;
+  AliHLTComponent::FillBlockData(bd);
+  for (i=0; i*elementsPerBlock<testData.size(); i++) {
+    bd.fPtr=&(testData[i*elementsPerBlock]);
+    bd.fSize=elementsPerBlock*sizeof(TestElement_t);
+    bd.fSpecification=i;
+    AliHLTComponent::SetDataType(bd.fDataType, "DUMMYDAT", "TEST");
+    blocks.push_back(bd);
+  }
+  
+  const char* testArguments[]={
+    "",
+    "-concatenate-blocks ",
+    "-concatenate-blocks -concatenate-events ",
+    // not currently working   "-burst-buffer 10000 ",
+    // not currently working   "-burst-buffer 5000 ",
+    // not currently working   "-burst-buffer 10000 -concatenate-blocks ",
+    "-burst-buffer 10000 -concatenate-blocks -concatenate-events ",
+    "-burst-buffer 5000 -concatenate-blocks -concatenate-events ",
+    NULL
+  };
+
+  for (const char** currentTest=testArguments; *currentTest!=NULL; currentTest++) {
+    TString arguments=*currentTest;
+      arguments+=" -directory "; arguments+=testDirectory;
+    if (!gSystem->AccessPathName(testDirectory)) {
+      TString command="rm -r "; command+=testDirectory;
+      gSystem->Exec(command);
+    }
+    cout << arguments.Data() << endl;
+    if ((iResult=TestCycle(pComponent, arguments.Data(), blocks, testData, 4))<0) {
+      break;
+    }
+    if ((iResult=CheckOutputFiles(blocks, testData, arguments.Contains("-concatenate-events "), arguments.Contains("-concatenate-blocks"), 4))<0) {
+      break;
+    }
+  };
+
+  delete pComponent;
+
+  return iResult;
+}
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+  int iResult=0;
+  if ((iResult=testAliHLTFileWriter())<0) {
+  }
+  return iResult;
+}
index ddaba1abf41e05bd084ff405f2ab688546212101..a4d521ccb48ff63a53bda94a0d4fd84944634f68 100644 (file)
@@ -1158,6 +1158,7 @@ AC_CONFIG_FILES([Makefile
                 BASE/setenv.csh
                 BASE/HOMER/Makefile
                 BASE/util/Makefile
+                BASE/util/test/Makefile
                 BASE/interface/Makefile
                 BASE/test/Makefile
                 BASE/interface/test/Makefile
index 6e3281b66394ef5332caa796985e5851ca36d20f..a6405fd5a269eb9d0502f9e1bd3f94685490050b 100644 (file)
@@ -40,6 +40,7 @@ CLASS_HDRS:=          AliHLTComponent.h \
                AliHLTMemoryFile.h \
                AliHLTMessage.h \
                AliHLTEventStatistics.h \
+               AliHLTBlockDataCollection.h \
                 AliHLTRunStatistics.h