/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 | | } |