array-format 0.9.0

A block-backed, footer-indexed container for storing multiple n-dimensional arrays in a single file, with a delta/overlay architecture and pluggable compression and storage backends.
Documentation
//! Block identifiers and chunk address types.
//!
//! A [`ChunkAddress`] locates a slice of array data within a specific
//! block by `(block_id, offset, size)`.

use rkyv::{Archive, Deserialize, Serialize};

#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Archive, Serialize, Deserialize)]
pub struct BlockAllocAddress {
    id: BlockId,
    offset: u64,
    size: u64,
}

/// A block identifier within the file.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Archive, Serialize, Deserialize)]
pub struct BlockId(pub u32);

/// Locates a contiguous slice of bytes within a block.
///
/// To read the data: find the block identified by [`block_id`](ChunkAddress::block_id),
/// seek to [`offset`](ChunkAddress::offset) bytes into the decompressed block,
/// and read [`size`](ChunkAddress::size) bytes.
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
pub struct ChunkAddress {
    /// Which block the data resides in.
    pub block_id: BlockId,
    /// Byte offset within the decompressed block.
    pub offset: u32,
    /// Number of bytes to read from the block.
    pub size: u32,
}

impl BlockAllocAddress {
    pub fn new(id: BlockId, offset: u64, size: u64) -> Self {
        Self { id, offset, size }
    }

    pub fn id(&self) -> BlockId {
        self.id
    }

    pub fn offset(&self) -> u64 {
        self.offset
    }

    pub fn size(&self) -> u64 {
        self.size
    }
}

impl From<BlockAllocAddress> for ChunkAddress {
    fn from(a: BlockAllocAddress) -> Self {
        ChunkAddress {
            block_id: a.id,
            offset: a.offset as u32,
            size: a.size as u32,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn block_id_copy() {
        let a = BlockId(7);
        let b = a;
        assert_eq!(a, b);
    }

    #[test]
    fn chunk_address_fields() {
        let addr = ChunkAddress {
            block_id: BlockId(3),
            offset: 1024,
            size: 4096,
        };
        assert_eq!(addr.block_id, BlockId(3));
        assert_eq!(addr.offset, 1024);
        assert_eq!(addr.size, 4096);
    }
}