From 63e4d2e6d6c4d91f133e81315af9c043d0678720 Mon Sep 17 00:00:00 2001 From: care0717 Date: Sun, 20 Jun 2021 14:13:16 +0900 Subject: [PATCH] feat: add stats command --- src/avl.rs | 7 +++++-- src/command.rs | 26 +++++++++++++++----------- src/decoder.rs | 21 +++++++++++---------- src/executor.rs | 6 +++++- src/memtable.rs | 1 + src/value.rs | 3 +-- 6 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/avl.rs b/src/avl.rs index 9807607..f7307ce 100644 --- a/src/avl.rs +++ b/src/avl.rs @@ -34,10 +34,13 @@ impl Memtable for Av fn search(&self, key: &T) -> Option<&U> { self.root.as_ref().map_or(None, |node| node.search(key)) } + fn to_vec(&self) -> Vec<(&T, &U)> { + self.iter().collect() + } } -impl<'a, T: 'a + Ord + Clone + Sync + Send, U: Clone + Sync + Send> AvlTreeMap { - fn iter(&'a self) -> AvlTreeSetIter<'a, T, U> { +impl AvlTreeMap { + fn iter(&self) -> AvlTreeSetIter<'_, T, U> { AvlTreeSetIter { prev_nodes: Vec::new(), current_tree: &self.root, diff --git a/src/command.rs b/src/command.rs index ac1af15..35582b6 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,20 +1,24 @@ -use crate::command::Command::{Delete, Get, Set}; +use crate::command::Command::{Delete, Get, Set, Stats}; use crate::value::Value; pub enum Command { Set { key: String, value: Value }, Get { key: String }, Delete { key: String }, + Stats {}, } -pub fn new_command_set<'a>(key: String, value: Value) -> Command { - return Set { key, value }; -} - -pub fn new_command_get(key: String) -> Command { - return Get { key }; -} - -pub fn new_command_delete(key: String) -> Command { - return Delete { key }; +impl Command { + pub fn new_set(key: String, value: Value) -> Self { + Set { key, value } + } + pub fn new_get(key: String) -> Self { + Get { key } + } + pub fn new_delete(key: String) -> Self { + Delete { key } + } + pub fn new_stats() -> Self { + Stats {} + } } diff --git a/src/decoder.rs b/src/decoder.rs index 95a4dcd..c12b5cc 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -1,4 +1,4 @@ -use crate::command; +use crate::command::Command; use crate::value::Value; use std::io; use std::io::BufRead; @@ -13,7 +13,7 @@ pub fn new(reader: R) -> Decoder { } impl Decoder { - pub fn decode(&mut self) -> Result { + pub fn decode(&mut self) -> Result { let mut buf = String::new(); let nbytes = self.reader.read_line(&mut buf)?; if nbytes == 0 { @@ -29,6 +29,7 @@ impl Decoder { &"set" => self.decode_set(commands), &"get" => self.decode_get(commands), &"delete" => self.decode_delete(commands), + &"stats" => Ok(Command::new_stats()), _ => Err(io::Error::new( io::ErrorKind::InvalidInput, format!("unknown command: {}\n", c), @@ -36,7 +37,7 @@ impl Decoder { }) } - fn decode_set(&mut self, commands: Vec<&str>) -> Result { + fn decode_set(&mut self, commands: Vec<&str>) -> Result { if commands.len() != 5 { return Err(io::Error::new( io::ErrorKind::InvalidInput, @@ -59,27 +60,27 @@ impl Decoder { return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "got eof\n")); } let value = Value::new(buf.trim().parse().unwrap(), flags, exptime); - Ok(command::new_command_set(key.to_string(), value)) + Ok(Command::new_set(key.to_string(), value)) } - fn decode_get(&mut self, commands: Vec<&str>) -> Result { + fn decode_get(&self, commands: Vec<&str>) -> Result { if commands.len() != 2 { return Err(io::Error::new( io::ErrorKind::InvalidInput, "get command length must be 2\n", )); } - let _key = commands[1]; - Ok(command::new_command_get(_key.to_string())) + let key = commands[1]; + Ok(Command::new_get(key.to_string())) } - fn decode_delete(&mut self, commands: Vec<&str>) -> Result { + fn decode_delete(&self, commands: Vec<&str>) -> Result { if commands.len() != 2 { return Err(io::Error::new( io::ErrorKind::InvalidInput, "delete command length must be 2\n", )); } - let _key = commands[1]; - Ok(command::new_command_delete(_key.to_string())) + let key = commands[1]; + Ok(Command::new_delete(key.to_string())) } } diff --git a/src/executor.rs b/src/executor.rs index 5259e7d..5155f1f 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -29,7 +29,7 @@ impl Executor { file.write(&binary)?; let binary_len = binary.len() as i32; file.write(&binary_len.to_le_bytes())?; - memtable.write()?.insert(key, value); + memtable.insert(key, value); Ok("STORED".to_string()) } Command::Get { key } => { @@ -51,6 +51,10 @@ impl Executor { memtable.delete(&key); Ok("DELETED".to_string()) } + Command::Stats {} => { + let memtable = self.memtable.read()?; + Ok(format!("STAT curr_items {}", memtable.to_vec().len())) + }, } } } diff --git a/src/memtable.rs b/src/memtable.rs index e368313..c8d9838 100644 --- a/src/memtable.rs +++ b/src/memtable.rs @@ -2,4 +2,5 @@ pub trait Memtable: Sync + Send { fn insert(&mut self, key: T, value: U); fn delete(&mut self, key: &T); fn search(&self, key: &T) -> Option<&U>; + fn to_vec(&self) -> Vec<(&T, &U)>; } diff --git a/src/value.rs b/src/value.rs index ff128dd..2a9d4c9 100644 --- a/src/value.rs +++ b/src/value.rs @@ -34,8 +34,7 @@ impl Value { let data = String::from_utf8(vec[index..(index + data_len)].to_vec())?; index -= size_of::(); - let exptime = - usize::from_le_bytes(vec[index..(index + size_of::())].try_into()?); + let exptime = usize::from_le_bytes(vec[index..(index + size_of::())].try_into()?); index -= size_of::(); let flags = usize::from_le_bytes(vec[index..(index + size_of::())].try_into()?);