Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
LRUFileManager.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2021 Euclid Science Ground Segment
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 3.0 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
21#include <sys/resource.h>
22
23namespace Euclid {
24namespace FilePool {
25
26LRUFileManager::LRUFileManager(unsigned limit) : m_limit(limit) {
27 if (m_limit == 0) {
28 struct rlimit rlim;
29 getrlimit(RLIMIT_NOFILE, &rlim);
30 assert(rlim.rlim_cur > 3);
31 m_limit = rlim.rlim_cur - 3; // Account for stdout, stderr and stdin
32 }
33}
34
38
40 // Only one thread can be making space
43
44 while (m_files.size() >= m_limit) {
45 bool closed = false;
46 for (auto& id : m_sorted_ids) {
47 auto& meta = m_files[id];
48 auto close_call = meta->m_request_close;
49 lock.unlock();
50 closed = close_call();
51 lock.lock();
52 // If the file was closed, the iterator on m_sorted_ids has been invalidated!
53 if (closed)
54 break;
55 }
56 if (!closed) {
57 throw Elements::Exception() << "Limit reached and failed to close any existing file descriptor";
58 }
59 }
60}
61
68
75
77 // Update count
78 FileMetadata* f_ptr = reinterpret_cast<FileMetadata*>(id);
79 f_ptr->m_last_used = Clock::now();
80 ++f_ptr->m_used_count;
81
82 // Bring it to the back, since it is the last used
84 auto iter = m_current_pos[id];
85 auto ptr = std::move(*iter);
86 m_sorted_ids.erase(iter);
89 --m_current_pos[id];
90}
91
92unsigned int LRUFileManager::getLimit() const {
93 return m_limit;
94}
95
96unsigned int LRUFileManager::getUsed() const {
97 return m_sorted_ids.size();
98}
99
100unsigned int LRUFileManager::getAvailable() const {
101 return m_limit - m_sorted_ids.size();
102}
103
104} // namespace FilePool
105} // namespace Euclid
intptr_t FileId
Opaque FileId, its concrete type should only be assumed to be copyable and hashable.
Definition FileManager.h:65
std::map< FileId, std::unique_ptr< FileMetadata > > m_files
std::map< FileId, std::list< FileId >::iterator > m_current_pos
std::list< FileId > m_sorted_ids
Sorted from less to more recent.
void notifyClosedFile(FileId id) override
void notifyUsed(FileId id) override
void notifyOpenedFile(FileId id) override
void notifyIntentToOpen(bool write) override
T emplace_back(T... args)
T end(T... args)
T erase(T... args)
T move(T... args)
T size(T... args)