Currently, there are some useless includes in the codebase. We can use a tool named include-what-you-use to optimize these includes. By using a strict include-what-you-use policy, we can get lots of benefits from it.
121 lines
4.9 KiB
C++
121 lines
4.9 KiB
C++
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
#include "vec/common/arena.h"
|
|
|
|
#include <gtest/gtest-message.h>
|
|
#include <gtest/gtest-test-part.h>
|
|
#include <stdint.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include "gtest/gtest_pred_impl.h"
|
|
#include "util/bit_util.h"
|
|
|
|
namespace doris {
|
|
|
|
TEST(ArenaTest, Basic) {
|
|
vectorized::Arena p;
|
|
vectorized::Arena p2;
|
|
vectorized::Arena p3;
|
|
|
|
// allocate a total of 24K in 32-byte pieces (for which we only request 25 bytes)
|
|
for (int i = 0; i < 768; ++i) {
|
|
// pads to 32 bytes
|
|
p.alloc(25);
|
|
}
|
|
std::cout << "ArenaTest 111 " << p.size() << ", " << p.remaining_space_in_current_chunk()
|
|
<< std::endl;
|
|
// 4096 + 4096 * 2 < 25 * 768 < 4096 + 4096 * 2 + 4096 * 2 * 2
|
|
EXPECT_EQ((4 + 8 + 16) * 1024, p.size());
|
|
EXPECT_EQ(16 * 1024 - 25 * (768 - (4 * 1024 - 15) / 25 - (8 * 1024 - 15) / 25) - 15,
|
|
p.remaining_space_in_current_chunk()); // padding 15 bytes
|
|
|
|
// we allocate 10K, for which there isn't enough room in the current chunk,
|
|
// so another one is allocated (32K)
|
|
p.alloc(10 * 1024);
|
|
std::cout << "ArenaTest 222 " << p.size() << ", " << p.remaining_space_in_current_chunk()
|
|
<< std::endl;
|
|
EXPECT_EQ((4 + 8 + 16 + 32) * 1024, p.size());
|
|
EXPECT_EQ(32 * 1024 - 10 * 1024 - 15, p.remaining_space_in_current_chunk());
|
|
|
|
// we allocate 65K, which doesn't fit into the current chunk or the default
|
|
// size of the next allocated chunk (64K)
|
|
p.alloc(65 * 1024);
|
|
std::cout << "ArenaTest 333 " << p.size() << ", " << p.remaining_space_in_current_chunk()
|
|
<< std::endl;
|
|
// (max(65 * 1024 + 15, 32 * 1024 * 2) + 4096 - 1) / 4096 * 4096
|
|
EXPECT_EQ((4 + 8 + 16 + 32) * 1024 + (65 * 1024 + 15 + 4096 - 1) / 4096 * 4096, p.size());
|
|
EXPECT_EQ((65 * 1024 + 15 + 4096 - 1) / 4096 * 4096 - 65 * 1024 - 15,
|
|
p.remaining_space_in_current_chunk());
|
|
}
|
|
|
|
// Maximum allocation size which exceeds 32-bit.
|
|
#define LARGE_ALLOC_SIZE (1LL << 32)
|
|
|
|
TEST(ArenaTest, MaxAllocation) {
|
|
int64_t int_max_rounded = BitUtil::round_up(LARGE_ALLOC_SIZE, 8);
|
|
size_t linear_growth_threshold = 128 * 1024 * 1024;
|
|
|
|
// Allocate a single LARGE_ALLOC_SIZE chunk
|
|
{
|
|
vectorized::Arena p1;
|
|
char* ptr = p1.alloc(LARGE_ALLOC_SIZE);
|
|
EXPECT_TRUE(ptr != nullptr);
|
|
EXPECT_EQ(4096 + (int_max_rounded + 15 + 4096 - 1) / 4096 * 4096, p1.size());
|
|
EXPECT_EQ((int_max_rounded + 15 + 4096 - 1) / 4096 * 4096 - int_max_rounded - 15,
|
|
p1.remaining_space_in_current_chunk());
|
|
}
|
|
|
|
// Allocate a small chunk (DEFAULT_INITIAL_CHUNK_SIZE) followed by an LARGE_ALLOC_SIZE chunk
|
|
{
|
|
vectorized::Arena p2;
|
|
p2.alloc(8);
|
|
EXPECT_EQ(p2.size(), 4096);
|
|
EXPECT_EQ(p2.remaining_space_in_current_chunk(), 4096 - 15 - 8);
|
|
char* ptr = p2.alloc(LARGE_ALLOC_SIZE);
|
|
EXPECT_TRUE(ptr != nullptr);
|
|
EXPECT_EQ(p2.size(), 4096LL + (int_max_rounded + 15 + 4096 - 1) / 4096 * 4096);
|
|
}
|
|
|
|
{
|
|
// Allocate three LARGE_ALLOC_SIZE chunks followed by a small chunk followed by another LARGE_ALLOC_SIZE
|
|
// chunk
|
|
vectorized::Arena p3;
|
|
p3.alloc(LARGE_ALLOC_SIZE);
|
|
// Allocates new int_max_rounded * 2 chunk
|
|
// NOTE: exceed MAX_CHUNK_SIZE limit, will not *2
|
|
char* ptr = p3.alloc(LARGE_ALLOC_SIZE);
|
|
EXPECT_TRUE(ptr != nullptr);
|
|
size_t size_after_grow =
|
|
((LARGE_ALLOC_SIZE + 15 + linear_growth_threshold - 1) / linear_growth_threshold) *
|
|
linear_growth_threshold;
|
|
EXPECT_EQ(4096 + (int_max_rounded + 15 + 4096 - 1) / 4096 * 4096 +
|
|
(size_after_grow + 4096 - 1) / 4096 * 4096,
|
|
p3.size());
|
|
// Uses existing int_max_rounded * 2 chunk
|
|
ptr = p3.alloc(LARGE_ALLOC_SIZE);
|
|
EXPECT_TRUE(ptr != nullptr);
|
|
EXPECT_EQ(4096 + (int_max_rounded + 15 + 4096 - 1) / 4096 * 4096 +
|
|
(size_after_grow + 4096 - 1) / 4096 * 4096 * 2,
|
|
p3.size());
|
|
EXPECT_EQ((size_after_grow + 4096 - 1) / 4096 * 4096 - int_max_rounded - 15,
|
|
p3.remaining_space_in_current_chunk());
|
|
}
|
|
}
|
|
} // namespace doris
|