in_thread_accounts_load.rs
Overview
This file defines the InThreadAccountsLoad struct and its associated functionality for analyzing and managing the load of accounts within a single thread context during transaction processing. It focuses on tracking distribution patterns of account routing bits within transaction messages contained in a block and provides mechanisms for determining optimal bit-based splits to balance workload. The file is primarily concerned with data aggregation about account routing bit usage and suggests splits that can be used in load balancing strategies.
Structs and Types
InThreadAccountsLoad
A structure holding account load metrics related to transaction processing within a thread.
Fields
total_transactions_count: i64
Tracks the total number of transactions accounted for in this load measurement.zero_bits_count: [[u32; 256]; 2]
A 2D fixed-size array that counts how many times each bit position in the account routing bits is zero across all accounted transactions. The outer dimension is size 2, and the inner dimension is 256 bits, representing two segments of routing bits.
Constants
MAX_ROUTE_PART_SPLIT: usize
Determines how many parts of the account routing bitmask are considered for splitting. It is set based on the feature flag allow-dappid-thread-split:If enabled:
2Otherwise:
1
Implementations for InThreadAccountsLoad
new_from<TOptimisticState>(block: &AckiNackiBlock, block_state: Arc<TOptimisticState>) -> Self
Creates a new InThreadAccountsLoad instance initialized by appending load data derived from the specified block and its optimistic state.
Parameters:
block: &AckiNackiBlock— The block containing transactions to analyze.block_state: Arc<TOptimisticState>— Shared reference to an optimistic state implementing theOptimisticStatetrait.
Returns:
A fully constructedInThreadAccountsLoadwith load data from the block.Usage Example:
let load = InThreadAccountsLoad::new_from(&block, block_state.clone());Implementation Detail:
Starts with a default instance and callsappend_fromto accumulate load data.
best_split(&self, current_bitmask: &Bitmask<AccountRouting>) -> Option<Bitmask<AccountRouting>>
Determines the best bit to split on, given the current bitmask, to balance the load between zero and one bits in the account routing.
Parameters:
current_bitmask: &Bitmask<AccountRouting>— The current routing bitmask indicating bits already used for splitting.
Returns:
AnOption<Bitmask<AccountRouting>>that contains a new bitmask with one additional split bit set if a suitable split is found; otherwise,None.Behavior:
Iterates over the bits in the routing mask according to
MAX_ROUTE_PART_SPLIT.Ignores bits already included in the current bitmask or bits where all transactions have the same bit value.
Chooses the bit with the smallest difference between zero and one counts (i.e., closest to evenly splitting transactions).
Returns a new bitmask with this best bit added to both the meaningful and mask bits.
Usage Example:
if let Some(new_mask) = load.best_split(¤t_mask) { // Use new_mask for load balancing }Important:
This function usesmeaningful_mask_bits()andmask_bits()from theBitmasktype for bit queries and updates.
append_from<TOptimisticState>(&mut self, block: &AckiNackiBlock, _block_state: Arc<TOptimisticState>)
Accumulates load data from the given block into the current InThreadAccountsLoad instance.
Parameters:
block: &AckiNackiBlock— The block to extract transaction messages from._block_state: Arc<TOptimisticState>— The optimistic state (unused in this function but required by trait bounds).
Returns:
()(modifiesselfin place).Behavior:
Iterates over inbound message descriptors in the block's extra data.
For each message, attempts to extract the source account and source DApp identifier.
Constructs an
AccountRoutingfrom the DApp ID and source account.Converts the routing into a bit-array representation.
Updates
zero_bits_countfor every bit that is false (zero) in the routing.Increments
total_transactions_countfor each message processed.
Implementation Details:
Uses
read_extra()andread_in_msg_descr()to get inbound messages.Uses
get_int_src_account_id()to get source account.Uses
int_header()for optional DApp ID extraction.Uses tuple
(Some(dapp_id), source)to createAccountRouting.Uses nested loops over bits to update zero counts.
add_in_place(&mut self, other: &Self)
Adds the account load counts from another InThreadAccountsLoad into self.
Parameters:
other: &Self— AnotherInThreadAccountsLoadinstance to add.
Returns:
()(modifiesselfin place).Behavior:
Adds
zero_bits_countelement-wise.Adds
total_transactions_count.
Usage Example:
load1.add_in_place(&load2);
sub_in_place(&mut self, other: &Self)
Subtracts the account load counts of another InThreadAccountsLoad from self.
Parameters:
other: &Self— AnotherInThreadAccountsLoadinstance to subtract.
Returns:
()(modifiesselfin place).Behavior:
Subtracts
zero_bits_countelement-wise.Subtracts
total_transactions_count.
Usage Example:
load1.sub_in_place(&load2);
Default implementation
Provides a default constructor setting total_transactions_count to zero and zeroing out all bit counts.
Interactions with Other Modules
AckiNackiBlock(frommultithreading::load_balancing_service)
Used as the source of transaction blocks for load calculation.OptimisticStateTrait (multithreading::load_balancing_service)
Represents the state of the block that may affect analysis.Bitmask<AccountRouting>(frombitmask::mask)
Used to represent and manipulate bitmasks of account routing bits for splitting decisions.AccountRoutingandDAppIdentifier(fromtypes)
Used to convert transaction source information into routing bits for load tracking.DirectBitAccessTrait (fromtypes::direct_bit_access_operations)
Provides bit-level operations on routing masks.
Key Algorithms and Implementation Notes
The core algorithm in
best_splittries to find a bit in the account routing mask that best balances the load by minimizing the absolute difference between the count of zero bits and one bits among transactions.append_fromextracts and decodes account routing bits from inbound messages in a block, counting zero bits to form a statistical profile of bit usage.The 2D array
zero_bits_counttracks bit positions split into two segments of 256 bits each, supporting up to 512 bits if the feature flag allows (MAX_ROUTE_PART_SPLIT).The
add_in_placeandsub_in_placemethods enable efficient incremental updates or removals of load data by combining or subtracting counts from other instances.
Visual Diagram of InThreadAccountsLoad Structure and Methods
classDiagram
class InThreadAccountsLoad {
- total_transactions_count: i64
- zero_bits_count: ["[u32;256"];2]
+ new_from()
+ best_split()
+ append_from()
+ add_in_place()
+ sub_in_place()
}
Usage Context
The InThreadAccountsLoad struct and its methods are intended to be used in the context of multi-threaded load balancing for transaction processing. By analyzing account routing bits across transactions in a block, the system can decide how to split workload across threads efficiently, improving parallelism and throughput.
This file's functionality integrates closely with load balancing services and multithreading infrastructure, as indicated by its reliance on types like AckiNackiBlock, OptimisticState, and routing bitmasks. It acts as a utility to gather statistics and suggest workload partitioning strategies based on transaction source characteristics. For more details on load balancing and transaction routing concepts, see Load Balancing Service and Account Routing.