/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWStorage/StorageFactory/src/LocalCacheFile.cc
179 строк
5 KB
Chris Jones
Move Utilities/StorageFactory to FWStorage/StorageFactory
10 дек 2025, 18:12
10 дек 2025, 18:12
852ff34
Код
Авторство
О чём код?
#include "FWStorage/StorageFactory/interface/LocalCacheFile.h" #include "FWCore/Utilities/interface/EDMException.h" #include <utility> #include <iostream> #include <cstdlib> #include <cstring> #include <unistd.h> #include <sys/mman.h> #include <cerrno> #include <sstream> using namespace edm::storage; static constexpr IOOffset CHUNK_SIZE = 128 * 1024 * 1024; static void nowrite(const std::string &why) { cms::Exception ex("LocalCacheFile"); ex << "Cannot change file but operation '" << why << "' was called"; ex.addContext("LocalCacheFile::" + why + "()"); throw ex; } LocalCacheFile::LocalCacheFile(std::unique_ptr<Storage> base, const std::string &tmpdir /* = "" */) : image_(base->size()), file_(), storage_(std::move(base)), closedFile_(false), cacheCount_(0), cacheTotal_((image_ + CHUNK_SIZE - 1) / CHUNK_SIZE) { present_.resize(cacheTotal_, 0); std::string pattern(tmpdir); if (pattern.empty()) if (char *p = std::getenv("TMPDIR")) pattern = p; if (pattern.empty()) pattern = "/tmp"; pattern += "/cmssw-shadow-XXXXXX"; std::vector<char> temp(pattern.c_str(), pattern.c_str() + pattern.size() + 1); int fd = mkstemp(&temp[0]); if (fd == -1) { edm::Exception ex(edm::errors::FileOpenError); ex << "Cannot create temporary file '" << pattern << "': " << strerror(errno) << " (error " << errno << ")"; ex.addContext("LocalCacheFile::LocalCacheFile"); } unlink(&temp[0]); file_ = std::make_unique<File>(fd); file_->resize(image_); } LocalCacheFile::~LocalCacheFile(void) {} void LocalCacheFile::cache(IOOffset start, IOOffset end) { start = (start / CHUNK_SIZE) * CHUNK_SIZE; end = std::min(end, image_); IOSize nread = 0; IOSize index = start / CHUNK_SIZE; while (start < end) { IOSize len = std::min(image_ - start, CHUNK_SIZE); if (!present_[index]) { void *window = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start); if (window == MAP_FAILED) { edm::Exception ex(edm::errors::FileReadError); ex << "Unable to map a window of local cache file: " << strerror(errno) << " (error " << errno << ")"; ex.addContext("LocalCacheFile::cache()"); throw ex; } try { nread = storage_->read(window, len, start); } catch (cms::Exception &e) { munmap(window, len); std::ostringstream ost; ost << "Unable to cache " << len << " byte file segment at " << start << ": "; edm::Exception ex(edm::errors::FileReadError, ost.str(), e); ex.addContext("LocalCacheFile::cache()"); throw ex; } munmap(window, len); if (nread != len) { edm::Exception ex(edm::errors::FileReadError); ex << "Unable to cache " << len << " byte file segment at " << start << ": got only " << nread << " bytes back"; ex.addContext("LocalCacheFile::cache()"); throw ex; } present_[index] = 1; ++cacheCount_; if (cacheCount_ == cacheTotal_) { storage_->close(); closedFile_ = true; } } start += len; ++index; } } IOSize LocalCacheFile::read(void *into, IOSize n) { IOOffset here = file_->position(); cache(here, here + n); return file_->read(into, n); } IOSize LocalCacheFile::read(void *into, IOSize n, IOOffset pos) { cache(pos, pos + n); return file_->read(into, n, pos); } IOSize LocalCacheFile::readv(IOBuffer *into, IOSize n) { IOOffset start = file_->position(); IOOffset end = start; for (IOSize i = 0; i < n; ++i) end += into[i].size(); cache(start, end); return file_->readv(into, n); } IOSize LocalCacheFile::readv(IOPosBuffer *into, IOSize n) { for (IOSize i = 0; i < n; ++i) { IOOffset start = into[i].offset(); IOOffset end = start + into[i].size(); cache(start, end); } return storage_->readv(into, n); } IOSize LocalCacheFile::write(const void * /*from*/, IOSize) { nowrite("write"); return 0; } IOSize LocalCacheFile::write(const void * /*from*/, IOSize, IOOffset /*pos*/) { nowrite("write"); return 0; } IOSize LocalCacheFile::writev(const IOBuffer * /*from*/, IOSize) { nowrite("writev"); return 0; } IOSize LocalCacheFile::writev(const IOPosBuffer * /*from*/, IOSize) { nowrite("writev"); return 0; } IOOffset LocalCacheFile::position(IOOffset offset, Relative whence) { return file_->position(offset, whence); } void LocalCacheFile::resize(IOOffset /*size*/) { nowrite("resize"); } void LocalCacheFile::flush(void) { nowrite("flush"); } void LocalCacheFile::close(void) { if (!closedFile_) { storage_->close(); } file_->close(); } bool LocalCacheFile::prefetch(const IOPosBuffer *what, IOSize n) { for (IOSize i = 0; i < n; ++i) { IOOffset start = what[i].offset(); IOOffset end = start + what[i].size(); cache(start, end); } return file_->prefetch(what, n); }