Fix repair for a range of slots (#4286)

* Fix repair for a range of slots

* Delete RepairInfo
This commit is contained in:
Sagar Dhawan
2019-05-15 11:37:20 -07:00
committed by GitHub
parent 3204a00e73
commit 916017ca2c

View File

@ -39,21 +39,6 @@ pub enum RepairType {
Blob(u64, u64), Blob(u64, u64),
} }
#[derive(Default)]
struct RepairInfo {
max_slot: u64,
repair_tries: u64,
}
impl RepairInfo {
fn new() -> Self {
RepairInfo {
max_slot: 0,
repair_tries: 0,
}
}
}
pub struct RepairSlotRange { pub struct RepairSlotRange {
pub start: u64, pub start: u64,
pub end: u64, pub end: u64,
@ -104,7 +89,6 @@ impl RepairService {
cluster_info: &Arc<RwLock<ClusterInfo>>, cluster_info: &Arc<RwLock<ClusterInfo>>,
repair_strategy: RepairStrategy, repair_strategy: RepairStrategy,
) { ) {
let mut repair_info = RepairInfo::new();
let mut epoch_slots: HashSet<u64> = HashSet::new(); let mut epoch_slots: HashSet<u64> = HashSet::new();
let id = cluster_info.read().unwrap().id(); let id = cluster_info.read().unwrap().id();
if let RepairStrategy::RepairAll { if let RepairStrategy::RepairAll {
@ -135,7 +119,6 @@ impl RepairService {
Self::generate_repairs_in_range( Self::generate_repairs_in_range(
blocktree, blocktree,
MAX_REPAIR_LENGTH, MAX_REPAIR_LENGTH,
&mut repair_info,
repair_slot_range, repair_slot_range,
) )
} }
@ -195,46 +178,30 @@ impl RepairService {
fn generate_repairs_in_range( fn generate_repairs_in_range(
blocktree: &Blocktree, blocktree: &Blocktree,
max_repairs: usize, max_repairs: usize,
repair_info: &mut RepairInfo,
repair_range: &RepairSlotRange, repair_range: &RepairSlotRange,
) -> Result<(Vec<RepairType>)> { ) -> Result<(Vec<RepairType>)> {
// Slot height and blob indexes for blobs we want to repair // Slot height and blob indexes for blobs we want to repair
let mut repairs: Vec<RepairType> = vec![]; let mut repairs: Vec<RepairType> = vec![];
let mut meta_iter = blocktree for slot in repair_range.start..=repair_range.end {
.slot_meta_iterator(repair_range.start) if repairs.len() >= max_repairs {
.expect("Couldn't get db iterator");
while repairs.len() < max_repairs && meta_iter.valid() {
let current_slot = meta_iter.key();
if current_slot.unwrap() > repair_range.end {
break; break;
} }
if current_slot.unwrap() > repair_info.max_slot { let meta = blocktree
repair_info.repair_tries = 0; .meta(slot)
repair_info.max_slot = current_slot.unwrap(); .expect("Unable to lookup slot meta")
} .unwrap_or(SlotMeta {
slot,
..SlotMeta::default()
});
if let Some(slot) = meta_iter.value() { let new_repairs = Self::generate_repairs_for_slot(
let new_repairs = Self::generate_repairs_for_slot( blocktree,
blocktree, slot,
current_slot.unwrap(), &meta,
&slot, max_repairs - repairs.len(),
max_repairs - repairs.len(), );
); repairs.extend(new_repairs);
repairs.extend(new_repairs);
}
meta_iter.next();
}
// Only increment repair_tries if the ledger contains every blob for every slot
if repairs.is_empty() {
repair_info.repair_tries += 1;
}
// Optimistically try the next slot if we haven't gotten any repairs
// for a while
if repair_info.repair_tries >= MAX_REPAIR_TRIES {
repairs.push(RepairType::HighestBlob(repair_info.max_slot + 1, 0))
} }
Ok(repairs) Ok(repairs)
@ -525,8 +492,6 @@ mod test {
{ {
let blocktree = Blocktree::open(&blocktree_path).unwrap(); let blocktree = Blocktree::open(&blocktree_path).unwrap();
let mut repair_info = RepairInfo::new();
let slots: Vec<u64> = vec![1, 3, 5, 7, 8]; let slots: Vec<u64> = vec![1, 3, 5, 7, 8];
let num_entries_per_slot = 10; let num_entries_per_slot = 10;
@ -542,16 +507,21 @@ mod test {
let mut repair_slot_range = RepairSlotRange::default(); let mut repair_slot_range = RepairSlotRange::default();
repair_slot_range.start = slots[start]; repair_slot_range.start = slots[start];
repair_slot_range.end = slots[end]; repair_slot_range.end = slots[end];
let expected: Vec<RepairType> = slots[start..end + 1] let expected: Vec<RepairType> = (repair_slot_range.start
.iter() ..=repair_slot_range.end)
.map(|slot_index| RepairType::Blob(*slot_index, 0)) .map(|slot_index| {
if slots.contains(&(slot_index as u64)) {
RepairType::Blob(slot_index as u64, 0)
} else {
RepairType::HighestBlob(slot_index as u64, 0)
}
})
.collect(); .collect();
assert_eq!( assert_eq!(
RepairService::generate_repairs_in_range( RepairService::generate_repairs_in_range(
&blocktree, &blocktree,
std::usize::MAX, std::usize::MAX,
&mut repair_info,
&repair_slot_range &repair_slot_range
) )
.unwrap(), .unwrap(),
@ -571,8 +541,6 @@ mod test {
let num_entries_per_slot = 10; let num_entries_per_slot = 10;
let mut repair_info = RepairInfo::new();
let num_slots = 1; let num_slots = 1;
let start = 5; let start = 5;
@ -585,7 +553,11 @@ mod test {
} }
let end = 4; let end = 4;
let expected: Vec<RepairType> = vec![RepairType::HighestBlob(end, 0)]; let expected: Vec<RepairType> = vec![
RepairType::HighestBlob(end - 2, 0),
RepairType::HighestBlob(end - 1, 0),
RepairType::HighestBlob(end, 0),
];
let mut repair_slot_range = RepairSlotRange::default(); let mut repair_slot_range = RepairSlotRange::default();
repair_slot_range.start = 2; repair_slot_range.start = 2;
@ -595,7 +567,6 @@ mod test {
RepairService::generate_repairs_in_range( RepairService::generate_repairs_in_range(
&blocktree, &blocktree,
std::usize::MAX, std::usize::MAX,
&mut repair_info,
&repair_slot_range &repair_slot_range
) )
.unwrap(), .unwrap(),