CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes
TStorageFactoryFile Class Reference

#include <TStorageFactoryFile.h>

Inheritance diagram for TStorageFactoryFile:

Public Member Functions

 ClassDef (TStorageFactoryFile, 0)
 
virtual Bool_t ReadBuffer (char *buf, Int_t len)
 
virtual Bool_t ReadBuffer (char *buf, Long64_t pos, Int_t len)
 
virtual Bool_t ReadBufferAsync (Long64_t off, Int_t len)
 
virtual Bool_t ReadBuffers (char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
 
void ResetErrno (void) const
 
 TStorageFactoryFile (const char *name, Option_t *option, const char *ftitle, Int_t compress, Int_t netopt, Bool_t parallelopen=kFALSE)
 
 TStorageFactoryFile (const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1)
 
virtual Bool_t WriteBuffer (const char *buf, Int_t len)
 
 ~TStorageFactoryFile (void)
 

Protected Member Functions

virtual Int_t SysClose (Int_t fd)
 
virtual Int_t SysOpen (const char *pathname, Int_t flags, UInt_t mode)
 
virtual Long64_t SysSeek (Int_t fd, Long64_t offset, Int_t whence)
 
virtual Int_t SysStat (Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
 
virtual Int_t SysSync (Int_t fd)
 

Private Member Functions

void Initialize (const char *name, Option_t *option="")
 
Bool_t ReadBuffersSync (char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
 
 TStorageFactoryFile (void)
 

Private Attributes

Storagestorage_
 

Detailed Description

TFile wrapper around StorageFactory and Storage.

Definition at line 14 of file TStorageFactoryFile.h.

Constructor & Destructor Documentation

TStorageFactoryFile::TStorageFactoryFile ( const char *  name,
Option_t *  option,
const char *  ftitle,
Int_t  compress,
Int_t  netopt,
Bool_t  parallelopen = kFALSE 
)

Definition at line 105 of file TStorageFactoryFile.cc.

References Initialize().

111  : TFile(path, "NET", ftitle, compress), // Pass "NET" to prevent local access in base class
112  storage_(0)
113 {
114  Initialize(path, option);
115 }
void Initialize(const char *name, Option_t *option="")
TStorageFactoryFile::TStorageFactoryFile ( const char *  name,
Option_t *  option = "",
const char *  ftitle = "",
Int_t  compress = 1 
)

Definition at line 117 of file TStorageFactoryFile.cc.

References Initialize().

121  : TFile(path, "NET", ftitle, compress), // Pass "NET" to prevent local access in base class
122  storage_(0)
123 {
124  Initialize(path, option);
125 }
void Initialize(const char *name, Option_t *option="")
TStorageFactoryFile::~TStorageFactoryFile ( void  )

Definition at line 212 of file TStorageFactoryFile.cc.

References storage_.

213 {
214  Close();
215  delete storage_;
216 }
TStorageFactoryFile::TStorageFactoryFile ( void  )
private

Definition at line 94 of file TStorageFactoryFile.cc.

References s_statsCtor, storageCounter(), and StorageAccount::Stamp::tick().

95  : storage_(0)
96 {
98  stats.tick(0);
99 }
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsCtor

Member Function Documentation

TStorageFactoryFile::ClassDef ( TStorageFactoryFile  ,
 
)
void TStorageFactoryFile::Initialize ( const char *  name,
Option_t *  option = "" 
)
private

Definition at line 128 of file TStorageFactoryFile.cc.

References edm::Exception::categoryCode(), SurfaceDeformationFactory::create(), alignCSCRings::e, edm::hlt::Exception, StorageFactory::get(), edm::Service< T >::isAvailable(), edm::errors::NotFound, IOFlags::OpenCreate, IOFlags::OpenRead, IOFlags::OpenWrite, getHLTPrescaleColumns::path, SiPixelLorentzAngle_cfi::read, s_statsCtor, edm::storage::StatisticsSenderService::setSize(), Storage::size(), storage_, storageCounter(), StorageAccount::Stamp::tick(), and update.

Referenced by TStorageFactoryFile().

130 {
131  StorageAccount::Stamp stats(storageCounter(s_statsCtor, "construct"));
132 
133  // Enable AsyncReading.
134  // This was the default for 5.27, but turned off by default for 5.32.
135  // In our testing, AsyncReading is the fastest mechanism available.
136  // In 5.32, the AsyncPrefetching mechanism is preferred, but has been a
137  // performance hit in our "average case" tests.
138  gEnv->SetValue("TFile.AsyncReading", 1);
139 
140  // Parse options; at the moment we only accept read!
141  fOption = option;
142  fOption.ToUpper();
143 
144  if (fOption == "NEW")
145  fOption = "CREATE";
146 
147  Bool_t create = (fOption == "CREATE");
148  Bool_t recreate = (fOption == "RECREATE");
149  Bool_t update = (fOption == "UPDATE");
150  Bool_t read = (fOption == "READ");
151 
152  if (!create && !recreate && !update && !read)
153  {
154  read = true;
155  fOption = "READ";
156  }
157 
158  if (recreate)
159  {
160  if (!gSystem->AccessPathName(path, kFileExists))
161  gSystem->Unlink(path);
162 
163  recreate = false;
164  create = true;
165  fOption = "CREATE";
166  }
167  assert(!recreate);
168 
169  if (update && gSystem->AccessPathName(path, kFileExists))
170  {
171  update = kFALSE;
172  create = kTRUE;
173  }
174 
175  assert(read || update || create);
176 
177  int openFlags = IOFlags::OpenRead;
178  if (!read) openFlags |= IOFlags::OpenWrite;
179  if (create) openFlags |= IOFlags::OpenCreate;
180  //if (recreate) openFlags |= IOFlags::OpenCreate | IOFlags::OpenTruncate;
181 
182  // Open storage
183  if (! (storage_ = StorageFactory::get()->open(path, openFlags)))
184  {
185  MakeZombie();
186  gDirectory = gROOT;
187  throw cms::Exception("TStorageFactoryFile::TStorageFactoryFile()")
188  << "Cannot open file '" << path << "'";
189  }
190 
191  // Record the statistics.
192  try {
194  if (statsService.isAvailable()) {
195  statsService->setSize(storage_->size());
196  }
197  } catch (edm::Exception e) {
198  if (e.categoryCode() != edm::errors::NotFound) {
199  throw;
200  }
201  }
202 
203  fRealName = path;
204  fD = 0; // sorry, meaningless
205  fWritable = read ? kFALSE : kTRUE;
206 
207  Init(create);
208 
209  stats.tick(0);
210 }
Code categoryCode() const
Definition: EDMException.h:94
static StorageFactory * get(void)
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsCtor
bool isAvailable() const
Definition: Service.h:47
virtual IOOffset size(void) const
Definition: Storage.cc:102
#define update(a, b)
SurfaceDeformation * create(int type, const std::vector< double > &params)
Bool_t TStorageFactoryFile::ReadBuffer ( char *  buf,
Int_t  len 
)
virtual

Definition at line 232 of file TStorageFactoryFile.cc.

References trackerHits::c, n, s_statsCPrefetch, s_statsCRead, s_statsRead, s_statsXRead, storage_, storageCounter(), StorageAccount::Stamp::tick(), and IOInput::xread().

Referenced by ReadBuffer().

233 {
234  // Check that it's valid to access this file.
235  if (IsZombie())
236  {
237  Error("ReadBuffer", "Cannot read from a zombie file");
238  return kTRUE;
239  }
240 
241  if (! IsOpen())
242  {
243  Error("ReadBuffer", "Cannot read from a file that is not open");
244  return kTRUE;
245  }
246 
247  // Read specified byte range from the storage. Returns kTRUE in
248  // case of error. Note that ROOT uses this function recursively
249  // to fill the cache; we use a flag to make sure our accounting
250  // is reflected in a comprehensible manner. The "read" counter
251  // will include both, "readc" indicates how much read from the
252  // cache, "readu" indicates how much we failed to read from the
253  // cache (excluding those recursive reads), and "readx" counts
254  // the amount actually passed to read from the storage object.
256 
257  // If we have a cache, read from there first. This returns 0
258  // if the block hasn't been prefetched, 1 if it was in cache,
259  // and 2 if there was an error.
260  if (TFileCacheRead *c = GetCacheRead())
261  {
262  Long64_t here = GetRelOffset();
263  Bool_t async = c->IsAsyncReading();
264 
265  StorageAccount::Stamp cstats(async
266  ? storageCounter(s_statsCPrefetch, "readPrefetchToCache")
267  : storageCounter(s_statsCRead, "readViaCache"));
268 
269  Int_t st = ReadBufferViaCache(async ? 0 : buf, len);
270 
271  if (st == 2) {
272  return kTRUE;
273  }
274 
275  if (st == 1) {
276  if (async) {
277  cstats.tick(len);
278  Seek(here);
279  } else {
280  cstats.tick(len);
281  stats.tick(len);
282  return kFALSE;
283  }
284  }
285  }
286 
287  // FIXME: Re-enable read-ahead if the data wasn't in cache.
288  // if (! st) storage_->caching(true, -1, s_readahead);
289 
290  // A real read
291  StorageAccount::Stamp xstats(storageCounter(s_statsXRead, "readActual"));
292  IOSize n = storage_->xread(buf, len);
293  xstats.tick(n);
294  stats.tick(n);
295  return n ? kFALSE : kTRUE;
296 }
IOSize xread(IOBuffer into)
Definition: IOInput.cc:166
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsRead
static StorageAccount::Counter * s_statsXRead
size_t IOSize
Definition: IOTypes.h:14
static StorageAccount::Counter * s_statsCPrefetch
static StorageAccount::Counter * s_statsCRead
Bool_t TStorageFactoryFile::ReadBuffer ( char *  buf,
Long64_t  pos,
Int_t  len 
)
virtual

Definition at line 223 of file TStorageFactoryFile.cc.

References ReadBuffer().

224 {
225  // This function needs to be optimized to minimize seeks.
226  // See TFile::ReadBuffer(char *buf, Long64_t pos, Int_t len) in ROOT 5.27.06.
227  Seek(pos);
228  return ReadBuffer(buf, len);
229 }
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Bool_t TStorageFactoryFile::ReadBufferAsync ( Long64_t  off,
Int_t  len 
)
virtual

Definition at line 299 of file TStorageFactoryFile.cc.

References StorageFactory::CACHE_HINT_APPLICATION, StorageFactory::CACHE_HINT_STORAGE, StorageFactory::cacheHint(), f, StorageFactory::get(), o2o::iov, Storage::prefetch(), PREFETCH_PROBE_LENGTH, s_statsARead, storage_, storageCounter(), and StorageAccount::Stamp::tick().

300 {
301  // Check that it's valid to access this file.
302  if (IsZombie())
303  {
304  Error("ReadBufferAsync", "Cannot read from a zombie file");
305  return kTRUE;
306  }
307 
308  if (! IsOpen())
309  {
310  Error("ReadBufferAsync", "Cannot read from a file that is not open");
311  return kTRUE;
312  }
313 
315 
316  // If asynchronous reading is disabled, bail out now, regardless
317  // whether the underlying storage supports prefetching. If it is
318  // forced on, pretend it's on, even if the storage doesn't support
319  // it, as this turns off the caching in ROOT's side.
321 
322  // Verify that we never using async reads in app-only mode
324  return kTRUE;
325 
326  // Let the I/O method indicate if it can do client-side prefetch.
327  // If it does, then for example TTreeCache will drop its own cache
328  // and will use the client-side cache of the actual I/O layer.
329  // If len is zero ROOT is probing for prefetch support.
330  if (len) {
331  // FIXME: Synchronise caching.
332  // storage_->caching(true, -1, 0);
333  ;
334  }
335 
336  IOPosBuffer iov(off, (void *) 0, len ? len : PREFETCH_PROBE_LENGTH);
337  if (storage_->prefetch(&iov, 1))
338  {
339  stats.tick(len);
340  return kFALSE;
341  }
342 
343  // Always ask ROOT to use async reads in storage-only mode,
344  // regardless of whether the storage system supports it.
346  return kFALSE;
347 
348  // Prefetching not available right now.
349  return kTRUE;
350 }
CacheHint cacheHint(void) const
#define PREFETCH_PROBE_LENGTH
Definition: Storage.h:18
static StorageFactory * get(void)
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsARead
tuple iov
Definition: o2o.py:307
double f[11][100]
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
Definition: Storage.cc:119
Bool_t TStorageFactoryFile::ReadBuffers ( char *  buf,
Long64_t *  pos,
Int_t *  len,
Int_t  nbuf 
)
virtual

Definition at line 420 of file TStorageFactoryFile.cc.

References i, o2o::iov, Storage::prefetch(), ReadBuffersSync(), s_statsARead, storage_, storageCounter(), summarizeEdmComparisonLogfiles::success, StorageAccount::Stamp::tick(), and pileupDistInMC::total.

421 {
422  // Check that it's valid to access this file.
423  if (IsZombie())
424  {
425  Error("ReadBuffers", "Cannot read from a zombie file");
426  return kTRUE;
427  }
428 
429  if (! IsOpen())
430  {
431  Error("ReadBuffers", "Cannot read from a file that is not open");
432  return kTRUE;
433  }
434 
435  // For synchronous reads, we have special logic to optimize the I/O requests
436  // from ROOT before handing it to the storage.
437  if (buf)
438  {
439  return ReadBuffersSync(buf, pos, len, nbuf);
440  }
441  // For an async read, we assume the storage system is smart enough to do the
442  // optimization itself.
443 
444  // Read from underlying storage.
445  void* const nobuf = 0;
446  Int_t total = 0;
447  std::vector<IOPosBuffer> iov;
448  iov.reserve(nbuf);
449  for (Int_t i = 0; i < nbuf; ++i)
450  {
451  iov.push_back(IOPosBuffer(pos[i], nobuf, len[i]));
452  total += len[i];
453  }
454 
455  // Null buffer means asynchronous reads into I/O system's cache.
456  bool success;
457  StorageAccount::Stamp astats(storageCounter(s_statsARead, "readAsync"));
458  // Synchronise low-level cache with the supposed cache in TFile.
459  // storage_->caching(true, -1, 0);
460  success = storage_->prefetch(&iov[0], nbuf);
461  astats.tick(total);
462 
463  // If it didn't suceeed, pass down to the base class.
464  return success ? kFALSE : TFile::ReadBuffers(buf, pos, len, nbuf);
465 }
int i
Definition: DBlmapReader.cc:9
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsARead
tuple iov
Definition: o2o.py:307
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
Definition: Storage.cc:119
Bool_t ReadBuffersSync(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Bool_t TStorageFactoryFile::ReadBuffersSync ( char *  buf,
Long64_t *  pos,
Int_t *  len,
Int_t  nbuf 
)
private

Most storage systems are not prepared for the onslaught of small reads that ROOT will perform, even if they implement a vectored read interface.

Typically, on the server side, the loop is unrolled and the reads are issued sequentially - giving the OS no hint that you're about to read a very close-by byte in the near future. Normally, OS read-ahead takes care of such situations; because the storage server has so many clients, and ROOT reads look random to the OS, the read-ahead becomes disabled.

Hence, this function will repack the application-layer request into an optimized storage-layer request. The resulting request to the storage layer typically has a slightly larger number of bytes, but far less individual reads.

On average, the server's disks see a smaller number of overall reads, the number of bytes transferred over the network increases modestly (around 10%), and the single application request becomes one-to-two I/O transactions. A clear win for all cases except high-latency WAN.

Definition at line 353 of file TStorageFactoryFile.cc.

References ReadRepacker::bufferUsed(), i, ReadRepacker::iov(), o2o::iov, ReadRepacker::pack(), pos, Storage::readv(), ReadRepacker::realBytesProcessed(), query::result, s_statsXRead, storage_, storageCounter(), StorageAccount::Stamp::tick(), and ReadRepacker::unpack().

Referenced by ReadBuffers().

354 {
375  Int_t remaining = nbuf; // Number of read requests left to process.
376  Int_t pack_count; // Number of read requests processed by this iteration.
377 
378  IOSize remaining_buffer_size=0;
379  // Calculate the remaining buffer size for the ROOT-owned buffer by adding
380  // the size of the various requests.
381  for (Int_t i=0; i<nbuf; i++) remaining_buffer_size+=len[i];
382 
383  char *current_buffer = buf;
384  Long64_t *current_pos = pos;
385  Int_t *current_len = len;
386 
387  ReadRepacker repacker;
388 
389  while (remaining > 0) {
390 
391  pack_count = repacker.pack(static_cast<long long int *>(current_pos), current_len, remaining, current_buffer, remaining_buffer_size);
392 
393  int real_bytes_processed = repacker.realBytesProcessed();
394  IOSize io_buffer_used = repacker.bufferUsed();
395 
396  // Issue readv, then unpack buffers.
397  StorageAccount::Stamp xstats(storageCounter(s_statsXRead, "readActual"));
398  std::vector<IOPosBuffer> &iov = repacker.iov();
399  IOSize result = storage_->readv(&iov[0], iov.size());
400  if (result != io_buffer_used) {
401  return kTRUE;
402  }
403  xstats.tick(io_buffer_used);
404  repacker.unpack(current_buffer);
405 
406  // Update the location of the unused part of the input buffer.
407  remaining_buffer_size -= real_bytes_processed;
408  current_buffer += real_bytes_processed;
409 
410  current_pos += pack_count;
411  current_len += pack_count;
412  remaining -= pack_count;
413 
414  }
415  assert(remaining_buffer_size == 0);
416  return kFALSE;
417 }
int i
Definition: DBlmapReader.cc:9
virtual IOSize readv(IOPosBuffer *into, IOSize buffers)
Definition: Storage.cc:31
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
IOSize realBytesProcessed() const
Definition: ReadRepacker.h:52
tuple iov
Definition: o2o.py:307
tuple result
Definition: query.py:137
int pack(long long int *pos, int *len, int nbuf, char *buf, IOSize buffer_size)
Definition: ReadRepacker.cc:22
void unpack(char *buf)
static StorageAccount::Counter * s_statsXRead
IOSize bufferUsed() const
Definition: ReadRepacker.h:49
std::vector< IOPosBuffer > & iov()
Definition: ReadRepacker.h:47
size_t IOSize
Definition: IOTypes.h:14
void TStorageFactoryFile::ResetErrno ( void  ) const

Definition at line 616 of file TStorageFactoryFile.cc.

617 {
618  TSystem::ResetErrno();
619 }
Int_t TStorageFactoryFile::SysClose ( Int_t  fd)
protectedvirtual

Definition at line 564 of file TStorageFactoryFile.cc.

References Storage::close(), s_statsClose, storage_, storageCounter(), and StorageAccount::Stamp::tick().

565 {
567 
568  if (storage_)
569  {
570  storage_->close();
571  delete storage_;
572  storage_ = 0;
573  }
574 
575  stats.tick();
576  return 0;
577 }
static StorageAccount::Counter * s_statsClose
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
virtual void close(void)
Definition: Storage.cc:128
Int_t TStorageFactoryFile::SysOpen ( const char *  pathname,
Int_t  flags,
UInt_t  mode 
)
protectedvirtual

Definition at line 531 of file TStorageFactoryFile.cc.

References Storage::close(), edm::hlt::Exception, StorageFactory::get(), O_NONBLOCK, IOFlags::OpenAppend, IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenNonBlock, IOFlags::OpenRead, IOFlags::OpenTruncate, IOFlags::OpenWrite, s_statsOpen, storage_, storageCounter(), and StorageAccount::Stamp::tick().

532 {
534 
535  if (storage_)
536  {
537  storage_->close();
538  delete storage_;
539  storage_ = 0;
540  }
541 
542  int openFlags = IOFlags::OpenRead;
543  if (flags & O_WRONLY) openFlags = IOFlags::OpenWrite;
544  else if (flags & O_RDWR) openFlags |= IOFlags::OpenWrite;
545  if (flags & O_CREAT) openFlags |= IOFlags::OpenCreate;
546  if (flags & O_APPEND) openFlags |= IOFlags::OpenAppend;
547  if (flags & O_EXCL) openFlags |= IOFlags::OpenExclusive;
548  if (flags & O_TRUNC) openFlags |= IOFlags::OpenTruncate;
549  if (flags & O_NONBLOCK) openFlags |= IOFlags::OpenNonBlock;
550 
551  if (! (storage_ = StorageFactory::get()->open(pathname, openFlags)))
552  {
553  MakeZombie();
554  gDirectory = gROOT;
555  throw cms::Exception("TStorageFactoryFile::SysOpen()")
556  << "Cannot open file '" << pathname << "'";
557  }
558 
559  stats.tick();
560  return 0;
561 }
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
static StorageFactory * get(void)
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
virtual void close(void)
Definition: Storage.cc:128
#define O_NONBLOCK
Definition: SysFile.h:21
static StorageAccount::Counter * s_statsOpen
Long64_t TStorageFactoryFile::SysSeek ( Int_t  fd,
Long64_t  offset,
Int_t  whence 
)
protectedvirtual

Definition at line 580 of file TStorageFactoryFile.cc.

References Storage::CURRENT, Storage::END, evf::evtn::offset(), Storage::position(), s_statsSeek, Storage::SET, storage_, storageCounter(), and StorageAccount::Stamp::tick().

581 {
583  Storage::Relative rel = (whence == SEEK_SET ? Storage::SET
584  : whence == SEEK_CUR ? Storage::CURRENT
585  : Storage::END);
586 
587  offset = storage_->position(offset, rel);
588  stats.tick();
589  return offset;
590 }
Relative
Definition: Storage.h:23
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
virtual IOOffset position(void) const
Definition: Storage.cc:95
unsigned int offset(bool)
static StorageAccount::Counter * s_statsSeek
Int_t TStorageFactoryFile::SysStat ( Int_t  fd,
Long_t *  id,
Long64_t *  size,
Long_t *  flags,
Long_t *  modtime 
)
protectedvirtual

Definition at line 602 of file TStorageFactoryFile.cc.

References s_statsStat, Storage::size(), storage_, storageCounter(), and StorageAccount::Stamp::tick().

604 {
606  // FIXME: Most of this is unsupported or makes no sense with Storage
607  *id = ::Hash(fRealName);
608  *size = storage_->size();
609  *flags = 0;
610  *modtime = 0;
611  stats.tick();
612  return 0;
613 }
static StorageAccount::Counter * s_statsStat
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
virtual IOOffset size(void) const
Definition: Storage.cc:102
tuple size
Write out results.
Int_t TStorageFactoryFile::SysSync ( Int_t  fd)
protectedvirtual

Definition at line 593 of file TStorageFactoryFile.cc.

References Storage::flush(), s_statsFlush, storage_, storageCounter(), and StorageAccount::Stamp::tick().

594 {
596  storage_->flush();
597  stats.tick();
598  return 0;
599 }
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
virtual void flush(void)
Definition: Storage.cc:124
static StorageAccount::Counter * s_statsFlush
Bool_t TStorageFactoryFile::WriteBuffer ( const char *  buf,
Int_t  len 
)
virtual

Definition at line 468 of file TStorageFactoryFile.cc.

References n, s_statsCWrite, s_statsWrite, s_statsXWrite, storage_, storageCounter(), StorageAccount::Stamp::tick(), and IOOutput::xwrite().

469 {
470  // Check that it's valid to access this file.
471  if (IsZombie())
472  {
473  Error("WriteBuffer", "Cannot write to a zombie file");
474  return kTRUE;
475  }
476 
477  if (! IsOpen())
478  {
479  Error("WriteBuffer", "Cannot write to a file that is not open");
480  return kTRUE;
481  }
482 
483  if (! fWritable)
484  {
485  Error("WriteBuffer", "File is not writable");
486  return kTRUE;
487  }
488 
490  StorageAccount::Stamp cstats(storageCounter(s_statsCWrite, "writeViaCache"));
491 
492  // Try first writing via a cache, and if that's not possible, directly.
493  Int_t st;
494  switch ((st = WriteBufferViaCache(buf, len)))
495  {
496  case 0:
497  // Actual write.
498  {
499  StorageAccount::Stamp xstats(storageCounter(s_statsXWrite, "writeActual"));
500  IOSize n = storage_->xwrite(buf, len);
501  xstats.tick(n);
502  stats.tick(n);
503 
504  // FIXME: What if it's a short write?
505  return n > 0 ? kFALSE : kTRUE;
506  }
507 
508  case 1:
509  cstats.tick(len);
510  stats.tick(len);
511  return kFALSE;
512 
513  case 2:
514  default:
515  Error("WriteBuffer", "Error writing to cache");
516  return kTRUE;
517  }
518 }
IOSize xwrite(const void *from, IOSize n)
Definition: IOOutput.cc:176
static StorageAccount::Counter * s_statsWrite
static StorageAccount::Counter * s_statsXWrite
static StorageAccount::Counter & storageCounter(StorageAccount::Counter *&c, const char *label)
static StorageAccount::Counter * s_statsCWrite
size_t IOSize
Definition: IOTypes.h:14

Member Data Documentation

Storage* TStorageFactoryFile::storage_
private