From 9122bc3385108dedefc77105267693c7bdcbe848 Mon Sep 17 00:00:00 2001 From: Alja Mrak-Tadel Date: Tue, 24 May 2016 11:26:33 -0700 Subject: [PATCH] FileBlockMode: recycle File object during delayed destruction. --- src/XrdFileCache/XrdFileCache.cc | 46 ++++++++++++-------- src/XrdFileCache/XrdFileCache.hh | 8 +++- src/XrdFileCache/XrdFileCacheFile.hh | 2 + src/XrdFileCache/XrdFileCacheIO.hh | 2 +- src/XrdFileCache/XrdFileCacheIOEntireFile.cc | 10 +---- src/XrdFileCache/XrdFileCacheIOFileBlock.cc | 43 +++++++++++++----- src/XrdFileCache/XrdFileCacheIOFileBlock.hh | 3 +- 7 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/XrdFileCache/XrdFileCache.cc b/src/XrdFileCache/XrdFileCache.cc index 8f80c92c207..4fbaf823563 100644 --- a/src/XrdFileCache/XrdFileCache.cc +++ b/src/XrdFileCache/XrdFileCache.cc @@ -169,19 +169,24 @@ int Cache::isAttached() void Cache::Detach(XrdOucCacheIO* io) { clLog()->Info(XrdCl::AppMsg, "Cache::Detach() %s", io->Path()); - std::map::iterator it = m_active.begin(); - while (it != m_active.end() ) + + // Cache owns File objects + XrdSysMutexHelper lock(&m_active_mutex); + std::vector::iterator it = m_active.begin(); + while ( it != m_active.end() ) { - if (it->second.io == io) { - m_active.erase(it++); + if (it->io == io) { + it->io->RelinquishFile(it->file); + delete it->file; + m_active.erase(it); } - else { + else ++it; - } } delete io; } + //______________________________________________________________________________ bool Cache::HaveFreeWritingSlots() @@ -276,26 +281,31 @@ Cache::RAMBlockReleased() m_RAMblocks_used--; } +void +Cache::AddActive(IO* io, File* file) +{ + XrdSysMutexHelper lock(&m_active_mutex); + m_active.push_back(DiskNetIO(io, file)); +} + //============================================================================== //======================= File relinquish at process of dying =================== //====================================================================== -File* Cache::GetFileForLocalPath(std::string path, IO* io) +File* Cache::GetFileWithLocalPath(std::string path, IO* iIo) { - typedef std::map ActiveMap_t; - ActiveMap_t::iterator it = m_active.find(path); - if (it == m_active.end()) + XrdSysMutexHelper lock(&m_active_mutex); + for ( std::vector::iterator it = m_active.begin(); it != m_active.end(); ++it) { - return 0; - } - else { - File* file = it->second.file; - it->second.io->RelinquishFile(file); - return file; + if (!strcmp(path.c_str(), it->file->lPath())) + { + it->io->RelinquishFile(it->file); + it->io = iIo; + return it->file; + } } + return 0; } - - //============================================================================== //======================= PREFETCH =================================== //============================================================================== diff --git a/src/XrdFileCache/XrdFileCache.hh b/src/XrdFileCache/XrdFileCache.hh index 847fece3788..6cd289018ef 100644 --- a/src/XrdFileCache/XrdFileCache.hh +++ b/src/XrdFileCache/XrdFileCache.hh @@ -186,7 +186,9 @@ namespace XrdFileCache XrdSysError& GetSysError() { return m_log; } - File* GetFileForLocalPath(std::string, IO*); + File* GetFileWithLocalPath(std::string, IO* io); + + void AddActive(IO*, File*); private: bool ConfigParameters(std::string, XrdOucStream&); @@ -224,11 +226,13 @@ namespace XrdFileCache struct DiskNetIO { + DiskNetIO(IO* iIO, File* iFile): io(iIO), file(iFile){} IO* io; File* file; }; - std::map m_active; + std::vector m_active; + XrdSysMutex m_active_mutex; // prefetching typedef std::vector PrefetchList; diff --git a/src/XrdFileCache/XrdFileCacheFile.hh b/src/XrdFileCache/XrdFileCacheFile.hh index 3f000a1913e..79d74f02555 100644 --- a/src/XrdFileCache/XrdFileCacheFile.hh +++ b/src/XrdFileCache/XrdFileCacheFile.hh @@ -140,6 +140,7 @@ namespace XrdFileCache float m_prefetchScore; //cached int m_prefetchCurrentCnt; + public: //------------------------------------------------------------------------ //! Constructor. @@ -189,6 +190,7 @@ namespace XrdFileCache //! Log path const char* lPath() const; + std::string GetLocalPath(); private: bool overlap(int blk, // block to query long long blk_size, // diff --git a/src/XrdFileCache/XrdFileCacheIO.hh b/src/XrdFileCache/XrdFileCacheIO.hh index ff2fa866848..088e2858cd1 100644 --- a/src/XrdFileCache/XrdFileCacheIO.hh +++ b/src/XrdFileCache/XrdFileCacheIO.hh @@ -34,7 +34,7 @@ namespace XrdFileCache virtual void Update(XrdOucCacheIO2 &iocp) { m_io = &iocp; } - virtual void RelinquishFile(File*) {} + virtual void RelinquishFile(File*) = 0; protected: XrdCl::Log* clLog() const { return XrdCl::DefaultEnv::GetLog(); } diff --git a/src/XrdFileCache/XrdFileCacheIOEntireFile.cc b/src/XrdFileCache/XrdFileCacheIOEntireFile.cc index 68f84ce5c96..c2cf4c6d68f 100644 --- a/src/XrdFileCache/XrdFileCacheIOEntireFile.cc +++ b/src/XrdFileCache/XrdFileCacheIOEntireFile.cc @@ -44,11 +44,12 @@ IOEntireFile::IOEntireFile(XrdOucCacheIO2 *io, XrdOucCacheStats &stats, Cache & XrdCl::URL url(m_io->Path()); std::string fname = Cache::GetInstance().RefConfiguration().m_cache_dir + url.GetPath(); - if (!Cache::GetInstance().GetFileForLocalPath(fname, this)) + if (!(m_file = Cache::GetInstance().GetFileWithLocalPath(fname, this))) { struct stat st; Fstat(st); m_file = new File(io, fname, 0, st.st_size); + Cache::GetInstance().AddActive(this, m_file); } } @@ -56,7 +57,6 @@ IOEntireFile::IOEntireFile(XrdOucCacheIO2 *io, XrdOucCacheStats &stats, Cache & IOEntireFile::~IOEntireFile() { - delete m_localStat; } @@ -119,12 +119,6 @@ XrdOucCacheIO *IOEntireFile::Detach() { XrdOucCacheIO * io = m_io; - if (m_file) { - m_statsGlobal.Add(m_file->GetStats()); - delete m_file; - m_file = 0; - } - // This will delete us! m_cache.Detach(this); return io; diff --git a/src/XrdFileCache/XrdFileCacheIOFileBlock.cc b/src/XrdFileCache/XrdFileCacheIOFileBlock.cc index 30cdade0825..cdcc139e654 100644 --- a/src/XrdFileCache/XrdFileCacheIOFileBlock.cc +++ b/src/XrdFileCache/XrdFileCacheIOFileBlock.cc @@ -50,7 +50,6 @@ XrdOucCacheIO* IOFileBlock::Detach() for (std::map::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it) { m_statsGlobal.Add(it->second->GetStats()); - delete it->second; } m_cache.Detach(this); // This will delete us! @@ -58,10 +57,6 @@ XrdOucCacheIO* IOFileBlock::Detach() return io; } -int IOFileBlock::Fstat(struct stat &sbuff) -{ - return m_io->Fstat(sbuff); -} //______________________________________________________________________________ void IOFileBlock::GetBlockSizeFromPath() { @@ -101,21 +96,49 @@ File* IOFileBlock::newBlockFile(long long off, int blocksize) fname = ss.str(); clLog()->Debug(XrdCl::AppMsg, "FileBlock::FileBlock(), create XrdFileCacheFile. %s", m_io->Path()); - File* prefetch = new File(m_io, fname, off, blocksize); + + File* file; + if (!(file = Cache::GetInstance().GetFileWithLocalPath(fname, this))) + { + file = new File(m_io, fname, off, m_io->FSize()); + Cache::GetInstance().AddActive(this, file); + } + + return file; +} - return prefetch; +//______________________________________________________________________________ +void IOFileBlock::RelinquishFile(File* f) +{ + // called from Cache::Detach() or Cache::GetFileWithLocalPath() + // the object is in process of dying + + XrdSysMutexHelper lock(&m_mutex); + for (std::map::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it) + { + if (it->second == f) + { + m_blocks.erase(it++); + break; + } + else + { + ++it; + } + } } //______________________________________________________________________________ bool IOFileBlock::ioActive() { - bool res = false; + XrdSysMutexHelper lock(&m_mutex); + for (std::map::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it) { if (it->second->InitiateClose()) - res = true; + return true; } - return res; + return false; } //______________________________________________________________________________ diff --git a/src/XrdFileCache/XrdFileCacheIOFileBlock.hh b/src/XrdFileCache/XrdFileCacheIOFileBlock.hh index c5f05a5fb29..dda7ff88f4d 100644 --- a/src/XrdFileCache/XrdFileCacheIOFileBlock.hh +++ b/src/XrdFileCache/XrdFileCacheIOFileBlock.hh @@ -64,7 +64,8 @@ namespace XrdFileCache //! Called to check if destruction needs to be done in a separate task. virtual bool ioActive(); - virtual int Fstat(struct stat &sbuff); + virtual void RelinquishFile(File*); + private: long long m_blocksize; //!< size of file-block std::map m_blocks; //!< map of created blocks