absurder_sql/storage/
block_info.rs

1//! Block storage information API for the AbsurderSQL Viewer
2//! Provides read-only access to block metadata and cache statistics
3
4// Reentrancy-safe lock macros
5#[cfg(target_arch = "wasm32")]
6macro_rules! lock_mutex {
7    ($mutex:expr) => {
8        $mutex
9            .try_borrow()
10            .expect("RefCell borrow failed - reentrancy detected in block_info.rs")
11    };
12}
13
14#[cfg(not(target_arch = "wasm32"))]
15macro_rules! lock_mutex {
16    ($mutex:expr) => {
17        $mutex.lock()
18    };
19}
20
21use super::block_storage::BlockStorage;
22use serde::{Deserialize, Serialize};
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct BlockInfo {
26    pub block_id: u64,
27    pub checksum: u64,
28    pub version: u32,
29    pub last_modified_ms: u64,
30    pub is_cached: bool,
31    pub is_dirty: bool,
32    pub is_allocated: bool,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct BlockStorageInfo {
37    pub db_name: String,
38    pub total_allocated_blocks: usize,
39    pub total_cached_blocks: usize,
40    pub total_dirty_blocks: usize,
41    pub cache_capacity: usize,
42    pub next_block_id: u64,
43    pub blocks: Vec<BlockInfo>,
44}
45
46impl BlockStorage {
47    /// Get comprehensive block storage information for the viewer
48    pub fn get_storage_info(&mut self) -> BlockStorageInfo {
49        // Get metadata for all allocated blocks
50        let metadata = self.get_block_metadata_for_testing();
51
52        let dirty_guard = lock_mutex!(self.dirty_blocks);
53        let mut blocks: Vec<BlockInfo> = Vec::new();
54
55        for &block_id in lock_mutex!(self.allocated_blocks).iter() {
56            let is_cached = lock_mutex!(self.cache).contains_key(&block_id);
57            let is_dirty = dirty_guard.contains_key(&block_id);
58
59            let (checksum, version, last_modified_ms) =
60                metadata.get(&block_id).copied().unwrap_or((0, 0, 0));
61
62            blocks.push(BlockInfo {
63                block_id,
64                checksum,
65                version,
66                last_modified_ms,
67                is_cached,
68                is_dirty,
69                is_allocated: true,
70            });
71        }
72
73        // Sort by block_id for consistent display
74        blocks.sort_by_key(|b| b.block_id);
75
76        BlockStorageInfo {
77            db_name: self.db_name.clone(),
78            total_allocated_blocks: lock_mutex!(self.allocated_blocks).len(),
79            total_cached_blocks: lock_mutex!(self.cache).len(),
80            total_dirty_blocks: dirty_guard.len(),
81            cache_capacity: self.capacity,
82            next_block_id: self.next_block_id.load(std::sync::atomic::Ordering::SeqCst),
83            blocks,
84        }
85    }
86}