| 638 | } |
| 639 | |
| 640 | void BufferPoolTest::TestBufferAllocation(bool reserved) { |
| 641 | // Allocate many buffers, each a power-of-two multiple of the minimum buffer length. |
| 642 | const int NUM_BUFFERS = 16; |
| 643 | const int64_t MAX_BUFFER_LEN = TEST_BUFFER_LEN << (NUM_BUFFERS - 1); |
| 644 | |
| 645 | // Total memory required to allocate TEST_BUFFER_LEN, 2*TEST_BUFFER_LEN, ..., |
| 646 | // MAX_BUFFER_LEN. |
| 647 | const int64_t TOTAL_MEM = 2 * MAX_BUFFER_LEN - TEST_BUFFER_LEN; |
| 648 | global_reservations_.InitRootTracker(NULL, TOTAL_MEM); |
| 649 | BufferPool pool(test_env_->metrics(), TEST_BUFFER_LEN, TOTAL_MEM, TOTAL_MEM); |
| 650 | BufferPool::ClientHandle client; |
| 651 | ASSERT_OK(pool.RegisterClient("test client", NULL, &global_reservations_, NULL, |
| 652 | TOTAL_MEM, NewProfile(), &client)); |
| 653 | if (reserved) { |
| 654 | ASSERT_TRUE(client.IncreaseReservationToFit(TOTAL_MEM)); |
| 655 | } |
| 656 | |
| 657 | vector<BufferPool::BufferHandle> handles(NUM_BUFFERS); |
| 658 | |
| 659 | // Create buffers of various valid sizes. |
| 660 | int64_t total_allocated = 0; |
| 661 | for (int i = 0; i < NUM_BUFFERS; ++i) { |
| 662 | int size_multiple = 1 << i; |
| 663 | int64_t buffer_len = TEST_BUFFER_LEN * size_multiple; |
| 664 | int64_t used_before = client.GetUsedReservation(); |
| 665 | if (reserved) { |
| 666 | ASSERT_OK(pool.AllocateBuffer(&client, buffer_len, &handles[i])); |
| 667 | } else { |
| 668 | // Reservation should be automatically increased. |
| 669 | ASSERT_OK(pool.AllocateUnreservedBuffer(&client, buffer_len, &handles[i])); |
| 670 | } |
| 671 | total_allocated += buffer_len; |
| 672 | ASSERT_TRUE(handles[i].is_open()); |
| 673 | ASSERT_TRUE(handles[i].data() != NULL); |
| 674 | ASSERT_EQ(handles[i].len(), buffer_len); |
| 675 | ASSERT_EQ(client.GetUsedReservation(), used_before + buffer_len); |
| 676 | |
| 677 | // Check that pool-wide values are updated correctly. |
| 678 | EXPECT_EQ(total_allocated, pool.GetSystemBytesAllocated()); |
| 679 | EXPECT_EQ(0, pool.GetNumFreeBuffers()); |
| 680 | EXPECT_EQ(0, pool.GetFreeBufferBytes()); |
| 681 | } |
| 682 | |
| 683 | if (!reserved) { |
| 684 | // Allocate all of the memory and test the failure path for unreserved allocations. |
| 685 | BufferPool::BufferHandle tmp_handle; |
| 686 | ASSERT_OK(pool.AllocateUnreservedBuffer(&client, TEST_BUFFER_LEN, &tmp_handle)); |
| 687 | ASSERT_FALSE(tmp_handle.is_open()) << "No reservation for buffer"; |
| 688 | } |
| 689 | |
| 690 | // Close the handles and check memory consumption. |
| 691 | for (int i = 0; i < NUM_BUFFERS; ++i) { |
| 692 | int64_t used_before = client.GetUsedReservation(); |
| 693 | int buffer_len = handles[i].len(); |
| 694 | pool.FreeBuffer(&client, &handles[i]); |
| 695 | ASSERT_EQ(client.GetUsedReservation(), used_before - buffer_len); |
| 696 | } |
| 697 |
nothing calls this directly
no test coverage detected