ic-memory 0.13.2

Durable stable-memory allocation governance for Internet Computer canisters
Documentation
use ic_stable_structures::{Memory, VectorMemory};
use std::{cell::Cell, rc::Rc};

#[derive(Clone, Copy, Debug, Default)]
pub struct Counts {
    pub reads: u64,
    pub read_bytes: u64,
    pub writes: u64,
    pub write_bytes: u64,
    pub grows: u64,
    pub grown_pages: u64,
}

#[derive(Clone, Default)]
pub struct Metered {
    pub bytes: VectorMemory,
    counts: Rc<Cell<Counts>>,
}

impl Metered {
    pub fn reset(&self) {
        self.counts.set(Counts::default());
    }
    pub fn counts(&self) -> Counts {
        self.counts.get()
    }
}

impl Memory for Metered {
    fn size(&self) -> u64 {
        self.bytes.size()
    }
    fn grow(&self, pages: u64) -> i64 {
        let result = self.bytes.grow(pages);
        let mut counts = self.counts.get();
        counts.grows += 1;
        if result >= 0 {
            counts.grown_pages += pages;
        }
        self.counts.set(counts);
        result
    }
    fn read(&self, offset: u64, dst: &mut [u8]) {
        let mut counts = self.counts.get();
        counts.reads += 1;
        counts.read_bytes += dst.len() as u64;
        self.counts.set(counts);
        self.bytes.read(offset, dst);
    }
    fn write(&self, offset: u64, src: &[u8]) {
        let mut counts = self.counts.get();
        counts.writes += 1;
        counts.write_bytes += src.len() as u64;
        self.counts.set(counts);
        self.bytes.write(offset, src);
    }
}