Skip to content

Commit 5b25d75

Browse files
authored
Merge pull request #2 from adhamsalama/use-rwlock-instead-of-mutix
Use Rwlock instead of Mutex
2 parents dd8db73 + 662eda9 commit 5b25d75

File tree

5 files changed

+32
-48
lines changed

5 files changed

+32
-48
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "sider"
33
description = "A Multithreaded Redis clone written from scratch in Rust."
44
license = "MIT"
5-
version = "0.1.1"
5+
version = "0.1.2"
66
edition = "2021"
77

88
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

README.md

+4-20
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,15 @@ On my machine which has an i5-9300H Intel CPU.
4646
```
4747
redis-benchmark -n 100000 -c 100 -t set,get
4848
49-
SET: 42844.90 requests per second
50-
GET: 43840.42 requests per second
49+
SET: 79365.08 requests per second
50+
GET: 82034.45 requests per second
5151
```
5252

5353
```
5454
redis-benchmark -n 500000 -c 1000 -t set,get
5555
56-
SET: 40041.64 requests per second
57-
GET: 40650.41 requests per second
58-
```
59-
60-
In comparsion to Redis (also on my machine):
61-
62-
```
63-
redis-benchmark -n 100000 -c 100 -t set,get
64-
65-
SET: 34246.57 requests per second
66-
GET: 34364.26 requests per second
67-
```
68-
69-
```
70-
redis-benchmark -n 500000 -c 1000 -t set,get
71-
72-
SET: 31527.84 requests per second
73-
GET: 32032.80 requests per second
56+
SET: 56433.41 requests per second
57+
GET: 57077.62 requests per second
7458
```
7559

7660
Performance may vary depending on the machine you run the benchmarks on.

src/handler.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{
22
collections::HashMap,
33
io::{BufRead, BufReader, Write},
44
net::TcpStream,
5-
sync::{Arc, Mutex},
5+
sync::{Arc, RwLock},
66
thread,
77
time::Duration,
88
};
@@ -13,7 +13,7 @@ static WRONG_TYPE_ERROR_RESPONSE: &str =
1313

1414
pub fn process_request(
1515
mut stream: TcpStream,
16-
cache: Arc<Mutex<HashMap<String, DataType>>>,
16+
cache: Arc<RwLock<HashMap<String, DataType>>>,
1717
timeout: Option<Duration>,
1818
) {
1919
loop {
@@ -55,7 +55,7 @@ pub fn process_request(
5555
}
5656
}
5757

58-
pub fn get_response(cache: Arc<Mutex<HashMap<String, DataType>>>, req: &Request) -> String {
58+
pub fn get_response(cache: Arc<RwLock<HashMap<String, DataType>>>, req: &Request) -> String {
5959
match req.command {
6060
Command::SET => handle_set(req, cache),
6161
Command::GET => handle_get(req, cache),
@@ -72,16 +72,16 @@ pub fn get_response(cache: Arc<Mutex<HashMap<String, DataType>>>, req: &Request)
7272
}
7373
}
7474

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

83-
pub fn handle_get(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
84-
let cache = cache.lock().unwrap();
83+
pub fn handle_get(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
84+
let cache = cache.read().unwrap();
8585
let request_value = cache.get(&req.key);
8686
match request_value {
8787
Some(value) => match value {
@@ -102,8 +102,8 @@ pub fn handle_get(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -
102102
}
103103
}
104104

105-
pub fn handle_rpush(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
106-
let mut cache = cache.lock().unwrap();
105+
pub fn handle_rpush(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
106+
let mut cache = cache.write().unwrap();
107107
let value = cache.get_mut(&req.key);
108108
match value {
109109
Some(existing) => match existing {
@@ -128,8 +128,8 @@ pub fn handle_rpush(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>)
128128
}
129129
}
130130

131-
pub fn handle_lrange(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
132-
let cache = cache.lock().unwrap();
131+
pub fn handle_lrange(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
132+
let cache = cache.read().unwrap();
133133
let value = cache.get(&req.key);
134134
match value {
135135
Some(existing) => match existing {
@@ -165,8 +165,8 @@ pub fn handle_lrange(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>
165165
}
166166
}
167167

168-
pub fn handle_del(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
169-
let mut cache = cache.lock().unwrap();
168+
pub fn handle_del(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
169+
let mut cache = cache.write().unwrap();
170170
let key_to_delete = cache.get(&req.key);
171171
match key_to_delete {
172172
Some(_) => {
@@ -181,8 +181,8 @@ pub fn handle_del(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -
181181
}
182182
}
183183

184-
pub fn handle_incr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
185-
let mut cache = cache.lock().unwrap();
184+
pub fn handle_incr(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
185+
let mut cache = cache.write().unwrap();
186186
let value = cache.get(&req.key);
187187
match value {
188188
Some(v) => match v {
@@ -214,8 +214,8 @@ pub fn handle_incr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>)
214214
}
215215
}
216216

217-
pub fn handle_incrby(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
218-
let mut cache = cache.lock().unwrap();
217+
pub fn handle_incrby(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
218+
let mut cache = cache.write().unwrap();
219219
let value = cache.get(&req.key);
220220
let amount = req.value[0].parse::<i64>().unwrap();
221221
match value {
@@ -248,8 +248,8 @@ pub fn handle_incrby(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>
248248
}
249249
}
250250

251-
pub fn handle_decr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
252-
let mut cache = cache.lock().unwrap();
251+
pub fn handle_decr(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
252+
let mut cache = cache.write().unwrap();
253253
let value = cache.get(&req.key);
254254
match value {
255255
Some(v) => match v {
@@ -281,8 +281,8 @@ pub fn handle_decr(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>)
281281
}
282282
}
283283

284-
pub fn handle_decrby(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
285-
let mut cache = cache.lock().unwrap();
284+
pub fn handle_decrby(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
285+
let mut cache = cache.write().unwrap();
286286
let value = cache.get(&req.key);
287287
let amount = req.value[0].parse::<i64>().unwrap();
288288
match value {
@@ -325,15 +325,15 @@ pub fn handle_command() -> String {
325325
response
326326
}
327327

328-
pub fn handle_expire(req: &Request, cache: Arc<Mutex<HashMap<String, DataType>>>) -> String {
328+
pub fn handle_expire(req: &Request, cache: Arc<RwLock<HashMap<String, DataType>>>) -> String {
329329
let key = req.key.clone();
330330
let seconds = req.value[0].parse::<u64>().unwrap();
331-
let unlocked_cache = cache.lock().unwrap();
331+
let unlocked_cache = cache.read().unwrap();
332332
let value = unlocked_cache.get(&req.key).clone();
333333
let cloned_cache = Arc::clone(&cache);
334334
thread::spawn(move || {
335335
thread::sleep(Duration::from_secs(seconds));
336-
let mut cache = cloned_cache.lock().unwrap();
336+
let mut cache = cloned_cache.write().unwrap();
337337
let value = cache.get(&key).clone();
338338
match value {
339339
Some(_) => {

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{
22
collections::HashMap,
33
net::TcpListener,
4-
sync::{Arc, Mutex},
4+
sync::{Arc, RwLock},
55
thread,
66
time::Duration,
77
};
@@ -27,7 +27,7 @@ impl Sider {
2727

2828
pub fn start(&self) {
2929
println!("Sider is running on port {}", self.port);
30-
let mut cache = Arc::new(Mutex::new(HashMap::new()));
30+
let mut cache = Arc::new(RwLock::new(HashMap::new()));
3131
let timeout = self.timeout;
3232
for stream in self.listener.incoming() {
3333
let cache = Arc::clone(&mut cache);

0 commit comments

Comments
 (0)