bity_ic_stable_memory/lib.rs
1//! Module for managing stable memory in the Internet Computer context.
2//!
3//! This module provides utilities for efficiently reading and writing to stable memory
4//! using buffers, and allows tracking memory usage.
5//!
6//! # Example
7//! ```
8//! use ic_stable_structures::DefaultMemoryImpl;
9//!
10//! let memory = DefaultMemoryImpl::default();
11//! let mut writer = get_writer(&mut memory);
12//! writer.write_all(b"Hello, World!").unwrap();
13//! ```
14
15use ic_cdk::api::stable::stable_size;
16use ic_cdk::api::stable::WASM_PAGE_SIZE_IN_BYTES;
17use ic_stable_structures::reader::{BufferedReader, Reader};
18use ic_stable_structures::writer::{BufferedWriter, Writer};
19use ic_stable_structures::Memory;
20use std::cmp::min;
21use std::io::{Read, Write};
22
23const MAX_READER_WRITER_BUFFER_SIZE: usize = 1024 * 1024; // 1MB
24
25/// Creates a new buffered reader for stable memory.
26///
27/// # Arguments
28/// * `memory` - The stable memory to use
29///
30/// # Returns
31/// A `Read` implementation that allows reading data from stable memory
32pub fn get_reader<M: Memory>(memory: &M) -> impl Read + '_ {
33 BufferedReader::new(buffer_size(memory), Reader::new(memory, 0))
34}
35
36/// Creates a new buffered writer for stable memory.
37///
38/// # Arguments
39/// * `memory` - The stable memory to use
40///
41/// # Returns
42/// A `Write` implementation that allows writing data to stable memory
43pub fn get_writer<M: Memory>(memory: &mut M) -> impl Write + '_ {
44 BufferedWriter::new(MAX_READER_WRITER_BUFFER_SIZE, Writer::new(memory, 0))
45}
46
47/// Calculates the optimal buffer size based on memory size.
48///
49/// # Arguments
50/// * `memory` - The stable memory to use
51///
52/// # Returns
53/// The buffer size in bytes, limited to `MAX_READER_WRITER_BUFFER_SIZE`
54fn buffer_size<M: Memory>(memory: &M) -> usize {
55 let memory_size = memory.size() * (WASM_PAGE_SIZE_IN_BYTES as u64);
56
57 match usize::try_from(memory_size) {
58 Ok(size) => min(size / 4, MAX_READER_WRITER_BUFFER_SIZE),
59 Err(_) => MAX_READER_WRITER_BUFFER_SIZE,
60 }
61}
62
63/// Returns the total amount of stable memory used in bytes.
64///
65/// # Returns
66/// The number of bytes of stable memory used
67pub fn used() -> u64 {
68 (stable_size() as u64) * (WASM_PAGE_SIZE_IN_BYTES as u64)
69}