dncurrency/nano/node/prioritization.cpp
theohax 9bb89ab323
Improvements in const correctness and 'const' positioning (#3510)
* Improve const correctness and adhere to 'const' specifier positioning style

Co-authored-by: Mario Ortiz Manero <marioortizmanero@gmail.com>
2021-10-21 16:20:09 +03:00

131 lines
3.2 KiB
C++

#include <nano/lib/blocks.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/prioritization.hpp>
#include <string>
bool nano::prioritization::value_type::operator< (value_type const & other_a) const
{
return time < other_a.time || (time == other_a.time && block->hash () < other_a.block->hash ());
}
bool nano::prioritization::value_type::operator== (value_type const & other_a) const
{
return time == other_a.time && block->hash () == other_a.block->hash ();
}
void nano::prioritization::next ()
{
++current;
if (current == schedule.end ())
{
current = schedule.begin ();
}
}
void nano::prioritization::seek ()
{
next ();
for (std::size_t i = 0, n = schedule.size (); buckets[*current].empty () && i < n; ++i)
{
next ();
}
}
void nano::prioritization::populate_schedule ()
{
for (auto i = 0; i < buckets.size (); ++i)
{
schedule.push_back (i);
}
}
nano::prioritization::prioritization (uint64_t maximum, std::function<void (std::shared_ptr<nano::block>)> const & drop_a) :
drop{ drop_a },
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;
}
populate_schedule ();
current = schedule.begin ();
}
void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> block)
{
auto was_empty = empty ();
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];
bucket.emplace (value_type{ time, block });
if (bucket.size () > std::max (decltype (maximum){ 1 }, maximum / buckets.size ()))
{
bucket.erase (--bucket.end ());
}
if (was_empty)
{
seek ();
}
}
std::shared_ptr<nano::block> nano::prioritization::top () const
{
debug_assert (!empty ());
debug_assert (!buckets[*current].empty ());
auto result = buckets[*current].begin ()->block;
return result;
}
void nano::prioritization::pop ()
{
debug_assert (!empty ());
debug_assert (!buckets[*current].empty ());
auto & bucket = buckets[*current];
bucket.erase (bucket.begin ());
seek ();
}
std::size_t nano::prioritization::size () const
{
std::size_t result{ 0 };
for (auto const & queue : buckets)
{
result += queue.size ();
}
return result;
}
std::size_t nano::prioritization::bucket_count () const
{
return buckets.size ();
}
std::size_t nano::prioritization::bucket_size (std::size_t index) const
{
return buckets[index].size ();
}
bool nano::prioritization::empty () const
{
return std::all_of (buckets.begin (), buckets.end (), [] (priority const & bucket_a) { return bucket_a.empty (); });
}
void nano::prioritization::dump ()
{
for (auto const & i : buckets)
{
for (auto const & j : i)
{
std::cerr << j.time << ' ' << j.block->hash ().to_string () << '\n';
}
}
std::cerr << "current: " << std::to_string (*current) << '\n';
}