#include <IOPool/TFileAdaptor/interface/TStorageFactoryFile.h>
Public Member Functions | |
ClassDef (TStorageFactoryFile, 0) | |
virtual Bool_t | ReadBuffer (char *buf, 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=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 | |
TStorageFactoryFile (void) | |
Private Attributes | |
Storage * | storage_ |
Definition at line 9 of file TStorageFactoryFile.h.
TStorageFactoryFile::TStorageFactoryFile | ( | const char * | name, | |
Option_t * | option = "" , |
|||
const char * | ftitle = "" , |
|||
Int_t | compress = 1 | |||
) |
Definition at line 100 of file TStorageFactoryFile.cc.
References Exception, StorageFactory::get(), IOFlags::OpenCreate, IOFlags::OpenRead, IOFlags::OpenTruncate, IOFlags::OpenWrite, SiStripLorentzAngle_cfi::read, storage_, storageCounter(), StorageAccount::Stamp::tick(), and update.
00104 : TFile(path, "NET", ftitle, compress), // Pass "NET" to prevent local access in base class 00105 storage_(0) 00106 { 00107 StorageAccount::Stamp stats(storageCounter(s_statsCtor, "construct")); 00108 00109 // Parse options; at the moment we only accept read! 00110 fOption = option; 00111 fOption.ToUpper(); 00112 00113 if (fOption == "NEW") 00114 fOption = "CREATE"; 00115 00116 Bool_t create = (fOption == "CREATE"); 00117 Bool_t recreate = (fOption == "RECREATE"); 00118 Bool_t update = (fOption == "UPDATE"); 00119 Bool_t read = (fOption == "READ"); 00120 00121 if (!create && !recreate && !update && !read) 00122 { 00123 read = true; 00124 fOption = "READ"; 00125 } 00126 00127 if (recreate) 00128 { 00129 if (!gSystem->AccessPathName(path, kFileExists)) 00130 gSystem->Unlink(path); 00131 00132 recreate = false; 00133 create = true; 00134 fOption = "CREATE"; 00135 } 00136 00137 if (update && gSystem->AccessPathName(path, kFileExists)) 00138 { 00139 update = kFALSE; 00140 create = kTRUE; 00141 } 00142 00143 int openFlags = IOFlags::OpenRead; 00144 if (!read) openFlags |= IOFlags::OpenWrite; 00145 if (create) openFlags |= IOFlags::OpenCreate; 00146 if (recreate) openFlags |= IOFlags::OpenCreate | IOFlags::OpenTruncate; 00147 00148 // Open storage 00149 if (! (storage_ = StorageFactory::get()->open(path, openFlags))) 00150 { 00151 MakeZombie(); 00152 gDirectory = gROOT; 00153 throw cms::Exception("TStorageFactoryFile::TStorageFactoryFile()") 00154 << "Cannot open file '" << path << "'"; 00155 } 00156 00157 fRealName = path; 00158 fD = 0; // sorry, meaningless 00159 fWritable = read ? kFALSE : kTRUE; 00160 00161 Init(create); 00162 00163 stats.tick(0); 00164 }
TStorageFactoryFile::~TStorageFactoryFile | ( | void | ) |
Definition at line 166 of file TStorageFactoryFile.cc.
References storage_.
00167 { 00168 Close(); 00169 delete storage_; 00170 }
TStorageFactoryFile::TStorageFactoryFile | ( | void | ) | [private] |
Definition at line 92 of file TStorageFactoryFile.cc.
References storageCounter(), and StorageAccount::Stamp::tick().
00093 : storage_(0) 00094 { 00095 StorageAccount::Stamp stats(storageCounter(s_statsCtor, "construct")); 00096 stats.tick(0); 00097 }
TStorageFactoryFile::ClassDef | ( | TStorageFactoryFile | , | |
0 | ||||
) |
Bool_t TStorageFactoryFile::ReadBuffer | ( | char * | buf, | |
Int_t | len | |||
) | [virtual] |
Definition at line 176 of file TStorageFactoryFile.cc.
References c, cond::Error, n, s_statsCPrefetch, s_statsCRead, s_statsRead, s_statsXRead, st, storage_, storageCounter(), StorageAccount::Stamp::tick(), and IOInput::xread().
00177 { 00178 // Check that it's valid to access this file. 00179 if (IsZombie()) 00180 { 00181 Error("ReadBuffer", "Cannot read from a zombie file"); 00182 return kTRUE; 00183 } 00184 00185 if (! IsOpen()) 00186 { 00187 Error("ReadBuffer", "Cannot read from a file that is not open"); 00188 return kTRUE; 00189 } 00190 00191 // Read specified byte range from the storage. Returns kTRUE in 00192 // case of error. Note that ROOT uses this function recursively 00193 // to fill the cache; we use a flag to make sure our accounting 00194 // is reflected in a comprehensible manner. The "read" counter 00195 // will include both, "readc" indicates how much read from the 00196 // cache, "readu" indicates how much we failed to read from the 00197 // cache (excluding those recursive reads), and "readx" counts 00198 // the amount actually passed to read from the storage object. 00199 StorageAccount::Stamp stats(storageCounter(s_statsRead, "read")); 00200 00201 // If we have a cache, read from there first. This returns 0 00202 // if the block hasn't been prefetched, 1 if it was in cache, 00203 // and 2 if there was an error. 00204 if (TFileCacheRead *c = GetCacheRead()) 00205 { 00206 Long64_t here = GetRelOffset(); 00207 Bool_t async = c->IsAsyncReading(); 00208 00209 StorageAccount::Stamp cstats(async 00210 ? storageCounter(s_statsCPrefetch, "read-prefetch-to-cache") 00211 : storageCounter(s_statsCRead, "read-via-cache")); 00212 00213 Int_t st = ReadBufferViaCache(async ? 0 : buf, len); 00214 00215 if (st == 2) 00216 return kTRUE; 00217 00218 if (st == 1) 00219 if (async) 00220 { 00221 cstats.tick(len); 00222 Seek(here); 00223 } 00224 else 00225 { 00226 cstats.tick(len); 00227 stats.tick(len); 00228 return kFALSE; 00229 } 00230 } 00231 00232 // FIXME: Re-enable read-ahead if the data wasn't in cache. 00233 // if (! st) storage_->caching(true, -1, s_readahead); 00234 00235 // A real read 00236 StorageAccount::Stamp xstats(storageCounter(s_statsXRead, "read-actual")); 00237 IOSize n = storage_->xread(buf, len); 00238 xstats.tick(n); 00239 stats.tick(n); 00240 return n ? kFALSE : kTRUE; 00241 }
Bool_t TStorageFactoryFile::ReadBufferAsync | ( | Long64_t | off, | |
Int_t | len | |||
) | [virtual] |
Definition at line 244 of file TStorageFactoryFile.cc.
References StorageFactory::CACHE_HINT_APPLICATION, StorageFactory::CACHE_HINT_STORAGE, StorageFactory::cacheHint(), cond::Error, f, StorageFactory::get(), Storage::prefetch(), s_statsARead, storage_, storageCounter(), and StorageAccount::Stamp::tick().
00245 { 00246 // Check that it's valid to access this file. 00247 if (IsZombie()) 00248 { 00249 Error("ReadBufferAsync", "Cannot read from a zombie file"); 00250 return kTRUE; 00251 } 00252 00253 if (! IsOpen()) 00254 { 00255 Error("ReadBufferAsync", "Cannot read from a file that is not open"); 00256 return kTRUE; 00257 } 00258 00259 StorageAccount::Stamp stats(storageCounter(s_statsARead, "read-async")); 00260 00261 // If asynchronous reading is disabled, bail out now, regardless 00262 // whether the underlying storage supports prefetching. If it is 00263 // forced on, pretend it's on, even if the storage doesn't support 00264 // it, as this turns off the caching in ROOT's side. 00265 StorageFactory *f = StorageFactory::get(); 00266 switch (f->cacheHint()) 00267 { 00268 case StorageFactory::CACHE_HINT_APPLICATION: 00269 return kTRUE; 00270 case StorageFactory::CACHE_HINT_STORAGE: 00271 return kFALSE; 00272 default: 00273 break; 00274 } 00275 00276 // Let the I/O method indicate if it can do client-side prefetch. 00277 // If it does, then for example TTreeCache will drop its own cache 00278 // and will use the client-side cache of the actual I/O layer. 00279 // If len is zero ROOT is probing for prefetch support. 00280 if (len) 00281 // FIXME: Synchronise caching. 00282 // storage_->caching(true, -1, 0); 00283 ; 00284 00285 IOPosBuffer iov(off, (void *) 0, len ? len : 4096); 00286 if (storage_->prefetch(&iov, 1)) 00287 { 00288 stats.tick(len); 00289 return kFALSE; 00290 } 00291 00292 // Prefetching not available right now. 00293 return kTRUE; 00294 }
Bool_t TStorageFactoryFile::ReadBuffers | ( | char * | buf, | |
Long64_t * | pos, | |||
Int_t * | len, | |||
Int_t | nbuf | |||
) | [virtual] |
Definition at line 297 of file TStorageFactoryFile.cc.
References cond::Error, i, n, Storage::prefetch(), Storage::readv(), s_statsARead, s_statsVRead, storage_, storageCounter(), and StorageAccount::Stamp::tick().
00298 { 00299 // Check that it's valid to access this file. 00300 if (IsZombie()) 00301 { 00302 Error("ReadBuffers", "Cannot read from a zombie file"); 00303 return kTRUE; 00304 } 00305 00306 if (! IsOpen()) 00307 { 00308 Error("ReadBuffers", "Cannot read from a file that is not open"); 00309 return kTRUE; 00310 } 00311 00312 // Read from underlying storage. 00313 Int_t total = 0; 00314 std::vector<IOPosBuffer> iov; 00315 iov.reserve(nbuf); 00316 for (Int_t i = 0; i < nbuf; ++i) 00317 { 00318 iov.push_back(IOPosBuffer(pos[i], buf ? buf + total : 0, len[i])); 00319 total += len[i]; 00320 } 00321 00322 // Null buffer means asynchronous reads into I/O system's cache. 00323 bool success; 00324 if (buf) 00325 { 00326 StorageAccount::Stamp stats(storageCounter(s_statsVRead, "readv-actual")); 00327 IOSize n = storage_->readv(&iov[0], nbuf); 00328 success = (n > 0); // FIXME: what if it's short!? 00329 stats.tick(n); 00330 } 00331 else 00332 { 00333 StorageAccount::Stamp astats(storageCounter(s_statsARead, "read-async")); 00334 // Synchronise low-level cache with the supposed cache in TFile. 00335 // storage_->caching(true, -1, 0); 00336 success = storage_->prefetch(&iov[0], nbuf); 00337 astats.tick(total); 00338 } 00339 00340 // If it didn't suceeed, pass down to the base class. 00341 return success ? kFALSE : TFile::ReadBuffers(buf, pos, len, nbuf); 00342 }
Int_t TStorageFactoryFile::SysClose | ( | Int_t | fd | ) | [protected, virtual] |
Definition at line 441 of file TStorageFactoryFile.cc.
References Storage::close(), s_statsClose, storage_, storageCounter(), and StorageAccount::Stamp::tick().
00442 { 00443 StorageAccount::Stamp stats(storageCounter(s_statsClose, "close")); 00444 00445 if (storage_) 00446 { 00447 storage_->close(); 00448 delete storage_; 00449 storage_ = 0; 00450 } 00451 00452 stats.tick(); 00453 return 0; 00454 }
Int_t TStorageFactoryFile::SysOpen | ( | const char * | pathname, | |
Int_t | flags, | |||
UInt_t | mode | |||
) | [protected, virtual] |
Definition at line 408 of file TStorageFactoryFile.cc.
References Storage::close(), 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().
00409 { 00410 StorageAccount::Stamp stats(storageCounter(s_statsOpen, "open")); 00411 00412 if (storage_) 00413 { 00414 storage_->close(); 00415 delete storage_; 00416 storage_ = 0; 00417 } 00418 00419 int openFlags = IOFlags::OpenRead; 00420 if (flags & O_WRONLY) openFlags = IOFlags::OpenWrite; 00421 else if (flags & O_RDWR) openFlags |= IOFlags::OpenWrite; 00422 if (flags & O_CREAT) openFlags |= IOFlags::OpenCreate; 00423 if (flags & O_APPEND) openFlags |= IOFlags::OpenAppend; 00424 if (flags & O_EXCL) openFlags |= IOFlags::OpenExclusive; 00425 if (flags & O_TRUNC) openFlags |= IOFlags::OpenTruncate; 00426 if (flags & O_NONBLOCK) openFlags |= IOFlags::OpenNonBlock; 00427 00428 if (! (storage_ = StorageFactory::get()->open(pathname, openFlags))) 00429 { 00430 MakeZombie(); 00431 gDirectory = gROOT; 00432 throw cms::Exception("TStorageFactoryFile::SysOpen()") 00433 << "Cannot open file '" << pathname << "'"; 00434 } 00435 00436 stats.tick(); 00437 return 0; 00438 }
Long64_t TStorageFactoryFile::SysSeek | ( | Int_t | fd, | |
Long64_t | offset, | |||
Int_t | whence | |||
) | [protected, virtual] |
Definition at line 457 of file TStorageFactoryFile.cc.
References Storage::CURRENT, Storage::END, Storage::position(), s_statsSeek, Storage::SET, storage_, storageCounter(), and StorageAccount::Stamp::tick().
00458 { 00459 StorageAccount::Stamp stats(storageCounter(s_statsSeek, "seek")); 00460 Storage::Relative rel = (whence == SEEK_SET ? Storage::SET 00461 : whence == SEEK_CUR ? Storage::CURRENT 00462 : Storage::END); 00463 00464 offset = storage_->position(offset, rel); 00465 stats.tick(); 00466 return offset; 00467 }
Int_t TStorageFactoryFile::SysStat | ( | Int_t | fd, | |
Long_t * | id, | |||
Long64_t * | size, | |||
Long_t * | flags, | |||
Long_t * | modtime | |||
) | [protected, virtual] |
Definition at line 479 of file TStorageFactoryFile.cc.
References s_statsStat, Storage::size(), storage_, storageCounter(), and StorageAccount::Stamp::tick().
00481 { 00482 StorageAccount::Stamp stats(storageCounter(s_statsStat, "stat")); 00483 // FIXME: Most of this is unsupported or makes no sense with Storage 00484 *id = ::Hash(fRealName); 00485 *size = storage_->size(); 00486 *flags = 0; 00487 *modtime = 0; 00488 stats.tick(); 00489 return 0; 00490 }
Int_t TStorageFactoryFile::SysSync | ( | Int_t | fd | ) | [protected, virtual] |
Definition at line 470 of file TStorageFactoryFile.cc.
References Storage::flush(), s_statsFlush, storage_, storageCounter(), and StorageAccount::Stamp::tick().
00471 { 00472 StorageAccount::Stamp stats(storageCounter(s_statsFlush, "flush")); 00473 storage_->flush(); 00474 stats.tick(); 00475 return 0; 00476 }
Bool_t TStorageFactoryFile::WriteBuffer | ( | const char * | buf, | |
Int_t | len | |||
) | [virtual] |
Definition at line 345 of file TStorageFactoryFile.cc.
References cond::Error, n, s_statsCWrite, s_statsWrite, s_statsXWrite, st, storage_, storageCounter(), StorageAccount::Stamp::tick(), and IOOutput::xwrite().
00346 { 00347 // Check that it's valid to access this file. 00348 if (IsZombie()) 00349 { 00350 Error("WriteBuffer", "Cannot write to a zombie file"); 00351 return kTRUE; 00352 } 00353 00354 if (! IsOpen()) 00355 { 00356 Error("WriteBuffer", "Cannot write to a file that is not open"); 00357 return kTRUE; 00358 } 00359 00360 if (! fWritable) 00361 { 00362 Error("WriteBuffer", "File is not writable"); 00363 return kTRUE; 00364 } 00365 00366 StorageAccount::Stamp stats(storageCounter(s_statsWrite, "write")); 00367 StorageAccount::Stamp cstats(storageCounter(s_statsCWrite, "write-via-cache")); 00368 00369 // Try first writing via a cache, and if that's not possible, directly. 00370 Int_t st; 00371 switch ((st = WriteBufferViaCache(buf, len))) 00372 { 00373 case 0: 00374 // Actual write. 00375 { 00376 StorageAccount::Stamp xstats(storageCounter(s_statsXWrite, "write-actual")); 00377 IOSize n = storage_->xwrite(buf, len); 00378 xstats.tick(n); 00379 stats.tick(n); 00380 00381 // FIXME: What if it's a short write? 00382 return n > 0 ? kFALSE : kTRUE; 00383 } 00384 00385 case 1: 00386 cstats.tick(len); 00387 stats.tick(len); 00388 return kFALSE; 00389 00390 case 2: 00391 default: 00392 Error("WriteBuffer", "Error writing to cache"); 00393 return kTRUE; 00394 } 00395 }
Storage* TStorageFactoryFile::storage_ [private] |
Definition at line 35 of file TStorageFactoryFile.h.
Referenced by ReadBuffer(), ReadBufferAsync(), ReadBuffers(), SysClose(), SysOpen(), SysSeek(), SysStat(), SysSync(), TStorageFactoryFile(), WriteBuffer(), and ~TStorageFactoryFile().