1use crate::{
2 SECTION_HEADER_COMPACT_SIZE, SECTION_MAGIC, SectionHandle, SectionHeader, SectionStorage,
3 UnifiedLogStatus, UnifiedLogWrite,
4};
5use bincode::Encode;
6use bincode::config::standard;
7use bincode::enc::EncoderImpl;
8use bincode::enc::write::SizeWriter;
9use bincode::error::EncodeError;
10use cu29_traits::{
11 CuResult, ObservedWriter, UnifiedLogType, abort_observed_encode, begin_observed_encode,
12 finish_observed_encode,
13};
14
15#[derive(Debug, Default)]
16pub struct NoopSectionStorage {
17 bytes_written: usize,
18}
19
20impl SectionStorage for NoopSectionStorage {
21 fn initialize<E: Encode>(&mut self, header: &E) -> Result<usize, EncodeError> {
22 let header_size = encoded_size(header)?;
23 self.bytes_written = header_size;
24 Ok(header_size)
25 }
26
27 fn post_update_header<E: Encode>(&mut self, header: &E) -> Result<usize, EncodeError> {
28 encoded_size(header)
29 }
30
31 fn append<E: Encode>(&mut self, entry: &E) -> Result<usize, EncodeError> {
32 let size = encoded_size(entry)?;
33 self.bytes_written = self.bytes_written.saturating_add(size);
34 Ok(size)
35 }
36
37 fn flush(&mut self) -> CuResult<usize> {
38 Ok(self.bytes_written)
39 }
40}
41
42#[derive(Debug, Default)]
43pub struct NoopLogger {
44 total_used_space: usize,
45 total_allocated_space: usize,
46}
47
48impl NoopLogger {
49 pub fn new() -> Self {
50 Self::default()
51 }
52}
53
54impl UnifiedLogWrite<NoopSectionStorage> for NoopLogger {
55 fn add_section(
56 &mut self,
57 entry_type: UnifiedLogType,
58 requested_section_size: usize,
59 ) -> CuResult<SectionHandle<NoopSectionStorage>> {
60 let allocated_size = requested_section_size.max(SECTION_HEADER_COMPACT_SIZE as usize);
61 let section_header = SectionHeader {
62 magic: SECTION_MAGIC,
63 block_size: SECTION_HEADER_COMPACT_SIZE,
64 entry_type,
65 offset_to_next_section: allocated_size.min(u32::MAX as usize) as u32,
66 used: 0,
67 is_open: true,
68 };
69
70 self.total_allocated_space = self.total_allocated_space.saturating_add(allocated_size);
71 SectionHandle::create(section_header, NoopSectionStorage::default())
72 }
73
74 fn flush_section(&mut self, section: &mut SectionHandle<NoopSectionStorage>) {
75 section.mark_closed();
76 let _ = section.post_update_header();
77 if let Ok(used) = section.get_storage_mut().flush() {
78 self.total_used_space = self.total_used_space.saturating_add(used);
79 }
80 }
81
82 fn status(&self) -> UnifiedLogStatus {
83 UnifiedLogStatus {
84 total_used_space: self.total_used_space,
85 total_allocated_space: self.total_allocated_space,
86 }
87 }
88}
89
90fn encoded_size<E: Encode>(value: &E) -> Result<usize, EncodeError> {
91 begin_observed_encode();
92 let result = (|| {
93 let mut encoder =
94 EncoderImpl::<_, _>::new(ObservedWriter::new(SizeWriter::default()), standard());
95 value.encode(&mut encoder)?;
96 Ok(encoder.into_writer().into_inner().bytes_written)
97 })();
98 match result {
99 Ok(size) => {
100 debug_assert_eq!(size, finish_observed_encode());
101 Ok(size)
102 }
103 Err(err) => {
104 abort_observed_encode();
105 Err(err)
106 }
107 }
108}