tinylfu_cached/cache/command/
mod.rs

1use std::hash::Hash;
2use std::time::Duration;
3
4use crate::cache::key_description::KeyDescription;
5use crate::cache::types::{KeyId, Weight};
6
7pub mod acknowledgement;
8pub mod error;
9pub mod command_executor;
10
11/// CommandType defines various write commands including:
12/// Put             : attempts to put the new key/value pair in the cache
13/// PutWithTTL      : attempts to put the new key/value pair with time_to_live in the cache
14/// Delete          : attempts to delete the key
15/// UpdateWeight    : updates the weight of the key. This command is sent as a part of `put_or_update` operation
16/// Shutdown        : informs the `crate::cache::command::command_executor::CommandExecutor` that the cache is being shutdown
17pub(crate) enum CommandType<Key, Value>
18    where Key: Hash + Eq + Clone {
19    Put(KeyDescription<Key>, Value),
20    PutWithTTL(KeyDescription<Key>, Value, Duration),
21    Delete(Key),
22    UpdateWeight(KeyId, Weight),
23    Shutdown,
24}
25
26/// Provides the description of each command
27/// `description` is used if there is an error in sending a command to the `crate::cache::command::command_executor::CommandExecutor`
28impl<Key, Value> CommandType<Key, Value>
29    where Key: Hash + Eq + Clone {
30    fn description(&self) -> String {
31        match self {
32            CommandType::Put(_, _) => "Put".to_string(),
33            CommandType::PutWithTTL(_, _, _) => "PutWithTTL".to_string(),
34            CommandType::Delete(_) => "Delete".to_string(),
35            CommandType::UpdateWeight(_, _) => "UpdateWeight".to_string(),
36            CommandType::Shutdown => "Shutdown".to_string(),
37        }
38    }
39}
40
41/// CommandStatus defines the status of each command.
42///
43/// `Pending`:        the initial status of the command, before a command is acted upon.
44///
45/// `Accepted`:       the command is successfully completed.
46///
47/// `Rejected`:       the command is rejected. `RejectionReason` is now available with the `Rejected` status (v0.0.3)
48    /// - `Put` may be rejected for various reasons. One reason is: the weight of the the incoming key/value pair is more than the total cache weight.
49    /// - `Delete` will be rejected if the key to be deleted is not preset in the cache.
50///
51/// `ShuttingDown`:   all the commands that could sneak in while the cache is being shutdown will be returned with `ShuttingDown` status.
52#[derive(Copy, Clone, Debug, Eq, PartialEq)]
53pub enum CommandStatus {
54    Pending,
55    Accepted,
56    Rejected(RejectionReason),
57    ShuttingDown,
58}
59
60/// RejectionReason defines the reason for a command getting rejected. Available since v0.0.3.
61///
62/// `EnoughSpaceIsNotAvailableAndKeyFailedToEvictOthers`: If the cache weight is full, and the incoming key can not evict others.
63///
64/// `KeyWeightIsGreaterThanCacheWeight`: The weight of the incoming key is greater than the total cache weight.
65///
66/// `KeyDoesNotExist`: Key does not exist during delete operation.
67///
68/// `KeyAlreadyExists`: Key already exists during put operation.
69#[non_exhaustive]
70#[derive(Copy, Clone, Debug, Eq, PartialEq)]
71pub enum RejectionReason {
72    EnoughSpaceIsNotAvailableAndKeyFailedToEvictOthers,
73    KeyWeightIsGreaterThanCacheWeight,
74    KeyDoesNotExist,
75    KeyAlreadyExists,
76}
77
78#[cfg(test)]
79mod tests {
80    use std::time::Duration;
81
82    use crate::cache::command::CommandType;
83    use crate::cache::key_description::KeyDescription;
84
85    #[test]
86    fn command_description_put() {
87        let put = CommandType::Put(
88            KeyDescription::new(
89                "topic", 1, 2090, 10,
90            ),
91            "microservices");
92
93        assert_eq!("Put", put.description());
94    }
95
96    #[test]
97    fn command_description_put_with_ttl() {
98        let put = CommandType::PutWithTTL(
99            KeyDescription::new(
100                "topic", 1, 2090, 10,
101            ),
102            "microservices",
103            Duration::from_millis(10),
104        );
105
106        assert_eq!("PutWithTTL", put.description());
107    }
108
109    #[test]
110    fn command_description_delete() {
111        let delete: CommandType<&str, &str> = CommandType::Delete("topic");
112
113        assert_eq!("Delete", delete.description());
114    }
115
116    #[test]
117    fn command_description_update_weight() {
118        let update_weight: CommandType<&str, &str> = CommandType::UpdateWeight(10, 200);
119
120        assert_eq!("UpdateWeight", update_weight.description());
121    }
122
123    #[test]
124    fn command_description_shutdown() {
125        let shutdown: CommandType<&str, &str> = CommandType::Shutdown;
126
127        assert_eq!("Shutdown", shutdown.description());
128    }
129}