use std::net::SocketAddr;
use fnv::FnvHashMap;
use crate::{IdBytes, PeerId};
#[derive(Debug)]
pub struct QueryTable {
id: IdBytes,
target: IdBytes,
peers: FnvHashMap<PeerId, PeerState>,
}
impl QueryTable {
pub fn new<T>(id: IdBytes, target: IdBytes, known_closest_peers: T) -> Self
where
T: IntoIterator<Item = PeerId>,
{
let peers: FnvHashMap<PeerId, PeerState> = known_closest_peers
.into_iter()
.map(|key| (key, PeerState::NotContacted))
.collect();
Self { id, target, peers }
}
#[expect(unused, reason = "from libp2p, might be useful later?")]
fn peers(&self) -> &FnvHashMap<PeerId, PeerState> {
&self.peers
}
#[expect(unused, reason = "from libp2p, might be useful later?")]
fn get_peer(&self, peer: &crate::Peer) -> Option<crate::Peer> {
self.peers
.keys()
.filter(|p| p.addr == peer.addr)
.map(|p| crate::Peer::from(p.addr))
.next()
}
#[expect(unused, reason = "from libp2p, might be useful later?")]
fn get_token(&self, peer: &crate::Peer) -> Option<&Vec<u8>> {
self.peers
.iter()
.filter(|(p, _)| p.addr == peer.addr)
.map(|(_, s)| s.get_token())
.next()
.flatten()
}
#[expect(unused, reason = "from libp2p, might be useful later?")]
fn set_all_not_contacted(&mut self) {
for state in self.peers.values_mut() {
*state = PeerState::NotContacted;
}
}
pub(crate) fn peers_mut(&mut self) -> &mut FnvHashMap<PeerId, PeerState> {
&mut self.peers
}
pub fn target(&self) -> &IdBytes {
&self.target
}
pub(crate) fn _add_unverified(&mut self, peer: PeerId) {
if peer.id == self.id {
return;
}
self.peers.insert(peer, PeerState::NotContacted);
}
pub(crate) fn add_verified(
&mut self,
key: PeerId,
roundtrip_token: Vec<u8>,
to: Option<SocketAddr>,
) {
if key.id == self.id {
return;
}
if let Some(prev) = self.peers.get_mut(&key) {
*prev = PeerState::Succeeded {
roundtrip_token,
to,
};
} else {
self.peers.insert(
key,
PeerState::Succeeded {
roundtrip_token,
to,
},
);
}
}
pub(crate) fn peers_iter(&self) -> Vec<(PeerId, PeerState)> {
self.peers
.clone()
.into_iter()
.map(|(k, v)| (k.clone(), v))
.collect()
}
}
#[expect(unused)] #[derive(Debug, Clone)]
pub(crate) struct Peer {
key: PeerId,
state: PeerState,
}
#[derive(Debug, Clone)]
pub enum PeerState {
NotContacted,
Failed,
Succeeded {
roundtrip_token: Vec<u8>,
to: Option<SocketAddr>,
},
}
impl PeerState {
pub fn is_verified(&self) -> bool {
matches!(self, PeerState::Succeeded { .. })
}
pub fn is_not_contacted(&self) -> bool {
matches!(self, PeerState::NotContacted)
}
pub fn get_token(&self) -> Option<&Vec<u8>> {
match self {
PeerState::Succeeded {
roundtrip_token, ..
} => Some(roundtrip_token),
_ => None,
}
}
}