blob: 7d139414c3e74ea8b12abcaba031e97e800bb8f4 [file] [log] [blame]
/**
* 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 <numa.h>
#include <cstddef>
#include <memory>
#include "catalog/NUMAPlacementScheme.hpp"
#include "catalog/PartitionSchemeHeader.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "gtest/gtest.h"
namespace quickstep {
// Test to check if the number of NUMA nodes in the system
// is the same as the number of NUMA nodes as reported by
// the NUMAPlacementScheme.
TEST(NUMAPlacementSchemeTest, CheckNumNUMANodes) {
// Number of partitions in the Catalog Relation.
std::size_t num_partitions = 4;
// Create a NUMAPlacementScheme object with the num_partitions.
std::unique_ptr<NUMAPlacementScheme> placement_scheme(
new NUMAPlacementScheme(num_partitions));
// Get the number of NUMA nodes in the system.
const std::size_t num_numa_nodes = numa_num_configured_nodes();
// Check if the number of NUMA nodes in NUMAPlacementScheme and that returned
// from the system are the same.
EXPECT_EQ(num_numa_nodes, placement_scheme->getNumNUMANodes());
}
// Test to check if the partitions are assigned the available NUMA nodes in a
// round-robin manner.
TEST(NUMAPlacementSchemeTest, CheckNUMANodesAssignment) {
// Number of partitions in the Catalog Relation.
std::size_t num_partitions = 64;
// Create a NUMAPlacementScheme object with the num_partitions.
std::unique_ptr<NUMAPlacementScheme> placement_scheme(
new NUMAPlacementScheme(num_partitions));
// Check that the partitions are assigned to the NUMA nodes in a
// round-robbin manner. Partition 0 should be assigned to NUMA node 0,
// partition 1 should be assigned to NUMA node 1, and so on. Partition n
// should be assigned to NUMA node n modulus number_of_NUMA_nodes.
for (std::size_t part_num = 0;
part_num < num_partitions;
++part_num) {
EXPECT_EQ(static_cast<int>(part_num % placement_scheme->getNumNUMANodes()),
placement_scheme->getNUMANodeForPartition(part_num));
}
}
// Test the serialization and deserialization of NUMAPlacementScheme object.
TEST(NUMAPlacementSchemeTest, NUMAPlacementSchemeSerializationTest) {
// Number of blocks in the Catalog Relation.
constexpr int kNumBlocks = 10;
// Number of partitions in the Catalog Relation.
std::size_t num_partitions = 64;
// Create a HashPartitionSchemeHeader object with 64 partitions and attribute
// 0 as the partitioning attribute.
std::unique_ptr<PartitionSchemeHeader> partition_scheme_header(
new HashPartitionSchemeHeader(num_partitions, { 0 }));
// Create a NUMAPlacementScheme object with the num_partitions.
std::unique_ptr<NUMAPlacementScheme> placement_scheme(
new NUMAPlacementScheme(num_partitions));
// Add some entries into block to NUMA node map.
for (block_id block = 0; block < kNumBlocks; ++block) {
placement_scheme->addBlockToNUMANodeMap(
block, block % placement_scheme->getNumNUMANodes());
}
// Check if the BlockToNUMANodeMap has exactly the same entries that we just
// inserted..
for (block_id block = 0; block < kNumBlocks; ++block) {
EXPECT_EQ(static_cast<int>(block % placement_scheme->getNumNUMANodes()),
placement_scheme->getNUMANodeForBlock(block));
}
// Create a new placement scheme object from the protobuf version of the
// previously created placement scheme object. Note that serialization is done
// using getProto() and deserialization is done using
// ReconstructFromProto() methods, respectively.
std::unique_ptr<NUMAPlacementScheme> placement_scheme_from_proto;
placement_scheme_from_proto.reset(
NUMAPlacementScheme::ReconstructFromProto(
placement_scheme->getProto(), partition_scheme_header->getNumPartitions()));
// Check if the number of NUMA nodes is the same in both the placement scheme
// objects.
EXPECT_EQ(placement_scheme->getNumNUMANodes(),
placement_scheme_from_proto->getNumNUMANodes());
// Check if the mapping between the partitions to the NUMA nodes is the same
// in both the placement scheme objects.
for (std::size_t part_id = 0; part_id < num_partitions; ++part_id) {
EXPECT_EQ(placement_scheme->getNUMANodeForPartition(part_id),
placement_scheme_from_proto->getNUMANodeForPartition(part_id));
}
// Check if the entries in the block to NUMA node map are the same in both the
// placement scheme objects.
for (block_id block = 0; block < kNumBlocks; ++block) {
EXPECT_EQ(placement_scheme->getNUMANodeForBlock(block),
placement_scheme_from_proto->getNUMANodeForBlock(block));
}
}
} // namespace quickstep