Skip to content

Commit

Permalink
Merge pull request #1 from adhamsalama/implement-expire-command
Browse files Browse the repository at this point in the history
Implement EXPIRE command
  • Loading branch information
adhamsalama authored Apr 18, 2023
2 parents 40d1e97 + b78d027 commit dd8db73
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "sider"
description = "A Multithreaded Redis clone written from scratch in Rust."
license = "MIT"
version = "0.1.0"
version = "0.1.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ cargo install sider
- INCRBY
- DECR
- DECRBY
- EXPIRE

## Benchmarks

Expand Down
80 changes: 57 additions & 23 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
io::{BufRead, BufReader, Write},
net::TcpStream,
sync::{Arc, Mutex},
thread,
time::Duration,
};

Expand Down Expand Up @@ -55,30 +56,32 @@ pub fn process_request(
}

pub fn get_response(cache: Arc<Mutex<HashMap<String, DataType>>>, req: &Request) -> String {
let mut cache = cache.lock().unwrap();
match req.command {
Command::SET => handle_set(req, &mut cache),
Command::GET => handle_get(req, &mut cache),
Command::RPUSH => handle_rpush(req, &mut cache),
Command::LRANGE => handle_lrange(req, &mut cache),
Command::DEL => handle_del(req, &mut cache),
Command::INCR => handle_incr(req, &mut cache),
Command::INCRBY => handle_incrby(req, &mut cache),
Command::DECR => handle_decr(req, &mut cache),
Command::DECRBY => handle_decrby(req, &mut cache),
Command::CONFIG => handle_config(req, &mut cache),
Command::COMMAND => handle_command(req, &mut cache),
Command::SET => handle_set(req, cache),
Command::GET => handle_get(req, cache),
Command::RPUSH => handle_rpush(req, cache),
Command::LRANGE => handle_lrange(req, cache),
Command::DEL => handle_del(req, cache),
Command::INCR => handle_incr(req, cache),
Command::INCRBY => handle_incrby(req, cache),
Command::DECR => handle_decr(req, cache),
Command::DECRBY => handle_decrby(req, cache),
Command::EXPIRE => handle_expire(req, cache),
Command::CONFIG => handle_config(),
Command::COMMAND => handle_command(),
}
}

pub fn handle_set(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_set(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = req.value[0].clone();
cache.insert(req.key.clone(), DataType::String(value));
let response = "+OK\r\n".to_string();
response
}

pub fn handle_get(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_get(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let cache = cache.lock().unwrap();
let request_value = cache.get(&req.key);
match request_value {
Some(value) => match value {
Expand All @@ -99,7 +102,8 @@ pub fn handle_get(req: &Request, cache: &mut HashMap<String, DataType>) -> Strin
}
}

pub fn handle_rpush(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_rpush(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = cache.get_mut(&req.key);
match value {
Some(existing) => match existing {
Expand All @@ -124,7 +128,8 @@ pub fn handle_rpush(req: &Request, cache: &mut HashMap<String, DataType>) -> Str
}
}

pub fn handle_lrange(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_lrange(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let cache = cache.lock().unwrap();
let value = cache.get(&req.key);
match value {
Some(existing) => match existing {
Expand Down Expand Up @@ -160,7 +165,8 @@ pub fn handle_lrange(req: &Request, cache: &mut HashMap<String, DataType>) -> St
}
}

pub fn handle_del(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_del(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let key_to_delete = cache.get(&req.key);
match key_to_delete {
Some(_) => {
Expand All @@ -175,7 +181,8 @@ pub fn handle_del(req: &Request, cache: &mut HashMap<String, DataType>) -> Strin
}
}

pub fn handle_incr(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_incr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = cache.get(&req.key);
match value {
Some(v) => match v {
Expand Down Expand Up @@ -207,7 +214,8 @@ pub fn handle_incr(req: &Request, cache: &mut HashMap<String, DataType>) -> Stri
}
}

pub fn handle_incrby(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_incrby(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = cache.get(&req.key);
let amount = req.value[0].parse::<i64>().unwrap();
match value {
Expand Down Expand Up @@ -240,7 +248,8 @@ pub fn handle_incrby(req: &Request, cache: &mut HashMap<String, DataType>) -> St
}
}

pub fn handle_decr(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_decr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = cache.get(&req.key);
match value {
Some(v) => match v {
Expand Down Expand Up @@ -272,7 +281,8 @@ pub fn handle_decr(req: &Request, cache: &mut HashMap<String, DataType>) -> Stri
}
}

pub fn handle_decrby(req: &Request, cache: &mut HashMap<String, DataType>) -> String {
pub fn handle_decrby(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let mut cache = cache.lock().unwrap();
let value = cache.get(&req.key);
let amount = req.value[0].parse::<i64>().unwrap();
match value {
Expand Down Expand Up @@ -305,12 +315,36 @@ pub fn handle_decrby(req: &Request, cache: &mut HashMap<String, DataType>) -> St
}
}

pub fn handle_config(_: &Request, _: &mut HashMap<String, DataType>) -> String {
pub fn handle_config() -> String {
let response = ":0\r\n".to_string();
response
}

pub fn handle_command(_: &Request, _: &mut HashMap<String, DataType>) -> String {
pub fn handle_command() -> String {
let response = ":0\r\n".to_string();
response
}

pub fn handle_expire(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
let key = req.key.clone();
let seconds = req.value[0].parse::<u64>().unwrap();
let unlocked_cache = cache.lock().unwrap();
let value = unlocked_cache.get(&req.key).clone();
let cloned_cache = Arc::clone(&cache);
thread::spawn(move || {
thread::sleep(Duration::from_secs(seconds));
let mut cache = cloned_cache.lock().unwrap();
let value = cache.get(&key).clone();
match value {
Some(_) => {
cache.remove(&key);
}
None => {}
}
});

match value {
Some(_) => ":1\r\n".to_string(),
None => ":0\r\n".to_string(),
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub enum Command {
INCRBY,
DECR,
DECRBY,
EXPIRE,
CONFIG,
COMMAND,
}
Expand Down
1 change: 1 addition & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub fn parse_resp(s: &String) -> Request {
"INCRBY" => command = Some(Command::INCRBY),
"DECR" => command = Some(Command::DECR),
"DECRBY" => command = Some(Command::DECRBY),
"EXPIRE" => command = Some(Command::EXPIRE),
"CONFIG" => command = Some(Command::CONFIG),
"COMMAND" => command = Some(Command::COMMAND),
other => {
Expand Down

0 comments on commit dd8db73

Please sign in to comment.