1 // @(#)alimdc:$Name$:$Id$
2 // Author: Fons Rademakers 26/11/99
4 /**************************************************************************
5 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * Author: The ALICE Off-line Project. *
8 * Contributors are mentioned in the code where appropriate. *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
19 //////////////////////////////////////////////////////////////////////////
23 //////////////////////////////////////////////////////////////////////////
31 #include "AliRawEvent.h"
32 #include "AliRawEventHeaderBase.h"
40 const char *AliRawDB::fgkAliRootTag = "$Name$";
42 //______________________________________________________________________________
43 AliRawDB::AliRawDB(AliRawEvent *event,
46 const char* fileName) :
59 // Create a new raw DB
62 if (!Create(fileName))
67 //______________________________________________________________________________
68 AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
72 Fatal("AliRawDB", "copy constructor not implemented");
75 //______________________________________________________________________________
76 AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
78 // assignment operator
80 Fatal("operator =", "assignment operator not implemented");
84 //______________________________________________________________________________
85 Bool_t AliRawDB::FSHasSpace(const char *fs) const
87 // Check for at least fMaxSize bytes of free space on the file system.
88 // If the space is not available return kFALSE, kTRUE otherwise.
90 Long_t id, bsize, blocks, bfree;
92 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
93 Error("FSHasSpace", "could not stat file system %s", fs);
97 // Leave 5 percent of diskspace free
98 Double_t avail = Double_t(bfree) * 0.95;
99 if (avail*bsize > fMaxSize)
102 Warning("FSHasSpace", "no space on file system %s", fs);
106 //______________________________________________________________________________
107 const char *AliRawDB::GetFileName() const
109 // Return filename based on hostname and date and time. This will make
110 // each file unique. Also makes sure (via FSHasSpace()) that there is
111 // enough space on the file system to store the file. Returns 0 in
112 // case of error or interrupt signal.
114 static TString fname;
115 static Bool_t fstoggle = kFALSE;
117 TString fs = fstoggle ? fFS2 : fFS1;
120 TString hostname = gSystem->HostName();
122 if ((pos = hostname.Index(".")) != kNPOS)
123 hostname.Remove(pos);
125 if (!FSHasSpace(fs)) {
127 fstoggle = !fstoggle;
128 fs = fstoggle ? fFS2 : fFS1;
129 if (FSHasSpace(fs)) break;
130 Info("GetFileName", "sleeping 30 seconds before retrying...");
131 gSystem->Sleep(30000); // sleep for 30 seconds
136 fname = fs + "/" + hostname + "_";
137 fname += dt.GetDate();
139 fname += dt.GetTime();
142 fstoggle = !fstoggle;
147 //______________________________________________________________________________
148 void AliRawDB::SetFS(const char* fs1, const char* fs2)
150 // set the file system location
153 if (fs1 && !fFS1.Contains(":")) {
154 gSystem->ResetErrno();
155 gSystem->MakeDirectory(fs1);
156 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
157 SysError("SetFS", "mkdir %s", fs1);
163 gSystem->ResetErrno();
164 gSystem->MakeDirectory(fs2);
165 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
166 SysError("SetFS", "mkdir %s", fs2);
171 //______________________________________________________________________________
172 Bool_t AliRawDB::Create(const char* fileName)
174 // Create a new raw DB.
176 const Int_t kMaxRetry = 1;
177 const Int_t kMaxSleep = 1; // seconds
178 const Int_t kMaxSleepLong = 10; // seconds
182 if (fStop) return kFALSE;
184 const char *fname = fileName;
185 if (!fname) fname = GetFileName();
187 Error("Create", "error getting raw DB file name");
193 fRawDB = TFile::Open(fname, GetOpenOption(),
194 Form("ALICE raw-data file (%s)", GetAliRootTag()), fCompress,
197 if (retry < kMaxRetry) {
198 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
199 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
200 gSystem->Sleep(kMaxSleep*1000);
203 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
207 Warning("Create", "succeeded to open file after %d retries", retry);
209 if (fRawDB->IsZombie()) {
210 if (fRawDB->GetErrno() == ENOSPC ||
211 fRawDB->GetErrno() == 1018 || // SECOMERR
212 fRawDB->GetErrno() == 1027) { // SESYSERR
213 fRawDB->ResetErrno();
215 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
216 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
217 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
220 Error("Create", "file %s is zombie", fname);
221 fRawDB->ResetErrno();
224 if (retry < kMaxRetry) {
225 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
226 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
227 gSystem->Sleep(kMaxSleep*1000);
230 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
234 // Create raw data TTree
240 //______________________________________________________________________________
241 void AliRawDB::MakeTree()
243 // Create ROOT Tree object container.
245 fTree = new TTree("RAW", Form("ALICE raw-data tree (%s)", GetAliRootTag()));
246 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
248 Int_t bufsize = 256000;
249 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
252 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
254 // Create tree which will contain the HLT ESD information
257 fESDTree = new TTree("esdTree", Form("ALICE HLT ESD tree (%s)", GetAliRootTag()));
258 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
260 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
265 //______________________________________________________________________________
266 Int_t AliRawDB::Close()
269 if (!fRawDB) return 0;
271 if (!fRawDB->IsOpen()) return 0;
276 Bool_t error = kFALSE;
277 if (fTree->Write() == 0)
280 if (fESDTree->Write() == 0)
283 // Close DB, this also deletes the fTree
286 Int_t filesize = fRawDB->GetEND();
289 gSystem->Unlink(fRawDB->GetName());
298 // Create semaphore to say this file is finished
299 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
310 //______________________________________________________________________________
311 Int_t AliRawDB::Fill()
313 // Fill the trees and return the number of written bytes
315 Double_t bytes = fRawDB->GetBytesWritten();
316 Bool_t error = kFALSE;
317 if (fTree->Fill() == -1)
320 if (fESDTree->Fill() == -1)
323 return Int_t(fRawDB->GetBytesWritten() - bytes);
328 //______________________________________________________________________________
329 Int_t AliRawDB::GetTotalSize()
331 // Return the total size of the trees
336 TDirectory *dir = fTree->GetDirectory();
338 TKey *key = dir->GetKey(fTree->GetName());
339 if (key) skey = key->GetKeylen();
342 if (fTree->GetZipBytes() > 0) total += fTree->GetTotBytes();
343 TBuffer b(TBuffer::kWrite,10000);
344 TTree::Class()->WriteBuffer(b,fTree);
351 TDirectory *dir = fESDTree->GetDirectory();
353 TKey *key = dir->GetKey(fESDTree->GetName());
354 if (key) skey = key->GetKeylen();
357 if (fESDTree->GetZipBytes() > 0) total += fESDTree->GetTotBytes();
358 TBuffer b(TBuffer::kWrite,10000);
359 TTree::Class()->WriteBuffer(b,fESDTree);
366 //______________________________________________________________________________
367 void AliRawDB::WriteStats(AliStats* stats)
369 // Write stats to raw DB, local run DB and global MySQL DB.
371 AliRawEventHeaderBase &header = *GetEvent()->GetHeader();
373 // Write stats into RawDB
374 TDirectory *ds = gDirectory;
376 stats->SetEvents(GetEvents());
377 stats->SetLastId(header.Get("RunNb"), header.GetP("Id")[0]);
378 stats->SetFileSize(GetBytesWritten());
379 stats->SetCompressionFactor(GetCompressionFactor());
381 stats->Write("stats");
385 //______________________________________________________________________________
386 Bool_t AliRawDB::NextFile(const char* fileName)
388 // Close te current file and open a new one.
389 // Returns kFALSE in case opening failed.
393 if (!Create(fileName)) return kFALSE;
397 //______________________________________________________________________________
398 Float_t AliRawDB::GetCompressionFactor() const
400 // Return compression factor.
402 if (fTree->GetZipBytes() == 0.)
405 return fTree->GetTotBytes()/fTree->GetZipBytes();
408 //______________________________________________________________________________
409 const char *AliRawDB::GetAliRootTag()
411 // Return the aliroot tag (version)
412 // used to generate the raw data file.
413 // Stored in the raw-data file title.
415 TString version = fgkAliRootTag;
416 version.Remove(TString::kBoth,'$');
417 version.ReplaceAll("Name","AliRoot version");
419 return version.Data();