Directory: | cvmfs/ |
---|---|
File: | cvmfs/cache_ram.cc |
Date: | 2025-07-06 02:35:01 |
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 | 610 | RamCacheManager::RamCacheManager(uint64_t max_size, | |
31 | unsigned max_entries, | ||
32 | MemoryKvStore::MemoryAllocator alloc, | ||
33 | 610 | perf::StatisticsTemplate statistics) | |
34 | 610 | : max_size_(max_size) | |
35 |
1/2✓ Branch 1 taken 610 times.
✗ Branch 2 not taken.
|
610 | , 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 610 times.
✗ Branch 2 not taken.
|
610 | , regular_entries_(max_entries, |
39 | alloc, | ||
40 | max_size, | ||
41 |
2/4✓ Branch 2 taken 610 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 610 times.
✗ Branch 6 not taken.
|
1220 | perf::StatisticsTemplate("kv.regular", statistics)) |
42 |
1/2✓ Branch 1 taken 610 times.
✗ Branch 2 not taken.
|
610 | , volatile_entries_(max_entries, |
43 | alloc, | ||
44 | max_size, | ||
45 |
2/4✓ Branch 2 taken 610 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 610 times.
✗ Branch 6 not taken.
|
1220 | perf::StatisticsTemplate("kv.volatile", statistics)) |
46 |
2/4✓ Branch 3 taken 610 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 610 times.
✗ Branch 7 not taken.
|
1220 | , counters_(statistics) { |
47 | 610 | const int retval = pthread_rwlock_init(&rwlock_, NULL); | |
48 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 610 times.
|
610 | assert(retval == 0); |
49 |
1/2✓ Branch 1 taken 610 times.
✗ Branch 2 not taken.
|
610 | LogCvmfs(kLogCache, kLogDebug, "max %lu B, %u entries", max_size, |
50 | max_entries); | ||
51 |
1/2✓ Branch 1 taken 610 times.
✗ Branch 2 not taken.
|
610 | LogCvmfs(kLogCache, kLogDebug | kLogSyslogWarn, |
52 | "DEPRECATION WARNING: The RAM cache manager is depcreated and " | ||
53 | "will be removed from future releases."); | ||
54 | 610 | } | |
55 | |||
56 | |||
57 | 1840 | RamCacheManager::~RamCacheManager() { pthread_rwlock_destroy(&rwlock_); } | |
58 | |||
59 | |||
60 | 275935 | int RamCacheManager::AddFd(const ReadOnlyHandle &handle) { | |
61 | 275935 | const int result = fd_table_.OpenFd(handle); | |
62 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 275910 times.
|
275935 | if (result == -ENFILE) { |
63 | 25 | LogCvmfs(kLogCache, kLogDebug, "too many open files"); | |
64 | 25 | perf::Inc(counters_.n_enfile); | |
65 | } | ||
66 | 275935 | return result; | |
67 | } | ||
68 | |||
69 | |||
70 | 270 | bool RamCacheManager::AcquireQuotaManager(QuotaManager *quota_mgr) { | |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
|
270 | assert(quota_mgr != NULL); |
72 | 270 | quota_mgr_ = quota_mgr; | |
73 | 270 | LogCvmfs(kLogCache, kLogDebug, "set quota manager"); | |
74 | 270 | return true; | |
75 | } | ||
76 | |||
77 | |||
78 | 255 | int RamCacheManager::Open(const LabeledObject &object) { | |
79 | 255 | const WriteLockGuard guard(rwlock_); | |
80 |
1/2✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
|
510 | return DoOpen(object.id); |
81 | 255 | } | |
82 | |||
83 | |||
84 | 460 | int RamCacheManager::DoOpen(const shash::Any &id) { | |
85 | bool ok; | ||
86 | bool is_volatile; | ||
87 |
1/2✓ Branch 1 taken 460 times.
✗ Branch 2 not taken.
|
460 | const MemoryBuffer buf; |
88 | |||
89 |
3/4✓ Branch 1 taken 460 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 300 times.
✓ Branch 4 taken 160 times.
|
460 | if (regular_entries_.Contains(id)) { |
90 | 300 | is_volatile = false; | |
91 |
3/4✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 150 times.
|
160 | } else if (volatile_entries_.Contains(id)) { |
92 | 10 | is_volatile = true; | |
93 | } else { | ||
94 |
2/4✓ Branch 1 taken 150 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 150 times.
✗ Branch 6 not taken.
|
150 | LogCvmfs(kLogCache, kLogDebug, "miss for %s", id.ToString().c_str()); |
95 | 150 | perf::Inc(counters_.n_openmiss); | |
96 | 150 | return -ENOENT; | |
97 | } | ||
98 | 310 | const ReadOnlyHandle generic_handle(id, is_volatile); | |
99 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
310 | const int fd = AddFd(generic_handle); |
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 310 times.
|
310 | 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 10 times.
✓ Branch 1 taken 300 times.
|
310 | if (is_volatile) { |
106 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | LogCvmfs(kLogCache, kLogDebug, "hit in volatile entries for %s", |
107 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
20 | id.ToString().c_str()); |
108 | 10 | perf::Inc(counters_.n_openvolatile); | |
109 | } else { | ||
110 |
1/2✓ Branch 2 taken 300 times.
✗ Branch 3 not taken.
|
300 | LogCvmfs(kLogCache, kLogDebug, "hit in regular entries for %s", |
111 |
1/2✓ Branch 1 taken 300 times.
✗ Branch 2 not taken.
|
600 | id.ToString().c_str()); |
112 | 300 | perf::Inc(counters_.n_openregular); | |
113 | } | ||
114 |
1/2✓ Branch 2 taken 310 times.
✗ Branch 3 not taken.
|
310 | ok = GetStore(generic_handle)->IncRef(id); |
115 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 310 times.
|
310 | assert(ok); |
116 | 310 | return fd; | |
117 | } | ||
118 | |||
119 | |||
120 | 90 | int64_t RamCacheManager::GetSize(int fd) { | |
121 | 90 | const ReadLockGuard guard(rwlock_); | |
122 |
1/2✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
|
90 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
123 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
|
90 | if (generic_handle.handle == kInvalidHandle) { |
124 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on GetSize", fd); | |
125 | ✗ | return -EBADF; | |
126 | } | ||
127 | 90 | perf::Inc(counters_.n_getsize); | |
128 |
1/2✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
|
90 | return GetStore(generic_handle)->GetSize(generic_handle.handle); |
129 | 90 | } | |
130 | |||
131 | |||
132 | 275760 | int RamCacheManager::Close(int fd) { | |
133 | bool rc; | ||
134 | |||
135 | 275760 | const WriteLockGuard guard(rwlock_); | |
136 |
1/2✓ Branch 1 taken 275760 times.
✗ Branch 2 not taken.
|
275760 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
137 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 275760 times.
|
275760 | 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 275760 times.
✗ Branch 3 not taken.
|
275760 | rc = GetStore(generic_handle)->Unref(generic_handle.handle); |
142 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 275760 times.
|
275760 | assert(rc); |
143 | |||
144 |
1/2✓ Branch 1 taken 275760 times.
✗ Branch 2 not taken.
|
275760 | const int rc_int = fd_table_.CloseFd(fd); |
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 275760 times.
|
275760 | assert(rc_int == 0); |
146 |
1/2✓ Branch 1 taken 275760 times.
✗ Branch 2 not taken.
|
275760 | LogCvmfs(kLogCache, kLogDebug, "closed fd %d", fd); |
147 | 275760 | perf::Inc(counters_.n_close); | |
148 | 275760 | return 0; | |
149 | 275760 | } | |
150 | |||
151 | |||
152 | 40 | int64_t RamCacheManager::Pread(int fd, | |
153 | void *buf, | ||
154 | uint64_t size, | ||
155 | uint64_t offset) { | ||
156 | 40 | const ReadLockGuard guard(rwlock_); | |
157 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
158 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
|
40 | if (generic_handle.handle == kInvalidHandle) { |
159 | ✗ | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Pread", fd); | |
160 | ✗ | return -EBADF; | |
161 | } | ||
162 | 40 | perf::Inc(counters_.n_pread); | |
163 | return GetStore(generic_handle) | ||
164 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | ->Read(generic_handle.handle, buf, size, offset); |
165 | 40 | } | |
166 | |||
167 | |||
168 | 275650 | int RamCacheManager::Dup(int fd) { | |
169 | bool ok; | ||
170 | int rc; | ||
171 | 275650 | const WriteLockGuard guard(rwlock_); | |
172 |
1/2✓ Branch 1 taken 275650 times.
✗ Branch 2 not taken.
|
275650 | const ReadOnlyHandle generic_handle = fd_table_.GetHandle(fd); |
173 |
2/2✓ Branch 1 taken 25 times.
✓ Branch 2 taken 275625 times.
|
275650 | if (generic_handle.handle == kInvalidHandle) { |
174 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | LogCvmfs(kLogCache, kLogDebug, "bad fd %d on Dup", fd); |
175 | 25 | return -EBADF; | |
176 | } | ||
177 |
1/2✓ Branch 1 taken 275625 times.
✗ Branch 2 not taken.
|
275625 | rc = AddFd(generic_handle); |
178 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 275600 times.
|
275625 | if (rc < 0) |
179 | 25 | return rc; | |
180 |
1/2✓ Branch 2 taken 275600 times.
✗ Branch 3 not taken.
|
275600 | ok = GetStore(generic_handle)->IncRef(generic_handle.handle); |
181 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 275600 times.
|
275600 | assert(ok); |
182 |
1/2✓ Branch 1 taken 275600 times.
✗ Branch 2 not taken.
|
275600 | LogCvmfs(kLogCache, kLogDebug, "dup fd %d", fd); |
183 | 275600 | perf::Inc(counters_.n_dup); | |
184 | 275600 | return rc; | |
185 | 275650 | } | |
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 | 785 | int RamCacheManager::StartTxn(const shash::Any &id, uint64_t size, void *txn) { | |
205 |
1/2✓ Branch 2 taken 785 times.
✗ Branch 3 not taken.
|
785 | LogCvmfs(kLogCache, kLogDebug, "new transaction with id %s", |
206 | 1570 | id.ToString().c_str()); | |
207 | 785 | Transaction *transaction = new (txn) Transaction(); | |
208 | 785 | transaction->buffer.id = id; | |
209 | 785 | transaction->pos = 0; | |
210 | 785 | transaction->expected_size = size; | |
211 |
1/2✓ Branch 0 taken 785 times.
✗ Branch 1 not taken.
|
785 | transaction->buffer.size = (size == kSizeUnknown) ? kPageSize : size; |
212 | 785 | transaction->buffer.address = malloc(transaction->buffer.size); | |
213 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 785 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
785 | 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 | 785 | perf::Inc(counters_.n_starttxn); | |
219 | 785 | return 0; | |
220 | } | ||
221 | |||
222 | |||
223 | 80 | void RamCacheManager::CtrlTxn(const Label &label, const int /* flags */, | |
224 | void *txn) { | ||
225 | 80 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
226 | 80 | transaction->description = label.GetDescription(); | |
227 | 80 | transaction->buffer.object_flags = label.flags; | |
228 |
1/2✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
|
80 | LogCvmfs(kLogCache, kLogDebug, "modified transaction %s", |
229 | 160 | transaction->buffer.id.ToString().c_str()); | |
230 | 80 | } | |
231 | |||
232 | |||
233 | 830 | int64_t RamCacheManager::Write(const void *buf, uint64_t size, void *txn) { | |
234 | 830 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
235 | |||
236 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 830 times.
|
830 | assert(transaction->pos <= transaction->buffer.size); |
237 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 805 times.
|
830 | if (transaction->pos + size > transaction->buffer.size) { |
238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
25 | 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 | 25 | LogCvmfs(kLogCache, kLogDebug, | |
255 | "attempted to write more than requested (%lu>%zu)", size, | ||
256 | transaction->buffer.size); | ||
257 | 25 | return -EFBIG; | |
258 | } | ||
259 | } | ||
260 | |||
261 |
2/4✓ Branch 0 taken 805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 805 times.
✗ Branch 3 not taken.
|
805 | if (transaction->buffer.address && buf) { |
262 | // LogCvmfs(kLogCache, kLogDebug, "copy %u bytes of transaction %s", | ||
263 | // size, transaction->id.ToString().c_str()); | ||
264 | 805 | memcpy(static_cast<char *>(transaction->buffer.address) + transaction->pos, | |
265 | buf, size); | ||
266 | } | ||
267 | 805 | transaction->pos += size; | |
268 | 805 | perf::Inc(counters_.n_write); | |
269 | 805 | return size; | |
270 | } | ||
271 | |||
272 | |||
273 | 30 | int RamCacheManager::Reset(void *txn) { | |
274 | 30 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
275 | 30 | transaction->pos = 0; | |
276 |
1/2✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
|
30 | LogCvmfs(kLogCache, kLogDebug, "reset transaction %s", |
277 | 60 | transaction->buffer.id.ToString().c_str()); | |
278 | 30 | perf::Inc(counters_.n_reset); | |
279 | 30 | return 0; | |
280 | } | ||
281 | |||
282 | |||
283 | 230 | int RamCacheManager::OpenFromTxn(void *txn) { | |
284 | 230 | const WriteLockGuard guard(rwlock_); | |
285 | 230 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
286 |
1/2✓ Branch 1 taken 230 times.
✗ Branch 2 not taken.
|
230 | const int64_t retval = CommitToKvStore(transaction); |
287 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 205 times.
|
230 | if (retval < 0) { |
288 |
1/2✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
|
50 | LogCvmfs(kLogCache, kLogDebug, |
289 | "error while committing transaction on %s: %s", | ||
290 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
50 | transaction->buffer.id.ToString().c_str(), strerror(-retval)); |
291 | 25 | return retval; | |
292 | } | ||
293 |
1/2✓ Branch 2 taken 205 times.
✗ Branch 3 not taken.
|
205 | LogCvmfs(kLogCache, kLogDebug, "open pending transaction for %s", |
294 |
1/2✓ Branch 1 taken 205 times.
✗ Branch 2 not taken.
|
410 | transaction->buffer.id.ToString().c_str()); |
295 | 205 | perf::Inc(counters_.n_committxn); | |
296 |
1/2✓ Branch 1 taken 205 times.
✗ Branch 2 not taken.
|
205 | return DoOpen(transaction->buffer.id); |
297 | 230 | } | |
298 | |||
299 | |||
300 | 30 | int RamCacheManager::AbortTxn(void *txn) { | |
301 | 30 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
302 | 30 | free(transaction->buffer.address); | |
303 |
1/2✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
|
30 | LogCvmfs(kLogCache, kLogDebug, "abort transaction %s", |
304 | 60 | transaction->buffer.id.ToString().c_str()); | |
305 | 30 | perf::Inc(counters_.n_aborttxn); | |
306 | 30 | return 0; | |
307 | } | ||
308 | |||
309 | |||
310 | 605 | int RamCacheManager::CommitTxn(void *txn) { | |
311 | 605 | const WriteLockGuard guard(rwlock_); | |
312 | 605 | Transaction *transaction = reinterpret_cast<Transaction *>(txn); | |
313 | 605 | perf::Inc(counters_.n_committxn); | |
314 |
1/2✓ Branch 1 taken 605 times.
✗ Branch 2 not taken.
|
605 | const int64_t rc = CommitToKvStore(transaction); |
315 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 580 times.
|
605 | if (rc < 0) |
316 | 25 | return rc; | |
317 | 580 | free(transaction->buffer.address); | |
318 | 580 | return rc; | |
319 | 605 | } | |
320 | |||
321 | |||
322 | 835 | int64_t RamCacheManager::CommitToKvStore(Transaction *transaction) { | |
323 | MemoryKvStore *store; | ||
324 | |||
325 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 800 times.
|
835 | if (transaction->buffer.object_flags & CacheManager::kLabelVolatile) { |
326 | 35 | store = &volatile_entries_; | |
327 | } else { | ||
328 | 800 | store = ®ular_entries_; | |
329 | } | ||
330 |
2/2✓ Branch 0 taken 810 times.
✓ Branch 1 taken 25 times.
|
835 | if ((transaction->buffer.object_flags & CacheManager::kLabelPinned) |
331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 810 times.
|
810 | || (transaction->buffer.object_flags & CacheManager::kLabelCatalog)) { |
332 | 25 | transaction->buffer.refcount = 1; | |
333 | } else { | ||
334 | 810 | transaction->buffer.refcount = 0; | |
335 | } | ||
336 | |||
337 | 835 | const int64_t regular_size = regular_entries_.GetUsed(); | |
338 | 835 | const int64_t volatile_size = volatile_entries_.GetUsed(); | |
339 | 835 | int64_t overrun = regular_size + volatile_size + transaction->buffer.size | |
340 | 835 | - max_size_; | |
341 | |||
342 |
2/2✓ Branch 0 taken 150 times.
✓ Branch 1 taken 685 times.
|
835 | if (overrun > 0) { |
343 | // if we're going to clean the cache, try to remove at least 25% | ||
344 | 150 | overrun = max(overrun, (int64_t)max_size_ >> 2); | |
345 | 150 | perf::Inc(counters_.n_overrun); | |
346 |
1/2✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
|
150 | volatile_entries_.ShrinkTo(max((int64_t)0, volatile_size - overrun)); |
347 | } | ||
348 | 835 | overrun -= volatile_size - volatile_entries_.GetUsed(); | |
349 |
2/2✓ Branch 0 taken 125 times.
✓ Branch 1 taken 710 times.
|
835 | if (overrun > 0) { |
350 |
1/2✓ Branch 2 taken 125 times.
✗ Branch 3 not taken.
|
125 | regular_entries_.ShrinkTo(max((int64_t)0, regular_size - overrun)); |
351 | } | ||
352 | 835 | overrun -= regular_size - regular_entries_.GetUsed(); | |
353 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 785 times.
|
835 | if (overrun > 0) { |
354 |
1/2✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
|
50 | LogCvmfs(kLogCache, kLogDebug, |
355 | "transaction for %s would overrun the cache limit by %ld", | ||
356 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
100 | transaction->buffer.id.ToString().c_str(), overrun); |
357 | 50 | perf::Inc(counters_.n_full); | |
358 | 50 | return -ENOSPC; | |
359 | } | ||
360 | |||
361 |
1/2✓ Branch 1 taken 785 times.
✗ Branch 2 not taken.
|
785 | const int rc = store->Commit(transaction->buffer); |
362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 785 times.
|
785 | 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 785 times.
✗ Branch 3 not taken.
|
785 | LogCvmfs(kLogCache, kLogDebug, "committed %s to cache", |
368 |
1/2✓ Branch 1 taken 785 times.
✗ Branch 2 not taken.
|
1570 | transaction->buffer.id.ToString().c_str()); |
369 | 785 | return 0; | |
370 | } | ||
371 |