feoxdb/core/store/
internal.rs1use ahash::RandomState;
2use bytes::Bytes;
3use scc::HashMap;
4use std::sync::atomic::Ordering;
5use std::sync::Arc;
6
7use crate::constants::Operation;
8use crate::core::record::Record;
9use crate::error::{FeoxError, Result};
10use crate::storage::write_buffer::WriteBuffer;
11
12use super::FeoxStore;
13
14impl FeoxStore {
15 pub(super) fn update_record_with_ttl(
16 &self,
17 old_record: &Record,
18 value: &[u8],
19 timestamp: u64,
20 ttl_expiry: u64,
21 ) -> Result<bool> {
22 let new_record = if ttl_expiry > 0 && self.enable_ttl {
23 Arc::new(Record::new_with_timestamp_ttl(
24 old_record.key.clone(),
25 value.to_vec(),
26 timestamp,
27 ttl_expiry,
28 ))
29 } else {
30 Arc::new(Record::new(
31 old_record.key.clone(),
32 value.to_vec(),
33 timestamp,
34 ))
35 };
36
37 let old_value_len = old_record.value_len;
38 let old_size = old_record.calculate_size();
39 let new_size = self.calculate_record_size(old_record.key.len(), value.len());
40
41 let old_record_arc =
42 if let Some(entry) = self.hash_table.read(&old_record.key, |_, v| v.clone()) {
43 entry
44 } else {
45 return Err(FeoxError::KeyNotFound);
46 };
47
48 let key_vec = new_record.key.clone();
49
50 old_record_arc.refcount.store(0, Ordering::Release);
51 self.hash_table
52 .upsert(key_vec.clone(), Arc::clone(&new_record));
53 self.tree.insert(key_vec.clone(), Arc::clone(&new_record));
54
55 if new_size > old_size {
56 self.stats
57 .memory_usage
58 .fetch_add(new_size - old_size, Ordering::AcqRel);
59 } else {
60 self.stats
61 .memory_usage
62 .fetch_sub(old_size - new_size, Ordering::AcqRel);
63 }
64
65 if !self.memory_only {
67 if self.enable_caching {
68 if let Some(ref cache) = self.cache {
69 cache.remove(&key_vec);
70 }
71 }
72
73 if let Some(ref wb) = self.write_buffer {
74 wb.add_write(Operation::Update, Arc::clone(&new_record), old_value_len)?;
75 wb.add_write(Operation::Delete, old_record_arc, old_value_len)?;
76 }
77 }
78
79 Ok(false)
80 }
81
82 pub(super) fn update_record_with_ttl_bytes(
84 &self,
85 old_record: &Record,
86 value: Bytes,
87 timestamp: u64,
88 ttl_expiry: u64,
89 ) -> Result<bool> {
90 let new_record = if ttl_expiry > 0 && self.enable_ttl {
91 Arc::new(Record::new_from_bytes_with_ttl(
92 old_record.key.clone(),
93 value,
94 timestamp,
95 ttl_expiry,
96 ))
97 } else {
98 Arc::new(Record::new_from_bytes(
99 old_record.key.clone(),
100 value,
101 timestamp,
102 ))
103 };
104
105 let old_value_len = old_record.value_len;
106 let old_size = old_record.calculate_size();
107 let new_size = new_record.calculate_size();
108
109 let old_record_arc =
110 if let Some(entry) = self.hash_table.read(&old_record.key, |_, v| v.clone()) {
111 entry
112 } else {
113 return Err(FeoxError::KeyNotFound);
114 };
115
116 let key_vec = new_record.key.clone();
117
118 old_record_arc.refcount.store(0, Ordering::Release);
119 self.hash_table
120 .upsert(key_vec.clone(), Arc::clone(&new_record));
121 self.tree.insert(key_vec.clone(), Arc::clone(&new_record));
122
123 if new_size > old_size {
124 self.stats
125 .memory_usage
126 .fetch_add(new_size - old_size, Ordering::AcqRel);
127 } else {
128 self.stats
129 .memory_usage
130 .fetch_sub(old_size - new_size, Ordering::AcqRel);
131 }
132
133 if !self.memory_only {
135 if self.enable_caching {
136 if let Some(ref cache) = self.cache {
137 cache.remove(&key_vec);
138 }
139 }
140
141 if let Some(ref wb) = self.write_buffer {
142 wb.add_write(Operation::Update, Arc::clone(&new_record), old_value_len)?;
143 wb.add_write(Operation::Delete, old_record_arc, old_value_len)?;
144 }
145 }
146
147 Ok(false)
148 }
149
150 pub(crate) fn get_hash_table(&self) -> &HashMap<Vec<u8>, Arc<Record>, RandomState> {
152 &self.hash_table
153 }
154
155 pub(crate) fn remove_from_tree(&self, key: &[u8]) {
157 self.tree.remove(key);
158 }
159
160 pub(crate) fn get_write_buffer(&self) -> Option<&Arc<WriteBuffer>> {
162 self.write_buffer.as_ref()
163 }
164}