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> {
11 match self.live_entry(key) {
12 None => Ok(false),
13 Some(e) => match &e.value {
14 Value::Set(s) => Ok(s.contains(member)),
15 Value::SegSet(s) => Ok(s.contains_key(member)),
16 Value::SmallSetInline(s) => Ok(s.contains(member)),
17 _ => Err(StoreError::WrongType),
18 },
19 }
20 }
21
22 pub fn scard(&mut self, key: &[u8]) -> Result<usize, StoreError> {
23 match self.live_entry(key) {
24 None => Ok(0),
25 Some(e) => match &e.value {
26 Value::Set(s) => Ok(s.len()),
27 Value::SegSet(s) => Ok(s.len()),
28 Value::SmallSetInline(s) => Ok(s.len()),
29 _ => Err(StoreError::WrongType),
30 },
31 }
32 }
33
34 pub fn smembers(&mut self, key: &[u8]) -> Result<Vec<Vec<u8>>, StoreError> {
35 match self.live_entry(key) {
36 None => Ok(Vec::new()),
37 Some(e) => match &e.value {
38 Value::Set(s) => {
39 Ok(s.iter().map(kevy_bytes::SmallBytes::to_vec).collect())
40 }
41 Value::SegSet(s) => Ok(s.keys().map(kevy_bytes::SmallBytes::to_vec).collect()),
42 Value::SmallSetInline(s) => {
43 Ok(s.iter_slices().map(<[u8]>::to_vec).collect())
44 }
45 _ => Err(StoreError::WrongType),
46 },
47 }
48 }
49
50 pub fn srandmember(&mut self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>, StoreError> {
58 let mut draws: Vec<u64> = (0..count.saturating_mul(3).max(8))
59 .map(|_| self.rng.next_u64())
60 .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
122 .iter()
123 .map(|d| all[(*d as usize) % all.len()].clone())
124 .collect())
125 }
126 Value::Set(s) => {
127 if s.is_empty() {
128 return Ok(Vec::new());
129 }
130 Ok(draws
131 .iter()
132 .filter_map(|d| {
133 s.iter_from_slot(*d as usize)
134 .next()
135 .map(kevy_bytes::SmallBytes::to_vec)
136 })
137 .collect())
138 }
139 Value::SegSet(s) => {
140 if s.is_empty() {
141 return Ok(Vec::new());
142 }
143 Ok(draws
144 .iter()
145 .filter_map(|d| s.rand_entry(*d).map(|(m, ())| m.to_vec()))
146 .collect())
147 }
148 _ => Err(StoreError::WrongType),
149 },
150 }
151 }
152
153 pub fn set_snapshot(&mut self, key: &[u8]) -> Result<Vec<Vec<u8>>, StoreError> {
155 self.smembers(key)
156 }
157}
158
159fn seg_srandmember(
163 s: &crate::seg_map::SegMap<()>,
164 count: usize,
165 draws: &mut Vec<u64>,
166) -> Vec<Vec<u8>> {
167 if count * 4 >= s.len() {
168 let mut all: Vec<Vec<u8>> = s.keys().map(kevy_bytes::SmallBytes::to_vec).collect();
169 let k = crate::set::shuffle_prefix(&mut all, count, draws);
170 all.truncate(k);
171 return all;
172 }
173 let mut out: Vec<Vec<u8>> = Vec::with_capacity(count);
174 for d in draws.iter() {
175 if out.len() == count {
176 break;
177 }
178 if let Some((m, ())) = s.rand_entry(*d)
179 && !out.contains(&m.to_vec())
180 {
181 out.push(m.to_vec());
182 }
183 }
184 out
185}