Skip to main content

geographdb_core/storage/
data_structures.rs

1use bytemuck::{Pod, Zeroable};
2
3// A wrapper struct for spatial indexing, containing the node's ID and its 3D position.
4#[derive(Clone, Copy, Debug, PartialEq)]
5pub struct NodePoint {
6    pub id: u64,
7    pub x: f32,
8    pub y: f32,
9    pub z: f32,
10}
11
12#[repr(C)]
13#[derive(Clone, Copy, Debug, Pod, Zeroable)]
14pub struct NodeRec {
15    pub id: u64,
16    pub morton_code: u64, // Changed back to u64 for alignment
17    pub x: f32,
18    pub y: f32,
19    pub z: f32,
20    pub edge_off: u32,
21    pub edge_len: u32,
22    pub flags: u32,
23    // MVCC fields for Tuple-MVCC
24    pub begin_ts: u64, // Transaction timestamp when this version was created
25    pub end_ts: u64,   // Transaction timestamp when this version was superseded (0 = current)
26    // Transaction tracking fields (Phase 1: WAL-MVCC Integration)
27    pub tx_id: u64, // Transaction ID that created this version (0 = system/bootstrap)
28    pub visibility: u8, // VERSION_UNCOMMITTED(0), VERSION_COMMITTED(1), VERSION_ABORTED(2)
29    pub _padding: [u8; 7], // Padding for 8-byte alignment (Pod trait requirement)
30}
31// Size: 72 bytes (was 56 bytes, increased by 16 bytes for transaction tracking)
32
33#[repr(C)]
34#[derive(Clone, Copy, Debug, Pod, Zeroable)]
35pub struct EdgeRec {
36    pub src: u64, // Source node index
37    pub dst: u64,
38    pub w: f32, // Semantic weight
39    pub flags: u32,
40    // MVCC fields for Tuple-MVCC
41    pub begin_ts: u64, // Transaction timestamp when this version was created
42    pub end_ts: u64,   // Transaction timestamp when this version was superseded (0 = current)
43    // Transaction tracking fields (Phase 1: WAL-MVCC Integration)
44    pub tx_id: u64, // Transaction ID that created this version (0 = system/bootstrap)
45    pub visibility: u8, // VERSION_UNCOMMITTED(0), VERSION_COMMITTED(1), VERSION_ABORTED(2)
46    pub _padding: [u8; 7], // Padding for 8-byte alignment (Pod trait requirement)
47}
48// Size: 48 bytes (was 32 bytes, increased by 16 bytes for transaction tracking)
49
50#[repr(C)]
51#[derive(Clone, Copy, Debug, Pod, Zeroable)]
52#[allow(dead_code)]
53pub struct OctreeNode {
54    pub min_x: f32,
55    pub min_y: f32,
56    pub min_z: f32,
57    pub max_x: f32,
58    pub max_y: f32,
59    pub max_z: f32,
60    pub children_ptr: u64, // Pointer to children nodes or 0 if leaf
61    pub data_ptr: u64,     // Pointer to data (e.g., NodeRec offsets)
62    pub data_len: u32,     // Number of data items
63    pub _padding: u32,     // For Pod compatibility
64}
65
66pub const WAL_ENTRY_NODE_CREATE: u8 = 1;
67pub const WAL_ENTRY_EDGE_CREATE: u8 = 2;
68pub const WAL_ENTRY_NODE_DELETE: u8 = 3;
69pub const WAL_ENTRY_EDGE_DELETE: u8 = 4;
70pub const WAL_ENTRY_PROPERTY_UPDATE: u8 = 5;
71pub const WAL_ENTRY_BEGIN_TX: u8 = 6;
72pub const WAL_ENTRY_COMMIT_TX: u8 = 7;
73pub const WAL_ENTRY_ABORT_TX: u8 = 8;
74
75pub const NODE_FLAG_TOMBSTONE: u32 = 0x1;
76pub const EDGE_FLAG_TOMBSTONE: u32 = 0x1;
77
78// Version visibility states for transaction tracking
79pub const VERSION_UNCOMMITTED: u8 = 0; // Created by active transaction, invisible to others
80pub const VERSION_COMMITTED: u8 = 1; // Committed, visible to snapshots >= commit_ts
81pub const VERSION_ABORTED: u8 = 2; // Rolled back, should be GC'd
82
83/// Fixed-size record for CFG block metadata (176 bytes for string storage)
84/// Stores terminator type and location info for each block
85#[repr(C)]
86#[derive(Clone, Copy, Debug, Pod, Zeroable)]
87pub struct MetadataRec {
88    /// Null-terminated string for block kind (max 31 bytes + null)
89    pub block_kind: [u8; 32],
90    /// Null-terminated string for terminator type (max 63 bytes + null)
91    pub terminator: [u8; 64],
92    pub byte_start: u64,
93    pub byte_end: u64,
94    pub start_line: u64,
95    pub start_col: u64,
96    pub end_line: u64,
97    pub end_col: u64,
98    pub _padding: [u8; 32],
99}
100
101impl MetadataRec {
102    pub const SIZE: usize = 176; // 32 + 64 + 6*8 + 32 = 176 bytes
103
104    /// Create from string values
105    #[allow(clippy::too_many_arguments)]
106    pub fn from_strings(
107        block_kind: &str,
108        terminator: &str,
109        byte_start: u64,
110        byte_end: u64,
111        start_line: u64,
112        start_col: u64,
113        end_line: u64,
114        end_col: u64,
115    ) -> Self {
116        let mut rec = Self {
117            block_kind: [0u8; 32],
118            terminator: [0u8; 64],
119            byte_start,
120            byte_end,
121            start_line,
122            start_col,
123            end_line,
124            end_col,
125            _padding: [0u8; 32],
126        };
127
128        // Copy block_kind (truncate if needed) - already zero-initialized
129        let kind_bytes = block_kind.as_bytes();
130        let len = kind_bytes.len().min(31);
131        if len > 0 {
132            rec.block_kind[..len].copy_from_slice(&kind_bytes[..len]);
133        }
134        // block_kind[len..] is already 0 from initialization
135
136        // Copy terminator (truncate if needed) - already zero-initialized
137        let term_bytes = terminator.as_bytes();
138        let len = term_bytes.len().min(63);
139        if len > 0 {
140            rec.terminator[..len].copy_from_slice(&term_bytes[..len]);
141        }
142        // terminator[len..] is already 0 from initialization
143
144        rec
145    }
146
147    /// Get block kind as string
148    pub fn get_block_kind(&self) -> String {
149        let null_pos = self.block_kind.iter().position(|&b| b == 0).unwrap_or(32);
150        String::from_utf8_lossy(&self.block_kind[..null_pos]).to_string()
151    }
152
153    /// Get terminator as string
154    pub fn get_terminator(&self) -> String {
155        let null_pos = self.terminator.iter().position(|&b| b == 0).unwrap_or(64);
156        String::from_utf8_lossy(&self.terminator[..null_pos]).to_string()
157    }
158}
159
160impl Default for MetadataRec {
161    fn default() -> Self {
162        Self {
163            block_kind: [0u8; 32],
164            terminator: [0u8; 64],
165            byte_start: 0,
166            byte_end: 0,
167            start_line: 0,
168            start_col: 0,
169            end_line: 0,
170            end_col: 0,
171            _padding: [0u8; 32],
172        }
173    }
174}
175
176#[repr(C)]
177#[derive(Clone, Copy, Debug, Pod, Zeroable)]
178pub struct WalEntry {
179    pub timestamp: u64,    // 8 bytes - Epoch when entry was created
180    pub node_id: u64,      // 8 bytes - Node ID for node operations
181    pub edge_dst: u64,     // 8 bytes - Edge destination for edge operations
182    pub x: f32,            // 4 bytes - X coordinate
183    pub y: f32,            // 4 bytes - Y coordinate
184    pub z: f32,            // 4 bytes - Z coordinate
185    pub edge_w: f32,       // 4 bytes - Edge weight
186    pub entry_type: u8,    // 1 byte - Entry type (NODE_CREATE, BEGIN_TX, etc.)
187    pub _padding: [u8; 7], // 7 bytes - Padding for alignment
188    pub tx_id: u64,        // 8 bytes - Transaction ID (0 = auto-commit)
189    pub lsn: u64,          // 8 bytes - Log Sequence Number
190}