htp: move transactions list from BTree to VecDeque

As it is more efficient in our case of pipelining requests
pull/13235/head
Philippe Antoine 3 months ago committed by Victor Julien
parent 756f28d086
commit c2756dec75

@ -1,6 +1,5 @@
use crate::{config::Config, log::Logger, transaction::Transaction}; use crate::{config::Config, log::Logger, transaction::Transaction};
use std::collections::btree_map::Entry; use std::collections::VecDeque;
use std::collections::BTreeMap;
/// Transaction is a structure which tracks request and response /// Transaction is a structure which tracks request and response
/// transactions, and guarantees that the current request or /// transactions, and guarantees that the current request or
@ -10,7 +9,7 @@ pub(crate) struct Transactions {
logger: Logger, logger: Logger,
request: usize, request: usize,
response: usize, response: usize,
transactions: BTreeMap<usize, Transaction>, transactions: VecDeque<Transaction>,
} }
impl Transactions { impl Transactions {
@ -21,7 +20,7 @@ impl Transactions {
logger: logger.clone(), logger: logger.clone(),
request: 0, request: 0,
response: 0, response: 0,
transactions: BTreeMap::default(), transactions: VecDeque::new(),
} }
} }
@ -34,7 +33,7 @@ impl Transactions {
// that transaction is started), or zero if neither // that transaction is started), or zero if neither
// request or response transaction exist yet // request or response transaction exist yet
let tx_to_check = std::cmp::max(self.request, self.response); let tx_to_check = std::cmp::max(self.request, self.response);
match self.transactions.get(&tx_to_check) { match self.transactions.get(tx_to_check) {
// Transaction is created, check if it is started // Transaction is created, check if it is started
Some(tx) => tx.index.wrapping_add(tx.is_started() as usize), Some(tx) => tx.index.wrapping_add(tx.is_started() as usize),
// Transaction doesn't exist yet, so the index is the size // Transaction doesn't exist yet, so the index is the size
@ -57,23 +56,24 @@ impl Transactions {
/// Get the current request transaction /// Get the current request transaction
pub(crate) fn request_mut(&mut self) -> Option<&mut Transaction> { pub(crate) fn request_mut(&mut self) -> Option<&mut Transaction> {
let cfg = &self.config;
let logger = &self.logger;
let request = self.request;
let nbtx = self.transactions.len(); let nbtx = self.transactions.len();
match self.transactions.entry(request) { // use rposition as the current request is rather the tx at the back of VecDeque
Entry::Occupied(entry) => Some(entry.into_mut()), if let Some(pos) = self
Entry::Vacant(entry) => { .transactions
if nbtx >= cfg.max_tx as usize { .iter()
return None; .rposition(|tx| tx.index == self.request)
} {
let tx = Transaction::new(cfg, logger, request, true); return Some(&mut self.transactions[pos]);
if let Some(tx) = tx {
return Some(entry.insert(tx));
}
None
}
} }
if nbtx >= self.config.max_tx as usize {
return None;
}
let tx = Transaction::new(self.config, &self.logger, self.request, true);
if let Some(tx) = tx {
self.transactions.push_back(tx);
return self.transactions.back_mut();
}
None
} }
/// Get the current response transaction index /// Get the current response transaction index
@ -91,23 +91,22 @@ impl Transactions {
/// Get the current response transaction /// Get the current response transaction
pub(crate) fn response_mut(&mut self) -> Option<&mut Transaction> { pub(crate) fn response_mut(&mut self) -> Option<&mut Transaction> {
let cfg = &self.config; if let Some(pos) = self
let logger = &self.logger; .transactions
let response = self.response; .iter()
let nbtx = self.transactions.len(); .position(|tx| tx.index == self.response)
match self.transactions.entry(response) { {
Entry::Occupied(entry) => Some(entry.into_mut()), return Some(&mut self.transactions[pos]);
Entry::Vacant(entry) => { }
if nbtx >= cfg.max_tx as usize { if self.transactions.len() >= self.config.max_tx as usize {
return None; return None;
}
let tx = Transaction::new(cfg, logger, response, false);
if let Some(tx) = tx {
return Some(entry.insert(tx));
}
None
}
} }
let tx = Transaction::new(self.config, &self.logger, self.response, false);
if let Some(tx) = tx {
self.transactions.push_back(tx);
return self.transactions.back_mut();
}
None
} }
/// Increment the request transaction number. /// Increment the request transaction number.
@ -128,17 +127,25 @@ impl Transactions {
/// Remove the transaction at the given index. If the transaction /// Remove the transaction at the given index. If the transaction
/// existed, it is returned. /// existed, it is returned.
pub(crate) fn remove(&mut self, index: usize) -> Option<Transaction> { pub(crate) fn remove(&mut self, index: usize) {
self.transactions.remove(&index) if let Some(pos) = self.transactions.iter().position(|tx| tx.index == index) {
self.transactions.remove(pos);
}
} }
/// Get the given transaction by index number /// Get the given transaction by index number
pub(crate) fn get(&self, index: usize) -> Option<&Transaction> { pub(crate) fn get(&self, index: usize) -> Option<&Transaction> {
self.transactions.get(&index) if let Some(pos) = self.transactions.iter().position(|tx| tx.index == index) {
return Some(&self.transactions[pos]);
}
None
} }
/// Get the given transaction by index number /// Get the given transaction by index number
pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut Transaction> { pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut Transaction> {
self.transactions.get_mut(&index) if let Some(pos) = self.transactions.iter().position(|tx| tx.index == index) {
return Some(&mut self.transactions[pos]);
}
None
} }
} }

Loading…
Cancel
Save