44 template<
typename ID,
typename RECORD>
51 using queue_type = std::vector<Entry>;
52 using iterator =
typename queue_type::iterator;
56 int write_queue_size()
const {
return m_write_queue.size(); }
57 bool read_queue_empty()
const {
return m_read_queue.empty(); }
58 int read_queue_size()
const {
return m_read_queue.size(); }
61 void push(
ID id, RECORD
stat) { m_write_queue.push_back({ id,
stat }); }
63 RECORD& write_record(
int pos) {
return m_write_queue[pos].record; }
66 int swap_queues() { m_read_queue.clear(); m_write_queue.swap(m_read_queue);
return read_queue_size(); }
67 const queue_type& read_queue()
const {
return m_read_queue; }
68 iterator begin()
const {
return m_read_queue.begin(); }
69 iterator end()
const {
return m_read_queue.end(); }
72 void shrink_read_queue() { m_read_queue.clear(); m_read_queue.shrink_to_fit(); }
75 queue_type m_write_queue, m_read_queue;
79 std::string m_filename;
80 unsigned int m_last_queue_swap_u1 = 0xffffffff;
81 int m_last_write_queue_pos = -1;
82 DirState *m_dir_state =
nullptr;
86 m_last_queue_swap_u1 = 0xffffffff;
87 m_last_write_queue_pos = -1;
88 m_dir_state =
nullptr;
94 StableChunkPool<AccessToken, 12, 1024> m_access_tokens;
107 long long m_size_in_st_blocks;
111 Queue<int, OpenRecord> m_file_open_q;
112 Queue<int, Stats> m_file_update_stats_q;
113 Queue<int, CloseRecord> m_file_close_q;
114 Queue<DirState*, PurgeRecord> m_file_purge_q1;
115 Queue<std::string, PurgeRecord> m_file_purge_q2;
116 Queue<std::string, long long> m_file_purge_q3;
119 long long m_current_usage_in_st_blocks = 0;
120 int m_dir_count_discrepancy = 0;
121 long long m_token_alloc_failures = 0;
123 XrdSysMutex m_queue_mutex;
124 unsigned int m_queue_swap_u1 = 0u;
126 DataFsState &m_fs_state;
133 const std::string &f_lfn;
134 XrdSysCondVar &f_cond;
139 std::set<std::string> m_protected_top_dirs;
141 bool is_in_protected_top_dir(
const std::string &path)
const {
142 size_t b = path.find_first_not_of(
'/');
143 if (b == std::string::npos)
return false;
144 size_t e = path.find(
'/', b);
145 return m_protected_top_dirs.find(
146 path.substr(b, e == std::string::npos ? std::string::npos : e - b))
147 != m_protected_top_dirs.end();
150 XrdSysMutex m_dir_scan_mutex;
151 std::list<LfnCondRecord> m_dir_scan_open_requests;
152 int m_dir_scan_check_counter = 0;
153 bool m_dir_scan_in_progress =
true;
156 static void seed_last_times_from_cinfo(DirUsage &u,
const struct stat &cinfo_stat) {
157 if (cinfo_stat.st_mtime > u.m_LastOpenTime) u.m_LastOpenTime = cinfo_stat.st_mtime;
158 if (cinfo_stat.st_mtime > u.m_LastCloseTime) u.m_LastCloseTime = cinfo_stat.st_mtime;
161 void process_inter_dir_scan_open_requests(FsTraversal &fst);
162 void cross_check_or_process_oob_lfn(
const std::string &lfn, FsTraversal &fst);
163 long long get_file_usage_bytes_to_remove(
const DataFsPurgeshot &ps,
long long previous_file_usage,
int logLeve);
179 int token_id = m_access_tokens.acquire();
182 ++m_token_alloc_failures;
185 AccessToken &at = m_access_tokens[token_id];
186 at.m_filename = filename;
187 at.m_last_queue_swap_u1 = m_queue_swap_u1 - 1;
189 m_file_open_q.push(token_id, {open_timestamp, existing_file});
194 if (token_id < 0)
return;
196 AccessToken &at =
token(token_id);
198 if (at.m_last_queue_swap_u1 != m_queue_swap_u1) {
199 m_file_update_stats_q.push(token_id, stats);
200 at.m_last_queue_swap_u1 = m_queue_swap_u1;
201 at.m_last_write_queue_pos = m_file_update_stats_q.write_queue_size() - 1;
203 Stats &existing_stats = m_file_update_stats_q.write_record(at.m_last_write_queue_pos);
204 existing_stats.
AddUp(stats);
213 if (token_id < 0)
return;
215 m_file_close_q.push(token_id, {close_timestamp, full_stats});
222 m_file_purge_q1.push(target, {size_in_st_blocks, 1});
226 m_file_purge_q1.push(target, {size_in_st_blocks, n_files});
230 m_file_purge_q2.push(target, {size_in_st_blocks, n_files});
234 m_file_purge_q3.push(filename, size_in_st_blocks);
245 AccessToken&
token(
int i) {
return m_access_tokens[i]; }
257 std::vector<DirStateElement> &vec,
262 std::vector<DirPurgeElement> &vec,