1#![allow(dead_code)]
3#![allow(static_mut_refs)]
4
5extern crate alloc;
6use alloc::vec::Vec;
7
8use super::block::{BlockDevice, MirroredBlockDevice, DATA_SIZE_PER_SECTOR};
9
10const MAX_KEYS: usize = 24;
11const KEY_LEN: usize = 16; #[repr(C, packed)]
19#[derive(Clone, Copy)]
20pub struct BTreeNode {
21 pub node_type: u8, pub num_keys: u8,
23 pub padding: [u8; 2],
24 pub keys: [[u8; KEY_LEN]; MAX_KEYS + 1], pub values: [u32; MAX_KEYS + 2], }
27
28const _: () = assert!(core::mem::size_of::<BTreeNode>() <= DATA_SIZE_PER_SECTOR);
32
33impl BTreeNode {
34 pub fn new(is_leaf: bool) -> Self {
35 Self {
36 node_type: if is_leaf { 0 } else { 1 },
37 num_keys: 0,
38 padding: [0; 2],
39 keys: [[0; KEY_LEN]; MAX_KEYS + 1],
40 values: [0; MAX_KEYS + 2],
41 }
42 }
43
44 pub fn from_bytes(bytes: &[u8]) -> Self {
46 let mut node = Self::new(true);
47 let ptr = &mut node as *mut Self as *mut u8;
48 unsafe {
49 core::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, core::mem::size_of::<Self>());
50 }
51 node
52 }
53
54 pub fn to_bytes(&self) -> [u8; DATA_SIZE_PER_SECTOR] {
56 let mut buf = [0u8; DATA_SIZE_PER_SECTOR];
57 let ptr = self as *const Self as *const u8;
58 unsafe {
59 core::ptr::copy_nonoverlapping(ptr, buf.as_mut_ptr(), core::mem::size_of::<Self>());
60 }
61 buf
62 }
63
64 fn compare_keys(a: &[u8; KEY_LEN], b: &[u8]) -> core::cmp::Ordering {
66 let b_len = b.len().min(KEY_LEN);
67 let mut b_padded = [0u8; KEY_LEN];
68 b_padded[..b_len].copy_from_slice(&b[..b_len]);
69 a.cmp(&b_padded)
70 }
71}
72
73pub struct CowBTree {
75 root_sector: u32,
76}
77
78impl CowBTree {
79 pub fn new(root_sector: u32) -> Self {
80 Self { root_sector }
81 }
82
83 pub fn get_root(&self) -> u32 {
84 self.root_sector
85 }
86
87 pub fn search<B: BlockDevice>(
90 &self,
91 device: &mut MirroredBlockDevice<B>,
92 key: &[u8; KEY_LEN],
93 ) -> Option<u32> {
94 let mut curr_sector = self.root_sector;
95 let mut buf = [0u8; DATA_SIZE_PER_SECTOR];
96 let mut loop_count = 0;
97
98 while curr_sector != 0 {
99 loop_count += 1;
100 if loop_count > 100 {
101 crate::println!(
102 " [BTree DBG] search loop exceeded 100 iterations! curr_sector={}",
103 curr_sector
104 );
105 return None;
106 }
107 if device.read_sector(curr_sector as usize, &mut buf).is_err() {
108 return None;
109 }
110 let node = BTreeNode::from_bytes(&buf);
111
112 let mut idx = 0;
114 while idx < node.num_keys as usize {
115 if idx >= MAX_KEYS {
116 crate::println!(
117 " [BTree DBG] search node num_keys is corrupted! num_keys={}",
118 node.num_keys
119 );
120 return None;
121 }
122 let cmp = BTreeNode::compare_keys(&node.keys[idx], key);
123 if cmp == core::cmp::Ordering::Equal {
124 if node.node_type == 0 {
125 return Some(node.values[idx]);
127 } else {
128 idx += 1;
130 break;
131 }
132 } else if cmp == core::cmp::Ordering::Greater {
133 break;
134 }
135 idx += 1;
136 }
137
138 if node.node_type == 0 {
139 break; } else {
141 curr_sector = node.values[idx]; }
143 }
144
145 None
146 }
147
148 pub fn insert<B: BlockDevice>(
151 &mut self,
152 device: &mut MirroredBlockDevice<B>,
153 key: &[u8; KEY_LEN],
154 val_sector: u32,
155 alloc_sector_fn: &mut dyn FnMut() -> u32,
156 ) -> Result<u32, &'static str> {
157 let root_sec = self.root_sector;
158
159 if root_sec == 0 {
161 let new_sec = alloc_sector_fn();
162 if new_sec == 0 {
163 return Err("btree: sector allocation failed");
164 }
165
166 let mut new_node = BTreeNode::new(true);
167 new_node.num_keys = 1;
168 new_node.keys[0] = *key;
169 new_node.values[0] = val_sector;
170
171 device.write_sector(new_sec as usize, &new_node.to_bytes())?;
172 self.root_sector = new_sec;
173 return Ok(new_sec);
174 }
175
176 let result = self.insert_recursive(device, root_sec, key, val_sector, alloc_sector_fn)?;
178
179 match result {
180 InsertResult::Ok(new_sec) => {
181 self.root_sector = new_sec;
182 Ok(new_sec)
183 }
184 InsertResult::Split(new_sec, split_key, split_sibling_sec) => {
185 let new_root_sec = alloc_sector_fn();
187 if new_root_sec == 0 {
188 return Err("btree: sector allocation failed");
189 }
190
191 let mut new_root = BTreeNode::new(false);
192 new_root.num_keys = 1;
193 new_root.keys[0] = split_key;
194 new_root.values[0] = new_sec;
195 new_root.values[1] = split_sibling_sec;
196
197 device.write_sector(new_root_sec as usize, &new_root.to_bytes())?;
198 self.root_sector = new_root_sec;
199 Ok(new_root_sec)
200 }
201 }
202 }
203
204 pub fn collect_leaf_entries<B: BlockDevice>(
206 &self,
207 device: &mut MirroredBlockDevice<B>,
208 out: &mut Vec<([u8; KEY_LEN], u32)>,
209 ) {
210 if self.root_sector == 0 {
211 return;
212 }
213 let mut visited = Vec::new();
214 self.collect_from_node(device, self.root_sector, out, &mut visited);
215 }
216
217 fn collect_from_node<B: BlockDevice>(
218 &self,
219 device: &mut MirroredBlockDevice<B>,
220 sector: u32,
221 out: &mut Vec<([u8; KEY_LEN], u32)>,
222 visited: &mut Vec<u32>,
223 ) {
224 if visited.contains(§or) {
225 crate::println!(
226 " [BTree DBG] Circular reference detected in collect_from_node: sector={}",
227 sector
228 );
229 return;
230 }
231 visited.push(sector);
232 if visited.len() > 100 {
233 crate::println!(" [BTree DBG] Recursion limit exceeded in collect_from_node!");
234 return;
235 }
236
237 let mut buf = [0u8; DATA_SIZE_PER_SECTOR];
238 if device.read_sector(sector as usize, &mut buf).is_err() {
239 return;
240 }
241
242 let node = BTreeNode::from_bytes(&buf);
243 if node.node_type == 0 {
244 let limit = (node.num_keys as usize).min(MAX_KEYS);
245 for i in 0..limit {
246 out.push((node.keys[i], node.values[i]));
247 }
248 return;
249 }
250
251 let limit = (node.num_keys as usize).min(MAX_KEYS);
252 for i in 0..=limit {
253 let child = node.values[i];
254 if child != 0 {
255 self.collect_from_node(device, child, out, visited);
256 }
257 }
258 }
259
260 fn insert_recursive<B: BlockDevice>(
262 &self,
263 device: &mut MirroredBlockDevice<B>,
264 curr_sector: u32,
265 key: &[u8; KEY_LEN],
266 val_sector: u32,
267 alloc_sector_fn: &mut dyn FnMut() -> u32,
268 ) -> Result<InsertResult, &'static str> {
269 let mut buf = [0u8; DATA_SIZE_PER_SECTOR];
270 if curr_sector as usize >= device.total_usable_sectors() {
281 crate::warn!(
282 "[SylFS][BTREE] 節点番号が実在範囲外 curr_sector={} usable={} (索引が壊れている)",
283 curr_sector,
284 device.total_usable_sectors()
285 );
286 return Err("btree: node sector out of range");
287 }
288 if let Err(e) = device.read_sector(curr_sector as usize, &mut buf) {
289 crate::warn!(
290 "[SylFS][BTREE] 節点の読み出しに失敗 curr_sector={} usable={} err={}",
291 curr_sector,
292 device.total_usable_sectors(),
293 e
294 );
295 return Err(e);
296 }
297
298 let mut node = BTreeNode::from_bytes(&buf);
300 let new_sector = alloc_sector_fn();
301 if new_sector == 0 {
302 return Err("btree: sector allocation failed");
303 }
304
305 let mut idx = 0;
307 while idx < node.num_keys as usize {
308 let cmp = BTreeNode::compare_keys(&node.keys[idx], key);
309 if cmp == core::cmp::Ordering::Equal {
310 if node.node_type == 0 {
311 node.values[idx] = val_sector;
313 device.write_sector(new_sector as usize, &node.to_bytes())?;
314 return Ok(InsertResult::Ok(new_sector));
315 } else {
316 idx += 1;
319 break;
320 }
321 } else if cmp == core::cmp::Ordering::Greater {
322 break;
323 }
324 idx += 1;
325 }
326
327 if node.node_type == 0 {
328 for i in (idx..node.num_keys as usize).rev() {
331 node.keys[i + 1] = node.keys[i];
332 node.values[i + 1] = node.values[i];
333 }
334 node.keys[idx] = *key;
335 node.values[idx] = val_sector;
336 node.num_keys += 1;
337
338 if node.num_keys as usize > MAX_KEYS {
339 let split_res = self.split_node(device, &mut node, new_sector, alloc_sector_fn)?;
341 Ok(split_res)
342 } else {
343 device.write_sector(new_sector as usize, &node.to_bytes())?;
345 Ok(InsertResult::Ok(new_sector))
346 }
347 } else {
348 let child_sec = node.values[idx];
350 let sub_result =
351 self.insert_recursive(device, child_sec, key, val_sector, alloc_sector_fn)?;
352
353 match sub_result {
354 InsertResult::Ok(new_child_sec) => {
355 node.values[idx] = new_child_sec;
357 device.write_sector(new_sector as usize, &node.to_bytes())?;
358 Ok(InsertResult::Ok(new_sector))
359 }
360 InsertResult::Split(new_child_sec, split_key, split_sibling_sec) => {
361 node.values[idx] = new_child_sec;
363
364 for i in (idx..node.num_keys as usize).rev() {
365 node.keys[i + 1] = node.keys[i];
366 node.values[i + 2] = node.values[i + 1];
367 }
368 node.keys[idx] = split_key;
369 node.values[idx + 1] = split_sibling_sec;
370 node.num_keys += 1;
371
372 if node.num_keys as usize > MAX_KEYS {
373 let split_res =
375 self.split_node(device, &mut node, new_sector, alloc_sector_fn)?;
376 Ok(split_res)
377 } else {
378 device.write_sector(new_sector as usize, &node.to_bytes())?;
379 Ok(InsertResult::Ok(new_sector))
380 }
381 }
382 }
383 }
384 }
385
386 fn split_node<B: BlockDevice>(
388 &self,
389 device: &mut MirroredBlockDevice<B>,
390 node: &mut BTreeNode,
391 new_sector: u32,
392 alloc_sector_fn: &mut dyn FnMut() -> u32,
393 ) -> Result<InsertResult, &'static str> {
394 let sibling_sector = alloc_sector_fn();
395 if sibling_sector == 0 {
396 return Err("btree: sector allocation failed");
397 }
398
399 let mut sibling = BTreeNode::new(node.node_type == 0);
400 let n = node.num_keys as usize;
402 let mid = n / 2;
403
404 let split_key = node.keys[mid];
406
407 if node.node_type == 0 {
408 let sibling_keys_num = n - mid;
411 for i in 0..sibling_keys_num {
412 sibling.keys[i] = node.keys[mid + i];
413 sibling.values[i] = node.values[mid + i];
414 }
415 sibling.num_keys = sibling_keys_num as u8;
416 } else {
417 let sibling_keys_num = n - mid - 1;
420 for i in 0..sibling_keys_num {
421 sibling.keys[i] = node.keys[mid + 1 + i];
422 sibling.values[i] = node.values[mid + 1 + i];
423 }
424 sibling.values[sibling_keys_num] = node.values[n]; sibling.num_keys = sibling_keys_num as u8;
426 }
427
428 node.num_keys = mid as u8;
430
431 device.write_sector(new_sector as usize, &node.to_bytes())?;
433 device.write_sector(sibling_sector as usize, &sibling.to_bytes())?;
434
435 Ok(InsertResult::Split(new_sector, split_key, sibling_sector))
436 }
437}
438
439enum InsertResult {
441 Ok(u32),
443 Split(u32, [u8; KEY_LEN], u32),
445}