use std::collections::HashMap;
+use std::sync::{Arc, Mutex};
+use bytes::Bytes;
use mini_redis::{Connection, Frame};
use mini_redis::Command::{self, Get, Set};
use tokio::net::{TcpListener, TcpStream};
+type Db = Arc<Mutex<HashMap<String, Bytes>>>;
+
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:6379").await.unwrap();
+ let db: Db = Arc::new(Mutex::new(HashMap::new()));
loop {
// The second item contains the IP and port of the new connection
let (socket, _) = listener.accept().await.unwrap();
- tokio::spawn(async move { process(socket).await });
+ let db_i = db.clone();
+ tokio::spawn(async move { process(socket, db_i).await });
}
}
-async fn process(socket: TcpStream) {
- let mut db = HashMap::new();
+async fn process(socket: TcpStream, db: Db) {
let mut connection = Connection::new(socket);
while let Some(frame) = connection.read_frame().await.unwrap() {
let response = match Command::from_frame(frame).unwrap() {
Set(cmd) => {
// The value is stored as `Vec<u8>`
- db.insert(cmd.key().to_string(), cmd.value().to_vec());
+ db.lock().unwrap().insert(cmd.key().to_string(), cmd.value().clone());
Frame::Simple("OK".to_string())
}
Get(cmd) => {
- if let Some(value) = db.get(cmd.key()) {
- // `Frame::Bulk` expects data to be of type `Bytes`. This
- // type will be covered later in the tutorial. For now,
- // `&Vec<u8>` is converted to `Bytes` using `into()`.
- Frame::Bulk(value.clone().into())
+ if let Some(value) = db.lock().unwrap().get(cmd.key()) {
+ Frame::Bulk(value.clone())
} else {
Frame::Null
}