1#[cfg(not(feature = "std"))]
11use crate::nostd_prelude::*;
12use alloc::borrow::Cow;
13use core::num::NonZeroU64;
14use alloc::sync::Arc;
15
16use crate::value::{SmallBytes, Value};
17use crate::{Entry, Store, StoreError};
18
19impl Store {
20 pub fn getbit(&mut self, key: &[u8], offset: u64) -> Result<u8, StoreError> {
24 let bytes = match self.get(key)? {
25 Some(cow) => cow,
26 None => return Ok(0),
27 };
28 let byte_idx = (offset / 8) as usize;
29 let bit_idx = 7 - (offset % 8) as u8;
30 if byte_idx >= bytes.len() {
31 return Ok(0);
32 }
33 Ok((bytes[byte_idx] >> bit_idx) & 1)
34 }
35
36 pub fn setbit(
41 &mut self,
42 key: &[u8],
43 offset: u64,
44 value: u8,
45 ) -> Result<u8, StoreError> {
46 if value > 1 {
47 return Err(StoreError::OutOfRange);
48 }
49 let byte_idx = (offset / 8) as usize;
50 let bit_idx = 7 - (offset % 8) as u8;
51
52 let mut owned: Vec<u8> = match self.get(key)? {
56 Some(Cow::Borrowed(b)) => b.to_vec(),
57 Some(Cow::Owned(v)) => v,
58 None => Vec::new(),
59 };
60 if byte_idx >= owned.len() {
61 owned.resize(byte_idx + 1, 0);
62 }
63 let prev = (owned[byte_idx] >> bit_idx) & 1;
64 if value == 1 {
65 owned[byte_idx] |= 1 << bit_idx;
66 } else {
67 owned[byte_idx] &= !(1u8 << bit_idx);
68 }
69 let new_val = if owned.is_empty() {
71 Value::Str(SmallBytes::from_slice(&[]))
72 } else {
73 Value::ArcBulk(Arc::new(owned.into_boxed_slice()))
74 };
75 let ttl_ns = self
78 .live_entry(key)
79 .and_then(|e| e.expire_at_ns.map(NonZeroU64::get));
80 self.insert_entry(
81 SmallBytes::from_slice(key),
82 Entry::new(new_val, ttl_ns),
83 );
84 Ok(prev)
85 }
86
87 pub fn bitcount(
91 &mut self,
92 key: &[u8],
93 range: Option<(i64, i64)>,
94 ) -> Result<u64, StoreError> {
95 let bytes = match self.get(key)? {
96 Some(cow) => cow,
97 None => return Ok(0),
98 };
99 if bytes.is_empty() {
100 return Ok(0);
101 }
102 let len = bytes.len() as i64;
103 let (s, e) = match range {
104 None => (0, (len - 1) as usize),
105 Some((start, end)) => {
106 let norm = |x: i64| -> i64 {
107 if x < 0 { (len + x).max(0) } else { x.min(len - 1) }
108 };
109 let s = norm(start);
110 let e = norm(end);
111 if s > e {
112 return Ok(0);
113 }
114 (s as usize, e as usize)
115 }
116 };
117 Ok(bytes[s..=e]
118 .iter()
119 .map(|b| u64::from(b.count_ones()))
120 .sum())
121 }
122
123 pub fn bitpos(
129 &mut self,
130 key: &[u8],
131 bit: u8,
132 range: Option<(i64, i64)>,
133 ) -> Result<Option<u64>, StoreError> {
134 if bit > 1 {
135 return Err(StoreError::OutOfRange);
136 }
137 let bytes = match self.get(key)? {
138 Some(cow) => cow,
139 None => return Ok(if bit == 0 { Some(0) } else { None }),
140 };
141 if bytes.is_empty() {
142 return Ok(if bit == 0 { Some(0) } else { None });
143 }
144 let len = bytes.len() as i64;
145 let (s, e) = match range {
146 None => (0usize, (len - 1) as usize),
147 Some((start, end)) => {
148 let norm = |x: i64| -> i64 {
149 if x < 0 { (len + x).max(0) } else { x.min(len - 1) }
150 };
151 let s = norm(start);
152 let e = norm(end);
153 if s > e {
154 return Ok(None);
155 }
156 (s as usize, e as usize)
157 }
158 };
159 for (i, &b) in bytes[s..=e].iter().enumerate() {
160 let target_mask = if bit == 1 { b } else { !b };
161 if target_mask != 0 {
162 let bit_in_byte = target_mask.leading_zeros() as u64;
163 let byte_idx = (s + i) as u64;
164 return Ok(Some(byte_idx * 8 + bit_in_byte));
165 }
166 }
167 Ok(None)
168 }
169
170 pub fn getrange(
174 &mut self,
175 key: &[u8],
176 start: i64,
177 end: i64,
178 ) -> Result<Vec<u8>, StoreError> {
179 let bytes = match self.get(key)? {
180 Some(cow) => cow,
181 None => return Ok(Vec::new()),
182 };
183 if bytes.is_empty() {
184 return Ok(Vec::new());
185 }
186 let len = bytes.len() as i64;
187 let norm = |x: i64| -> i64 {
188 if x < 0 { (len + x).max(0) } else { x.min(len - 1) }
189 };
190 let s = norm(start) as usize;
191 let e = norm(end) as usize;
192 if s > e {
193 return Ok(Vec::new());
194 }
195 Ok(bytes[s..=e].to_vec())
196 }
197
198 pub fn setrange(
203 &mut self,
204 key: &[u8],
205 offset: u64,
206 value: &[u8],
207 ) -> Result<usize, StoreError> {
208 let offset = offset as usize;
209 let mut owned: Vec<u8> = match self.get(key)? {
210 Some(Cow::Borrowed(b)) => b.to_vec(),
211 Some(Cow::Owned(v)) => v,
212 None => Vec::new(),
213 };
214 let needed = offset + value.len();
215 if needed > owned.len() {
216 owned.resize(needed, 0);
217 }
218 owned[offset..offset + value.len()].copy_from_slice(value);
219 let new_len = owned.len();
220 let new_val = if owned.is_empty() {
221 Value::Str(SmallBytes::from_slice(&[]))
222 } else {
223 Value::ArcBulk(Arc::new(owned.into_boxed_slice()))
224 };
225 let ttl_ns = self
226 .live_entry(key)
227 .and_then(|e| e.expire_at_ns.map(NonZeroU64::get));
228 self.insert_entry(
229 SmallBytes::from_slice(key),
230 Entry::new(new_val, ttl_ns),
231 );
232 Ok(new_len)
233 }
234}