// @(#)root/io:$Id$
// Author: Andreas Peters + Fons Rademakers   26/5/2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TFileMerger
#define ROOT_TFileMerger

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TStopwatch
#include "TStopwatch.h"
#endif

class TList;
class TFile;
class TDirectory;


class TFileMerger : public TObject {
private:
   TFileMerger(const TFileMerger&); // Not implemented
   TFileMerger& operator=(const TFileMerger&); // Not implemented

protected:
   TStopwatch     fWatch;            ///< Stop watch to measure file copy speed
   TList         *fFileList;         ///< A list the file (TFile*) which shall be merged
   TFile         *fOutputFile;       ///< The outputfile for merging
   TString        fOutputFilename;   ///< The name of the outputfile for merging
   Bool_t         fFastMethod;       ///< True if using Fast merging algorithm (default)
   Bool_t         fNoTrees;          ///< True if Trees should not be merged (default is kFALSE)
   Bool_t         fExplicitCompLevel;///< True if the user explicitly requested a compressio level change (default kFALSE)
   Bool_t         fCompressionChange;///< True if the output and input have different compression level (default kFALSE)
   Int_t          fPrintLevel;       ///< How much information to print out at run time
   TString        fMergeOptions;     ///< Options (in string format) to be passed down to the Merge functions
   TString        fMsgPrefix;        ///< Prefix to be used when printing informational message (default TFileMerger)

   Int_t          fMaxOpenedFiles;  ///< Maximum number of files opened at the same time by the TFileMerger
   Bool_t         fLocal;           ///< Makes local copies of merging files if True (default is kTRUE)
   Bool_t         fHistoOneGo;      ///< Merger histos in one go (default is kTRUE)
   TString        fObjectNames;     ///< List of object names to be either merged exclusively or skipped
   TList         *fMergeList;       ///< list of TObjString containing the name of the files need to be merged
   TList         *fExcessFiles;     ///<! List of TObjString containing the name of the files not yet added to fFileList due to user or system limitiation on the max number of files opened.

   Bool_t         OpenExcessFiles();
   virtual Bool_t AddFile(TFile *source, Bool_t own, Bool_t cpProgress);
   virtual Bool_t MergeRecursive(TDirectory *target, TList *sourcelist, Int_t type = kRegular | kAll);

public:
   /// Type of the partial merge
   enum EPartialMergeType {
      kRegular      = 0,             ///< Normal merge, overwritting the output file.
      kIncremental  = BIT(1),        ///< Merge the input file with the content of the output file (if already exising).
      kResetable    = BIT(2),        ///< Only the objects with a MergeAfterReset member function.
      kNonResetable = BIT(3),        ///< Only the objects without a MergeAfterReset member function.

      kAll            = BIT(2)|BIT(3),      ///< Merge all type of objects (default)
      kAllIncremental = kIncremental | kAll, ///< Merge incrementally all type of objects.

      kOnlyListed     = BIT(4),        ///< Only the objects specified in fObjectNames list
      kSkipListed     = BIT(5),        ///< Skip objects specified in fObjectNames list
      kKeepCompression= BIT(6)         ///< Keep compression level unchanged for each input files
   };
   TFileMerger(Bool_t isLocal = kTRUE, Bool_t histoOneGo = kTRUE);
   virtual ~TFileMerger();

   Int_t       GetPrintLevel() const { return fPrintLevel; }
   void        SetPrintLevel(Int_t level) { fPrintLevel = level; }
   Bool_t      HasCompressionChange() const { return fCompressionChange; }
   const char *GetOutputFileName() const { return fOutputFilename; }
   TList      *GetMergeList() const { return fMergeList;  }
   TFile      *GetOutputFile() const { return fOutputFile; }
   Int_t       GetMaxOpenedFiles() const { return fMaxOpenedFiles; }
   void        SetMaxOpenedFiles(Int_t newmax);
   const char *GetMsgPrefix() const { return fMsgPrefix; }
   void        SetMsgPrefix(const char *prefix);
   const char *GetMergeOptions() { return fMergeOptions; }
   void        SetMergeOptions(const std::string_view &options) { fMergeOptions = options; }
   void        AddObjectNames(const char *name) {fObjectNames += name; fObjectNames += " ";}
   const char *GetObjectNames() const {return fObjectNames.Data();}
   void        ClearObjectNames() {fObjectNames.Clear();}

    //--- file management interface
   virtual Bool_t SetCWD(const char * /*path*/) { MayNotUse("SetCWD"); return kFALSE; }
   virtual const char *GetCWD() { MayNotUse("GetCWD"); return 0; }

   //--- file merging interface
   virtual void   Reset();
   virtual Bool_t AddFile(const char *url, Bool_t cpProgress = kTRUE);
   virtual Bool_t AddFile(TFile *source, Bool_t cpProgress = kTRUE);
   virtual Bool_t AddAdoptFile(TFile *source, Bool_t cpProgress = kTRUE);
   virtual Bool_t OutputFile(const char *url, Bool_t force);
   virtual Bool_t OutputFile(const char *url, Bool_t force, Int_t compressionLevel);
   virtual Bool_t OutputFile(const char *url, const char *mode = "RECREATE");
   virtual Bool_t OutputFile(const char *url, const char *mode, Int_t compressionLevel);
   virtual void   PrintFiles(Option_t *options);
   virtual Bool_t Merge(Bool_t = kTRUE);
   virtual Bool_t PartialMerge(Int_t type = kAll | kIncremental);
   virtual void   SetFastMethod(Bool_t fast=kTRUE)  {fFastMethod = fast;}
   virtual void   SetNotrees(Bool_t notrees=kFALSE) {fNoTrees = notrees;}
   virtual void        RecursiveRemove(TObject *obj);

   ClassDef(TFileMerger,5)  // File copying and merging services
};

#endif

 TFileMerger.h:1
 TFileMerger.h:2
 TFileMerger.h:3
 TFileMerger.h:4
 TFileMerger.h:5
 TFileMerger.h:6
 TFileMerger.h:7
 TFileMerger.h:8
 TFileMerger.h:9
 TFileMerger.h:10
 TFileMerger.h:11
 TFileMerger.h:12
 TFileMerger.h:13
 TFileMerger.h:14
 TFileMerger.h:15
 TFileMerger.h:16
 TFileMerger.h:17
 TFileMerger.h:18
 TFileMerger.h:19
 TFileMerger.h:20
 TFileMerger.h:21
 TFileMerger.h:22
 TFileMerger.h:23
 TFileMerger.h:24
 TFileMerger.h:25
 TFileMerger.h:26
 TFileMerger.h:27
 TFileMerger.h:28
 TFileMerger.h:29
 TFileMerger.h:30
 TFileMerger.h:31
 TFileMerger.h:32
 TFileMerger.h:33
 TFileMerger.h:34
 TFileMerger.h:35
 TFileMerger.h:36
 TFileMerger.h:37
 TFileMerger.h:38
 TFileMerger.h:39
 TFileMerger.h:40
 TFileMerger.h:41
 TFileMerger.h:42
 TFileMerger.h:43
 TFileMerger.h:44
 TFileMerger.h:45
 TFileMerger.h:46
 TFileMerger.h:47
 TFileMerger.h:48
 TFileMerger.h:49
 TFileMerger.h:50
 TFileMerger.h:51
 TFileMerger.h:52
 TFileMerger.h:53
 TFileMerger.h:54
 TFileMerger.h:55
 TFileMerger.h:56
 TFileMerger.h:57
 TFileMerger.h:58
 TFileMerger.h:59
 TFileMerger.h:60
 TFileMerger.h:61
 TFileMerger.h:62
 TFileMerger.h:63
 TFileMerger.h:64
 TFileMerger.h:65
 TFileMerger.h:66
 TFileMerger.h:67
 TFileMerger.h:68
 TFileMerger.h:69
 TFileMerger.h:70
 TFileMerger.h:71
 TFileMerger.h:72
 TFileMerger.h:73
 TFileMerger.h:74
 TFileMerger.h:75
 TFileMerger.h:76
 TFileMerger.h:77
 TFileMerger.h:78
 TFileMerger.h:79
 TFileMerger.h:80
 TFileMerger.h:81
 TFileMerger.h:82
 TFileMerger.h:83
 TFileMerger.h:84
 TFileMerger.h:85
 TFileMerger.h:86
 TFileMerger.h:87
 TFileMerger.h:88
 TFileMerger.h:89
 TFileMerger.h:90
 TFileMerger.h:91
 TFileMerger.h:92
 TFileMerger.h:93
 TFileMerger.h:94
 TFileMerger.h:95
 TFileMerger.h:96
 TFileMerger.h:97
 TFileMerger.h:98
 TFileMerger.h:99
 TFileMerger.h:100
 TFileMerger.h:101
 TFileMerger.h:102
 TFileMerger.h:103
 TFileMerger.h:104
 TFileMerger.h:105
 TFileMerger.h:106
 TFileMerger.h:107
 TFileMerger.h:108
 TFileMerger.h:109
 TFileMerger.h:110
 TFileMerger.h:111
 TFileMerger.h:112
 TFileMerger.h:113
 TFileMerger.h:114
 TFileMerger.h:115
 TFileMerger.h:116
 TFileMerger.h:117