Copy an election's votes and hashes without node-based containers (#5218) * Say why the ballot weighs blocks in a small flat map The map of vote weight per block hash is a sorted vector with inline room for a few entries, which the header left unexplained. The ballot now names the type, `weight_map`, and its comment says what the container is and why it fits an election that rarely weighs more than a few hashes. * Copy an election's votes flat for the request loop An election handed the request loop a snapshot of its votes as a std::unordered_map built from the ballot's flat map, one node per voter plus the table, every time a vote request or block broadcast was due, and the solicitor only looked representatives up in it. The ballot now names its vote map type, and the snapshot, the extended status and the ballot's copy use it, so a copy is one allocation. The public `election::votes ()`, which only tests call, keeps returning a std::unordered_map. * Log an election's hashes without building a hash set The debug logs on election start, erase and expiry listed the held block hashes through a std::unordered_set built from a copy of the ballot's block map, whether the log was on or not. The ballot now hands its held hashes out in a small vector sized for the default block limit. * Keep the ballot's held blocks in a small flat map The ballot kept its competing blocks in a std::unordered_map, a node per block and a hashed lookup for every held-block check a counted vote makes, while the vote weight per hash beside them already sits in a small flat map. An election rarely holds more than a few blocks, so the held blocks move to the same container: the first ones need no allocation and a check is a few comparisons. Eviction already breaks ties by hash, so the sorted order changes nothing there. The ballot names the type, `block_map`, and hands it out as is from `blocks ()`, through the election's copy and in the extended status, so the RPC and log views of an election's blocks no longer rebuild a std::unordered_map from it. * List an election's hashes only when the log line is emitted The four active elections debug lines passed the election's held block hashes as a ready-made list, so every start, erase, checkup cancel and stale report locked the election and copied its hashes before spdlog compared the level and dropped the line. The hashes now go in as a lazy wrapper, `nano::log::as_election_hashes`, whose stream operator fetches and joins them only while the line is formatted, in the style of the lib's `as_nano` and `as_size` wrappers. Node types get their own formatting header for it, as the transport layer has. * Build an election's extended status only when tracing can emit it confirm_once built the extended status on every confirmation, a copy of the votes and blocks plus a full tally with a weight query per voter, to feed a trace line that is compiled out without tracing and a debug line that only reads four counters the plain status beside it already carries. The debug line now reads the plain status, and both the confirmation and the expiry trace calls build the extended status inside a compile-time tracing check, so a build without tracing never copies and tallies an election just to log it.
__________
Type: commit
Hash: 0b9ad5e5474a25e952afd3304a7f3023fd2457e5
Created: yesterday
__________
gr0v1ty/nano-node:0b9ad5e5474a25e952afd3304a7f3023fd2457e5
| Test Case | Status | Duration | Median Deviation | Log | Graph |
|---|