pub(crate) struct SelectableTransaction {
pub(crate) gas_limit: u64,
pub(crate) p: f64,
}
impl SelectableTransaction {
pub(crate) fn new(tx_value: f64, gas_limit: u64, alpha: i32) -> Self {
Self { gas_limit, p: tx_value.powi(alpha) }
}
}
pub(crate) type SelectableTransactions = Vec<SelectableTransaction>;
pub(crate) type TransactionIndex = usize;
pub(crate) struct Candidate {
pub(crate) index: TransactionIndex,
pub(crate) start: f64,
pub(crate) end: f64,
pub(crate) is_marked_for_deletion: bool,
}
impl Candidate {
pub(crate) fn new(index: usize, start: f64, end: f64) -> Self {
Self { index, start, end, is_marked_for_deletion: false }
}
}
#[derive(Default)]
pub(crate) struct CandidateList {
pub(crate) candidates: Vec<Candidate>,
pub(crate) total_p: f64,
}
impl CandidateList {
pub(crate) fn new(selectable_txs: &SelectableTransactions) -> Self {
let mut candidates = Vec::with_capacity(selectable_txs.len());
let mut total_p = 0.0;
selectable_txs.iter().enumerate().for_each(|(i, tx)| {
let current_p = tx.p;
let candidate = Candidate::new(i, total_p, total_p + current_p);
candidates.push(candidate);
total_p += current_p;
});
Self { candidates, total_p }
}
pub(crate) fn is_empty(&self) -> bool {
self.candidates.len() == 0
}
pub(crate) fn rebalanced(&self, selectable_txs: &SelectableTransactions) -> Self {
let mut candidates = Vec::with_capacity(self.candidates.len());
let mut total_p = 0.0;
self.candidates.iter().filter(|x| !x.is_marked_for_deletion).for_each(|x| {
let current_p = selectable_txs[x.index].p;
let candidate = Candidate::new(x.index, total_p, total_p + current_p);
candidates.push(candidate);
total_p += current_p;
});
Self { candidates, total_p }
}
pub(crate) fn find(&self, r: f64) -> usize {
let mut min = 0;
let mut max = self.candidates.len() - 1;
loop {
let i = (min + max) / 2;
let candidate = &self.candidates[i];
if candidate.end < r {
min = i + 1;
continue;
} else if candidate.start > r {
max = i - 1;
continue;
}
return i;
}
}
}