Skip to main content

reddb_server/storage/unified/store/
impl_native_a.rs

1use super::*;
2
3impl UnifiedStore {
4    pub fn update_physical_file_header(
5        &self,
6        physical: PhysicalFileHeader,
7    ) -> Result<(), StoreError> {
8        let Some(pager) = &self.pager else {
9            return Ok(());
10        };
11        pager
12            .update_physical_header(physical)
13            .map_err(|err| StoreError::Serialization(err.to_string()))
14    }
15
16    /// Read the minimal physical header mirrored into page 0 for paged databases.
17    pub fn physical_file_header(&self) -> Option<PhysicalFileHeader> {
18        self.pager
19            .as_ref()
20            .and_then(|pager| pager.physical_header().ok())
21    }
22
23    /// Persist native collection roots into a dedicated page in the paged file.
24    pub fn write_native_collection_roots(
25        &self,
26        roots: &BTreeMap<String, u64>,
27        existing_page: Option<u32>,
28    ) -> Result<(u32, u64), StoreError> {
29        let Some(pager) = &self.pager else {
30            return Ok((0, 0));
31        };
32
33        let page_id = match existing_page.filter(|page| *page != 0) {
34            Some(page) => page,
35            None => pager
36                .allocate_page(crate::storage::engine::PageType::NativeMeta)
37                .map_err(|err| StoreError::Serialization(err.to_string()))?
38                .page_id(),
39        };
40
41        let data = reddb_file::encode_native_collection_roots_page(roots);
42        let checksum = reddb_file::native_store_page_checksum(&data);
43        let mut page = crate::storage::engine::Page::new(
44            crate::storage::engine::PageType::NativeMeta,
45            page_id,
46        );
47        let bytes = page.as_bytes_mut();
48        let content_start = crate::storage::engine::HEADER_SIZE;
49        let copy_len = data.len().min(bytes.len() - content_start);
50        bytes[content_start..content_start + copy_len].copy_from_slice(&data[..copy_len]);
51        pager
52            .write_page(page_id, page)
53            .map_err(|err| StoreError::Serialization(err.to_string()))?;
54        Ok((page_id, checksum))
55    }
56
57    /// Read native collection roots from a dedicated page in the paged file.
58    pub fn read_native_collection_roots(
59        &self,
60        page_id: u32,
61    ) -> Result<BTreeMap<String, u64>, StoreError> {
62        let Some(pager) = &self.pager else {
63            return Ok(BTreeMap::new());
64        };
65        if page_id == 0 {
66            return Ok(BTreeMap::new());
67        }
68
69        let page = pager
70            .read_page(page_id)
71            .map_err(|err| StoreError::Serialization(err.to_string()))?;
72        let bytes = page.as_bytes();
73        let content = &bytes[crate::storage::engine::HEADER_SIZE..];
74        reddb_file::decode_native_collection_roots_page(content)
75            .map_err(|err| StoreError::Serialization(err.to_string()))
76    }
77
78    /// Persist a compact native manifest summary into a dedicated page in the paged file.
79    pub fn write_native_manifest_summary(
80        &self,
81        sequence: u64,
82        events: &[ManifestEvent],
83        existing_page: Option<u32>,
84    ) -> Result<(u32, u64), StoreError> {
85        let Some(pager) = &self.pager else {
86            return Ok((0, 0));
87        };
88
89        let page_id = match existing_page.filter(|page| *page != 0) {
90            Some(page) => page,
91            None => pager
92                .allocate_page(crate::storage::engine::PageType::NativeMeta)
93                .map_err(|err| StoreError::Serialization(err.to_string()))?
94                .page_id(),
95        };
96
97        let data = reddb_file::encode_native_manifest_summary_page(sequence, events);
98        let checksum = reddb_file::native_store_page_checksum(&data);
99        let mut page = crate::storage::engine::Page::new(
100            crate::storage::engine::PageType::NativeMeta,
101            page_id,
102        );
103        let bytes = page.as_bytes_mut();
104        let content_start = crate::storage::engine::HEADER_SIZE;
105        let copy_len = data.len().min(bytes.len() - content_start);
106        bytes[content_start..content_start + copy_len].copy_from_slice(&data[..copy_len]);
107        pager
108            .write_page(page_id, page)
109            .map_err(|err| StoreError::Serialization(err.to_string()))?;
110        Ok((page_id, checksum))
111    }
112
113    /// Read a compact native manifest summary from a dedicated page in the paged file.
114    pub fn read_native_manifest_summary(
115        &self,
116        page_id: u32,
117    ) -> Result<NativeManifestSummary, StoreError> {
118        let Some(pager) = &self.pager else {
119            return Err(StoreError::Serialization(
120                "native manifest summary requires paged mode".to_string(),
121            ));
122        };
123        if page_id == 0 {
124            return Err(StoreError::Serialization(
125                "native manifest summary page is not set".to_string(),
126            ));
127        }
128
129        let page = pager
130            .read_page(page_id)
131            .map_err(|err| StoreError::Serialization(err.to_string()))?;
132        let bytes = page.as_bytes();
133        let content = &bytes[crate::storage::engine::HEADER_SIZE..];
134        reddb_file::decode_native_manifest_summary_page(content)
135            .map_err(|err| StoreError::Serialization(err.to_string()))
136    }
137
138    /// Persist a compact native operational registry summary into a dedicated page.
139    pub fn write_native_registry_summary(
140        &self,
141        summary: &NativeRegistrySummary,
142        existing_page: Option<u32>,
143    ) -> Result<(u32, u64), StoreError> {
144        let Some(pager) = &self.pager else {
145            return Ok((0, 0));
146        };
147
148        let page_id = match existing_page.filter(|page| *page != 0) {
149            Some(page) => page,
150            None => pager
151                .allocate_page(crate::storage::engine::PageType::NativeMeta)
152                .map_err(|err| StoreError::Serialization(err.to_string()))?
153                .page_id(),
154        };
155
156        let data = reddb_file::encode_native_registry_summary_page(summary);
157        let checksum = reddb_file::native_store_page_checksum(&data);
158        let mut page = crate::storage::engine::Page::new(
159            crate::storage::engine::PageType::NativeMeta,
160            page_id,
161        );
162        let bytes = page.as_bytes_mut();
163        let content_start = crate::storage::engine::HEADER_SIZE;
164        let copy_len = data.len().min(bytes.len() - content_start);
165        bytes[content_start..content_start + copy_len].copy_from_slice(&data[..copy_len]);
166        pager
167            .write_page(page_id, page)
168            .map_err(|err| StoreError::Serialization(err.to_string()))?;
169        Ok((page_id, checksum))
170    }
171}