linkrs_storage/edge/property_schema.rs
1//! Property Schema and Statistics
2//!
3//! Contains schema definitions and compaction statistics for property storage.
4//! These types are separated from the table implementation for better modularity.
5
6use crate::encoding::EncodingType;
7use linkrs_core::{DataType, Value};
8use std::sync::Arc;
9
10/// Default version chain capacity for property storage
11pub const DEFAULT_VERSION_CHAIN_CAP: usize = 64;
12
13/// Property schema definition
14#[derive(Debug, Clone)]
15pub struct PropertySchema {
16 pub name: Arc<str>,
17 pub prop_id: i32,
18 pub data_type: DataType,
19 pub nullable: bool,
20 pub encoding_type: EncodingType,
21 pub default_value: Option<Value>,
22}
23
24impl PropertySchema {
25 pub fn new(name: impl Into<Arc<str>>, prop_id: i32, data_type: DataType) -> Self {
26 Self {
27 name: name.into(),
28 prop_id,
29 data_type,
30 nullable: false,
31 encoding_type: EncodingType::None,
32 default_value: None,
33 }
34 }
35
36 pub fn nullable(mut self, nullable: bool) -> Self {
37 self.nullable = nullable;
38 self
39 }
40
41 pub fn with_encoding(mut self, encoding_type: EncodingType) -> Self {
42 self.encoding_type = encoding_type;
43 self
44 }
45
46 pub fn with_default_value(mut self, default_value: Option<Value>) -> Self {
47 self.default_value = default_value;
48 self
49 }
50}
51
52/// Statistics about property table fragmentation and compaction.
53///
54/// Tracks fragmentation metrics to help decide when to perform compaction
55/// and measure the effectiveness of compaction operations.
56///
57/// Fragmentation is measured in two ways:
58/// 1. **Record-level**: tombstone_count / total_records
59/// - Quick check for excessive deleted records
60/// - Not size-aware (100 large records vs 100 tiny records look the same)
61///
62/// 2. **Byte-level**: reclaimable_bytes
63/// - Actual storage waste from deleted records
64/// - More accurate indicator of compaction benefit
65///
66/// Compaction decisions should primarily consider reclaimable_bytes
67/// rather than just fragmentation ratio.
68#[derive(Debug, Clone, Default)]
69pub struct PropertyCompactionStats {
70 /// Number of deleted/tombstoned records
71 pub tombstone_count: usize,
72 /// Total number of records including tombstones
73 pub total_records: usize,
74 /// Number of live (non-deleted) records
75 /// Equal to total_records - tombstone_count
76 pub live_records: usize,
77 /// Estimated bytes that could be recovered through compaction
78 pub reclaimable_bytes: usize,
79}
80
81impl PropertyCompactionStats {
82 /// Get fragmentation ratio as a decimal (0.0 to 1.0)
83 pub fn fragmentation_ratio(&self) -> f64 {
84 if self.total_records == 0 {
85 0.0
86 } else {
87 self.tombstone_count as f64 / self.total_records as f64
88 }
89 }
90}