kevy_embedded/
ops_bitmap.rs1use crate::{KevyError, KevyResult};
8use kevy_store::BitOp;
9
10use crate::store::ensure_writable;
11use crate::store::{Store, commit_write, store_err};
12
13impl Store {
14 pub fn getbit(&self, key: &[u8], offset: u64) -> KevyResult<u8> {
17 self.wshard(key).store.getbit(key, offset).map_err(store_err)
18 }
19
20 pub fn setbit(&self, key: &[u8], offset: u64, value: u8) -> KevyResult<u8> {
24 ensure_writable(self)?;
25 let mut g = self.wshard(key);
26 let prev = g.store.setbit(key, offset, value).map_err(store_err)?;
27 let off_str = format!("{offset}");
28 let val_str = format!("{value}");
29 commit_write(&mut g, &[b"SETBIT", key, off_str.as_bytes(), val_str.as_bytes()])?;
30 Ok(prev)
31 }
32
33 pub fn bitcount(&self, key: &[u8], range: Option<(i64, i64)>) -> KevyResult<u64> {
37 self.wshard(key).store.bitcount(key, range).map_err(store_err)
38 }
39
40 pub fn bitpos(
44 &self,
45 key: &[u8],
46 bit: u8,
47 range: Option<(i64, i64)>,
48 ) -> KevyResult<Option<u64>> {
49 self.wshard(key).store.bitpos(key, bit, range).map_err(store_err)
50 }
51
52 pub fn getrange(&self, key: &[u8], start: i64, end: i64) -> KevyResult<Vec<u8>> {
55 self.wshard(key).store.getrange(key, start, end).map_err(store_err)
56 }
57
58 pub fn setrange(&self, key: &[u8], offset: u64, value: &[u8]) -> KevyResult<usize> {
62 ensure_writable(self)?;
63 let mut g = self.wshard(key);
64 let new_len = g.store.setrange(key, offset, value).map_err(store_err)?;
65 let off_str = format!("{offset}");
66 commit_write(&mut g, &[b"SETRANGE", key, off_str.as_bytes(), value])?;
67 Ok(new_len)
68 }
69
70 pub fn bitop(&self, op: BitOp, dst: &[u8], srcs: &[&[u8]]) -> KevyResult<usize> {
76 ensure_writable(self)?;
77 if srcs.is_empty() {
78 return Ok(0);
79 }
80 if matches!(op, BitOp::Not) && srcs.len() != 1 {
81 return Err(KevyError::InvalidInput("BITOP NOT takes exactly one source key".into()));
82 }
83 let mut srcs_bytes: Vec<Vec<u8>> = Vec::with_capacity(srcs.len());
85 for k in srcs {
86 let v = self.get(k)?.unwrap_or_default();
87 srcs_bytes.push(v);
88 }
89 let max_len = srcs_bytes.iter().map(Vec::len).max().unwrap_or(0);
90 if max_len == 0 {
91 self.del(&[dst])?;
93 return Ok(0);
94 }
95 let out = kevy_store::bitop_combine(op, &srcs_bytes, max_len);
96 self.set(dst, &out)?;
98 Ok(max_len)
99 }
100
101 pub fn time(&self) -> (u64, u32) {
104 let now =
105 std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap_or_default();
106 (now.as_secs(), now.subsec_micros())
107 }
108}