mappy_core/
resize.rs

1//! Dynamic resizing and merging
2//!
3//! Implements dynamic resizing and merging capabilities for maplets.
4
5use crate::{MapletError, MapletResult};
6
7/// Resize manager for maplets
8#[derive(Debug, Clone)]
9pub struct ResizeManager {
10    /// Current capacity
11    capacity: usize,
12    /// Growth factor for resizing
13    growth_factor: f64,
14    /// Maximum capacity
15    max_capacity: usize,
16}
17
18impl ResizeManager {
19    /// Create a new resize manager
20    #[must_use]
21    pub const fn new(initial_capacity: usize) -> Self {
22        Self {
23            capacity: initial_capacity,
24            growth_factor: 2.0,
25            max_capacity: usize::MAX,
26        }
27    }
28
29    /// Calculate new capacity for resizing
30    #[must_use]
31    pub fn calculate_new_capacity(&self, _current_load: usize) -> usize {
32        #[allow(
33            clippy::cast_possible_truncation,
34            clippy::cast_sign_loss,
35            clippy::cast_precision_loss
36        )]
37        {
38            let new_capacity = (self.capacity as f64 * self.growth_factor) as usize;
39            new_capacity.min(self.max_capacity)
40        }
41    }
42
43    /// Check if resizing is needed
44    #[must_use]
45    pub fn should_resize(&self, current_load: usize, max_load_factor: f64) -> bool {
46        #[allow(clippy::cast_precision_loss)]
47        {
48            let load_factor = current_load as f64 / self.capacity as f64;
49            load_factor > max_load_factor
50        }
51    }
52
53    /// Update capacity after resize
54    pub const fn update_capacity(&mut self, new_capacity: usize) {
55        self.capacity = new_capacity;
56    }
57}
58
59/// Merge manager for combining maplets
60#[derive(Debug, Clone)]
61pub struct MergeManager {
62    /// Maximum merge operations allowed
63    max_merges: usize,
64    /// Current merge count
65    merge_count: usize,
66}
67
68impl MergeManager {
69    /// Create a new merge manager
70    #[must_use]
71    pub const fn new(max_merges: usize) -> Self {
72        Self {
73            max_merges,
74            merge_count: 0,
75        }
76    }
77
78    /// Check if merge is allowed
79    #[must_use]
80    pub const fn can_merge(&self) -> bool {
81        self.merge_count < self.max_merges
82    }
83
84    /// Record a merge operation
85    ///
86    /// # Errors
87    ///
88    /// Returns an error if the merge limit is exceeded
89    pub fn record_merge(&mut self) -> MapletResult<()> {
90        if !self.can_merge() {
91            return Err(MapletError::MergeFailed(
92                "Maximum merges exceeded".to_string(),
93            ));
94        }
95        self.merge_count += 1;
96        Ok(())
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_resize_manager() {
106        let mut manager = ResizeManager::new(100);
107
108        assert_eq!(manager.capacity, 100);
109        assert!(!manager.should_resize(50, 0.8));
110        assert!(manager.should_resize(90, 0.8));
111
112        let new_capacity = manager.calculate_new_capacity(90);
113        assert_eq!(new_capacity, 200);
114
115        manager.update_capacity(200);
116        assert_eq!(manager.capacity, 200);
117    }
118
119    #[test]
120    fn test_merge_manager() {
121        let mut manager = MergeManager::new(5);
122
123        assert!(manager.can_merge());
124
125        for _ in 0..5 {
126            assert!(manager.record_merge().is_ok());
127        }
128
129        assert!(!manager.can_merge());
130        assert!(manager.record_merge().is_err());
131    }
132}