feoxdb/core/store/
init.rs1use 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 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, 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 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 pub fn with_config(config: StoreConfig) -> Result<Self> {
83 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 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}