fast_cache/commands/
del.rs1mod engine;
7#[cfg(feature = "server")]
8mod fcnp;
9#[cfg(feature = "server")]
10mod server;
11
12use smallvec::SmallVec;
13
14use crate::Result;
15use crate::protocol::{FastCommand, Frame};
16#[cfg(feature = "server")]
17use crate::server::commands::{BorrowedCommandContext, DirectCommandContext};
18use crate::storage::{Command, EngineCommandContext, EngineFrameFuture};
19
20use super::DecodedFastCommand;
21use super::parsing::CommandArity;
22
23type BorrowedKeys<'a> = SmallVec<[&'a [u8]; 8]>;
24
25pub(crate) struct Del;
27pub(crate) static COMMAND: Del = Del;
28
29#[derive(Debug, Clone)]
31pub(crate) struct OwnedDel {
32 keys: Vec<Vec<u8>>,
33}
34
35impl OwnedDel {
36 fn new(keys: Vec<Vec<u8>>) -> Self {
37 Self { keys }
38 }
39}
40
41impl super::OwnedCommandData for OwnedDel {
42 type Spec = Del;
43
44 fn route_key(&self) -> Option<&[u8]> {
45 self.keys.first().map(Vec::as_slice)
46 }
47
48 fn to_borrowed_command(&self) -> super::BorrowedCommandBox<'_> {
49 Box::new(BorrowedDel::from_owned(&self.keys))
50 }
51}
52
53#[derive(Debug, Clone)]
55pub(crate) struct BorrowedDel<'a> {
56 keys: BorrowedKeys<'a>,
57}
58
59impl<'a> BorrowedDel<'a> {
60 fn new(keys: impl IntoIterator<Item = &'a [u8]>) -> Self {
61 Self {
62 keys: keys.into_iter().collect(),
63 }
64 }
65
66 fn from_owned(keys: &'a [Vec<u8>]) -> Self {
67 Self::new(keys.iter().map(Vec::as_slice))
68 }
69}
70
71impl<'a> super::BorrowedCommandData<'a> for BorrowedDel<'a> {
72 type Spec = Del;
73
74 fn route_key(&self) -> Option<&'a [u8]> {
75 self.keys.first().copied()
76 }
77
78 fn to_owned_command(&self) -> Command {
79 Command::new(Box::new(OwnedDel::new(
80 self.keys.iter().map(|key| key.to_vec()).collect(),
81 )))
82 }
83
84 fn execute_engine<'b>(&'b self, ctx: EngineCommandContext<'b>) -> EngineFrameFuture<'b>
85 where
86 'a: 'b,
87 {
88 let keys = self.keys.clone();
89 Box::pin(async move { Del::execute_engine_frame(ctx, keys.as_slice()).await })
90 }
91
92 #[cfg(feature = "server")]
93 fn execute_borrowed_frame(&self, store: &crate::storage::EmbeddedStore, _now_ms: u64) -> Frame {
94 Frame::Integer(Del::delete_embedded_keys(store, self.keys.as_slice()))
95 }
96
97 #[cfg(feature = "server")]
98 fn execute_borrowed(&self, ctx: BorrowedCommandContext<'_, '_, '_>) {
99 Del::execute_borrowed(ctx, self.keys.as_slice());
100 }
101
102 #[cfg(feature = "server")]
103 fn execute_direct_borrowed(&self, ctx: DirectCommandContext) -> Frame {
104 Frame::Integer(self.keys.iter().filter(|key| ctx.delete(key)).count() as i64)
105 }
106}
107
108impl super::CommandSpec for Del {
109 const NAME: &'static str = "DEL";
110 const MUTATES_VALUE: bool = true;
111}
112
113impl super::OwnedCommandParse for Del {
114 fn parse_owned(parts: &[Vec<u8>]) -> Result<Command> {
115 CommandArity::<Self>::at_least(parts.len(), 2, "key")?;
116 Ok(Command::new(Box::new(OwnedDel::new(parts[1..].to_vec()))))
117 }
118}
119
120impl<'a> super::BorrowedCommandParse<'a> for Del {
121 fn parse_borrowed(parts: &[&'a [u8]]) -> Result<super::BorrowedCommandBox<'a>> {
122 CommandArity::<Self>::at_least(parts.len(), 2, "key")?;
123 Ok(Box::new(BorrowedDel::new(parts[1..].iter().copied())))
124 }
125}
126
127impl DecodedFastCommand for Del {
128 fn matches_decoded_fast(&self, command: &FastCommand<'_>) -> bool {
129 matches!(command, FastCommand::Delete { .. })
130 }
131}