ic_storage/adapter/
log.rs1use super::{LogIter, LogWriteError, Memory, Storable};
3use crate::substrate::{self, DefaultMemoryImpl};
4use ic_memory::RuntimeMemory;
5
6pub struct StableLog<T: Storable, M: Memory = DefaultMemoryImpl> {
8 inner: substrate::Log<T, RuntimeMemory<M>, RuntimeMemory<M>>,
9}
10impl<T: Storable, M: Memory> StableLog<T, M> {
11 pub fn create(index_memory: RuntimeMemory<M>, data_memory: RuntimeMemory<M>) -> Self {
17 assert_eq!(index_memory.size(), 0, "log index is not empty");
18 assert_eq!(data_memory.size(), 0, "log data is not empty");
19 Self::reset(index_memory, data_memory)
20 }
21
22 pub fn reset(index_memory: RuntimeMemory<M>, data_memory: RuntimeMemory<M>) -> Self {
27 Self {
28 inner: substrate::Log::new(index_memory, data_memory),
29 }
30 }
31
32 pub fn load(index_memory: RuntimeMemory<M>, data_memory: RuntimeMemory<M>) -> Self {
38 assert!(
39 index_memory.size() > 0 && data_memory.size() > 0,
40 "log memory is empty"
41 );
42 let mut magic = [0; 3];
43 data_memory.read(0, &mut magic);
44 assert_eq!(&magic, b"GLD", "foreign log data");
45 Self {
48 inner: substrate::Log::init(index_memory, data_memory),
49 }
50 }
51 pub fn first(&self) -> Option<T> {
53 self.inner.first()
54 }
55 pub fn last(&self) -> Option<T> {
57 self.inner.last()
58 }
59 pub fn get(&self, idx: u64) -> Option<T> {
61 self.inner.get(idx)
62 }
63 pub fn len(&self) -> u64 {
65 self.inner.len()
66 }
67 pub fn is_empty(&self) -> bool {
69 self.inner.is_empty()
70 }
71 pub fn append(&self, item: &T) -> Result<u64, LogWriteError> {
75 self.inner.append(item)
76 }
77 pub fn iter(&self) -> LogIter<'_, T, M> {
79 self.inner.iter()
80 }
81}
82
83impl<'a, T: Storable, M: Memory> IntoIterator for &'a StableLog<T, M> {
84 type Item = T;
85 type IntoIter = LogIter<'a, T, M>;
86 fn into_iter(self) -> Self::IntoIter {
87 self.iter()
88 }
89}