Garage v0.9 #473

Merged
lx merged 175 commits from next into main 2023-10-10 13:28:29 +00:00
2 changed files with 64 additions and 81 deletions
Showing only changes of commit 948ff93cf1 - Show all commits

View file

@ -195,8 +195,8 @@ impl ClusterLayout {
.collect::<Vec<(String, usize)>>(); .collect::<Vec<(String, usize)>>();
//We create an indexing of the zones //We create an indexing of the zones
let mut zone_id = HashMap::<String, usize>::new(); let mut zone_id = HashMap::<String, usize>::new();
for i in 0..part_per_zone_vec.len() { for (i, ppz) in part_per_zone_vec.iter().enumerate() {
zone_id.insert(part_per_zone_vec[i].0.clone(), i); zone_id.insert(ppz.0.clone(), i);
} }
//We compute a candidate for the new partition to zone //We compute a candidate for the new partition to zone
@ -212,7 +212,7 @@ impl ClusterLayout {
let mut node_assignation = vec![vec![None; self.replication_factor]; nb_partitions]; let mut node_assignation = vec![vec![None; self.replication_factor]; nb_partitions];
//We will decrement part_per_nod to keep track of the number //We will decrement part_per_nod to keep track of the number
//of partitions that we still have to associate. //of partitions that we still have to associate.
let mut part_per_nod = part_per_nod.clone(); let mut part_per_nod = part_per_nod;
//We minimize the distance to the former assignation(if any) //We minimize the distance to the former assignation(if any)
@ -265,7 +265,7 @@ impl ClusterLayout {
&& part_per_nod[*id] > 0 && part_per_nod[*id] > 0
}) })
.collect(); .collect();
assert!(possible_nodes.len() > 0); assert!(!possible_nodes.is_empty());
//We randomly pick a node //We randomly pick a node
if let Some(nod) = possible_nodes.choose(&mut rng) { if let Some(nod) = possible_nodes.choose(&mut rng) {
node_assignation[i][j] = Some(*nod); node_assignation[i][j] = Some(*nod);
@ -277,12 +277,12 @@ impl ClusterLayout {
//We write the assignation in the 1D table //We write the assignation in the 1D table
self.ring_assignation_data = Vec::<CompactNodeType>::new(); self.ring_assignation_data = Vec::<CompactNodeType>::new();
for i in 0..nb_partitions { for ass in node_assignation {
for j in 0..self.replication_factor { for nod in ass {
if let Some(id) = node_assignation[i][j] { if let Some(id) = nod {
self.ring_assignation_data.push(id as CompactNodeType); self.ring_assignation_data.push(id as CompactNodeType);
} else { } else {
assert!(false) panic!()
} }
} }
} }
@ -318,7 +318,7 @@ impl ClusterLayout {
self.node_id_vec = new_node_id_vec; self.node_id_vec = new_node_id_vec;
self.ring_assignation_data = vec![]; self.ring_assignation_data = vec![];
return node_assignation; node_assignation
} }
///This function compute the number of partition to assign to ///This function compute the number of partition to assign to
@ -345,7 +345,7 @@ impl ClusterLayout {
//Compute the optimal number of partitions per zone //Compute the optimal number of partitions per zone
let sum_capacities: u32 = zone_capacity.values().sum(); let sum_capacities: u32 = zone_capacity.values().sum();
if sum_capacities <= 0 { if sum_capacities == 0 {
println!("No storage capacity in the network."); println!("No storage capacity in the network.");
return None; return None;
} }
@ -493,14 +493,10 @@ impl ClusterLayout {
.map(|id_nod| match self.node_role(id_nod) { .map(|id_nod| match self.node_role(id_nod) {
Some(NodeRole { Some(NodeRole {
zone: _, zone: _,
capacity, capacity: Some(c),
tags: _, tags: _,
}) => { }) => {
if let Some(c) = capacity {
*c *c
} else {
0
}
} }
_ => 0, _ => 0,
}) })

View file

@ -31,8 +31,8 @@ struct WeightedEdge {
* as possible to old_match. * as possible to old_match.
* */ * */
pub fn optimize_matching( pub fn optimize_matching(
old_match: &Vec<Vec<usize>>, old_match: &[Vec<usize>],
new_match: &Vec<Vec<usize>>, new_match: &[Vec<usize>],
nb_right: usize, nb_right: usize,
) -> Vec<Vec<usize>> { ) -> Vec<Vec<usize>> {
let nb_left = old_match.len(); let nb_left = old_match.len();
@ -72,17 +72,12 @@ pub fn optimize_matching(
//Discovering and flipping a cycle with positive weight in this //Discovering and flipping a cycle with positive weight in this
//graph will make the matching closer to old_match. //graph will make the matching closer to old_match.
//We use Bellman Ford algorithm to discover positive cycles //We use Bellman Ford algorithm to discover positive cycles
loop { while let Some(cycle) = positive_cycle(&edge_vec, nb_left, nb_right) {
if let Some(cycle) = positive_cycle(&edge_vec, nb_left, nb_right) {
for i in cycle { for i in cycle {
//We flip the edges of the cycle. //We flip the edges of the cycle.
(edge_vec[i].u, edge_vec[i].v) = (edge_vec[i].v, edge_vec[i].u); (edge_vec[i].u, edge_vec[i].v) = (edge_vec[i].v, edge_vec[i].u);
edge_vec[i].w *= -1; edge_vec[i].w *= -1;
} }
} else {
//If there is no cycle, we return the optimal matching.
break;
}
} }
//The optimal matching is build from the graph structure. //The optimal matching is build from the graph structure.
@ -97,7 +92,7 @@ pub fn optimize_matching(
//This function finds a positive cycle in a bipartite wieghted graph. //This function finds a positive cycle in a bipartite wieghted graph.
fn positive_cycle( fn positive_cycle(
edge_vec: &Vec<WeightedEdge>, edge_vec: &[WeightedEdge],
nb_left: usize, nb_left: usize,
nb_right: usize, nb_right: usize,
) -> Option<Vec<usize>> { ) -> Option<Vec<usize>> {
@ -122,8 +117,7 @@ fn positive_cycle(
//the number of partitions can be much larger than the //the number of partitions can be much larger than the
//number of nodes, we optimize that. //number of nodes, we optimize that.
for _ in 0..(2 * nb_side_min) { for _ in 0..(2 * nb_side_min) {
for j in 0..edge_vec.len() { for (j, e) in edge_vec.iter().enumerate() {
let e = edge_vec[j];
if weight[e.v] < weight[e.u] + e.w { if weight[e.v] < weight[e.u] + e.w {
weight[e.v] = weight[e.u] + e.w; weight[e.v] = weight[e.u] + e.w;
prev[e.v] = j; prev[e.v] = j;
@ -148,8 +142,7 @@ fn positive_cycle(
curr = edge_vec[prev[curr]].u; curr = edge_vec[prev[curr]].u;
} }
//Now curr is on the cycle. We collect the edges ids. //Now curr is on the cycle. We collect the edges ids.
let mut cycle = Vec::<usize>::new(); let mut cycle = vec![prev[curr]];
cycle.push(prev[curr]);
let mut cycle_vert = edge_vec[prev[curr]].u; let mut cycle_vert = edge_vec[prev[curr]].u;
while cycle_vert != curr { while cycle_vert != curr {
cycle.push(prev[cycle_vert]); cycle.push(prev[cycle_vert]);
@ -180,16 +173,16 @@ pub fn dinic_compute_matching(left_cap_vec: Vec<u32>, right_cap_vec: Vec<u32>) -
// 0 will be the source // 0 will be the source
graph.push(vec![ed; left_cap_vec.len()]); graph.push(vec![ed; left_cap_vec.len()]);
for i in 0..left_cap_vec.len() { for (i, c) in left_cap_vec.iter().enumerate() {
graph[0][i].c = left_cap_vec[i] as i32; graph[0][i].c = *c as i32;
graph[0][i].v = i + 2; graph[0][i].v = i + 2;
graph[0][i].rev = 0; graph[0][i].rev = 0;
} }
//1 will be the sink //1 will be the sink
graph.push(vec![ed; right_cap_vec.len()]); graph.push(vec![ed; right_cap_vec.len()]);
for i in 0..right_cap_vec.len() { for (i, c) in right_cap_vec.iter().enumerate() {
graph[1][i].c = right_cap_vec[i] as i32; graph[1][i].c = *c as i32;
graph[1][i].v = i + 2 + left_cap_vec.len(); graph[1][i].v = i + 2 + left_cap_vec.len();
graph[1][i].rev = 0; graph[1][i].rev = 0;
} }
@ -267,18 +260,15 @@ pub fn dinic_compute_matching(left_cap_vec: Vec<u32>, right_cap_vec: Vec<u32>) -
let mut next_nbd = vec![0; nb_vertices]; let mut next_nbd = vec![0; nb_vertices];
let mut lifo = VecDeque::new(); let mut lifo = VecDeque::new();
let flow_upper_bound; let flow_upper_bound = if let Some(x) = left_cap_vec.iter().max() {
if let Some(x) = left_cap_vec.iter().max() { *x as i32
flow_upper_bound = *x as i32;
} else { } else {
flow_upper_bound = 0; panic!();
assert!(false); };
}
lifo.push_back((0, flow_upper_bound)); lifo.push_back((0, flow_upper_bound));
loop { while let Some((id_tmp, f_tmp)) = lifo.back() {
if let Some((id_tmp, f_tmp)) = lifo.back() {
let id = *id_tmp; let id = *id_tmp;
let f = *f_tmp; let f = *f_tmp;
if id == 1 { if id == 1 {
@ -316,9 +306,6 @@ pub fn dinic_compute_matching(left_cap_vec: Vec<u32>, right_cap_vec: Vec<u32>) -
} }
//otherwise, we send flow to nbd. //otherwise, we send flow to nbd.
lifo.push_back((graph[id][nbd].v, new_flow)); lifo.push_back((graph[id][nbd].v, new_flow));
} else {
break;
}
} }
} }