feoxdb/core/store/
init.rs

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