Coverage Report

Created: 2026-01-04 13:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/runner/work/feoxdb/feoxdb/src/core/store/init.rs
Line
Count
Source
1
use ahash::RandomState;
2
use crossbeam_skiplist::SkipMap;
3
use parking_lot::RwLock;
4
use scc::HashMap;
5
use std::sync::Arc;
6
7
use crate::constants::*;
8
use crate::error::Result;
9
use crate::stats::Statistics;
10
use crate::storage::free_space::FreeSpaceManager;
11
use crate::storage::metadata::Metadata;
12
use crate::storage::write_buffer::WriteBuffer;
13
14
use super::{FeoxStore, StoreConfig};
15
16
impl FeoxStore {
17
    /// Create a new FeoxStore with default configuration
18
63
    pub fn new(device_path: Option<String>) -> Result<Self> {
19
63
        let memory_only = device_path.is_none();
20
63
        let config = StoreConfig {
21
63
            hash_bits: DEFAULT_HASH_BITS,
22
63
            memory_only,
23
63
            enable_caching: !memory_only, // Disable caching for memory-only mode
24
63
            device_path,
25
63
            file_size: None,
26
63
            max_memory: Some(DEFAULT_MAX_MEMORY),
27
63
            enable_ttl: false,
28
63
            ttl_config: None,
29
63
        };
30
63
        let hash_table =
31
63
            HashMap::with_capacity_and_hasher(1 << config.hash_bits, RandomState::new());
32
33
63
        let free_space = Arc::new(RwLock::new(FreeSpaceManager::new()));
34
63
        let metadata = Arc::new(RwLock::new(Metadata::new()));
35
63
        let stats = Arc::new(Statistics::new());
36
37
63
        let cache = if config.enable_caching {
38
18
            Some(Arc::new(crate::core::cache::ClockCache::new(stats.clone())))
39
        } else {
40
45
            None
41
        };
42
43
63
        let mut store = Self {
44
63
            hash_table,
45
63
            tree: Arc::new(SkipMap::new()),
46
63
            stats: stats.clone(),
47
63
            write_buffer: None,
48
63
            free_space: free_space.clone(),
49
63
            _metadata: metadata,
50
63
            memory_only: config.memory_only,
51
63
            enable_caching: config.enable_caching,
52
63
            max_memory: config.max_memory,
53
63
            cache,
54
63
            #[cfg(unix)]
55
63
            device_fd: None,
56
63
            device_size: 0,
57
63
            device_file: None,
58
63
            disk_io: None,
59
63
            ttl_sweeper: Arc::new(RwLock::new(None)),
60
63
            enable_ttl: config.enable_ttl,
61
63
        };
62
63
63
        if !config.memory_only {
64
18
            store.open_device(&config.device_path, config.file_size)
?0
;
65
18
            store.load_indexes()
?0
;
66
67
            // Initialize write buffer for persistent mode
68
18
            if let Some(ref disk_io) = store.disk_io {
69
18
                let metadata_version = store._metadata.read().version;
70
18
                let mut write_buffer =
71
18
                    WriteBuffer::new(disk_io.clone(), free_space, stats.clone(), metadata_version);
72
18
                let num_workers = (num_cpus::get() / 2).max(1);
73
18
                write_buffer.start_workers(num_workers);
74
18
                store.write_buffer = Some(Arc::new(write_buffer));
75
18
            
}0
76
45
        }
77
78
63
        Ok(store)
79
63
    }
80
81
    /// Create a new FeoxStore with custom configuration
82
15
    pub fn with_config(config: StoreConfig) -> Result<Self> {
83
        // Initialize hash table with configured capacity
84
15
        let hash_table =
85
15
            HashMap::with_capacity_and_hasher(1 << config.hash_bits, RandomState::new());
86
87
15
        let free_space = Arc::new(RwLock::new(FreeSpaceManager::new()));
88
15
        let metadata = Arc::new(RwLock::new(Metadata::new()));
89
15
        let stats = Arc::new(Statistics::new());
90
91
15
        let cache = if config.enable_caching {
92
0
            Some(Arc::new(crate::core::cache::ClockCache::new(stats.clone())))
93
        } else {
94
15
            None
95
        };
96
97
15
        let mut store = Self {
98
15
            hash_table,
99
15
            tree: Arc::new(SkipMap::new()),
100
15
            stats: stats.clone(),
101
15
            write_buffer: None,
102
15
            free_space: free_space.clone(),
103
15
            _metadata: metadata,
104
15
            memory_only: config.memory_only,
105
15
            enable_caching: config.enable_caching,
106
15
            max_memory: config.max_memory,
107
15
            cache,
108
15
            #[cfg(unix)]
109
15
            device_fd: None,
110
15
            device_size: 0,
111
15
            device_file: None,
112
15
            disk_io: None,
113
15
            ttl_sweeper: Arc::new(RwLock::new(None)),
114
15
            enable_ttl: config.enable_ttl,
115
15
        };
116
117
15
        if !config.memory_only {
118
0
            store.open_device(&config.device_path, config.file_size)?;
119
0
            store.load_indexes()?;
120
121
            // Initialize write buffer for persistent mode
122
0
            if let Some(ref disk_io) = store.disk_io {
123
0
                let metadata_version = store._metadata.read().version;
124
0
                let mut write_buffer =
125
0
                    WriteBuffer::new(disk_io.clone(), free_space, stats.clone(), metadata_version);
126
0
                let num_workers = (num_cpus::get() / 2).max(1);
127
0
                write_buffer.start_workers(num_workers);
128
0
                store.write_buffer = Some(Arc::new(write_buffer));
129
0
            }
130
15
        }
131
132
15
        Ok(store)
133
15
    }
134
}