kevy_embedded/
ops_zset_algebra.rs1use std::io;
17
18use kevy_store::{ZAggregate, zdiff, zinter, zintercard, zunion};
19
20type ScoredInput = Vec<(Vec<u8>, f64)>;
22
23#[cfg(not(target_arch = "wasm32"))]
24use crate::replica_glue::ensure_writable;
25use crate::store::{Store, commit_write, store_err};
26
27#[cfg(target_arch = "wasm32")]
28fn ensure_writable(_s: &Store) -> io::Result<()> {
29 Ok(())
30}
31
32impl Store {
33 fn gather_scored(&self, keys: &[&[u8]]) -> io::Result<Vec<ScoredInput>> {
34 keys.iter()
35 .map(|k| self.wshard(k).store.zset_or_set_members(k).map_err(store_err))
36 .collect()
37 }
38
39 fn store_zset_result(&self, dst: &[u8], pairs: &[(Vec<u8>, f64)]) -> io::Result<usize> {
40 ensure_writable(self)?;
41 let mut g = self.wshard(dst);
42 let n = g.store.zstore_result(dst, pairs);
43 commit_write(&mut g, &[b"DEL", dst])?;
44 if !pairs.is_empty() {
45 let score_strs: Vec<Vec<u8>> =
46 pairs.iter().map(|(_, s)| format!("{s}").into_bytes()).collect();
47 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + pairs.len() * 2);
48 argv.push(b"ZADD");
49 argv.push(dst);
50 for (i, (m, _)) in pairs.iter().enumerate() {
51 argv.push(&score_strs[i]);
52 argv.push(m);
53 }
54 commit_write(&mut g, &argv)?;
55 }
56 Ok(n)
57 }
58
59 pub fn zinterstore(
62 &self,
63 dst: &[u8],
64 keys: &[&[u8]],
65 weights: Option<&[f64]>,
66 aggregate: ZAggregate,
67 ) -> io::Result<usize> {
68 let inputs = self.gather_scored(keys)?;
69 self.store_zset_result(dst, &zinter(&inputs, weights, aggregate))
70 }
71
72 pub fn zunionstore(
74 &self,
75 dst: &[u8],
76 keys: &[&[u8]],
77 weights: Option<&[f64]>,
78 aggregate: ZAggregate,
79 ) -> io::Result<usize> {
80 let inputs = self.gather_scored(keys)?;
81 self.store_zset_result(dst, &zunion(&inputs, weights, aggregate))
82 }
83
84 pub fn zdiffstore(&self, dst: &[u8], keys: &[&[u8]]) -> io::Result<usize> {
86 let inputs = self.gather_scored(keys)?;
87 self.store_zset_result(dst, &zdiff(&inputs))
88 }
89
90 pub fn zintercard(&self, keys: &[&[u8]], limit: usize) -> io::Result<usize> {
92 let inputs = self.gather_scored(keys)?;
93 Ok(zintercard(&inputs, limit))
94 }
95
96 pub fn sinterstore(&self, dst: &[u8], keys: &[&[u8]]) -> io::Result<usize> {
98 let members = self.sinter(keys)?;
99 self.store_set_result(dst, &members)
100 }
101
102 pub fn sunionstore(&self, dst: &[u8], keys: &[&[u8]]) -> io::Result<usize> {
104 let members = self.sunion(keys)?;
105 self.store_set_result(dst, &members)
106 }
107
108 pub fn sdiffstore(&self, dst: &[u8], keys: &[&[u8]]) -> io::Result<usize> {
110 let members = self.sdiff(keys)?;
111 self.store_set_result(dst, &members)
112 }
113
114 fn store_set_result(&self, dst: &[u8], members: &[Vec<u8>]) -> io::Result<usize> {
115 ensure_writable(self)?;
116 let mut g = self.wshard(dst);
117 let del = [dst.to_vec()];
118 g.store.del(&del);
119 commit_write(&mut g, &[b"DEL", dst])?;
120 if members.is_empty() {
121 return Ok(0);
122 }
123 let owned: Vec<Vec<u8>> = members.to_vec();
124 let n = g.store.sadd(dst, &owned).map_err(store_err)?;
125 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + members.len());
126 argv.push(b"SADD");
127 argv.push(dst);
128 argv.extend(members.iter().map(Vec::as_slice));
129 commit_write(&mut g, &argv)?;
130 Ok(n)
131 }
132}