MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / reserve

Method reserve

src/storage/buffer_manager/buffer_manager.cpp:372–426  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

370}
371
372bool BufferManager::reserve(uint64_t sizeToReserve) {
373 // Reserve the memory for the page.
374 usedMemory += sizeToReserve;
375 uint64_t totalClaimedMemory = 0;
376 uint64_t nonEvictableClaimedMemory = 0;
377 const auto needMoreMemory = [&]() {
378 // The only time we should exceed the buffer pool size should be when threads are currently
379 // attempting to reserve space and have pre-allocated space. So if we've claimed enough
380 // space for what we're trying to reserve, then we can continue even if the current total is
381 // higher than the buffer pool size as we should never actually exceed the buffer pool size.
382 return sizeToReserve > totalClaimedMemory &&
383 // usedMemory - totalClaimedMemory could underflow
384 usedMemory > bufferPoolSize.load() - totalClaimedMemory;
385 };
386 uint8_t failedCount = 0;
387 // Evict pages if necessary until we have enough memory.
388 while (needMoreMemory()) {
389 uint64_t memoryClaimed = 0;
390 // Avoid reducing the evictable memory below 1/2 at first to reduce thrashing if most of the
391 // memory is non-evictable
392 if (!spiller || usedMemory - nonEvictableMemory > bufferPoolSize / 2) {
393 memoryClaimed = evictPages();
394 } else {
395 auto [_memoryClaimed, nowEvictableMemory] = spiller->claimNextGroup();
396 memoryClaimed = _memoryClaimed;
397 nonEvictableClaimedMemory += _memoryClaimed;
398 nonEvictableMemory -= nowEvictableMemory;
399 // If we're unable to claim anything from the spiller, fall back to evicting pages
400 // We may also need to evict pages if the spiller just unpins BM pages
401 if (memoryClaimed == 0 || nowEvictableMemory > 0) {
402 memoryClaimed = evictPages();
403 }
404 }
405 if (memoryClaimed == 0 && needMoreMemory()) {
406 if (failedCount++ < 2) {
407 // If we failed to find any memory to free, try waiting briefly for other threads to
408 // stop using memory
409 std::this_thread::sleep_for(std::chrono::milliseconds(5));
410 } else {
411 // Cannot find more pages to be evicted. Free the memory we reserved and return
412 // false.
413 freeUsedMemory(sizeToReserve + totalClaimedMemory);
414 nonEvictableMemory -= nonEvictableClaimedMemory;
415 return false;
416 }
417 }
418 totalClaimedMemory += memoryClaimed;
419 }
420 // Have enough memory available now
421 if (totalClaimedMemory > 0) {
422 freeUsedMemory(totalClaimedMemory);
423 nonEvictableMemory -= nonEvictableClaimedMemory;
424 }
425 return true;
426}
427
428uint64_t BufferManager::tryEvictPage(std::atomic<EvictionCandidate>& _candidate) {
429 auto candidate = _candidate.load();

Callers 1

mallocBufferMethod · 0.45

Calls 2

claimNextGroupMethod · 0.80
loadMethod · 0.45

Tested by

no test coverage detected