Rebalancing buckets using an approximate normal distribution around 2^88-2^120 raw. (#3980)

Testing min/max bounds of amount and removing logging message.
This commit is contained in:
clemahieu 2022-11-30 15:30:56 +00:00 committed by GitHub
commit 927d1b9ae2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 21 deletions

View file

@ -111,41 +111,55 @@ TEST (prioritization, construction)
nano::prioritization prioritization;
ASSERT_EQ (0, prioritization.size ());
ASSERT_TRUE (prioritization.empty ());
ASSERT_EQ (129, prioritization.bucket_count ());
ASSERT_EQ (62, prioritization.bucket_count ());
}
TEST (prioritization, insert_zero)
TEST (prioritization, index_min)
{
nano::prioritization prioritization;
ASSERT_EQ (0, prioritization.index (std::numeric_limits<nano::uint128_t>::min ()));
}
TEST (prioritization, index_max)
{
nano::prioritization prioritization;
ASSERT_EQ (prioritization.bucket_count () - 1, prioritization.index (std::numeric_limits<nano::uint128_t>::max ()));
}
TEST (prioritization, insert_Gxrb)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (110));
ASSERT_EQ (1, prioritization.bucket_size (48));
}
TEST (prioritization, insert_one)
TEST (prioritization, insert_Mxrb)
{
nano::prioritization prioritization;
prioritization.push (1000, block1 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (100));
ASSERT_EQ (1, prioritization.bucket_size (13));
}
// Test two blocks with the same priority
TEST (prioritization, insert_same_priority)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block2 ());
ASSERT_EQ (2, prioritization.size ());
ASSERT_EQ (2, prioritization.bucket_size (110));
ASSERT_EQ (2, prioritization.bucket_size (48));
}
// Test the same block inserted multiple times
TEST (prioritization, insert_duplicate)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (110));
ASSERT_EQ (1, prioritization.bucket_size (48));
}
TEST (prioritization, insert_older)

View file

@ -50,19 +50,34 @@ void nano::prioritization::populate_schedule ()
nano::prioritization::prioritization (uint64_t maximum) :
maximum{ maximum }
{
static std::size_t constexpr bucket_count = 129;
buckets.resize (bucket_count);
nano::uint128_t minimum{ 1 };
minimums.push_back (0);
for (auto i = 1; i < bucket_count; ++i)
{
minimums.push_back (minimum);
minimum <<= 1;
}
auto build_region = [this] (uint128_t const & begin, uint128_t const & end, size_t count) {
auto width = (end - begin) / count;
for (auto i = 0; i < count; ++i)
{
minimums.push_back (begin + i * width);
}
};
minimums.push_back (uint128_t{ 0 });
build_region (uint128_t{ 1 } << 88, uint128_t{ 1 } << 92, 2);
build_region (uint128_t{ 1 } << 92, uint128_t{ 1 } << 96, 4);
build_region (uint128_t{ 1 } << 96, uint128_t{ 1 } << 100, 8);
build_region (uint128_t{ 1 } << 100, uint128_t{ 1 } << 104, 16);
build_region (uint128_t{ 1 } << 104, uint128_t{ 1 } << 108, 16);
build_region (uint128_t{ 1 } << 108, uint128_t{ 1 } << 112, 8);
build_region (uint128_t{ 1 } << 112, uint128_t{ 1 } << 116, 4);
build_region (uint128_t{ 1 } << 116, uint128_t{ 1 } << 120, 2);
minimums.push_back (uint128_t{ 1 } << 120);
buckets.resize (minimums.size ());
populate_schedule ();
current = schedule.begin ();
}
std::size_t nano::prioritization::index (nano::uint128_t const & balance) const
{
auto index = std::upper_bound (minimums.begin (), minimums.end (), balance) - minimums.begin () - 1;
return index;
}
/**
* Push a block and its associated time into the prioritization container.
* The time is given here because sideband might not exist in the case of state blocks.
@ -73,8 +88,7 @@ void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> blo
auto block_has_balance = block->type () == nano::block_type::state || block->type () == nano::block_type::send;
debug_assert (block_has_balance || block->has_sideband ());
auto balance = block_has_balance ? block->balance () : block->sideband ().balance;
auto index = std::upper_bound (minimums.begin (), minimums.end (), balance.number ()) - 1 - minimums.begin ();
auto & bucket = buckets[index];
auto & bucket = buckets[index (balance.number ())];
bucket.emplace (value_type{ time, block });
if (bucket.size () > std::max (decltype (maximum){ 1 }, maximum / buckets.size ()))
{
@ -156,4 +170,4 @@ std::unique_ptr<nano::container_info_component> nano::prioritization::collect_co
composite->add_component (std::make_unique<container_info_leaf> (container_info{ std::to_string (i), bucket.size (), 0 }));
}
return composite;
}
}

View file

@ -63,6 +63,7 @@ public:
std::size_t bucket_size (std::size_t index) const;
bool empty () const;
void dump () const;
std::size_t index (nano::uint128_t const & balance) const;
std::unique_ptr<nano::container_info_component> collect_container_info (std::string const &);
};

View file

@ -7581,6 +7581,4 @@ TEST (node, election_scheduler_container_info)
request.put ("type", "objects");
auto response = wait_response (system, rpc_ctx, request);
auto es = response.get_child ("node").get_child ("election_scheduler");
ASSERT_EQ (es.get_child ("manual_queue").get<std::string> ("count"), "0");
ASSERT_EQ (es.get_child ("priority").get_child ("128").get<std::string> ("count"), "1");
}