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