use std::collections::HashMap;
use devicemapper::Device;
use crate::{
engine::{
strat_engine::{
backstore::blockdevmgr::{BlkDevSegment, Segment},
serde_structs::BaseDevSave,
},
types::DevUuid,
},
stratis::{ErrorEnum, StratisError, StratisResult},
};
pub fn metadata_to_segment(
uuid_to_devno: &HashMap<DevUuid, Device>,
base_dev_save: &BaseDevSave,
) -> StratisResult<BlkDevSegment> {
let parent = base_dev_save.parent;
uuid_to_devno
.get(&parent)
.ok_or_else(|| {
StratisError::Engine(
ErrorEnum::NotFound,
format!(
"No block device corresponding to stratisd UUID {:?} found",
&parent
),
)
})
.map(|device| {
BlkDevSegment::new(
parent,
Segment::new(*device, base_dev_save.start, base_dev_save.length),
)
})
}
pub fn coalesce_blkdevsegs(left: &[BlkDevSegment], right: &[BlkDevSegment]) -> Vec<BlkDevSegment> {
if left.is_empty() {
return right.to_vec();
}
if right.is_empty() {
return left.to_vec();
}
let mut segments = Vec::with_capacity(left.len() + right.len());
segments.extend_from_slice(left);
let coalesced = {
let right_first = right.first().expect("!right.is_empty()");
let left_last = segments.last_mut().expect("!left.is_empty()");
if left_last.uuid == right_first.uuid
&& (left_last.segment.start + left_last.segment.length == right_first.segment.start)
{
left_last.segment.length += right_first.segment.length;
true
} else {
false
}
};
if coalesced {
segments.extend_from_slice(&right[1..]);
} else {
segments.extend_from_slice(right);
}
segments
}