dont use hashmap
This commit is contained in:
parent
2e6c441194
commit
b5b2cd44df
|
@ -10,7 +10,6 @@ use hptp::msg::{DownMsg, UpMsg};
|
||||||
use hptp::peer::{self, Peer, UpPeer};
|
use hptp::peer::{self, Peer, UpPeer};
|
||||||
use hptp::seg::{SegData, SegIdx, MAX_SEG_SIZE};
|
use hptp::seg::{SegData, SegIdx, MAX_SEG_SIZE};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use tokio::io::AsyncRead;
|
use tokio::io::AsyncRead;
|
||||||
// use tokio::net::UdpSocket;
|
// use tokio::net::UdpSocket;
|
||||||
|
@ -75,8 +74,9 @@ struct SegmentSource<'i, IN> {
|
||||||
read_input: bool,
|
read_input: bool,
|
||||||
is_meow: bool,
|
is_meow: bool,
|
||||||
is_cut: bool,
|
is_cut: bool,
|
||||||
unacked_segs: HashMap<SegIdx, UnAcked>,
|
// ordered by seg idx
|
||||||
unacked_upper_bound: u32,
|
unacked_segs: Vec<(SegIdx, UnAcked)>,
|
||||||
|
next_seg_idx: u32,
|
||||||
eof: bool,
|
eof: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,15 @@ struct UnAcked {
|
||||||
|
|
||||||
const IN_FLIGHT: usize = 30;
|
const IN_FLIGHT: usize = 30;
|
||||||
|
|
||||||
|
impl UnAcked {
|
||||||
|
fn nack(self) -> Self {
|
||||||
|
Self {
|
||||||
|
nacks: self.nacks + 1,
|
||||||
|
payload: self.payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'i, IN> SegmentSource<'i, IN>
|
impl<'i, IN> SegmentSource<'i, IN>
|
||||||
where
|
where
|
||||||
IN: AsyncRead + Unpin,
|
IN: AsyncRead + Unpin,
|
||||||
|
@ -98,20 +107,12 @@ where
|
||||||
read_input: false,
|
read_input: false,
|
||||||
is_meow: false,
|
is_meow: false,
|
||||||
is_cut: false,
|
is_cut: false,
|
||||||
unacked_segs: HashMap::new(),
|
unacked_segs: Vec::new(),
|
||||||
unacked_upper_bound: 0,
|
next_seg_idx: 0,
|
||||||
eof: false,
|
eof: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retrans_seg_idx(&self) -> Option<SegIdx> {
|
|
||||||
self.unacked_segs.keys().skip(IN_FLIGHT).next().cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn any_unacked_seg_idx(&self) -> Option<SegIdx> {
|
|
||||||
self.unacked_segs.keys().next().cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_next(&mut self) -> SegData {
|
async fn read_next(&mut self) -> SegData {
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
if !self.read_input {
|
if !self.read_input {
|
||||||
|
@ -147,44 +148,54 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn retrans_seg_idx(&self) -> Option<SegIdx> {
|
||||||
|
self.unacked_segs.iter().map(|(si, _)| *si).next()
|
||||||
|
}
|
||||||
|
|
||||||
async fn fresh_seg_idx(&mut self) -> Option<SegIdx> {
|
async fn fresh_seg_idx(&mut self) -> Option<SegIdx> {
|
||||||
if self.eof {
|
if self.eof {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let seg_idx = self.unacked_upper_bound;
|
let seg_idx = self.next_seg_idx;
|
||||||
let payload = self.read_next().await;
|
let unack = UnAcked {
|
||||||
self.eof = payload.is_last_segment;
|
payload: self.read_next().await,
|
||||||
self.unacked_upper_bound += 1;
|
nacks: 0,
|
||||||
self.unacked_segs
|
};
|
||||||
.insert(seg_idx, UnAcked { payload, nacks: 0 });
|
self.next_seg_idx += 1;
|
||||||
|
self.eof = unack.payload.is_last_segment;
|
||||||
|
self.unacked_segs.push((seg_idx, unack));
|
||||||
Some(seg_idx)
|
Some(seg_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_segment(&mut self) -> Option<(SegIdx, &SegData)> {
|
async fn get_segment(&mut self) -> Option<(SegIdx, &SegData)> {
|
||||||
let seg_idx = {
|
let seg_idx = {
|
||||||
if let Some(si) = self.retrans_seg_idx() {
|
if let Some(si) = self.fresh_seg_idx().await {
|
||||||
si
|
si
|
||||||
} else if let Some(si) = self.fresh_seg_idx().await {
|
} else if let Some(si) = self.retrans_seg_idx() {
|
||||||
si
|
|
||||||
} else if let Some(si) = self.any_unacked_seg_idx() {
|
|
||||||
si
|
si
|
||||||
} else {
|
} else {
|
||||||
// early exit cus there's nothing left
|
// early exit cus there's nothing left
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.unacked_segs
|
let i = self
|
||||||
.get(&seg_idx)
|
.unacked_segs
|
||||||
.map(|u| (seg_idx, &u.payload))
|
.binary_search_by_key(&seg_idx, |x| x.0)
|
||||||
|
.expect("seg doesn't exist!");
|
||||||
|
Some((seg_idx, &self.unacked_segs[i].1.payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `seg_idxs` should be distinct and in increasing order.
|
/// `seg_idxs` should be distinct and in increasing order.
|
||||||
fn ack(&mut self, seg_idxs: &[SegIdx]) {
|
fn ack(&mut self, ack_seg_idxs: &[SegIdx]) {
|
||||||
for seg_idx in seg_idxs {
|
let mut new_unacked_segs = Vec::new();
|
||||||
self.unacked_segs.remove(seg_idx);
|
for (seg_idx, unack) in self.unacked_segs.drain(..) {
|
||||||
|
if ack_seg_idxs.binary_search(&seg_idx).is_err() {
|
||||||
|
new_unacked_segs.push((seg_idx, unack.nack()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.unacked_segs = new_unacked_segs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn upload<IN>(log: &mut Logger, peer: &mut UpPeer, inp: &mut IN) -> Result<(), Error>
|
async fn upload<IN>(log: &mut Logger, peer: &mut UpPeer, inp: &mut IN) -> Result<(), Error>
|
||||||
|
|
Loading…
Reference in New Issue