1#[cfg(not(feature = "std"))]
5use crate::nostd_prelude::*;
6use crate::value::Value;
7use crate::{Store, StoreError};
8
9impl Store {
10 pub fn sismember(&mut self, key: &[u8], member: &[u8]) -> Result<bool, StoreError> {
13 match self.live_entry(key) {
14 None => Ok(false),
15 Some(e) => match &e.value {
16 Value::Set(s) => Ok(s.contains(member)),
17 Value::SegSet(s) => Ok(s.contains_key(member)),
18 Value::SmallSetInline(s) => Ok(s.contains(member)),
19 _ => Err(StoreError::WrongType),
20 },
21 }
22 }
23
24 pub fn scard(&mut self, key: &[u8]) -> Result<usize, StoreError> {
26 match self.live_entry(key) {
27 None => Ok(0),
28 Some(e) => match &e.value {
29 Value::Set(s) => Ok(s.len()),
30 Value::SegSet(s) => Ok(s.len()),
31 Value::SmallSetInline(s) => Ok(s.len()),
32 _ => Err(StoreError::WrongType),
33 },
34 }
35 }
36
37 pub fn smembers(&mut self, key: &[u8]) -> Result<Vec<Vec<u8>>, StoreError> {
40 match self.live_entry(key) {
41 None => Ok(Vec::new()),
42 Some(e) => match &e.value {
43 Value::Set(s) => Ok(s.iter().map(kevy_bytes::SmallBytes::to_vec).collect()),
44 Value::SegSet(s) => Ok(s.keys().map(kevy_bytes::SmallBytes::to_vec).collect()),
45 Value::SmallSetInline(s) => Ok(s.iter_slices().map(<[u8]>::to_vec).collect()),
46 _ => Err(StoreError::WrongType),
47 },
48 }
49 }
50
51 pub fn srandmember(&mut self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>, StoreError> {
59 let mut draws: Vec<u64> =
60 (0..count.saturating_mul(3).max(8)).map(|_| self.rng.next_u64()).collect();
61 match self.live_entry(key) {
62 None => Ok(Vec::new()),
63 Some(e) => match &e.value {
64 Value::SmallSetInline(s) => {
65 let mut all: Vec<Vec<u8>> = s.iter_slices().map(<[u8]>::to_vec).collect();
66 let k = crate::set::shuffle_prefix(&mut all, count, &mut draws);
67 all.truncate(k);
68 Ok(all)
69 }
70 Value::Set(s) => {
71 let n = s.len();
72 if count >= n {
73 return Ok(s.iter().map(kevy_bytes::SmallBytes::to_vec).collect());
74 }
75 if count * 4 >= n {
76 let mut all: Vec<Vec<u8>> =
78 s.iter().map(kevy_bytes::SmallBytes::to_vec).collect();
79 let k = crate::set::shuffle_prefix(&mut all, count, &mut draws);
80 all.truncate(k);
81 return Ok(all);
82 }
83 let mut out: Vec<Vec<u8>> = Vec::with_capacity(count);
84 for slot in &draws {
85 if out.len() == count {
86 break;
87 }
88 if let Some(m) = s
89 .iter_from_slot(*slot as usize)
90 .next()
91 .map(kevy_bytes::SmallBytes::to_vec)
92 && !out.contains(&m)
93 {
94 out.push(m);
95 }
96 }
97 Ok(out)
98 }
99 Value::SegSet(s) => Ok(seg_srandmember(s, count, &mut draws)),
100 _ => Err(StoreError::WrongType),
101 },
102 }
103 }
104
105 pub fn srandmember_with_repeats(
108 &mut self,
109 key: &[u8],
110 count: usize,
111 ) -> Result<Vec<Vec<u8>>, StoreError> {
112 let draws: Vec<u64> = (0..count).map(|_| self.rng.next_u64()).collect();
113 match self.live_entry(key) {
114 None => Ok(Vec::new()),
115 Some(e) => match &e.value {
116 Value::SmallSetInline(s) => {
117 let all: Vec<Vec<u8>> = s.iter_slices().map(<[u8]>::to_vec).collect();
118 if all.is_empty() {
119 return Ok(Vec::new());
120 }
121 Ok(draws.iter().map(|d| all[(*d as usize) % all.len()].clone()).collect())
122 }
123 Value::Set(s) => {
124 if s.is_empty() {
125 return Ok(Vec::new());
126 }
127 Ok(draws
128 .iter()
129 .filter_map(|d| {
130 s.iter_from_slot(*d as usize).next().map(kevy_bytes::SmallBytes::to_vec)
131 })
132 .collect())
133 }
134 Value::SegSet(s) => {
135 if s.is_empty() {
136 return Ok(Vec::new());
137 }
138 Ok(draws
139 .iter()
140 .filter_map(|d| s.rand_entry(*d).map(|(m, ())| m.to_vec()))
141 .collect())
142 }
143 _ => Err(StoreError::WrongType),
144 },
145 }
146 }
147
148 pub fn set_snapshot(&mut self, key: &[u8]) -> Result<Vec<Vec<u8>>, StoreError> {
150 self.smembers(key)
151 }
152}
153
154fn seg_srandmember(
158 s: &crate::seg_map::SegMap<()>,
159 count: usize,
160 draws: &mut Vec<u64>,
161) -> Vec<Vec<u8>> {
162 if count * 4 >= s.len() {
163 let mut all: Vec<Vec<u8>> = s.keys().map(kevy_bytes::SmallBytes::to_vec).collect();
164 let k = crate::set::shuffle_prefix(&mut all, count, draws);
165 all.truncate(k);
166 return all;
167 }
168 let mut out: Vec<Vec<u8>> = Vec::with_capacity(count);
169 for d in draws.iter() {
170 if out.len() == count {
171 break;
172 }
173 if let Some((m, ())) = s.rand_entry(*d)
174 && !out.contains(&m.to_vec())
175 {
176 out.push(m.to_vec());
177 }
178 }
179 out
180}