use logfile_partition::LogfilePartition;
use measure::Measurement;
use std::fs;
#[derive(Debug, Clone)]
pub struct LogfileReader<'a> {
partitions: &'a [LogfilePartition],
}
impl<'a> LogfileReader<'a> {
pub fn new(partitions: &'a [LogfilePartition]) -> LogfileReader<'a> {
LogfileReader { partitions }
}
pub fn fetch_measurements(
&self,
time_start: Option<u64>,
time_limit: Option<u64>,
limit: Option<u64>,
) -> Result<Vec<Measurement>, ::Error> {
let mut measurements = Vec::<Measurement>::new();
'scan: for partition in self.partitions.iter().rev() {
if let Some(time_start) = time_start {
if partition.get_time_tail() > time_start {
continue;
}
}
if let Some(time_limit) = time_limit {
if partition.get_time_head() <= time_limit {
break 'scan;
}
}
let mut file = fs::File::open(partition.get_file_path())?;
let mut file_offset = partition.get_file_offset();
while file_offset > 0 {
let measurement = Measurement::decode(&mut file, file_offset)?;
if measurement.get_encoded_size() <= file_offset {
file_offset -= measurement.get_encoded_size();
} else {
return Err(err_server!("corrupt file"));
}
if let Some(time_start) = time_start {
if measurement.time > time_start {
continue;
}
}
if let Some(time_limit) = time_limit {
if measurement.time <= time_limit {
break 'scan;
}
}
measurements.push(measurement);
if let Some(limit) = limit {
if measurements.len() as u64 == limit {
break 'scan;
}
}
}
}
Ok(measurements)
}
}