Alice dependencies removed.
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
CommitLineData
a197a4ce 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3
4/**************************************************************************
5 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
6 * *
7 * Author: The ALICE Off-line Project. *
8 * Contributors are mentioned in the code where appropriate. *
9 * *
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 **************************************************************************/
18
19//////////////////////////////////////////////////////////////////////////
20// //
21// AliRawDB //
22// //
23//////////////////////////////////////////////////////////////////////////
24
25#include <errno.h>
26
27#include <TSystem.h>
28
29#ifdef ALI_DATE
30#include "event.h"
31#endif
32
33#include "AliRawEvent.h"
34#include "AliRawEventHeader.h"
35#include "AliMDC.h"
36
37#include "AliRawDB.h"
38
39
40ClassImp(AliRawDB)
41
42
43//______________________________________________________________________________
44AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
45 Bool_t create)
46{
47 // Create a new raw DB containing at most maxsize bytes.
48
49 fEvent = event;
50 fMaxSize = maxsize;
51 fCompress = compress;
52
53 // Consistency check with DATE header file
54#ifdef ALI_DATE
55 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
56 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
57 MakeZombie();
58 return;
59 }
60#endif
61
62 if (create) {
63 if (!Create())
64 MakeZombie();
65 }
66}
67
68//______________________________________________________________________________
69AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
70{
71// copy constructor
72
73 Fatal("AliRawDB", "copy constructor not implemented");
74}
75
76//______________________________________________________________________________
77AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
78{
79// assignment operator
80
81 Fatal("operator =", "assignment operator not implemented");
82 return *this;
83}
84
85//______________________________________________________________________________
86Bool_t AliRawDB::FSHasSpace(const char *fs) const
87{
88 // Check for at least fMaxSize bytes of free space on the file system.
89 // If the space is not available return kFALSE, kTRUE otherwise.
90
91 Long_t id, bsize, blocks, bfree;
92
93 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
94 Error("FSHasSpace", "could not stat file system %s", fs);
95 return kFALSE;
96 }
97
98 // Leave 5 percent of diskspace free
99 Double_t avail = Double_t(bfree) * 0.95;
100 if (avail*bsize > fMaxSize)
101 return kTRUE;
102
103 Warning("FSHasSpace", "no space on file system %s", fs);
104 return kFALSE;
105}
106
107//______________________________________________________________________________
108const char *AliRawDB::GetFileName() const
109{
110 // Return filename based on hostname and date and time. This will make
111 // each file unique. Also makes sure (via FSHasSpace()) that there is
112 // enough space on the file system to store the file. Returns 0 in
113 // case of error or interrupt signal.
114
115 static TString fname;
116 static Bool_t fstoggle = kFALSE;
117
118 TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
119 TDatime dt;
120
121 TString hostname = gSystem->HostName();
122 Int_t pos;
123 if ((pos = hostname.Index(".")) != kNPOS)
124 hostname.Remove(pos);
125
126 if (!FSHasSpace(fs)) {
127 while (1) {
128 fstoggle = !fstoggle;
129 fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
130 if (FSHasSpace(fs)) break;
131 Info("GetFileName", "sleeping 30 seconds before retrying...");
132 gSystem->Sleep(30000); // sleep for 30 seconds
133 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
134 return 0;
135 }
136 }
137
138 fname = fs + "/" + hostname + "_";
139 fname += dt.GetDate();
140 fname += "_";
141 fname += dt.GetTime();
142 fname += ".root";
143
144 fstoggle = !fstoggle;
145
146 return fname;
147}
148
149//______________________________________________________________________________
150Bool_t AliRawDB::Create()
151{
152 // Create a new raw DB.
153
154 const Int_t kMaxRetry = 200;
155 const Int_t kMaxSleep = 1; // seconds
156 const Int_t kMaxSleepLong = 10; // seconds
157 Int_t retry = 0;
158
159again:
160 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
161 return kFALSE;
162
163 const char *fname = GetFileName();
164 if (!fname) {
165 Error("Create", "error getting raw DB file name");
166 return kFALSE;
167 }
168
169 retry++;
170
171 fRawDB = TFile::Open(fname, GetOpenOption(),
172 Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress,
173 GetNetopt());
174 if (!fRawDB) {
175 if (retry < kMaxRetry) {
176 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
177 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
178 gSystem->Sleep(kMaxSleep*1000);
179 goto again;
180 }
181 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
182 return kFALSE;
183 }
184 if (retry > 1)
185 Warning("Create", "succeeded to open file after %d retries", retry);
186
187 if (fRawDB->IsZombie()) {
188 if (fRawDB->GetErrno() == ENOSPC ||
189 fRawDB->GetErrno() == 1018 || // SECOMERR
190 fRawDB->GetErrno() == 1027) { // SESYSERR
191 fRawDB->ResetErrno();
192 delete fRawDB;
193 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
194 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
195 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
196 goto again;
197 }
198 Error("Create", "file %s is zombie", fname);
199 fRawDB->ResetErrno();
200 delete fRawDB;
201 fRawDB = 0;
202 if (retry < kMaxRetry) {
203 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
204 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
205 gSystem->Sleep(kMaxSleep*1000);
206 goto again;
207 }
208 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
209 return kFALSE;
210 }
211
212 // Create raw data TTree
213 MakeTree();
214
215 return kTRUE;
216}
217
218//______________________________________________________________________________
219void AliRawDB::MakeTree()
220{
221 // Create ROOT Tree object container.
222
223 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC));
224 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
225
226 Int_t bufsize = 256000;
227 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
228 //Int_t split = 1;
229 Int_t split = 0;
230 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
231}
232
233//______________________________________________________________________________
234void AliRawDB::Close()
235{
236 // Close raw DB.
237
238 if (!fRawDB) return;
239
240 fRawDB->cd();
241
242 // Write the tree.
243 fTree->Write();
244
245 // Close DB, this also deletes the fTree
246 fRawDB->Close();
247
248 if (AliMDC::DeleteFiles()) {
249 gSystem->Unlink(fRawDB->GetName());
250 delete fRawDB;
251 fRawDB = 0;
252 return;
253 }
254
255 // Create semaphore to say this file is finished
256 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
257 close(tfd);
258
259 delete fRawDB;
260 fRawDB = 0;
261}
262
263//______________________________________________________________________________
264Bool_t AliRawDB::NextFile()
265{
266 // Close te current file and open a new one.
267 // Returns kFALSE in case opening failed.
268
269 Close();
270
271 if (!Create()) return kFALSE;
272 return kTRUE;
273}
274
275//______________________________________________________________________________
276Float_t AliRawDB::GetCompressionFactor() const
277{
278 // Return compression factor.
279
280 if (fTree->GetZipBytes() == 0.)
281 return 1.0;
282 else
283 return fTree->GetTotBytes()/fTree->GetZipBytes();
284}