| 1442 | } |
| 1443 | |
| 1444 | void BufferPoolTest::TestEvictionPolicy(int64_t page_size) { |
| 1445 | // The eviction policy changes if there are multiple NUMA nodes, because buffers from |
| 1446 | // clean pages on the local node are claimed in preference to free buffers on the |
| 1447 | // non-local node. The rest of the test assumes that it executes on a single NUMA node. |
| 1448 | if (CpuInfo::GetMaxNumNumaNodes() > 1) CpuTestUtil::PinToCore(0); |
| 1449 | const int MAX_NUM_BUFFERS = 5; |
| 1450 | int64_t total_mem = MAX_NUM_BUFFERS * page_size; |
| 1451 | global_reservations_.InitRootTracker(NewProfile(), total_mem); |
| 1452 | MetricGroup tmp_metrics("test-metrics"); |
| 1453 | BufferPool pool(&tmp_metrics, TEST_BUFFER_LEN, total_mem, total_mem); |
| 1454 | |
| 1455 | ClientHandle client; |
| 1456 | RuntimeProfile* profile = NewProfile(); |
| 1457 | ASSERT_OK(pool.RegisterClient("test client", NewFileGroup(), &global_reservations_, |
| 1458 | nullptr, total_mem, profile, &client)); |
| 1459 | ASSERT_TRUE(client.IncreaseReservation(total_mem)); |
| 1460 | |
| 1461 | RuntimeProfileBase* buffer_pool_profile = nullptr; |
| 1462 | vector<RuntimeProfileBase*> profile_children; |
| 1463 | profile->GetChildren(&profile_children); |
| 1464 | for (RuntimeProfileBase* child : profile_children) { |
| 1465 | if (child->name() == "Buffer pool") { |
| 1466 | buffer_pool_profile = child; |
| 1467 | break; |
| 1468 | } |
| 1469 | } |
| 1470 | ASSERT_TRUE(buffer_pool_profile != nullptr); |
| 1471 | RuntimeProfile::Counter* cumulative_bytes_alloced = |
| 1472 | buffer_pool_profile->GetCounter("CumulativeAllocationBytes"); |
| 1473 | RuntimeProfile::Counter* write_ios = buffer_pool_profile->GetCounter("WriteIoOps"); |
| 1474 | RuntimeProfile::Counter* read_ios = buffer_pool_profile->GetCounter("ReadIoOps"); |
| 1475 | |
| 1476 | vector<PageHandle> pages; |
| 1477 | CreatePages(&pool, &client, page_size, total_mem, &pages); |
| 1478 | WriteData(pages, 0); |
| 1479 | |
| 1480 | // Unpin pages. Writes should be started and memory should not be deallocated. |
| 1481 | EXPECT_EQ(total_mem, cumulative_bytes_alloced->value()); |
| 1482 | EXPECT_EQ(total_mem, pool.GetSystemBytesAllocated()); |
| 1483 | UnpinAll(&pool, &client, &pages); |
| 1484 | ASSERT_GT(write_ios->value(), 0); |
| 1485 | |
| 1486 | // Re-pin all the pages and validate their data. This should not require reading the |
| 1487 | // pages back from disk. |
| 1488 | ASSERT_OK(PinAll(&pool, &client, &pages)); |
| 1489 | ASSERT_EQ(0, read_ios->value()); |
| 1490 | VerifyData(pages, 0); |
| 1491 | |
| 1492 | // Unpin all pages. Writes should be started again. |
| 1493 | int64_t prev_write_ios = write_ios->value(); |
| 1494 | UnpinAll(&pool, &client, &pages); |
| 1495 | ASSERT_GT(write_ios->value(), prev_write_ios); |
| 1496 | |
| 1497 | // Allocate two more buffers. Two unpinned pages must be evicted to make room. |
| 1498 | const int NUM_EXTRA_BUFFERS = 2; |
| 1499 | vector<BufferHandle> extra_buffers; |
| 1500 | AllocateBuffers( |
| 1501 | &pool, &client, page_size, page_size * NUM_EXTRA_BUFFERS, &extra_buffers); |
nothing calls this directly
no test coverage detected