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:
parent
0dc23f1a32
commit
927d1b9ae2
4 changed files with 48 additions and 21 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 &);
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue