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