1
0
mirror of synced 2025-02-03 03:14:43 +00:00

Implement filler with original side replication (#702)

This commit is contained in:
Daniel Sanchez 2024-08-26 10:20:47 +02:00 committed by GitHub
parent 37c22d23ce
commit 2f6d265aa6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 126 additions and 3 deletions

View File

@ -1 +1,2 @@
pub mod v1;
pub mod v2;

View File

@ -79,12 +79,12 @@ mod test {
#[test]
fn test_distribution_fill_from_node_list() {
let nodes: Vec<_> = std::iter::repeat_with(PeerId::random).take(100).collect();
let replication_factor = 2;
let dispersal_factor = 2;
let subnetwork_size = 1024;
let distribution = FillFromNodeList::new(&nodes, subnetwork_size, replication_factor);
let distribution = FillFromNodeList::new(&nodes, subnetwork_size, dispersal_factor);
assert_eq!(distribution.assignations.len(), subnetwork_size);
for subnetwork in &distribution.assignations {
assert_eq!(subnetwork.len(), replication_factor);
assert_eq!(subnetwork.len(), dispersal_factor);
}
}
}

View File

@ -0,0 +1,122 @@
use crate::MembershipHandler;
use libp2p_identity::PeerId;
use std::collections::HashSet;
pub struct FillWithOriginalReplication {
pub assignations: Vec<HashSet<PeerId>>,
pub subnetwork_size: usize,
pub dispersal_factor: usize,
pub original_replication: usize,
pub pivot: u16,
}
impl FillWithOriginalReplication {
pub fn new(
peers: &[PeerId],
subnetwork_size: usize,
dispersal_factor: usize,
original_replication: usize,
pivot: u16,
) -> Self {
Self {
assignations: Self::fill(
peers,
subnetwork_size,
dispersal_factor,
original_replication,
pivot,
),
subnetwork_size,
dispersal_factor,
original_replication,
pivot,
}
}
fn fill(
peers: &[PeerId],
subnetwork_size: usize,
dispersal_factor: usize,
original_replication: usize,
pivot: u16,
) -> Vec<HashSet<PeerId>> {
assert!(!peers.is_empty());
// sort list to make it deterministic
let mut peers = peers.to_vec();
peers.sort_unstable();
// take n peers and fill a subnetwork until all subnetworks are filled
let mut cycle = peers.into_iter().cycle();
(0..subnetwork_size)
.map(|subnetwork| {
(0..{
// choose factor depending on if it is in the original size of the encoding or not
if subnetwork < pivot as usize {
original_replication
} else {
dispersal_factor
}
})
.map(|_| cycle.next().unwrap())
.collect()
})
.collect()
}
}
impl MembershipHandler for FillWithOriginalReplication {
type NetworkId = u16;
type Id = PeerId;
fn membership(&self, id: &Self::Id) -> HashSet<Self::NetworkId> {
self.assignations
.iter()
.enumerate()
.filter_map(|(netowrk_id, subnetwork)| {
subnetwork
.contains(id)
.then_some(netowrk_id as Self::NetworkId)
})
.collect()
}
fn is_allowed(&self, id: &Self::Id) -> bool {
for subnetwork in &self.assignations {
if subnetwork.contains(id) {
return true;
}
}
false
}
fn members_of(&self, network_id: &Self::NetworkId) -> HashSet<Self::Id> {
self.assignations[*network_id as usize].clone()
}
}
#[cfg(test)]
mod test {
use crate::versions::v2::FillWithOriginalReplication;
use libp2p_identity::PeerId;
#[test]
fn test_distribution_fill_with_original_replication_from_node_list() {
let nodes: Vec<_> = std::iter::repeat_with(PeerId::random).take(100).collect();
let dispersal_factor = 2;
let subnetwork_size = 1024;
let original_replication = 10;
let pivot = 512;
let distribution = FillWithOriginalReplication::new(
&nodes,
subnetwork_size,
dispersal_factor,
original_replication,
pivot,
);
assert_eq!(distribution.assignations.len(), subnetwork_size);
for subnetwork in &distribution.assignations[..pivot as usize] {
assert_eq!(subnetwork.len(), original_replication);
}
for subnetwork in &distribution.assignations[pivot as usize..] {
assert_eq!(subnetwork.len(), dispersal_factor);
}
}
}