Directory: | cvmfs/ |
---|---|
File: | cvmfs/cache_ram.cc |
Date: | 2025-06-22 02:36:02 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 191 | 229 | 83.4% |
Branches: | 100 | 208 | 48.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #include "cache_ram.h" | ||
6 | |||
7 | #include <errno.h> | ||
8 | |||
9 | #include <algorithm> | ||
10 | #include <cassert> | ||
11 | #include <cstring> | ||
12 | #include <new> | ||
13 | |||
14 | #include "kvstore.h" | ||
15 | #include "util/concurrency.h" | ||
16 | #include "util/logging.h" | ||
17 | #include "util/posix.h" | ||
18 | #include "util/string.h" | ||
19 | |||
20 | using namespace std; // NOLINT | ||
21 | |||
22 | const shash::Any RamCacheManager::kInvalidHandle; | ||
23 | |||
24 | ✗ | string RamCacheManager::Describe() { | |
25 | return "Internal in-memory cache manager (size " | ||
26 | ✗ | + StringifyInt(max_size_ / (1024 * 1024)) + "MB)\n"; | |
27 | } | ||
28 | |||
29 | |||
30 | 1409 | RamCacheManager::RamCacheManager(uint64_t max_size, | |
31 | unsigned max_entries, | ||
32 | MemoryKvStore::MemoryAllocator alloc, | ||
33 | 1409 | perf::StatisticsTemplate statistics) | |
34 | 1409 | : max_size_(max_size) | |
35 |
1/2✓ Branch 1 taken 1409 times.
✗ Branch 2 not taken.
|
1409 | , fd_table_(max_entries, ReadOnlyHandle()) |
36 | // TODO(jblomer): the number of slots in the kv-stores should _not_ be the | ||
37 | // number of open files. | ||
38 |
1/2✓ Branch 1 taken 1409 times.
✗ Branch 2 not taken.
|
1409 | , regular_entries_(max_entries, |
39 | alloc, | ||
40 | max_size, | ||
41 |
2/4✓ Branch 2 taken 1409 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1409 times.
✗ Branch 6 not taken.
|
2818 | perf::StatisticsTemplate("kv.regular", statistics)) |
42 |
1/2✓ Branch 1 taken 1409 times.
✗ Branch 2 not taken.
|
1409 | , volatile_entries_(max_entries, |
43 | alloc, | ||
44 | max_size, | ||
45 |
2/4✓ Branch 2 taken 1409 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1409 times.
✗ Branch 6 not taken.
|
2818 | perf::StatisticsTemplate("kv.volatile", statistics)) |
46 |
2/4✓ Branch 3 taken 1409 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1409 times.
✗ Branch 7 not taken.
|
2818 | , counters_(statistics) { |
47 | 1409 | const int retval = pthread_rwlock_init(&rwlock_, NULL); | |
48 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
|
1409 | assert(retval == 0); |
49 |
1/2✓ Branch 1 taken 1409 times.
✗ Branch 2 not taken.
|
1409 | LogCvmfs(kLogCache, kLogDebug, "max %lu B, %u entries", max_size, |
50 | max_entries); | ||
51 |
1/2✓ Branch 1 taken 1409 times.
✗ Branch 2 not taken.
|
1409 | LogCvmfs(kLogCache, kLogDebug | kLogSyslogWarn, |
52 | "DEPRECATION WARNING: The RAM cache manager is depcreated and " | ||
53 | "will be removed from future releases."); | ||
54 | 1409 | } | |
55 | |||
56 | |||
57 | 4484 | RamCacheManager::~RamCacheManager() { pthread_rwlock_destroy(&rwlock_); } | |
58 | |||
59 | |||
60 | 530071 | int RamCacheManager::AddFd(const ReadOnlyHandle &handle) { | |
61 | 530071 | const int result = fd_table_.OpenFd(handle); | |
62 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 530023 times.
|
530071 | if (result == -ENFILE) { |
63 | 48 | LogCvmfs(kLogCache, kLogDebug, "too many open files"); | |
64 | 48 | perf::Inc(counters_.n_enfile); | |
65 | } | ||
66 | 530071 | return result; | |
67 | } | ||
68 | |||
69 | |||
70 | 441 | bool RamCacheManager::AcquireQuotaManager(QuotaManager *quota_mgr) { | |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 441 times.
|
441 | assert(quota_mgr != NULL); |
72 | 441 | quota_mgr_ = quota_mgr; | |
73 | 441 | LogCvmfs(kLogCache, kLogDebug, "set quota manager"); | |
74 | 441 | return true; | |
75 | } | ||
76 | |||
77 | |||
78 | 1120 | int RamCacheManager::Open(const LabeledObject &object) { | |
79 | 1120 | const WriteLockGuard guard(rwlock_); | |
80 |
1/2✓ Branch 1 taken 1120 times.
✗ Branch 2 not taken.
|
2240 | return DoOpen(object.id); |
81 | 1120 | } | |
82 | |||
83 | |||
84 | 1553 | int RamCacheManager::DoOpen(const shash::Any &id) { | |
85 | bool ok; | ||
86 | bool is_volatile; | ||
87 |
1/2✓ Branch 1 taken 1553 times.
✗ Branch 2 not taken.
|
1553 | const MemoryBuffer buf; |
88 | |||
89 |
3/4✓ Branch 1 taken 1553 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 773 times.
✓ Branch 4 taken 780 times.
|
1553 | if (regular_entries_.Contains(id)) { |
90 | 773 | is_volatile = false; | |
91 |
3/4✓ Branch 1 taken 780 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 682 times.
|
780 | } else if (volatile_entries_.Contains(id)) { |
92 | 98 | is_volatile = true; | |
93 | } else { | ||
94 |
2/4✓ Branch 1 taken 682 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 682 times.
✗ Branch 6 not taken.
|
682 | LogCvmfs(kLogCache, kLogDebug, "miss for %s", id.ToString().c_str()); |
95 | 682 | perf::Inc(counters_.n_openmiss); | |
96 | 682 | return -ENOENT; | |
97 | } | ||
98 | 871 | const ReadOnlyHandle generic_handle(id, is_volatile); | |
99 |
1/2✓ Branch 1 taken 871 times.
✗ Branch 2 not taken.
|
871 | const int fd = AddFd(generic_handle); |
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 871 times.
|
871 | if (fd < 0) { |
101 | ✗ | LogCvmfs(kLogCache, kLogDebug, "error while opening %s: %s", | |
102 | ✗ | id.ToString().c_str(), strerror(-fd)); | |
103 | ✗ | return fd; | |
104 | } | ||
105 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 773 times.
|
871 | if (is_volatile) { |
106 |
1/2✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
|
98 | LogCvmfs(kLogCache, kLogDebug, "hit in volatile entries for %s", |
107 |
1/2✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
|
196 | id.ToString().c_str()); |
108 | 98 | perf::Inc(counters_.n_openvolatile); | |
109 | } else { | ||
110 |
1/2✓ Branch 2 taken 773 times.
✗ Branch 3 not taken.
|
773 | LogCvmfs(kLogCache, kLogDebug, "hit in regular entries for %s", |
111 |
1/2✓ Branch 1 taken 773 times.
✗ Branch 2 not taken.
|
1546 | id.ToString().c_str()); |
112 | 773 | perf::Inc(counters_.n_openregular); | |
113 | } | ||
114 |
1/2✓ Branch 2 taken 871 times.
✗ Branch 3 not taken.
|
871 | ok = GetStore(generic_handle)->IncRef(id); |
115 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 871 times.
|
871 | assert(ok); |
116 | 871 | return fd; | |
117 | } | ||
118 | |||
119 | |||
120 | 291 | int64_t RamCacheManager::GetSize(int fd) { | |
121 | 291 | const ReadLockGuard guard(rwlock_); | |
122 |
1/2✓ Branch 1 taken 291 times.
✗ Branch 2 not taken.
|
291 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
123 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 291 times.
|
291 | if (generic_handle.handle == kInvalidHandle) { |
124 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on GetSize", fd); | |
125 | ✗ | return -EBADF; | |
126 | } | ||
127 | 291 | perf::Inc(counters_.n_getsize); | |
128 |
1/2✓ Branch 2 taken 291 times.
✗ Branch 3 not taken.
|
291 | return GetStore(generic_handle)->GetSize(generic_handle.handle); |
129 | 291 | } | |
130 | |||
131 | |||
132 | 529735 | int RamCacheManager::Close(int fd) { | |
133 | bool rc; | ||
134 | |||
135 | 529735 | const WriteLockGuard guard(rwlock_); | |
136 |
1/2✓ Branch 1 taken 529735 times.
✗ Branch 2 not taken.
|
529735 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
137 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 529735 times.
|
529735 | if (generic_handle.handle == kInvalidHandle) { |
138 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Close", fd); | |
139 | ✗ | return -EBADF; | |
140 | } | ||
141 |
1/2✓ Branch 2 taken 529735 times.
✗ Branch 3 not taken.
|
529735 | rc = GetStore(generic_handle)->Unref(generic_handle.handle); |
142 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 529735 times.
|
529735 | assert(rc); |
143 | |||
144 |
1/2✓ Branch 1 taken 529735 times.
✗ Branch 2 not taken.
|
529735 | const int rc_int = fd_table_.CloseFd(fd); |
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 529735 times.
|
529735 | assert(rc_int == 0); |
146 |
1/2✓ Branch 1 taken 529735 times.
✗ Branch 2 not taken.
|
529735 | LogCvmfs(kLogCache, kLogDebug, "closed fd %d", fd); |
147 | 529735 | perf::Inc(counters_.n_close); | |
148 | 529735 | return 0; | |
149 | 529735 | } | |
150 | |||
151 | |||
152 | 195 | int64_t RamCacheManager::Pread(int fd, | |
153 | void *buf, | ||
154 | uint64_t size, | ||
155 | uint64_t offset) { | ||
156 | 195 | const ReadLockGuard guard(rwlock_); | |
157 |
1/2✓ Branch 1 taken 195 times.
✗ Branch 2 not taken.
|
195 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
158 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 195 times.
|
195 | if (generic_handle.handle == kInvalidHandle) { |
159 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Pread", fd); | |
160 | ✗ | return -EBADF; | |
161 | } | ||
162 | 195 | perf::Inc(counters_.n_pread); | |
163 | return GetStore(generic_handle) | ||
164 |
1/2✓ Branch 2 taken 195 times.
✗ Branch 3 not taken.
|
195 | ->Read(generic_handle.handle, buf, size, offset); |
165 | 195 | } | |
166 | |||
167 | |||
168 | 529248 | int RamCacheManager::Dup(int fd) { | |
169 | bool ok; | ||
170 | int rc; | ||
171 | 529248 | const WriteLockGuard guard(rwlock_); | |
172 |
1/2✓ Branch 1 taken 529248 times.
✗ Branch 2 not taken.
|
529248 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
173 |
2/2✓ Branch 1 taken 48 times.
✓ Branch 2 taken 529200 times.
|
529248 | if (generic_handle.handle == kInvalidHandle) { |
174 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Dup", fd); |
175 | 48 | return -EBADF; | |
176 | } | ||
177 |
1/2✓ Branch 1 taken 529200 times.
✗ Branch 2 not taken.
|
529200 | rc = AddFd(generic_handle); |
178 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 529152 times.
|
529200 | if (rc < 0) |
179 | 48 | return rc; | |
180 |
1/2✓ Branch 2 taken 529152 times.
✗ Branch 3 not taken.
|
529152 | ok = GetStore(generic_handle)->IncRef(generic_handle.handle); |
181 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 529152 times.
|
529152 | assert(ok); |
182 |
1/2✓ Branch 1 taken 529152 times.
✗ Branch 2 not taken.
|
529152 | LogCvmfs(kLogCache, kLogDebug, "dup fd %d", fd); |
183 | 529152 | perf::Inc(counters_.n_dup); | |
184 | 529152 | return rc; | |
185 | 529248 | } | |
186 | |||
187 | |||
188 | /** | ||
189 | * For a RAM cache, read-ahead is a no-op. | ||
190 | */ | ||
191 | ✗ | int RamCacheManager::Readahead(int fd) { | |
192 | ✗ | const ReadLockGuard guard(rwlock_); | |
193 | ✗ | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); | |
194 | ✗ | if (generic_handle.handle == kInvalidHandle) { | |
195 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Readahead", fd); | |
196 | ✗ | return -EBADF; | |
197 | } | ||
198 | ✗ | LogCvmfs(kLogCache, kLogDebug, "readahead (no-op) on %d", fd); | |
199 | ✗ | perf::Inc(counters_.n_readahead); | |
200 | ✗ | return 0; | |
201 | } | ||
202 | |||
203 | |||
204 | 1783 | int RamCacheManager::StartTxn(const shash::Any &id, uint64_t size, void *txn) { | |
205 |
1/2✓ Branch 2 taken 1783 times.
✗ Branch 3 not taken.
|
1783 | LogCvmfs(kLogCache, kLogDebug, "new transaction with id %s", |
206 | 3566 | id.ToString().c_str()); | |
207 | 1783 | Transaction *transaction = new (txn) Transaction(); | |
208 | 1783 | transaction->buffer.id = id; | |
209 | 1783 | transaction->pos = 0; | |
210 | 1783 | transaction->expected_size = size; | |
211 |
1/2✓ Branch 0 taken 1783 times.
✗ Branch 1 not taken.
|
1783 | transaction->buffer.size = (size == kSizeUnknown) ? kPageSize : size; |
212 | 1783 | transaction->buffer.address = malloc(transaction->buffer.size); | |
213 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1783 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1783 | if (!transaction->buffer.address && size > 0) { |
214 | ✗ | LogCvmfs(kLogCache, kLogDebug, "failed to allocate %lu B for %s", size, | |
215 | ✗ | id.ToString().c_str()); | |
216 | ✗ | return -errno; | |
217 | } | ||
218 | 1783 | perf::Inc(counters_.n_starttxn); | |
219 | 1783 | return 0; | |
220 | } | ||
221 | |||
222 | |||
223 | 390 | void RamCacheManager::CtrlTxn(const Label &label, const int /* flags */, | |
224 | void *txn) { | ||
225 | 390 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
226 | 390 | transaction->description = label.GetDescription(); | |
227 | 390 | transaction->buffer.object_flags = label.flags; | |
228 |
1/2✓ Branch 2 taken 390 times.
✗ Branch 3 not taken.
|
390 | LogCvmfs(kLogCache, kLogDebug, "modified transaction %s", |
229 | 780 | transaction->buffer.id.ToString().c_str()); | |
230 | 390 | } | |
231 | |||
232 | |||
233 | 1830 | int64_t RamCacheManager::Write(const void *buf, uint64_t size, void *txn) { | |
234 | 1830 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
235 | |||
236 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1830 times.
|
1830 | assert(transaction->pos <= transaction->buffer.size); |
237 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1782 times.
|
1830 | if (transaction->pos + size > transaction->buffer.size) { |
238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | if (transaction->expected_size == kSizeUnknown) { |
239 | ✗ | perf::Inc(counters_.n_realloc); | |
240 | ✗ | const size_t new_size = max(2 * transaction->buffer.size, | |
241 | ✗ | static_cast<size_t>(size + transaction->pos)); | |
242 | ✗ | LogCvmfs(kLogCache, kLogDebug, "reallocate transaction for %s to %lu B", | |
243 | ✗ | transaction->buffer.id.ToString().c_str(), | |
244 | transaction->buffer.size); | ||
245 | ✗ | void *new_ptr = realloc(transaction->buffer.address, new_size); | |
246 | ✗ | if (!new_ptr) { | |
247 | ✗ | LogCvmfs(kLogCache, kLogDebug, "failed to allocate %lu B for %s", | |
248 | ✗ | new_size, transaction->buffer.id.ToString().c_str()); | |
249 | ✗ | return -EIO; | |
250 | } | ||
251 | ✗ | transaction->buffer.address = new_ptr; | |
252 | ✗ | transaction->buffer.size = new_size; | |
253 | } else { | ||
254 | 48 | LogCvmfs(kLogCache, kLogDebug, | |
255 | "attempted to write more than requested (%lu>%zu)", size, | ||
256 | transaction->buffer.size); | ||
257 | 48 | return -EFBIG; | |
258 | } | ||
259 | } | ||
260 | |||
261 |
2/4✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1782 times.
✗ Branch 3 not taken.
|
1782 | if (transaction->buffer.address && buf) { |
262 | // LogCvmfs(kLogCache, kLogDebug, "copy %u bytes of transaction %s", | ||
263 | // size, transaction->id.ToString().c_str()); | ||
264 | 1782 | memcpy(static_cast<char *>(transaction->buffer.address) + transaction->pos, | |
265 | buf, size); | ||
266 | } | ||
267 | 1782 | transaction->pos += size; | |
268 | 1782 | perf::Inc(counters_.n_write); | |
269 | 1782 | return size; | |
270 | } | ||
271 | |||
272 | |||
273 | 97 | int RamCacheManager::Reset(void *txn) { | |
274 | 97 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
275 | 97 | transaction->pos = 0; | |
276 |
1/2✓ Branch 2 taken 97 times.
✗ Branch 3 not taken.
|
97 | LogCvmfs(kLogCache, kLogDebug, "reset transaction %s", |
277 | 194 | transaction->buffer.id.ToString().c_str()); | |
278 | 97 | perf::Inc(counters_.n_reset); | |
279 | 97 | return 0; | |
280 | } | ||
281 | |||
282 | |||
283 | 481 | int RamCacheManager::OpenFromTxn(void *txn) { | |
284 | 481 | const WriteLockGuard guard(rwlock_); | |
285 | 481 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
286 |
1/2✓ Branch 1 taken 481 times.
✗ Branch 2 not taken.
|
481 | const int64_t retval = CommitToKvStore(transaction); |
287 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 433 times.
|
481 | if (retval < 0) { |
288 |
1/2✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
|
96 | LogCvmfs(kLogCache, kLogDebug, |
289 | "error while committing transaction on %s: %s", | ||
290 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
96 | transaction->buffer.id.ToString().c_str(), strerror(-retval)); |
291 | 48 | return retval; | |
292 | } | ||
293 |
1/2✓ Branch 2 taken 433 times.
✗ Branch 3 not taken.
|
433 | LogCvmfs(kLogCache, kLogDebug, "open pending transaction for %s", |
294 |
1/2✓ Branch 1 taken 433 times.
✗ Branch 2 not taken.
|
866 | transaction->buffer.id.ToString().c_str()); |
295 | 433 | perf::Inc(counters_.n_committxn); | |
296 |
1/2✓ Branch 1 taken 433 times.
✗ Branch 2 not taken.
|
433 | return DoOpen(transaction->buffer.id); |
297 | 481 | } | |
298 | |||
299 | |||
300 | 97 | int RamCacheManager::AbortTxn(void *txn) { | |
301 | 97 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
302 | 97 | free(transaction->buffer.address); | |
303 |
1/2✓ Branch 2 taken 97 times.
✗ Branch 3 not taken.
|
97 | LogCvmfs(kLogCache, kLogDebug, "abort transaction %s", |
304 | 194 | transaction->buffer.id.ToString().c_str()); | |
305 | 97 | perf::Inc(counters_.n_aborttxn); | |
306 | 97 | return 0; | |
307 | } | ||
308 | |||
309 | |||
310 | 1398 | int RamCacheManager::CommitTxn(void *txn) { | |
311 | 1398 | const WriteLockGuard guard(rwlock_); | |
312 | 1398 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
313 | 1398 | perf::Inc(counters_.n_committxn); | |
314 |
1/2✓ Branch 1 taken 1398 times.
✗ Branch 2 not taken.
|
1398 | const int64_t rc = CommitToKvStore(transaction); |
315 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1350 times.
|
1398 | if (rc < 0) |
316 | 48 | return rc; | |
317 | 1350 | free(transaction->buffer.address); | |
318 | 1350 | return rc; | |
319 | 1398 | } | |
320 | |||
321 | |||
322 | 1879 | int64_t RamCacheManager::CommitToKvStore(Transaction *transaction) { | |
323 | MemoryKvStore *store; | ||
324 | |||
325 |
2/2✓ Branch 0 taken 146 times.
✓ Branch 1 taken 1733 times.
|
1879 | if (transaction->buffer.object_flags & CacheManager::kLabelVolatile) { |
326 | 146 | store = &volatile_entries_; | |
327 | } else { | ||
328 | 1733 | store = ®ular_entries_; | |
329 | } | ||
330 |
2/2✓ Branch 0 taken 1831 times.
✓ Branch 1 taken 48 times.
|
1879 | if ((transaction->buffer.object_flags & CacheManager::kLabelPinned) |
331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
|
1831 | || (transaction->buffer.object_flags & CacheManager::kLabelCatalog)) { |
332 | 48 | transaction->buffer.refcount = 1; | |
333 | } else { | ||
334 | 1831 | transaction->buffer.refcount = 0; | |
335 | } | ||
336 | |||
337 | 1879 | const int64_t regular_size = regular_entries_.GetUsed(); | |
338 | 1879 | const int64_t volatile_size = volatile_entries_.GetUsed(); | |
339 | 1879 | int64_t overrun = regular_size + volatile_size + transaction->buffer.size | |
340 | 1879 | - max_size_; | |
341 | |||
342 |
2/2✓ Branch 0 taken 288 times.
✓ Branch 1 taken 1591 times.
|
1879 | if (overrun > 0) { |
343 | // if we're going to clean the cache, try to remove at least 25% | ||
344 | 288 | overrun = max(overrun, (int64_t)max_size_ >> 2); | |
345 | 288 | perf::Inc(counters_.n_overrun); | |
346 |
1/2✓ Branch 2 taken 288 times.
✗ Branch 3 not taken.
|
288 | volatile_entries_.ShrinkTo(max((int64_t)0, volatile_size - overrun)); |
347 | } | ||
348 | 1879 | overrun -= volatile_size - volatile_entries_.GetUsed(); | |
349 |
2/2✓ Branch 0 taken 240 times.
✓ Branch 1 taken 1639 times.
|
1879 | if (overrun > 0) { |
350 |
1/2✓ Branch 2 taken 240 times.
✗ Branch 3 not taken.
|
240 | regular_entries_.ShrinkTo(max((int64_t)0, regular_size - overrun)); |
351 | } | ||
352 | 1879 | overrun -= regular_size - regular_entries_.GetUsed(); | |
353 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 1783 times.
|
1879 | if (overrun > 0) { |
354 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | LogCvmfs(kLogCache, kLogDebug, |
355 | "transaction for %s would overrun the cache limit by %ld", | ||
356 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
192 | transaction->buffer.id.ToString().c_str(), overrun); |
357 | 96 | perf::Inc(counters_.n_full); | |
358 | 96 | return -ENOSPC; | |
359 | } | ||
360 | |||
361 |
1/2✓ Branch 1 taken 1783 times.
✗ Branch 2 not taken.
|
1783 | const int rc = store->Commit(transaction->buffer); |
362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1783 times.
|
1783 | if (rc < 0) { |
363 | ✗ | LogCvmfs(kLogCache, kLogDebug, "commit on %s failed", | |
364 | ✗ | transaction->buffer.id.ToString().c_str()); | |
365 | ✗ | return rc; | |
366 | } | ||
367 |
1/2✓ Branch 2 taken 1783 times.
✗ Branch 3 not taken.
|
1783 | LogCvmfs(kLogCache, kLogDebug, "committed %s to cache", |
368 |
1/2✓ Branch 1 taken 1783 times.
✗ Branch 2 not taken.
|
3566 | transaction->buffer.id.ToString().c_str()); |
369 | 1783 | return 0; | |
370 | } | ||
371 |