Skip to main content

feldera_storage/
block.rs

1use size_of::SizeOf;
2use std::fmt::Display;
3
4/// A block that can be read or written in a [crate::FileReader] or [crate::FileWriter].
5#[derive(Copy, Clone, Debug, SizeOf)]
6pub struct BlockLocation {
7    /// Byte offset, a multiple of 512.
8    pub offset: u64,
9
10    /// Size in bytes, a multiple of 512, less than `2**31`.
11    ///
12    /// (The upper limit is because some kernel APIs return the number of bytes
13    /// read as an `i32`.)
14    pub size: usize,
15}
16
17impl BlockLocation {
18    /// Constructs a new [BlockLocation], validating `offset` and `size`.
19    pub fn new(offset: u64, size: usize) -> Result<Self, InvalidBlockLocation> {
20        if !offset.is_multiple_of(512)
21            || !(512..1 << 31).contains(&size)
22            || !size.is_multiple_of(512)
23        {
24            Err(InvalidBlockLocation { offset, size })
25        } else {
26            Ok(Self { offset, size })
27        }
28    }
29
30    /// File offset just after this block.
31    pub fn after(&self) -> u64 {
32        self.offset + self.size as u64
33    }
34}
35
36impl Display for BlockLocation {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        write!(f, "{} bytes at offset {}", self.size, self.offset)
39    }
40}
41
42/// A range of bytes in a file that doesn't satisfy the constraints for
43/// [BlockLocation].
44#[derive(Copy, Clone, Debug)]
45pub struct InvalidBlockLocation {
46    /// Byte offset.
47    pub offset: u64,
48
49    /// Number of bytes.
50    pub size: usize,
51}
52
53impl Display for InvalidBlockLocation {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        write!(f, "{} bytes at offset {}", self.size, self.offset)
56    }
57}