Skip to main content

harmos_storage/
writes.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12pub mod convert;
13mod decoded;
14
15/* === Re-Exports === */
16
17pub use decoded::DecodedBatch;
18pub use harmos_domain::model::storage::{BatchReceipt, DataBatch, WriteCompletion, WriteReceipt};
19
20/* === Imports === */
21
22// Standard Library Imports
23use std::sync::Arc;
24// Third Party Imports
25// Local Imports
26use super::manager::ENTRY_OVERHEAD;
27use super::{SchemaKey, StorageCursor, StoreHistory};
28use crate::schema::graph::Schema;
29use crate::{Error, MemorySize, Result};
30
31/* === Constants === */
32
33/* === Macros === */
34
35/* === Type Aliases === */
36
37/* === Structs === */
38
39#[derive(Clone, Debug, PartialEq, Eq)]
40pub struct StorageSchema {
41    pub position: StorageCursor,
42    pub key: SchemaKey,
43    pub schema: Arc<Schema>,
44}
45
46/* === Enums === */
47
48/* === Traits === */
49
50/* === Implementations === */
51
52impl MemorySize for StorageSchema {
53    fn memory_size(&self) -> usize {
54        std::mem::size_of::<Self>()
55            .saturating_add(self.position.memory_size().saturating_sub(std::mem::size_of::<StorageCursor>()))
56            .saturating_add(self.key.memory_size().saturating_sub(std::mem::size_of::<SchemaKey>()))
57            .saturating_add(self.schema.memory_size().saturating_add(2 * std::mem::size_of::<usize>()))
58    }
59}
60
61impl StorageSchema {
62    pub fn new(position: StorageCursor, key: SchemaKey, schema: impl Into<Arc<Schema>>) -> Self {
63        Self { position, key, schema: schema.into() }
64    }
65
66    pub(super) fn resident_bytes(key: &SchemaKey, schema: &Schema, history: &StoreHistory) -> Result<usize> {
67        let allocations = schema.memory_size().checked_add(2 * std::mem::size_of::<usize>()).ok_or_else(size_error)?;
68        [
69            std::mem::size_of::<Self>(),
70            ENTRY_OVERHEAD,
71            key.id.as_str().len(),
72            history.store.as_str().len(),
73            history.epoch.as_str().len(),
74            allocations,
75        ]
76        .into_iter()
77        .try_fold(0usize, |bytes, next| bytes.checked_add(next))
78        .ok_or_else(size_error)
79    }
80}
81
82/* === Public Functions === */
83
84/* === Private Functions === */
85
86fn size_error() -> Error {
87    Error::InvalidInput { field: "storage schema", reason: "size overflow" }
88}
89
90/* === Tests === */