1use std::collections::HashSet;
32
33use yo_common::Result;
34
35use crate::db::{Db, Holds};
36use crate::keyspace::Keyspace;
37use crate::scan::Cursor;
38use crate::set::{Member, Set};
39use crate::setops::{self, PerSet};
40use crate::strings;
41use crate::value::{self, Kind};
42
43impl Keyspace {
44 pub fn sadd<'m>(
53 &mut self,
54 key: &[u8],
55 members: impl Iterator<Item = &'m [u8]> + Clone,
56 ) -> Result<usize> {
57 for m in members.clone() {
58 strings::check_len(key, m.len())?;
59 }
60 let at = match self.set_slot(key)? {
61 Some(at) => at,
62 None => {
63 let Some(first) = members.clone().next() else {
69 return Ok(0);
70 };
71 let hint = members.clone().count();
72 self.new_set(key, first, hint)
73 }
74 };
75
76 let limits = self.limits;
79 let set = self
80 .sets
81 .get_mut(at)
82 .expect("the record points at its body");
83 let mut added = 0;
84 for m in members {
85 if set.add(m, &limits) {
86 added += 1;
87 }
88 }
89 Ok(added)
90 }
91
92 pub fn srem<'m>(
96 &mut self,
97 key: &[u8],
98 members: impl Iterator<Item = &'m [u8]>,
99 ) -> Result<usize> {
100 let Some(at) = self.set_slot(key)? else {
101 return Ok(0);
102 };
103 let set = self
104 .sets
105 .get_mut(at)
106 .expect("the record points at its body");
107 let mut gone = 0;
108 for m in members {
109 if set.remove(m) {
110 gone += 1;
111 }
112 }
113 if set.is_empty() {
114 self.drop_key(key);
115 }
116 Ok(gone)
117 }
118
119 pub fn sismember(&mut self, key: &[u8], member: &[u8]) -> Result<bool> {
121 match self.set_slot(key)? {
122 Some(at) => Ok(self.set_at(at).contains(member)),
123 None => Ok(false),
124 }
125 }
126
127 pub fn smismember<'m>(
132 &mut self,
133 key: &[u8],
134 members: impl Iterator<Item = &'m [u8]>,
135 ) -> Result<Vec<bool>> {
136 let Some(at) = self.set_slot(key)? else {
137 return Ok(members.map(|_| false).collect());
138 };
139 let set = self.set_at(at);
140 Ok(members.map(|m| set.contains(m)).collect())
141 }
142
143 pub fn scard(&mut self, key: &[u8]) -> Result<usize> {
145 match self.set_slot(key)? {
146 Some(at) => Ok(self.set_at(at).len()),
147 None => Ok(0),
148 }
149 }
150
151 pub fn smembers(&mut self, key: &[u8]) -> Result<Option<impl Iterator<Item = Member<'_>>>> {
159 let Some(at) = self.set_slot(key)? else {
160 return Ok(None);
161 };
162 Ok(Some(self.set_at(at).iter()))
163 }
164
165 pub fn spop(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
174 let Some(at) = self.set_slot(key)? else {
175 return Ok(None);
176 };
177 let len = self.set_at(at).len();
180 let pick = self.rng.below(len);
181 let got = self
182 .sets
183 .get_mut(at)
184 .expect("the record points at its body")
185 .remove_at(pick);
186 if self.set_at(at).is_empty() {
187 self.drop_key(key);
188 }
189 Ok(got)
190 }
191
192 pub fn spop_n(&mut self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>> {
201 let Some(at) = self.set_slot(key)? else {
202 return Ok(Vec::new());
203 };
204 let take = count.min(self.set_at(at).len());
205 let mut out = Vec::with_capacity(take);
206 for _ in 0..take {
207 let pick = self.rng.below(self.set_at(at).len());
211 out.push(
212 self.sets
213 .get_mut(at)
214 .expect("the record points at its body")
215 .remove_at(pick)
216 .expect("the draw was under the length"),
217 );
218 }
219 if self.set_at(at).is_empty() {
220 self.drop_key(key);
221 }
222 Ok(out)
223 }
224
225 pub fn spop_into<F>(&mut self, key: &[u8], count: usize, mut f: F) -> Result<usize>
244 where
245 F: FnMut(Member<'_>),
246 {
247 let Some(at) = self.set_slot(key)? else {
248 return Ok(0);
249 };
250 let take = count.min(self.set_at(at).len());
251 for _ in 0..take {
252 let rng = &mut self.rng;
256 let set = self.sets.get(at).expect("the record points at its body");
257 let pick = rng.below(set.len());
258 f(set.at(pick).expect("the draw was under the length"));
259 self.sets
260 .get_mut(at)
261 .expect("the record points at its body")
262 .drop_at(pick);
263 }
264 if self.set_at(at).is_empty() {
265 self.drop_key(key);
266 }
267 Ok(take)
268 }
269
270 pub fn srandmember<R>(
281 &mut self,
282 key: &[u8],
283 f: impl FnOnce(Option<Member<'_>>) -> R,
284 ) -> Result<R> {
285 let Some(at) = self.set_slot(key)? else {
286 return Ok(f(None));
287 };
288 let pick = self.rng.below(self.sets.get(at).expect("a body").len());
289 Ok(f(self.set_at(at).at(pick)))
290 }
291
292 pub fn srandmember_n<F>(&mut self, key: &[u8], count: i64, mut f: F) -> Result<()>
313 where
314 F: FnMut(Member<'_>),
315 {
316 let Some(at) = self.set_slot(key)? else {
317 return Ok(());
318 };
319 let rng = &mut self.rng;
323 let set = self.sets.get(at).expect("the record points at its body");
324 let len = set.len();
325
326 let Ok(want) = usize::try_from(count) else {
327 let repeats = usize::try_from(count.unsigned_abs()).unwrap_or(usize::MAX);
328 for _ in 0..repeats {
329 f(set
330 .at(rng.below(len))
331 .expect("the draw was under the length"));
332 }
333 return Ok(());
334 };
335 if want >= len {
336 for m in set.iter() {
337 f(m);
338 }
339 return Ok(());
340 }
341 if want.saturating_mul(3) > len {
342 let mut need = want;
343 for i in 0..len {
344 if rng.below(len - i) < need {
345 f(set.at(i).expect("i is under the length"));
346 need -= 1;
347 }
348 }
349 return Ok(());
350 }
351 let mut drawn = HashSet::with_capacity(want);
352 while drawn.len() < want {
353 let i = rng.below(len);
354 if drawn.insert(i) {
355 f(set.at(i).expect("the draw was under the length"));
356 }
357 }
358 Ok(())
359 }
360
361 pub fn sscan<F>(&mut self, key: &[u8], cursor: Cursor, count: usize, f: F) -> Result<Cursor>
369 where
370 F: FnMut(Member<'_>),
371 {
372 let Some(at) = self.set_slot(key)? else {
373 return Ok(Cursor::END);
374 };
375 Ok(self.set_at(at).scan(cursor, count, f))
376 }
377
378 pub fn smove(&mut self, source: &[u8], destination: &[u8], member: &[u8]) -> Result<bool> {
390 let Some(from) = self.set_slot(source)? else {
391 return Ok(false);
392 };
393 let onto = self.set_slot(destination)?;
394 if source == destination {
395 return Ok(self.set_at(from).contains(member));
396 }
397 if !self
398 .sets
399 .get_mut(from)
400 .expect("the record points at its body")
401 .remove(member)
402 {
403 return Ok(false);
404 }
405 let limits = self.limits;
409 let at = match onto {
410 Some(at) => at,
411 None => self.new_set(destination, member, 1),
412 };
413 self.sets
414 .get_mut(at)
415 .expect("the record points at its body")
416 .add(member, &limits);
417 if self.set_at(from).is_empty() {
418 self.drop_key(source);
419 }
420 Ok(true)
421 }
422
423 pub fn sinter<'k, F>(
429 &mut self,
430 keys: impl Iterator<Item = &'k [u8]>,
431 limit: usize,
432 f: F,
433 ) -> Result<usize>
434 where
435 F: FnMut(&[u8]),
436 {
437 let slots = self.set_slots(keys)?;
438 if slots.is_empty() || slots.iter().any(Option::is_none) {
442 return Ok(0);
443 }
444 let mut scratch = std::mem::take(&mut self.setops);
447 let sets = self.bodies_of(&slots);
448 let n = setops::inter(&mut scratch, &sets, limit, f);
449 self.setops = scratch;
450 Ok(n)
451 }
452
453 pub fn sintercard<'k>(
455 &mut self,
456 keys: impl Iterator<Item = &'k [u8]>,
457 limit: usize,
458 ) -> Result<usize> {
459 self.sinter(keys, limit, |_| {})
460 }
461
462 pub fn sunion<'k, F>(
471 &mut self,
472 keys: impl Iterator<Item = &'k [u8]>,
473 limit: usize,
474 f: F,
475 ) -> Result<usize>
476 where
477 F: FnMut(&[u8]),
478 {
479 let slots = self.set_slots(keys)?;
480 let mut scratch = std::mem::take(&mut self.setops);
484 let sets = self.bodies_of(&slots);
485 let n = setops::union(&mut scratch, &sets, limit, f);
486 self.setops = scratch;
487 Ok(n)
488 }
489
490 pub fn sunioncard<'k>(
492 &mut self,
493 keys: impl Iterator<Item = &'k [u8]>,
494 limit: usize,
495 ) -> Result<usize> {
496 self.sunion(keys, limit, |_| {})
497 }
498
499 pub fn sdiff<'k, F>(
505 &mut self,
506 keys: impl Iterator<Item = &'k [u8]>,
507 limit: usize,
508 f: F,
509 ) -> Result<usize>
510 where
511 F: FnMut(&[u8]),
512 {
513 let slots = self.set_slots(keys)?;
514 let Some(Some(_)) = slots.first() else {
515 return Ok(0);
516 };
517 let sets = self.bodies_of(&slots);
518 Ok(setops::diff(&sets, limit, f))
519 }
520
521 pub fn sdiffcard<'k>(
523 &mut self,
524 keys: impl Iterator<Item = &'k [u8]>,
525 limit: usize,
526 ) -> Result<usize> {
527 self.sdiff(keys, limit, |_| {})
528 }
529
530 pub fn sinterstore<'k>(
532 &mut self,
533 destination: &[u8],
534 keys: impl Iterator<Item = &'k [u8]>,
535 ) -> Result<usize> {
536 let slots = self.set_slots(keys)?;
537 let mut scratch = std::mem::take(&mut self.setops);
538 let built = if slots.is_empty() || slots.iter().any(Option::is_none) {
539 None
540 } else {
541 let sets = self.bodies_of(&slots);
542 let upper = sets.iter().map(|s| s.len()).min().unwrap_or(0);
544 setops::collect(upper, &self.limits, |f| {
545 setops::inter(&mut scratch, &sets, 0, f);
546 })
547 };
548 self.setops = scratch;
549 Ok(self.put_set(destination, built))
550 }
551
552 pub fn sunionstore<'k>(
554 &mut self,
555 destination: &[u8],
556 keys: impl Iterator<Item = &'k [u8]>,
557 ) -> Result<usize> {
558 let slots = self.set_slots(keys)?;
559 let mut scratch = std::mem::take(&mut self.setops);
560 let built = {
561 let sets = self.bodies_of(&slots);
562 let upper = sets.iter().map(|s| s.len()).sum();
566 setops::collect(upper, &self.limits, |f| {
567 setops::union(&mut scratch, &sets, 0, f);
568 })
569 };
570 self.setops = scratch;
571 Ok(self.put_set(destination, built))
572 }
573
574 pub fn sdiffstore<'k>(
576 &mut self,
577 destination: &[u8],
578 keys: impl Iterator<Item = &'k [u8]>,
579 ) -> Result<usize> {
580 let slots = self.set_slots(keys)?;
581 let built = match slots.first() {
582 Some(Some(_)) => {
583 let sets = self.bodies_of(&slots);
584 let upper = sets[0].len();
585 setops::collect(upper, &self.limits, |f| {
586 setops::diff(&sets, 0, f);
587 })
588 }
589 _ => None,
590 };
591 Ok(self.put_set(destination, built))
592 }
593
594 fn set_slots<'k>(
612 &mut self,
613 keys: impl Iterator<Item = &'k [u8]>,
614 ) -> Result<PerSet<Option<u32>>> {
615 let mut out = PerSet::new();
618 for key in keys {
619 out.push(self.set_slot(key)?);
620 }
621 Ok(out)
622 }
623
624 #[inline]
626 fn bodies_of(&self, slots: &[Option<u32>]) -> PerSet<&Set> {
627 slots.iter().flatten().map(|&at| self.set_at(at)).collect()
628 }
629
630 fn put_set(&mut self, key: &[u8], set: Option<Set>) -> usize {
648 let Some(set) = set else {
649 self.drop_key(key);
650 return 0;
651 };
652 self.free_body(key);
653 let len = set.len();
654 let at = self.sets.insert(set);
655 let record = value::slot_record_len(false);
656 self.write_rec(key, record, |out| {
657 value::write_slot_record(out, Kind::Set, at, None);
658 });
659 self.bodies += 1;
660 len
661 }
662
663 pub fn with_set<R>(&mut self, key: &[u8], f: impl FnOnce(Option<&Set>) -> R) -> Result<R> {
676 let at = self.set_slot(key)?;
677 Ok(f(at.map(|at| self.set_at(at))))
678 }
679
680 fn set_slot(&mut self, key: &[u8]) -> Result<Option<u32>> {
686 self.live_slot(key, Kind::Set)
687 }
688
689 #[inline]
695 fn set_at(&self, at: u32) -> &Set {
696 self.sets.get(at).expect("the record points at its body")
697 }
698
699 fn new_set(&mut self, key: &[u8], first: &[u8], hint: usize) -> u32 {
705 let at =
709 yo_alloc::first_touch(|| self.sets.insert(Set::with_hint(first, hint, &self.limits)));
710 let len = value::slot_record_len(false);
711 self.write_rec(key, len, |out| {
712 value::write_slot_record(out, Kind::Set, at, None);
713 });
714 self.bodies += 1;
715 at
716 }
717}
718
719type Home = (usize, u32);
725
726impl Db {
727 pub fn smove(&self, source: &[u8], destination: &[u8], member: &[u8]) -> Result<bool> {
740 let (from, onto) = (self.stripe_of(source), self.stripe_of(destination));
741 if from == onto {
742 return self.hold_stripe(from).smove(source, destination, member);
743 }
744 let mut held = self.hold_many([from, onto].into_iter());
748 let Some(at) = held.stripe_mut(from).set_slot(source)? else {
749 return Ok(false);
750 };
751 let there = held.stripe_mut(onto).set_slot(destination)?;
752 if !held
753 .stripe_mut(from)
754 .sets
755 .get_mut(at)
756 .expect("the record points at its body")
757 .remove(member)
758 {
759 return Ok(false);
760 }
761
762 let dest = held.stripe_mut(onto);
763 let limits = dest.limits;
764 let into = match there {
765 Some(into) => into,
766 None => dest.new_set(destination, member, 1),
767 };
768 dest.sets
769 .get_mut(into)
770 .expect("the record points at its body")
771 .add(member, &limits);
772
773 let src = held.stripe_mut(from);
774 if src.set_at(at).is_empty() {
775 src.drop_key(source);
776 }
777 Ok(true)
778 }
779
780 pub fn sinter<'k, F>(
782 &self,
783 keys: impl Iterator<Item = &'k [u8]> + Clone,
784 limit: usize,
785 f: F,
786 ) -> Result<usize>
787 where
788 F: FnMut(&[u8]),
789 {
790 if let Some(home) = self.one_stripe(keys.clone()) {
791 return self.hold_stripe(home).sinter(keys, limit, f);
792 }
793 let mut spare = self.spare();
796 let scratch = &mut spare.setops;
797 let mut held = self.hold_sets(keys.clone(), None);
798 let slots = self.set_slots(&mut held, keys)?;
799 if slots.is_empty() || slots.iter().any(Option::is_none) {
800 return Ok(0);
801 }
802 let sets = bodies_of(&held, &slots);
803 Ok(setops::inter(scratch, &sets, limit, f))
804 }
805
806 pub fn sintercard<'k>(
808 &self,
809 keys: impl Iterator<Item = &'k [u8]> + Clone,
810 limit: usize,
811 ) -> Result<usize> {
812 self.sinter(keys, limit, |_| {})
813 }
814
815 pub fn sunion<'k, F>(
817 &self,
818 keys: impl Iterator<Item = &'k [u8]> + Clone,
819 limit: usize,
820 f: F,
821 ) -> Result<usize>
822 where
823 F: FnMut(&[u8]),
824 {
825 if let Some(home) = self.one_stripe(keys.clone()) {
826 return self.hold_stripe(home).sunion(keys, limit, f);
827 }
828 let mut spare = self.spare();
831 let scratch = &mut spare.setops;
832 let mut held = self.hold_sets(keys.clone(), None);
833 let slots = self.set_slots(&mut held, keys)?;
834 let sets = bodies_of(&held, &slots);
835 Ok(setops::union(scratch, &sets, limit, f))
836 }
837
838 pub fn sunioncard<'k>(
840 &self,
841 keys: impl Iterator<Item = &'k [u8]> + Clone,
842 limit: usize,
843 ) -> Result<usize> {
844 self.sunion(keys, limit, |_| {})
845 }
846
847 pub fn sdiff<'k, F>(
849 &self,
850 keys: impl Iterator<Item = &'k [u8]> + Clone,
851 limit: usize,
852 f: F,
853 ) -> Result<usize>
854 where
855 F: FnMut(&[u8]),
856 {
857 if let Some(home) = self.one_stripe(keys.clone()) {
858 return self.hold_stripe(home).sdiff(keys, limit, f);
859 }
860 let mut held = self.hold_sets(keys.clone(), None);
861 let slots = self.set_slots(&mut held, keys)?;
862 let Some(Some(_)) = slots.first() else {
863 return Ok(0);
864 };
865 let sets = bodies_of(&held, &slots);
866 Ok(setops::diff(&sets, limit, f))
867 }
868
869 pub fn sdiffcard<'k>(
871 &self,
872 keys: impl Iterator<Item = &'k [u8]> + Clone,
873 limit: usize,
874 ) -> Result<usize> {
875 self.sdiff(keys, limit, |_| {})
876 }
877
878 pub fn sinterstore<'k>(
885 &self,
886 destination: &'k [u8],
887 keys: impl Iterator<Item = &'k [u8]> + Clone,
888 ) -> Result<usize> {
889 if let Some(home) = self.one_stripe(std::iter::once(destination).chain(keys.clone())) {
890 return self.hold_stripe(home).sinterstore(destination, keys);
891 }
892 let mut spare = self.spare();
895 let scratch = &mut spare.setops;
896 let onto = self.stripe_of(destination);
897 let mut held = self.hold_sets(keys.clone(), Some(destination));
898 let slots = self.set_slots(&mut held, keys)?;
899 let built = if slots.is_empty() || slots.iter().any(Option::is_none) {
900 None
901 } else {
902 let limits = held.stripe(onto).limits;
903 let sets = bodies_of(&held, &slots);
904 let upper = sets.iter().map(|s| s.len()).min().unwrap_or(0);
905 setops::collect(upper, &limits, |f| {
906 setops::inter(scratch, &sets, 0, f);
907 })
908 };
909 Ok(held.stripe_mut(onto).put_set(destination, built))
910 }
911
912 pub fn sunionstore<'k>(
914 &self,
915 destination: &'k [u8],
916 keys: impl Iterator<Item = &'k [u8]> + Clone,
917 ) -> Result<usize> {
918 if let Some(home) = self.one_stripe(std::iter::once(destination).chain(keys.clone())) {
919 return self.hold_stripe(home).sunionstore(destination, keys);
920 }
921 let mut spare = self.spare();
924 let scratch = &mut spare.setops;
925 let onto = self.stripe_of(destination);
926 let mut held = self.hold_sets(keys.clone(), Some(destination));
927 let slots = self.set_slots(&mut held, keys)?;
928 let built = {
929 let limits = held.stripe(onto).limits;
930 let sets = bodies_of(&held, &slots);
931 let upper = sets.iter().map(|s| s.len()).sum();
932 setops::collect(upper, &limits, |f| {
933 setops::union(scratch, &sets, 0, f);
934 })
935 };
936 Ok(held.stripe_mut(onto).put_set(destination, built))
937 }
938
939 pub fn sdiffstore<'k>(
941 &self,
942 destination: &'k [u8],
943 keys: impl Iterator<Item = &'k [u8]> + Clone,
944 ) -> Result<usize> {
945 if let Some(home) = self.one_stripe(std::iter::once(destination).chain(keys.clone())) {
946 return self.hold_stripe(home).sdiffstore(destination, keys);
947 }
948 let onto = self.stripe_of(destination);
949 let mut held = self.hold_sets(keys.clone(), Some(destination));
950 let slots = self.set_slots(&mut held, keys)?;
951 let built = match slots.first() {
952 Some(Some(_)) => {
953 let limits = held.stripe(onto).limits;
954 let sets = bodies_of(&held, &slots);
955 let upper = sets[0].len();
956 setops::collect(upper, &limits, |f| {
957 setops::diff(&sets, 0, f);
958 })
959 }
960 _ => None,
961 };
962 Ok(held.stripe_mut(onto).put_set(destination, built))
963 }
964
965 #[inline]
973 fn hold_sets<'k>(
974 &self,
975 keys: impl Iterator<Item = &'k [u8]>,
976 destination: Option<&[u8]>,
977 ) -> Holds<'_> {
978 let named = keys.map(|key| self.stripe_of(key));
979 self.hold_many(named.chain(destination.map(|d| self.stripe_of(d))))
980 }
981
982 fn set_slots<'k>(
990 &self,
991 held: &mut Holds<'_>,
992 keys: impl Iterator<Item = &'k [u8]>,
993 ) -> Result<PerSet<Option<Home>>> {
994 let mut out = PerSet::new();
995 for key in keys {
996 let stripe = self.stripe_of(key);
997 let at = held.stripe_mut(stripe).set_slot(key)?;
998 out.push(at.map(|at| (stripe, at)));
999 }
1000 Ok(out)
1001 }
1002}
1003
1004#[inline]
1006fn bodies_of<'h>(held: &'h Holds<'_>, slots: &[Option<Home>]) -> PerSet<&'h Set> {
1007 slots
1008 .iter()
1009 .flatten()
1010 .map(|&(stripe, at)| held.stripe(stripe).set_at(at))
1011 .collect()
1012}
1013
1014#[cfg(test)]
1015mod tests {
1016 use super::*;
1017 use crate::Clock;
1018 use crate::set::Encoding;
1019 use yo_common::Code;
1020
1021 fn db() -> Keyspace {
1022 Keyspace::with_clock(Clock::fixed(1_000))
1023 }
1024
1025 fn add(d: &mut Keyspace, key: &[u8], members: &[&[u8]]) -> usize {
1026 d.sadd(key, members.iter().copied()).expect("a set")
1027 }
1028
1029 fn members(d: &mut Keyspace, key: &[u8]) -> Vec<String> {
1030 let mut v: Vec<String> = d
1031 .smembers(key)
1032 .expect("a set")
1033 .expect("a key")
1034 .map(|m| String::from_utf8(m.to_vec()).expect("utf8 in these tests"))
1035 .collect();
1036 v.sort();
1037 v
1038 }
1039
1040 #[test]
1043 fn a_union_over_text_sets_does_not_allocate_once_its_table_is_warm() {
1044 let mut d = db();
1045 add(&mut d, b"a", &[b"alpha", b"beta", b"gamma", b"delta"]);
1046 add(&mut d, b"b", &[b"gamma", b"delta", b"epsilon", b"zeta"]);
1047 assert_eq!(
1050 d.sunion([b"a".as_slice(), b"b"].into_iter(), 0, |_| {}),
1051 Ok(6)
1052 );
1053 let (_, allocs) = crate::tally::counted(|| {
1054 for _ in 0..50 {
1055 assert_eq!(
1056 d.sunion([b"a".as_slice(), b"b"].into_iter(), 0, |_| {}),
1057 Ok(6)
1058 );
1059 }
1060 });
1061 assert_eq!(allocs, 0, "sunion allocated {allocs} times in fifty");
1062 }
1063
1064 #[test]
1067 fn a_union_larger_than_the_last_one_grows_the_table_and_is_still_right() {
1068 let mut d = db();
1069 add(&mut d, b"a", &[b"one", b"two"]);
1070 add(&mut d, b"b", &[b"two", b"three"]);
1071 assert_eq!(
1072 d.sunion([b"a".as_slice(), b"b"].into_iter(), 0, |_| {}),
1073 Ok(3)
1074 );
1075
1076 let many: Vec<Vec<u8>> = (0..500).map(|i| format!("m{i}").into_bytes()).collect();
1077 let refs: Vec<&[u8]> = many.iter().map(Vec::as_slice).collect();
1078 add(&mut d, b"c", &refs);
1079 let mut seen = Vec::new();
1080 assert_eq!(
1081 d.sunion([b"a".as_slice(), b"c"].into_iter(), 0, |m: &[u8]| seen
1082 .push(m.to_vec())),
1083 Ok(502)
1084 );
1085 seen.sort();
1086 seen.dedup();
1087 assert_eq!(seen.len(), 502, "every member came back once");
1088
1089 assert_eq!(
1092 d.sunion([b"a".as_slice(), b"b"].into_iter(), 0, |_| {}),
1093 Ok(3)
1094 );
1095 }
1096
1097 #[test]
1098 fn adding_to_a_key_that_is_not_there_makes_it() {
1099 let mut d = db();
1100 assert_eq!(add(&mut d, b"s", &[b"a", b"b", b"c"]), 3);
1101 assert_eq!(d.scard(b"s").expect("a set"), 3);
1102 assert_eq!(d.kind_of(b"s"), Some(Kind::Set));
1103 assert_eq!(members(&mut d, b"s"), ["a", "b", "c"]);
1104 assert_eq!(d.len(), 1, "one key, whatever the set holds");
1105 }
1106
1107 #[test]
1108 fn adding_answers_how_many_were_new_and_not_how_many_arrived() {
1109 let mut d = db();
1110 assert_eq!(add(&mut d, b"s", &[b"a", b"b"]), 2);
1111 assert_eq!(add(&mut d, b"s", &[b"b", b"c"]), 1);
1112 assert_eq!(
1113 add(&mut d, b"s", &[b"x", b"x", b"x"]),
1114 1,
1115 "the same member three times in one call is one member"
1116 );
1117 assert_eq!(d.scard(b"s").expect("a set"), 4);
1118 }
1119
1120 #[test]
1121 fn everything_answers_for_a_key_that_is_not_there() {
1122 let mut d = db();
1123 assert_eq!(d.scard(b"nope").expect("missing is fine"), 0);
1124 assert!(!d.sismember(b"nope", b"a").expect("missing is fine"));
1125 assert!(d.smembers(b"nope").expect("missing is fine").is_none());
1126 assert_eq!(
1127 d.srem(b"nope", [b"a".as_slice()].into_iter()).expect("ok"),
1128 0
1129 );
1130 assert_eq!(
1131 d.smismember(b"nope", [b"a".as_slice(), b"b"].into_iter())
1132 .expect("ok"),
1133 [false, false]
1134 );
1135 assert_eq!(d.len(), 0, "and none of that created anything");
1136 }
1137
1138 #[test]
1139 fn membership_answers_for_members_and_strangers() {
1140 let mut d = db();
1141 add(&mut d, b"s", &[b"a", b"b"]);
1142 assert!(d.sismember(b"s", b"a").expect("a set"));
1143 assert!(!d.sismember(b"s", b"z").expect("a set"));
1144 assert_eq!(
1145 d.smismember(b"s", [b"a".as_slice(), b"z", b"b"].into_iter())
1146 .expect("a set"),
1147 [true, false, true]
1148 );
1149 }
1150
1151 #[test]
1152 fn removing_the_last_member_removes_the_key() {
1153 let mut d = db();
1155 add(&mut d, b"s", &[b"a", b"b"]);
1156 assert_eq!(d.srem(b"s", [b"a".as_slice()].into_iter()).expect("ok"), 1);
1157 assert!(d.exists(b"s"), "one member left");
1158
1159 assert_eq!(
1160 d.srem(b"s", [b"b".as_slice(), b"gone"].into_iter())
1161 .expect("ok"),
1162 1,
1163 "one of the two was there"
1164 );
1165 assert!(!d.exists(b"s"), "and now the key is gone with it");
1166 assert_eq!(d.kind_of(b"s"), None);
1167 assert_eq!(d.len(), 0);
1168 }
1169
1170 #[test]
1171 fn a_set_is_deleted_body_and_all() {
1172 let mut d = db();
1176 add(&mut d, b"s", &[b"a", b"b"]);
1177 assert_eq!(d.sets.len(), 1);
1178
1179 assert!(d.del(b"s"));
1180 assert_eq!(d.sets.len(), 0, "the body went with the key");
1181 assert_eq!(d.bodies, 0);
1182
1183 add(&mut d, b"t", &[b"x"]);
1185 assert_eq!(d.sets.len(), 1);
1186 }
1187
1188 #[test]
1189 fn writing_a_string_over_a_set_takes_the_body_with_it() {
1190 let mut d = db();
1193 add(&mut d, b"k", &[b"a", b"b"]);
1194 assert_eq!(d.sets.len(), 1);
1195
1196 d.set_plain(b"k", b"now a string").expect("room");
1197 assert_eq!(d.sets.len(), 0, "the set went when it was written over");
1198 assert_eq!(d.bodies, 0);
1199 assert_eq!(d.kind_of(b"k"), Some(Kind::String));
1200 assert_eq!(
1201 d.get(b"k").expect("a string").map(|v| v.to_vec()),
1202 Some(b"now a string".to_vec())
1203 );
1204 }
1205
1206 #[test]
1207 fn a_set_that_expires_takes_its_body_with_it() {
1208 let mut d = db();
1209 add(&mut d, b"s", &[b"a"]);
1210 assert!(d.set_expiry(b"s", Some(1_100)));
1211 assert_eq!(d.expire_at(b"s"), Some(1_100));
1212 assert_eq!(d.sets.len(), 1);
1213 assert_eq!(d.scard(b"s").expect("a set"), 1, "still alive at 1000");
1214
1215 d.clock().advance(100);
1216 assert_eq!(d.scard(b"s").expect("gone is not an error"), 0);
1217 assert_eq!(d.sets.len(), 0, "reaping freed the body");
1218 assert_eq!(d.bodies, 0);
1219 assert_eq!(d.expired_keys(), 1);
1220 }
1221
1222 #[test]
1223 fn flushing_takes_every_body_with_it() {
1224 let mut d = db();
1225 for i in 0..10 {
1226 add(&mut d, format!("s{i}").as_bytes(), &[b"a", b"b"]);
1227 }
1228 assert_eq!(d.sets.len(), 10);
1229
1230 d.clear();
1231 assert_eq!(d.sets.len(), 0);
1232 assert_eq!(d.bodies, 0);
1233 assert_eq!(d.len(), 0);
1234 }
1235
1236 #[test]
1237 fn a_set_command_at_a_string_is_wrongtype() {
1238 let mut d = db();
1239 d.set_plain(b"k", b"v").expect("room");
1240
1241 let err = d.sadd(b"k", [b"a".as_slice()].into_iter()).expect_err("no");
1242 assert_eq!(err.code(), Code::WrongType);
1243 assert_eq!(
1244 err.message(),
1245 "Operation against a key holding the wrong kind of value"
1246 );
1247 assert!(d.scard(b"k").is_err());
1248 assert!(d.sismember(b"k", b"a").is_err());
1249 assert!(d.smembers(b"k").is_err());
1250 assert!(d.srem(b"k", [b"a".as_slice()].into_iter()).is_err());
1251 assert!(d.smismember(b"k", [b"a".as_slice()].into_iter()).is_err());
1252 assert_eq!(
1253 d.get(b"k").expect("still a string").map(|v| v.to_vec()),
1254 Some(b"v".to_vec()),
1255 "and none of that damaged it"
1256 );
1257 }
1258
1259 #[test]
1260 fn a_string_command_at_a_set_is_wrongtype() {
1261 let mut d = db();
1262 add(&mut d, b"s", &[b"a"]);
1263
1264 assert_eq!(d.get(b"s").expect_err("no").code(), Code::WrongType);
1265 assert!(d.strlen(b"s").is_err());
1266 assert!(d.getrange(b"s", 0, -1).is_err());
1267 assert!(d.getdel(b"s").is_err());
1268 assert!(d.incr(b"s").is_err());
1269 assert!(d.append(b"s", b"x").is_err());
1270 assert_eq!(d.scard(b"s").expect("a set"), 1, "and it is still a set");
1271 }
1272
1273 #[test]
1274 fn the_commands_that_do_not_care_still_do_not_care() {
1275 let mut d = db();
1278 add(&mut d, b"s", &[b"a"]);
1279
1280 assert!(d.exists(b"s"));
1281 assert_eq!(d.kind_of(b"s"), Some(Kind::Set));
1282 assert_eq!(d.encoding_name(b"s"), Some("listpack"));
1283 assert!(d.set_expiry(b"s", Some(6_000)));
1284 assert_eq!(d.expire_at(b"s"), Some(6_000));
1285 assert!(d.set_expiry(b"s", None), "and PERSIST takes it off again");
1286 assert_eq!(d.expire_at(b"s"), None);
1287 assert_eq!(d.scard(b"s").expect("a set"), 1, "through all of that");
1288 assert!(d.del(b"s"));
1289 }
1290
1291 #[test]
1292 fn mget_says_nil_for_a_set_rather_than_failing() {
1293 let mut d = db();
1297 d.set_plain(b"a", b"1").expect("room");
1298 add(&mut d, b"s", &[b"x"]);
1299 d.set_plain(b"z", b"2").expect("room");
1300
1301 let got: Vec<Option<Vec<u8>>> = d
1302 .mget(&[b"a", b"s", b"z", b"nope"])
1303 .into_iter()
1304 .map(|v| v.map(|s| s.to_vec()))
1305 .collect();
1306 assert_eq!(got, [Some(b"1".to_vec()), None, Some(b"2".to_vec()), None]);
1307 }
1308
1309 #[test]
1310 fn the_representation_follows_the_members_through_the_keyspace() {
1311 let mut d = db();
1315 add(&mut d, b"s", &[b"1", b"2", b"3"]);
1316 assert_eq!(d.set_encoding(b"s"), Some(Encoding::Intset));
1317
1318 add(&mut d, b"s", &[b"hello"]);
1319 assert_eq!(d.set_encoding(b"s"), Some(Encoding::Listpack));
1320 assert_eq!(members(&mut d, b"s"), ["1", "2", "3", "hello"]);
1321
1322 let long: Vec<u8> = vec![b'z'; 100];
1323 add(&mut d, b"s", &[&long]);
1324 assert_eq!(d.set_encoding(b"s"), Some(Encoding::Hashtable));
1325 assert_eq!(d.scard(b"s").expect("a set"), 5);
1326 assert!(d.sismember(b"s", b"1").expect("a set"), "nothing was lost");
1327 assert!(d.sismember(b"s", &long).expect("a set"));
1328 }
1329
1330 #[test]
1331 fn a_thousand_members_at_once_builds_a_table_without_converting() {
1332 let mut d = db();
1333 let owned: Vec<Vec<u8>> = (0..1000).map(|i| format!("m{i}").into_bytes()).collect();
1334 let refs: Vec<&[u8]> = owned.iter().map(Vec::as_slice).collect();
1335 assert_eq!(d.sadd(b"s", refs.iter().copied()).expect("a set"), 1000);
1336 assert_eq!(d.set_encoding(b"s"), Some(Encoding::Hashtable));
1337 assert_eq!(d.scard(b"s").expect("a set"), 1000);
1338 }
1339
1340 fn many(d: &mut Keyspace, key: &[u8], n: usize) {
1342 let owned: Vec<Vec<u8>> = (0..n).map(|i| format!("m{i}").into_bytes()).collect();
1343 let refs: Vec<&[u8]> = owned.iter().map(Vec::as_slice).collect();
1344 d.sadd(key, refs.iter().copied()).expect("a set");
1345 }
1346
1347 fn fill(d: &mut Keyspace, key: &[u8], n: usize, ints: bool) {
1350 let owned: Vec<Vec<u8>> = (0..n)
1351 .map(|i| {
1352 if ints {
1353 i.to_string().into_bytes()
1354 } else {
1355 format!("m{i}").into_bytes()
1356 }
1357 })
1358 .collect();
1359 let refs: Vec<&[u8]> = owned.iter().map(Vec::as_slice).collect();
1360 d.sadd(key, refs.iter().copied()).expect("a set");
1361 }
1362
1363 fn drawn(d: &mut Keyspace, key: &[u8], count: i64) -> Vec<String> {
1364 let mut out = Vec::new();
1365 d.srandmember_n(key, count, |m| {
1366 out.push(String::from_utf8(m.to_vec()).expect("utf8 in these tests"));
1367 })
1368 .expect("a set");
1369 out
1370 }
1371
1372 #[test]
1373 fn popping_takes_a_member_out_and_the_key_with_the_last_one() {
1374 let mut d = db();
1375 add(&mut d, b"s", &[b"a", b"b"]);
1376 let first = d.spop(b"s").expect("a set").expect("two members");
1377 assert_eq!(d.scard(b"s").expect("a set"), 1);
1378
1379 let second = d.spop(b"s").expect("a set").expect("one member");
1380 assert_ne!(first, second, "the same member came back twice");
1381 assert!(!d.exists(b"s"), "the last member took the key");
1382 assert_eq!(d.sets.len(), 0, "and the body");
1383 assert_eq!(d.spop(b"s").expect("gone is not an error"), None);
1384 }
1385
1386 #[test]
1387 fn popping_a_count_empties_a_set_without_repeating_itself() {
1388 for n in [4usize, 100, 300] {
1392 let mut d = db();
1393 many(&mut d, b"s", n);
1394 let got = d.spop_n(b"s", n + 10).expect("a set");
1395 assert_eq!(got.len(), n, "asked for more than there was");
1396 let mut sorted = got.clone();
1397 sorted.sort();
1398 sorted.dedup();
1399 assert_eq!(sorted.len(), n, "a member came back twice");
1400 assert!(!d.exists(b"s"));
1401 assert_eq!(d.sets.len(), 0);
1402 }
1403 }
1404
1405 #[test]
1406 fn popping_part_of_a_set_leaves_the_rest_of_it() {
1407 let mut d = db();
1408 many(&mut d, b"s", 10);
1409 let got = d.spop_n(b"s", 4).expect("a set");
1410 assert_eq!(got.len(), 4);
1411 assert_eq!(d.scard(b"s").expect("a set"), 6);
1412 for m in &got {
1413 assert!(!d.sismember(b"s", m).expect("a set"), "still there");
1414 }
1415 assert_eq!(
1416 d.spop_n(b"s", 0).expect("a set").len(),
1417 0,
1418 "and zero is none"
1419 );
1420 assert_eq!(d.scard(b"s").expect("a set"), 6);
1421 }
1422
1423 #[test]
1424 fn the_borrowing_draw_pops_the_same_set_the_copying_one_does() {
1425 for n in [4usize, 100, 300] {
1429 let mut a = db();
1430 a.seed(20_260_829);
1431 many(&mut a, b"s", n);
1432 let copied = a.spop_n(b"s", n).expect("a set");
1433
1434 let mut b = db();
1435 b.seed(20_260_829);
1436 many(&mut b, b"s", n);
1437 let mut borrowed = Vec::new();
1438 b.spop_into(b"s", n, |m| borrowed.push(m.to_vec()))
1439 .expect("a set");
1440
1441 assert_eq!(copied, borrowed, "{n} members drew differently");
1442 assert!(!b.exists(b"s"), "the last member took the key");
1443 assert_eq!(b.sets.len(), 0, "and the body");
1444 }
1445 }
1446
1447 #[test]
1448 fn the_borrowing_draw_allocates_nothing() {
1449 for n in [4usize, 100, 300] {
1455 for ints in [false, true] {
1456 let mut d = db();
1457 fill(&mut d, b"s", n, ints);
1458 let (drawn, allocs) = crate::tally::counted(|| {
1459 let mut bytes = 0;
1460 let mut count = 0;
1461 d.spop_into(b"s", n, |m| {
1462 bytes += m.byte_len();
1465 count += 1;
1466 })
1467 .expect("a set");
1468 (bytes, count)
1469 });
1470 assert_eq!(drawn.1, n, "{n} members, ints {ints}");
1471 assert!(drawn.0 > 0, "the members came back empty");
1472 assert_eq!(
1473 allocs, 0,
1474 "{n} members, ints {ints}: {allocs} allocations on the way out"
1475 );
1476 }
1477 }
1478 }
1479
1480 #[test]
1491 fn a_small_set_operation_stops_paying_per_key() {
1492 for (ints, want) in [(true, 0), (false, 6)] {
1493 let mut d = db();
1494 fill(&mut d, b"a", 8, ints);
1495 fill(&mut d, b"b", 8, ints);
1496 fill(&mut d, b"c", 8, ints);
1497 let keys: [&[u8]; 3] = [b"a", b"b", b"c"];
1498
1499 let (found, allocs) = crate::tally::counted(|| {
1500 let mut n = 0;
1501 d.sinter(keys.iter().copied(), 0, |_| n += 1).expect("sets");
1502 d.sunion(keys.iter().copied(), 0, |_| n += 1).expect("sets");
1503 d.sdiff(keys.iter().copied(), 0, |_| n += 1).expect("sets");
1504 n
1505 });
1506 assert!(found > 0, "ints {ints}: the operations found nothing");
1507 assert_eq!(
1508 allocs, want,
1509 "ints {ints}: {allocs} allocations for three ops, wanted {want}"
1510 );
1511 }
1512 }
1513
1514 #[test]
1517 fn a_wide_set_operation_still_answers() {
1518 let wide = crate::setops::INLINE_KEYS + 3;
1519 let mut d = db();
1520 let names: Vec<Vec<u8>> = (0..wide).map(|i| format!("k{i}").into_bytes()).collect();
1521 for name in &names {
1522 fill(&mut d, name, 8, true);
1523 }
1524 let keys = || names.iter().map(|k| k.as_slice());
1525 let mut inter = 0;
1526 d.sinter(keys(), 0, |_| inter += 1).expect("sets");
1527 assert_eq!(inter, 8);
1529 let mut union = 0;
1530 d.sunion(keys(), 0, |_| union += 1).expect("sets");
1531 assert_eq!(union, 8);
1532 }
1533
1534 #[test]
1535 fn the_copying_draw_allocates_a_member_at_a_time() {
1536 let mut d = db();
1540 many(&mut d, b"s", 100);
1541 let (got, allocs) = crate::tally::counted(|| d.spop_n(b"s", 100).expect("a set"));
1542 assert_eq!(got.len(), 100);
1543 assert!(allocs >= 100, "only {allocs} allocations for a hundred");
1544 }
1545
1546 #[test]
1547 fn a_pinned_seed_draws_the_same_members_twice() {
1548 let mut runs = Vec::new();
1552 for _ in 0..2 {
1553 let mut d = db();
1554 d.seed(20_260_828);
1555 many(&mut d, b"s", 50);
1556 runs.push(d.spop_n(b"s", 10).expect("a set"));
1557 }
1558 assert_eq!(runs[0], runs[1]);
1559 }
1560
1561 #[test]
1562 fn a_single_draw_reaches_every_member_and_removes_none() {
1563 let mut d = db();
1564 d.seed(7);
1565 add(&mut d, b"s", &[b"a", b"b", b"c"]);
1566 let mut seen = std::collections::HashSet::new();
1567 for _ in 0..200 {
1568 let got = d
1569 .srandmember(b"s", |m| m.map(|m| m.to_vec()))
1570 .expect("a set")
1571 .expect("a member");
1572 seen.insert(got);
1573 }
1574 assert_eq!(seen.len(), 3, "a draw that never reaches a member");
1575 assert_eq!(d.scard(b"s").expect("a set"), 3, "and nothing was taken");
1576
1577 assert!(
1578 d.srandmember(b"nope", |m| m.map(|m| m.to_vec()))
1579 .expect("missing is fine")
1580 .is_none()
1581 );
1582 }
1583
1584 #[test]
1585 fn a_negative_count_repeats_itself_and_a_positive_one_does_not() {
1586 let mut d = db();
1587 d.seed(11);
1588 add(&mut d, b"s", &[b"a", b"b", b"c"]);
1589
1590 let with_repeats = drawn(&mut d, b"s", -20);
1591 assert_eq!(with_repeats.len(), 20, "more members than the set holds");
1592
1593 let mut distinct = drawn(&mut d, b"s", 2);
1594 distinct.sort();
1595 distinct.dedup();
1596 assert_eq!(distinct.len(), 2);
1597 }
1598
1599 #[test]
1600 fn asking_for_more_than_the_set_holds_answers_all_of_it_once() {
1601 let mut d = db();
1602 d.seed(3);
1603 add(&mut d, b"s", &[b"a", b"b", b"c"]);
1604 let mut got = drawn(&mut d, b"s", 99);
1605 got.sort();
1606 assert_eq!(got, ["a", "b", "c"]);
1607 assert_eq!(drawn(&mut d, b"s", 0).len(), 0);
1608 assert_eq!(drawn(&mut d, b"nope", 5).len(), 0);
1609 assert_eq!(drawn(&mut d, b"nope", -5).len(), 0);
1610 }
1611
1612 #[test]
1613 fn both_ways_of_drawing_distinct_members_are_distinct_and_uniform() {
1614 let mut d = db();
1618 d.seed(99);
1619 many(&mut d, b"s", 1000);
1620
1621 for count in [2, 100, 400, 900] {
1622 let got = drawn(&mut d, b"s", count);
1623 let mut sorted = got.clone();
1624 sorted.sort();
1625 sorted.dedup();
1626 assert_eq!(
1627 sorted.len(),
1628 got.len(),
1629 "a draw of {count} repeated a member"
1630 );
1631 assert_eq!(got.len(), count as usize);
1632 }
1633
1634 let mut seen = std::collections::HashSet::new();
1637 for _ in 0..40 {
1638 seen.extend(drawn(&mut d, b"s", 900));
1639 seen.extend(drawn(&mut d, b"s", 2));
1640 }
1641 assert_eq!(seen.len(), 1000, "some member is never drawn");
1642 assert_eq!(d.scard(b"s").expect("a set"), 1000, "and none were taken");
1643 }
1644
1645 #[test]
1646 fn a_scan_walks_a_set_of_any_size_exactly_once() {
1647 for n in [3usize, 100, 500] {
1648 let mut d = db();
1649 many(&mut d, b"s", n);
1650 let mut seen = Vec::new();
1651 let mut c = Cursor::START;
1652 let mut turns = 0;
1653 loop {
1654 c = d
1655 .sscan(b"s", c, 10, |m| seen.push(m.to_vec()))
1656 .expect("a set");
1657 turns += 1;
1658 assert!(turns < 200, "the scan did not finish for {n} members");
1659 if c.is_end() {
1660 break;
1661 }
1662 }
1663 seen.sort();
1664 seen.dedup();
1665 assert_eq!(seen.len(), n, "a scan of {n} members missed one");
1666 }
1667 }
1668
1669 #[test]
1670 fn a_scan_of_a_key_that_is_not_there_is_a_finished_scan() {
1671 let mut d = db();
1672 let mut hit = 0;
1673 let c = d
1674 .sscan(b"nope", Cursor::START, 10, |_| hit += 1)
1675 .expect("ok");
1676 assert!(c.is_end());
1677 assert_eq!(hit, 0);
1678 }
1679
1680 #[test]
1681 fn a_scan_returns_everything_that_was_there_the_whole_time() {
1682 let mut d = db();
1687 many(&mut d, b"s", 500);
1688 let mut seen = Vec::new();
1689 let mut c = Cursor::START;
1690 let mut turns = 0;
1691 loop {
1692 c = d
1693 .sscan(b"s", c, 10, |m| seen.push(m.to_vec()))
1694 .expect("a set");
1695 let victim = format!("m{}", 400 + turns).into_bytes();
1698 d.srem(b"s", [victim.as_slice()].into_iter())
1699 .expect("a set");
1700 turns += 1;
1701 if c.is_end() {
1702 break;
1703 }
1704 }
1705 seen.sort();
1706 seen.dedup();
1707 for i in 0..400 {
1708 let m = format!("m{i}").into_bytes();
1709 assert!(seen.binary_search(&m).is_ok(), "m{i} was never returned");
1710 }
1711 }
1712
1713 #[test]
1714 fn moving_a_member_takes_it_off_one_set_and_puts_it_on_another() {
1715 let mut d = db();
1716 add(&mut d, b"a", &[b"x", b"y"]);
1717 add(&mut d, b"b", &[b"z"]);
1718
1719 assert!(d.smove(b"a", b"b", b"x").expect("two sets"));
1720 assert_eq!(members(&mut d, b"a"), ["y"]);
1721 assert_eq!(members(&mut d, b"b"), ["x", "z"]);
1722
1723 assert!(
1724 !d.smove(b"a", b"b", b"gone").expect("two sets"),
1725 "a member that is not in the source does not move"
1726 );
1727 assert!(
1728 d.smove(b"a", b"b", b"y").expect("two sets"),
1729 "and the last one still moves"
1730 );
1731 assert!(!d.exists(b"a"), "the source went with its last member");
1732 assert_eq!(d.sets.len(), 1, "and so did its body");
1733 assert_eq!(members(&mut d, b"b"), ["x", "y", "z"]);
1734 }
1735
1736 #[test]
1737 fn moving_onto_a_destination_that_is_not_there_makes_it() {
1738 let mut d = db();
1739 add(&mut d, b"a", &[b"x", b"y"]);
1740 assert!(d.smove(b"a", b"b", b"x").expect("a set"));
1741 assert_eq!(d.kind_of(b"b"), Some(Kind::Set));
1742 assert_eq!(members(&mut d, b"b"), ["x"]);
1743 assert_eq!(d.sets.len(), 2);
1744 }
1745
1746 #[test]
1747 fn moving_a_member_onto_its_own_set_changes_nothing() {
1748 let mut d = db();
1749 add(&mut d, b"a", &[b"x", b"y"]);
1750 assert!(d.smove(b"a", b"a", b"x").expect("a set"), "it is there");
1751 assert!(!d.smove(b"a", b"a", b"z").expect("a set"), "it is not");
1752 assert_eq!(members(&mut d, b"a"), ["x", "y"]);
1753 }
1754
1755 #[test]
1756 fn moving_checks_the_types_in_the_order_redis_checks_them() {
1757 let mut d = db();
1758 d.set_plain(b"str", b"v").expect("room");
1759 add(&mut d, b"s", &[b"x"]);
1760
1761 assert!(
1762 !d.smove(b"nope", b"str", b"x").expect("no source, no error"),
1763 "a missing source answers zero without looking at the destination"
1764 );
1765 assert_eq!(
1766 d.smove(b"str", b"s", b"x").expect_err("no").code(),
1767 Code::WrongType
1768 );
1769 assert_eq!(
1770 d.smove(b"s", b"str", b"x").expect_err("no").code(),
1771 Code::WrongType
1772 );
1773 assert_eq!(
1774 members(&mut d, b"s"),
1775 ["x"],
1776 "and the failed move left the source alone"
1777 );
1778 }
1779
1780 #[test]
1781 fn the_new_commands_answer_wrongtype_at_a_string() {
1782 let mut d = db();
1783 d.set_plain(b"k", b"v").expect("room");
1784 assert!(d.spop(b"k").is_err());
1785 assert!(d.spop_n(b"k", 2).is_err());
1786 assert!(d.srandmember(b"k", |m| m.is_some()).is_err());
1787 assert!(d.srandmember_n(b"k", 2, |_| ()).is_err());
1788 assert!(d.sscan(b"k", Cursor::START, 10, |_| ()).is_err());
1789 assert_eq!(
1790 d.get(b"k").expect("still a string").map(|v| v.to_vec()),
1791 Some(b"v".to_vec())
1792 );
1793 }
1794
1795 fn algebra(d: &mut Keyspace, op: &str, keys: &[&[u8]]) -> Vec<String> {
1798 let mut got = Vec::new();
1799 let mut take = |m: &[u8]| got.push(String::from_utf8_lossy(m).into_owned());
1800 let n = match op {
1801 "inter" => d.sinter(keys.iter().copied(), 0, &mut take),
1802 "union" => d.sunion(keys.iter().copied(), 0, &mut take),
1803 "diff" => d.sdiff(keys.iter().copied(), 0, &mut take),
1804 other => unreachable!("{other}"),
1805 }
1806 .expect("sets");
1807 assert_eq!(n, got.len(), "the count and the members disagree");
1808 got.sort();
1809 got
1810 }
1811
1812 #[test]
1813 fn the_algebra_answers_what_the_sets_share_and_do_not() {
1814 let mut d = db();
1815 add(&mut d, b"a", &[b"1", b"2", b"3"]);
1816 add(&mut d, b"b", &[b"2", b"3", b"4"]);
1817 add(&mut d, b"c", &[b"3", b"4", b"5"]);
1818
1819 assert_eq!(algebra(&mut d, "inter", &[b"a", b"b", b"c"]), ["3"]);
1820 assert_eq!(
1821 algebra(&mut d, "union", &[b"a", b"b", b"c"]),
1822 ["1", "2", "3", "4", "5"]
1823 );
1824 assert_eq!(algebra(&mut d, "diff", &[b"a", b"b"]), ["1"]);
1825 assert_eq!(
1826 algebra(&mut d, "diff", &[b"a"]),
1827 ["1", "2", "3"],
1828 "one set is that set"
1829 );
1830 assert_eq!(
1831 d.sintercard([b"a".as_slice(), b"b"].into_iter(), 0)
1832 .expect("sets"),
1833 2
1834 );
1835 assert_eq!(
1836 d.sintercard([b"a".as_slice(), b"b"].into_iter(), 1)
1837 .expect("sets"),
1838 1,
1839 "and a limit stops it early"
1840 );
1841 }
1842
1843 #[test]
1846 fn a_key_that_is_not_there_is_an_empty_set_everywhere() {
1847 let mut d = db();
1848 add(&mut d, b"a", &[b"1", b"2"]);
1849
1850 assert!(algebra(&mut d, "inter", &[b"a", b"nope"]).is_empty());
1851 assert!(algebra(&mut d, "inter", &[b"nope", b"a"]).is_empty());
1852 assert_eq!(algebra(&mut d, "union", &[b"a", b"nope"]), ["1", "2"]);
1853 assert_eq!(algebra(&mut d, "diff", &[b"a", b"nope"]), ["1", "2"]);
1854 assert!(
1855 algebra(&mut d, "diff", &[b"nope", b"a"]).is_empty(),
1856 "nothing minus anything is nothing"
1857 );
1858 assert!(algebra(&mut d, "union", &[b"nope"]).is_empty());
1859 assert_eq!(d.len(), 1, "and none of that made a key");
1860 }
1861
1862 #[test]
1863 fn a_store_form_writes_the_answer_and_says_how_big_it_is() {
1864 let mut d = db();
1865 add(&mut d, b"a", &[b"1", b"2", b"3"]);
1866 add(&mut d, b"b", &[b"2", b"3", b"4"]);
1867
1868 assert_eq!(
1869 d.sinterstore(b"d", [b"a".as_slice(), b"b"].into_iter())
1870 .expect("sets"),
1871 2
1872 );
1873 assert_eq!(members(&mut d, b"d"), ["2", "3"]);
1874 assert_eq!(
1875 d.sunionstore(b"d", [b"a".as_slice(), b"b"].into_iter())
1876 .expect("sets"),
1877 4
1878 );
1879 assert_eq!(members(&mut d, b"d"), ["1", "2", "3", "4"]);
1880 assert_eq!(
1881 d.sdiffstore(b"d", [b"a".as_slice(), b"b"].into_iter())
1882 .expect("sets"),
1883 1
1884 );
1885 assert_eq!(members(&mut d, b"d"), ["1"]);
1886 assert_eq!(d.encoding_name(b"d"), Some(Encoding::Intset.name()));
1889 }
1890
1891 #[test]
1894 fn a_store_form_of_nothing_deletes_the_destination() {
1895 let mut d = db();
1896 add(&mut d, b"a", &[b"1"]);
1897 add(&mut d, b"b", &[b"2"]);
1898 add(&mut d, b"d", &[b"old"]);
1899
1900 assert_eq!(
1901 d.sinterstore(b"d", [b"a".as_slice(), b"b"].into_iter())
1902 .expect("sets"),
1903 0
1904 );
1905 assert_eq!(d.kind_of(b"d"), None, "the destination went, not emptied");
1906 assert!(!d.exists(b"d"));
1907
1908 add(&mut d, b"d", &[b"old"]);
1911 assert_eq!(
1912 d.sdiffstore(b"d", [b"a".as_slice(), b"a"].into_iter())
1913 .expect("sets"),
1914 0
1915 );
1916 assert!(!d.exists(b"d"));
1917 add(&mut d, b"d", &[b"old"]);
1918 assert_eq!(
1919 d.sunionstore(b"d", [b"nope".as_slice()].into_iter())
1920 .expect("sets"),
1921 0
1922 );
1923 assert!(!d.exists(b"d"));
1924 }
1925
1926 #[test]
1929 fn a_store_form_can_write_over_one_of_its_own_sources() {
1930 let mut d = db();
1931 add(&mut d, b"a", &[b"1", b"2", b"3"]);
1932 add(&mut d, b"b", &[b"2", b"3", b"4"]);
1933
1934 assert_eq!(
1935 d.sinterstore(b"a", [b"a".as_slice(), b"b"].into_iter())
1936 .expect("sets"),
1937 2
1938 );
1939 assert_eq!(members(&mut d, b"a"), ["2", "3"]);
1940
1941 assert_eq!(
1943 d.sunionstore(b"a", [b"a".as_slice(), b"a"].into_iter())
1944 .expect("sets"),
1945 2
1946 );
1947 assert_eq!(members(&mut d, b"a"), ["2", "3"]);
1948 }
1949
1950 #[test]
1953 fn a_store_form_overwrites_whatever_the_destination_held() {
1954 let mut d = db();
1955 add(&mut d, b"a", &[b"1", b"2"]);
1956 d.set_plain(b"d", b"a string").expect("room");
1957 assert!(d.set_expiry(b"d", Some(9_999_999)));
1958
1959 assert_eq!(
1960 d.sunionstore(b"d", [b"a".as_slice()].into_iter())
1961 .expect("sets"),
1962 2
1963 );
1964 assert_eq!(d.kind_of(b"d"), Some(Kind::Set));
1965 assert_eq!(members(&mut d, b"d"), ["1", "2"]);
1966 assert_eq!(d.expire_at(b"d"), None, "and the deadline went with it");
1967 }
1968
1969 #[test]
1972 fn the_algebra_answers_wrongtype_before_it_writes_anything() {
1973 let mut d = db();
1974 add(&mut d, b"a", &[b"1"]);
1975 d.set_plain(b"str", b"v").expect("room");
1976 add(&mut d, b"d", &[b"old"]);
1977
1978 assert!(
1979 d.sinter([b"a".as_slice(), b"str"].into_iter(), 0, |_| ())
1980 .is_err()
1981 );
1982 assert!(
1983 d.sunion([b"str".as_slice()].into_iter(), 0, |_| ())
1984 .is_err()
1985 );
1986 assert!(
1987 d.sdiff([b"a".as_slice(), b"str"].into_iter(), 0, |_| ())
1988 .is_err()
1989 );
1990 assert!(
1991 d.sinterstore(b"d", [b"a".as_slice(), b"str"].into_iter())
1992 .is_err()
1993 );
1994 assert_eq!(members(&mut d, b"d"), ["old"], "and left it alone");
1995 }
1996
1997 #[test]
2000 fn the_algebra_works_across_the_representations() {
2001 let mut d = db();
2002 let big: Vec<Vec<u8>> = (0..600).map(|i| i.to_string().into_bytes()).collect();
2003 let refs: Vec<&[u8]> = big.iter().map(Vec::as_slice).collect();
2004 d.sadd(b"table", refs.iter().copied()).expect("a set");
2005 add(&mut d, b"ints", &[b"1", b"2", b"999"]);
2006 add(&mut d, b"packed", &[b"2", b"3", b"x"]);
2007 assert_eq!(d.encoding_name(b"table"), Some(Encoding::Hashtable.name()));
2008 assert_eq!(d.encoding_name(b"ints"), Some(Encoding::Intset.name()));
2009 assert_eq!(d.encoding_name(b"packed"), Some(Encoding::Listpack.name()));
2010
2011 assert_eq!(algebra(&mut d, "inter", &[b"ints", b"table"]), ["1", "2"]);
2015 assert_eq!(algebra(&mut d, "inter", &[b"packed", b"table"]), ["2", "3"]);
2016 assert_eq!(algebra(&mut d, "inter", &[b"ints", b"packed"]), ["2"]);
2017 assert_eq!(algebra(&mut d, "diff", &[b"ints", b"table"]), ["999"]);
2018 assert_eq!(
2019 algebra(&mut d, "union", &[b"ints", b"packed"]),
2020 ["1", "2", "3", "999", "x"]
2021 );
2022 }
2023
2024 #[test]
2025 fn a_set_is_counted_in_what_the_database_is_holding() {
2026 let mut d = db();
2027 let before = d.memory_bytes();
2028 let owned: Vec<Vec<u8>> = (0..500).map(|i| i.to_string().into_bytes()).collect();
2029 let refs: Vec<&[u8]> = owned.iter().map(Vec::as_slice).collect();
2030 d.sadd(b"s", refs.iter().copied()).expect("a set");
2031
2032 let after = d.memory_bytes();
2033 assert!(
2034 after > before + 500,
2035 "five hundred members have to show up somewhere: {before} then {after}"
2036 );
2037 d.del(b"s");
2038 assert!(d.memory_bytes() < after, "and go away again");
2039 }
2040
2041 #[test]
2048 fn a_deleted_key_does_not_answer_with_whatever_took_its_slot() {
2049 let mut d = db();
2050 add(&mut d, b"a", &[b"x", b"y", b"z"]);
2051 assert_eq!(d.scard(b"a").expect("a set"), 3);
2052
2053 d.del(b"a");
2054 add(&mut d, b"b", &[b"one"]);
2055
2056 assert_eq!(d.scard(b"a").expect("gone"), 0);
2057 assert!(!d.sismember(b"a", b"x").expect("gone"));
2058 assert_eq!(d.scard(b"b").expect("a set"), 1);
2059 }
2060
2061 #[test]
2065 fn a_key_that_comes_back_as_another_type_is_wrongtype() {
2066 let mut d = db();
2067 add(&mut d, b"k", &[b"x"]);
2068 assert_eq!(d.scard(b"k").expect("a set"), 1);
2069
2070 d.del(b"k");
2071 d.hset(b"k", [(&b"f"[..], &b"v"[..])].into_iter())
2072 .expect("a hash");
2073
2074 let err = d.scard(b"k").expect_err("a hash is not a set");
2075 assert_eq!(err.code(), Code::WrongType);
2076 }
2077
2078 #[test]
2082 fn a_key_with_a_deadline_still_expires_after_it_has_been_read() {
2083 let mut d = db();
2084 add(&mut d, b"k", &[b"x", b"y"]);
2085 assert_eq!(d.scard(b"k").expect("a set"), 2);
2086
2087 assert!(d.set_expiry(b"k", Some(1_500)));
2088 assert_eq!(d.scard(b"k").expect("still alive"), 2);
2089
2090 d.clock().advance(600);
2091 assert_eq!(d.scard(b"k").expect("past its deadline"), 0);
2092 assert!(!d.sismember(b"k", b"x").expect("past its deadline"));
2093 }
2094
2095 #[test]
2099 fn two_keys_in_a_row_do_not_answer_for_each_other() {
2100 let mut d = db();
2101 add(&mut d, b"a", &[b"1"]);
2102 add(&mut d, b"b", &[b"1", b"2", b"3"]);
2103 for _ in 0..8 {
2104 assert_eq!(d.scard(b"a").expect("a set"), 1);
2105 assert_eq!(d.scard(b"b").expect("a set"), 3);
2106 }
2107 }
2108
2109 #[test]
2112 fn a_flush_does_not_leave_the_last_key_behind() {
2113 let mut d = db();
2114 add(&mut d, b"k", &[b"x"]);
2115 assert_eq!(d.scard(b"k").expect("a set"), 1);
2116
2117 d.clear();
2118 assert_eq!(d.scard(b"k").expect("flushed"), 0);
2119 }
2120
2121 #[test]
2125 fn a_key_longer_than_the_memo_still_works() {
2126 let mut d = db();
2127 let long = vec![b'k'; 200];
2128 add(&mut d, &long, &[b"x", b"y"]);
2129 for _ in 0..4 {
2130 assert_eq!(d.scard(&long).expect("a set"), 2);
2131 }
2132 d.del(&long);
2133 assert_eq!(d.scard(&long).expect("gone"), 0);
2134 }
2135}