trine-kv 0.6.0

Embedded LSM MVCC key-value database.
Documentation
use super::{
    Arc, CONTENT_ACCESS_BARRIER_MAGIC, CONTENT_ACCESS_COORDINATE_MAGIC, ContentAccessBarrierId,
    Error, Result, StorageDomainId, array_at,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct ContentAccessBarrierRecord {
    pub(crate) storage_domain_id: StorageDomainId,
    pub(crate) barrier_id: ContentAccessBarrierId,
}

impl ContentAccessBarrierRecord {
    pub(crate) fn encode(self) -> Arc<[u8]> {
        let mut bytes = Vec::with_capacity(8 + 16 + 16);
        bytes.extend_from_slice(CONTENT_ACCESS_BARRIER_MAGIC);
        bytes.extend_from_slice(&self.storage_domain_id.to_bytes());
        bytes.extend_from_slice(&self.barrier_id.to_bytes());
        bytes.into()
    }

    pub(crate) fn decode(bytes: &[u8], storage_domain_id: StorageDomainId) -> Result<Self> {
        const RECORD_LEN: usize = 8 + 16 + 16;
        if bytes.len() != RECORD_LEN || bytes.get(..8) != Some(CONTENT_ACCESS_BARRIER_MAGIC) {
            return Err(Error::InvalidFormat {
                message: "invalid content access-barrier header or length".to_owned(),
            });
        }
        let stored_domain = StorageDomainId::from_bytes(array_at::<16>(
            bytes,
            8,
            "content access-barrier storage domain",
        )?);
        let barrier_id = ContentAccessBarrierId::from_bytes(array_at::<16>(
            bytes,
            24,
            "content access-barrier identity",
        )?)?;
        if stored_domain != storage_domain_id {
            return Err(Error::Corruption {
                message: "content access-barrier record differs from its storage path".to_owned(),
            });
        }
        Ok(Self {
            storage_domain_id,
            barrier_id,
        })
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct ContentAccessCoordinateRecord {
    pub(crate) storage_domain_id: StorageDomainId,
    pub(crate) barrier_id: ContentAccessBarrierId,
    pub(crate) enforced_at: crate::ReadVersion,
}

impl ContentAccessCoordinateRecord {
    pub(crate) fn commit_prefix(
        storage_domain_id: StorageDomainId,
        barrier_id: ContentAccessBarrierId,
    ) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(8 + 16 + 16);
        bytes.extend_from_slice(CONTENT_ACCESS_COORDINATE_MAGIC);
        bytes.extend_from_slice(&storage_domain_id.to_bytes());
        bytes.extend_from_slice(&barrier_id.to_bytes());
        bytes
    }

    pub(crate) fn decode(bytes: &[u8], storage_domain_id: StorageDomainId) -> Result<Self> {
        const RECORD_LEN: usize = 8 + 16 + 16 + 8;
        if bytes.len() != RECORD_LEN || bytes.get(..8) != Some(CONTENT_ACCESS_COORDINATE_MAGIC) {
            return Err(Error::InvalidFormat {
                message: "invalid content access-coordinate header or length".to_owned(),
            });
        }
        let stored_domain = StorageDomainId::from_bytes(array_at::<16>(
            bytes,
            8,
            "content access-coordinate storage domain",
        )?);
        let barrier_id = ContentAccessBarrierId::from_bytes(array_at::<16>(
            bytes,
            24,
            "content access-coordinate barrier identity",
        )?)?;
        let enforced_at = crate::ReadVersion::from_u64(u64::from_be_bytes(array_at::<8>(
            bytes,
            40,
            "content access-coordinate commit sequence",
        )?));
        if stored_domain != storage_domain_id || enforced_at.as_u64() == 0 {
            return Err(Error::Corruption {
                message: "content access-coordinate has invalid protected coordinates".to_owned(),
            });
        }
        Ok(Self {
            storage_domain_id,
            barrier_id,
            enforced_at,
        })
    }
}

pub(crate) fn content_access_coordinate_key(storage_domain_id: StorageDomainId) -> Vec<u8> {
    let mut key = Vec::with_capacity(7 + 16);
    key.extend_from_slice(b"access:");
    key.extend_from_slice(&storage_domain_id.to_bytes());
    key
}