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