diff --git a/crates/lox-library/src/lib.rs b/crates/lox-library/src/lib.rs index d04c297..16027ca 100644 --- a/crates/lox-library/src/lib.rs +++ b/crates/lox-library/src/lib.rs @@ -556,8 +556,24 @@ impl BridgeAuth { } res = ReplaceSuccess::Replaced } else if !self.bridge_table.spares.is_empty() { + // First get the bucketnums for the replacement bridge in case it is a spare + let mut bucketnums: Vec = Vec::new(); + for (bucketnum, _) in positions.iter() { + bucketnums.push(*bucketnum); + } // Get the first spare and remove it from the spares set. - let spare = *self.bridge_table.spares.iter().next().unwrap(); + let mut spare = *self.bridge_table.spares.iter().next().unwrap(); + // Check that the first spare in the list of spares is not the one to be replaced + if bucketnums.contains(&spare) { + // If it is, take the last spare instead + spare = *self.bridge_table.spares.iter().last().unwrap(); + // If this is the same bucketnum, there is only one spare bucket with the bridge + // to be replaced in it, so don't replace it. + if bucketnums.contains(&spare) { + res = ReplaceSuccess::NotReplaced; + return res; + } + } self.bridge_table.spares.remove(&spare); self.bridge_table.recycleable_keys.push(spare); // Get the actual bridges from the spare bucket @@ -596,6 +612,7 @@ impl BridgeAuth { } res = ReplaceSuccess::Replaced } else { + println!("No available bridges"); // If there are no available bridges that can be assigned here, the only thing // that can be done is return an indication that updating the gone bridge // didn't work. diff --git a/crates/lox-library/src/tests.rs b/crates/lox-library/src/tests.rs index bb2a986..f74284d 100644 --- a/crates/lox-library/src/tests.rs +++ b/crates/lox-library/src/tests.rs @@ -1032,13 +1032,15 @@ fn test_update_bridge() { #[test] fn test_bridge_replace() { // Create 3 open invitation buckets and 3 spare buckets - let cases = vec!["not found", "available", "unallocated", "failed", "spare"]; + let cases = vec!["not found", "available", "unallocated", "spare", "failed"]; + let num_buckets = 5; + let hot_spare = 0; for case in cases { let mut th: TestHarness; - if case != "failed" { + if String::from(case) != "failed" { th = TestHarness::new(); } else { - th = TestHarness::new_buckets(5, 0); + th = TestHarness::new_buckets(num_buckets, hot_spare); } // Randomly select a bridge to replace @@ -1047,6 +1049,7 @@ fn test_bridge_replace() { while !th.ba.bridge_table.buckets.contains_key(&num) { num = rand::thread_rng().gen_range(0..th.ba.bridge_table.counter); } + println!("chosen num is: {:?}", num); let replaceable_bucket = *th.ba.bridge_table.buckets.get(&num).unwrap(); let replacement_bridge = &replaceable_bucket[0]; assert!( @@ -1182,7 +1185,7 @@ fn test_bridge_replace() { "Extra spare bridges not added to unallocated bridges" ); - println!("Successfully added unallocated bridgeline"); + println!("Successfully added bridgeline from spare"); } "failed" => { // Case four: available_bridge == None and unallocated_bridges == None and spare buckets == None