Add comments to class nano::prioritization (#3742)

* Remove drop function which is unused, even if passed in the constructor

* Mark function nano::prioritization::dump as const

* Make nano::prioritization::maximum a private member

* Add comments to class nano::prioritization
This commit is contained in:
Dimitrios Siganos 2022-02-23 15:49:42 +00:00 committed by GitHub
commit 5d6feca8b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 10 deletions

View file

@ -14,6 +14,7 @@ bool nano::prioritization::value_type::operator== (value_type const & other_a) c
return time == other_a.time && block->hash () == other_a.block->hash (); return time == other_a.time && block->hash () == other_a.block->hash ();
} }
/** Moves the bucket pointer to the next bucket */
void nano::prioritization::next () void nano::prioritization::next ()
{ {
++current; ++current;
@ -23,6 +24,7 @@ void nano::prioritization::next ()
} }
} }
/** Seek to the next non-empty bucket, if one exists */
void nano::prioritization::seek () void nano::prioritization::seek ()
{ {
next (); next ();
@ -32,6 +34,7 @@ void nano::prioritization::seek ()
} }
} }
/** Initialise the schedule vector */
void nano::prioritization::populate_schedule () void nano::prioritization::populate_schedule ()
{ {
for (auto i = 0; i < buckets.size (); ++i) for (auto i = 0; i < buckets.size (); ++i)
@ -40,8 +43,11 @@ void nano::prioritization::populate_schedule ()
} }
} }
nano::prioritization::prioritization (uint64_t maximum, std::function<void (std::shared_ptr<nano::block>)> const & drop_a) : /**
drop{ drop_a }, * Prioritization constructor, construct a container containing approximately 'maximum' number of blocks.
* @param maximum number of blocks that this container can hold, this is a soft and approximate limit.
*/
nano::prioritization::prioritization (uint64_t maximum) :
maximum{ maximum } maximum{ maximum }
{ {
static std::size_t constexpr bucket_count = 129; static std::size_t constexpr bucket_count = 129;
@ -57,6 +63,10 @@ nano::prioritization::prioritization (uint64_t maximum, std::function<void (std:
current = schedule.begin (); current = schedule.begin ();
} }
/**
* 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.
*/
void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> block) void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> block)
{ {
auto was_empty = empty (); auto was_empty = empty ();
@ -76,6 +86,7 @@ void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> blo
} }
} }
/** Return the highest priority block of the current bucket */
std::shared_ptr<nano::block> nano::prioritization::top () const std::shared_ptr<nano::block> nano::prioritization::top () const
{ {
debug_assert (!empty ()); debug_assert (!empty ());
@ -84,6 +95,7 @@ std::shared_ptr<nano::block> nano::prioritization::top () const
return result; return result;
} }
/** Pop the current block from the container and seek to the next block, if it exists */
void nano::prioritization::pop () void nano::prioritization::pop ()
{ {
debug_assert (!empty ()); debug_assert (!empty ());
@ -93,6 +105,7 @@ void nano::prioritization::pop ()
seek (); seek ();
} }
/** Returns the total number of blocks in buckets */
std::size_t nano::prioritization::size () const std::size_t nano::prioritization::size () const
{ {
std::size_t result{ 0 }; std::size_t result{ 0 };
@ -103,22 +116,26 @@ std::size_t nano::prioritization::size () const
return result; return result;
} }
/** Returns number of buckets, 129 by default */
std::size_t nano::prioritization::bucket_count () const std::size_t nano::prioritization::bucket_count () const
{ {
return buckets.size (); return buckets.size ();
} }
/** Returns number of items in bucket with index 'index' */
std::size_t nano::prioritization::bucket_size (std::size_t index) const std::size_t nano::prioritization::bucket_size (std::size_t index) const
{ {
return buckets[index].size (); return buckets[index].size ();
} }
/** Returns true if all buckets are empty */
bool nano::prioritization::empty () const bool nano::prioritization::empty () const
{ {
return std::all_of (buckets.begin (), buckets.end (), [] (priority const & bucket_a) { return bucket_a.empty (); }); return std::all_of (buckets.begin (), buckets.end (), [] (priority const & bucket_a) { return bucket_a.empty (); });
} }
void nano::prioritization::dump () /** Print the state of the class in stderr */
void nano::prioritization::dump () const
{ {
for (auto const & i : buckets) for (auto const & i : buckets)
{ {

View file

@ -9,6 +9,17 @@
namespace nano namespace nano
{ {
class block; class block;
/** A container for holding blocks and their arrival/creation time.
*
* The container consists of a number of buckets. Each bucket holds an ordered set of 'value_type' items.
* The buckets are accessed in a round robin fashion. The index 'current' holds the index of the bucket to access next.
* When a block is inserted, the bucket to go into is determined by the account balance and the priority inside that
* bucket is determined by its creation/arrival time.
*
* The arrival/creation time is only an approximation and it could even be wildly wrong,
* for example, in the event of bootstrapped blocks.
*/
class prioritization final class prioritization final
{ {
class value_type class value_type
@ -19,19 +30,31 @@ class prioritization final
bool operator< (value_type const & other_a) const; bool operator< (value_type const & other_a) const;
bool operator== (value_type const & other_a) const; bool operator== (value_type const & other_a) const;
}; };
using priority = std::set<value_type>; using priority = std::set<value_type>;
/** container for the buckets to be read in round robin fashion */
std::vector<priority> buckets; std::vector<priority> buckets;
/** thresholds that define the bands for each bucket, the minimum balance an account must have to enter a bucket,
* the container writes a block to the lowest indexed bucket that has balance larger than the bucket's minimum value */
std::vector<nano::uint128_t> minimums; std::vector<nano::uint128_t> minimums;
/** Contains bucket indicies to iterate over when making the next scheduling decision */
std::vector<uint8_t> schedule;
/** index of bucket to read next */
decltype (schedule)::const_iterator current;
/** maximum number of blocks in whole container, each bucket's maximum is maximum / bucket_number */
uint64_t const maximum;
void next (); void next ();
void seek (); void seek ();
void populate_schedule (); void populate_schedule ();
std::function<void (std::shared_ptr<nano::block>)> drop;
// Contains bucket indicies to iterate over when making the next scheduling decision
std::vector<uint8_t> schedule;
decltype (schedule)::const_iterator current;
public: public:
prioritization (uint64_t maximum = 250000u, std::function<void (std::shared_ptr<nano::block>)> const & drop_a = nullptr); prioritization (uint64_t maximum = 250000u);
void push (uint64_t time, std::shared_ptr<nano::block> block); void push (uint64_t time, std::shared_ptr<nano::block> block);
std::shared_ptr<nano::block> top () const; std::shared_ptr<nano::block> top () const;
void pop (); void pop ();
@ -39,8 +62,7 @@ public:
std::size_t bucket_count () const; std::size_t bucket_count () const;
std::size_t bucket_size (std::size_t index) const; std::size_t bucket_size (std::size_t index) const;
bool empty () const; bool empty () const;
void dump (); void dump () const;
uint64_t const maximum;
std::unique_ptr<nano::container_info_component> collect_container_info (std::string const &); std::unique_ptr<nano::container_info_component> collect_container_info (std::string const &);
}; };