From f8fb7f696f296d212519b653618857221717b5ac Mon Sep 17 00:00:00 2001 From: fengyang Date: Wed, 14 Dec 2022 21:29:08 +0800 Subject: [PATCH 1/7] level_error_toString --- src/traits/comparator_trait.rs | 13 +++--- src/util/comparator.rs | 77 ++++++++++++++++++++-------------- src/util/comparator_test.rs | 2 +- src/util/status.rs | 75 ++++++++++++++++++++------------- src/util/status_test.rs | 59 +++++++++++++++++--------- 5 files changed, 140 insertions(+), 86 deletions(-) diff --git a/src/traits/comparator_trait.rs b/src/traits/comparator_trait.rs index 2d82ba6..aaa0138 100644 --- a/src/traits/comparator_trait.rs +++ b/src/traits/comparator_trait.rs @@ -31,11 +31,14 @@ pub trait ComparatorTrait { /// 返回comparator的名字 fn get_name() -> String; - /// 函数:用于减少像index blocks这样的内部数据结构占用的空间, 其中的*start和*key参数都是IN OUT的。 - /// - /// 这个函数的作用就是: - /// 如果*start < limit,就在[startlimit,)中找到一个短字符串,并赋给*start返回. 如“helloworld”和”hellozoomer”之间最短的key可以是”hellox”。 - /// 简单的comparator实现可能不改变*start(start==limit),这也是正确的 + /// 函数:找到start、limit之间最短的字符串,如“helloworld”和”hellozoomer”之间最短的key可以是”hellox” + /// + /// 作用是: + /// 作用是,如果start < limit,就把start修改为*start和limit的共同前缀后面多一个字符加1 + /// 例如: + /// start: helloWorld + /// limit: helloZookeeper + /// 由于 *start < limit, 所以调用 FindShortSuccessor(start, limit)之后,start变成: helloX (保留前缀,第一个不相同的字符+1) /// /// # Arguments /// diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 51d0123..1e455bc 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -1,5 +1,5 @@ -use std::cmp::Ordering; +use std::cmp::{min, Ordering}; use crate::traits::comparator_trait::{ComparatorTrait}; use crate::util::slice::Slice; @@ -18,7 +18,20 @@ impl ComparatorTrait for BytewiseComparatorImpl { } fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { - todo!() + // 首先计算共同前缀字符串的长度 + let min_lengrh: usize = min(start.len(), limit.len()); + + // let mut diff_index: usize = 0; + // let start_char_vec: Vec = start.chars().collect::>(); + // let limit_char_vec: Vec = limit.chars().collect::>(); + // while ( + // (diff_index < min_lengt) && + // (start_char_vec[diff_index] == limit_char_vec[diff_index]) + // ){ + // diff_index = diff_index + 1; + // } + + String::from("") } fn find_short_successor(&self, key: &String) -> String { @@ -32,33 +45,33 @@ impl Default for BytewiseComparatorImpl { } } -/// InternalKeyComparator -pub struct InternalKeyComparator { - // fn user_comparator(&self) -> Box { - // todo!() - // } - - // fn Compare(InternalKey, InternalKey) -} - -/// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 -/// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 -impl ComparatorTrait for InternalKeyComparator { - // todo InternalKeyComparator 的构造方法 - - fn compare(&self, a: &Slice, b: &Slice) -> Option { - todo!() - } - - fn get_name() -> String { - String::from("leveldb.InternalKeyComparator") - } - - fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { - todo!() - } - - fn find_short_successor(&self, key: &String) -> String { - todo!() - } -} +// /// InternalKeyComparator +// pub struct InternalKeyComparator { +// // fn user_comparator(&self) -> Box { +// // todo!() +// // } +// +// // fn Compare(InternalKey, InternalKey) +// } +// +// /// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 +// /// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 +// impl ComparatorTrait for InternalKeyComparator { +// // todo InternalKeyComparator 的构造方法 +// +// fn compare(&self, a: &Slice, b: &Slice) -> Option { +// todo!() +// } +// +// fn get_name() -> String { +// String::from("leveldb.InternalKeyComparator") +// } +// +// fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { +// todo!() +// } +// +// fn find_short_successor(&self, key: &String) -> String { +// todo!() +// } +// } diff --git a/src/util/comparator_test.rs b/src/util/comparator_test.rs index b7f3af3..420581f 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -2,7 +2,7 @@ mod test { use std::cmp::Ordering; use crate::traits::comparator_trait::ComparatorTrait; - use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; + use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::slice::Slice; #[test] diff --git a/src/util/status.rs b/src/util/status.rs index 9b534bd..9bb6662 100644 --- a/src/util/status.rs +++ b/src/util/status.rs @@ -1,5 +1,4 @@ use std::fmt::{Display, Error, Formatter}; -use std::ops::Deref; use crate::util::r#const::COLON_WHITE_SPACE; use crate::util::ResultT; use crate::util::slice::Slice; @@ -78,6 +77,10 @@ impl Status { self.err.is_invalid_argument() } + pub fn get_error_string(&self) -> String { + self.err.to_string() + } + /// 请注意, err 的所有权会发生转移!!! pub fn get_error(self) -> LevelError { self.err @@ -102,8 +105,8 @@ impl Status { /// assert_eq!("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc: 456456456456456456456456456456456456456456456456", /// String::from(slice.unwrap())); /// ``` - pub fn into_msg(self) -> Option { - Some(self.msg) + pub fn into_msg(self) -> Slice { + self.msg } @@ -144,6 +147,29 @@ impl Status { } } +// impl Display for Status { +// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +// let mut print = String::new(); +// +// if self.is_ok() { +// print.push_str("OK"); +// write!(f, "{}", print); +// +// return Ok(()); +// } +// +// print.push_str(&self.get_error_string()); +// +// let slice: &Slice = &self.msg; +// let errMsg = String::from(slice); +// print.push_str(errMsg.as_str()); +// +// write!(f, "{}", print); +// +// Ok(()) +// } +// } + /// Status 的状态 pub enum LevelError { KOk, @@ -316,32 +342,23 @@ impl TryFrom for LevelError { } } -// /// 实现Display,自动提供to_string -// impl Display for LevelError { -// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { -// let mut print = String::new(); -// -// if self.is_default() { -// print.push_str("OK"); -// return write!(f, "{}", print); -// } -// -// let msg_type = match self { -// KOk => "OK", -// KNotFound(_) => "NotFound: ", -// KCorruption(_) => "Corruption: ", -// KNotSupported(_) => "Not implemented: ", -// KInvalidArgument(_) => "Invalid argument: ", -// KIOError(_) => "IO error: " -// }; -// print.push_str(msg_type); -// -// let mut msg_err: Slice = self.into_msg().unwrap(); -// print.push_str(msg_err.borrow_data().as_str()); -// -// write!(f, "{}", print) -// } -// } +impl Display for LevelError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut print = String::new(); + + let msg_type = match &self { + KOk => "OK", + KNotFound => "NotFound: ", + KCorruption => "Corruption: ", + KNotSupported => "Not implemented: ", + KInvalidArgument => "Invalid argument: ", + KIOError => "IO error: " + }; + print.push_str(msg_type); + + write!(f, "{}", print) + } +} // impl Deref for LevelError { // type Target = i32; diff --git a/src/util/status_test.rs b/src/util/status_test.rs index af745d0..eadccd3 100644 --- a/src/util/status_test.rs +++ b/src/util/status_test.rs @@ -1,5 +1,6 @@ mod test { + use std::borrow::Cow; use crate::util::r#const::COLON_WHITE_SPACE; use crate::util::slice::Slice; use crate::util::status::{LevelError, Status}; @@ -10,9 +11,9 @@ mod test { let status = Status::wrapper(LevelError::KIOError, String::from(msg1).into()); assert!(&status.is_io_error()); - let slice: Option = status.into_msg(); + let slice: Slice = status.into_msg(); assert_eq!("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc", - String::from(slice.unwrap())); + String::from(slice)); let ss = Status::wrapper(LevelError::KOk, String::from(msg1).into()); assert!(&ss.is_ok()); @@ -25,27 +26,27 @@ mod test { let msg2 = "456456456456456456456456456456456456456456456456"; let status = Status::wrappers(LevelError::KIOError, String::from(msg1).into(), String::from(msg2).into()); - let slice: Option = status.into_msg(); + let slice: Slice = status.into_msg(); assert_eq!("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc: 456456456456456456456456456456456456456456456456", - String::from(slice.unwrap())); + String::from(slice)); let err: Status = LevelError::invalid_argument(String::from(msg1).into(), String::from(msg2).into()); - assert!(&err.get_error().is_invalid_argument()); + assert!(&err.is_invalid_argument()); // assert_eq!(err.into_code(), 4); let err: Status = LevelError::corruption(String::from(msg1).into(), String::from(msg2).into()); - assert!(&err.get_error().is_corruption()); + assert!(&err.is_corruption()); // assert_eq!(err.into_code(), 2); let err: Status = LevelError::not_found(String::from(msg1).into(), String::from(msg2).into()); - assert!(&err.get_error().is_not_found()); + assert!(&err.is_not_found()); let err: Status = LevelError::not_supported(String::from(msg1).into(), String::from(msg2).into()); - assert!(&err.get_error().is_not_supported_error()); + assert!(&err.is_not_supported_error()); let err: LevelError = LevelError::KOk; assert!(&err.is_ok()); @@ -55,7 +56,22 @@ mod test { } #[test] - fn test_toString() { + fn test_is_default() { + let err: Status = LevelError::ok(); + assert!(err.is_ok()); + + let err: Status = LevelError::io_error(String::from("a").into(), + String::from("b").into()); + assert!(!err.is_ok()); + + let status: Status = LevelError::not_found(String::from("a").into(), + String::from("b").into()); + assert!(status.is_not_found()); + assert!(status.get_error().is_not_found()); + } + + #[test] + fn test_status_to_string() { // ok let status: Status = LevelError::ok(); assert_eq!("OK", status.to_string()); @@ -84,21 +100,26 @@ mod test { } #[test] - fn test_is_default() { - let err: Status = LevelError::ok(); - assert!(err.get_error().is_ok()); + fn test_level_error_toString() { + // ok + let status: Status = LevelError::ok(); + assert_eq!("OK", status.to_string()); - let err: Status = LevelError::io_error(String::from("a").into(), - String::from("b").into()); - assert!(!err.get_error().is_ok()); + // err invalid_argument + let msg1 = "bcabcabcabcabcabcbc"; + let msg2 = "56"; + let error: Status = LevelError::invalid_argument(String::from(msg1).into(), + String::from(msg2).into()); + + let le_err: LevelError = error.get_error(); + println!("{}", &le_err); - // let err: LevelError = LevelError::ok(); - // let a = err.into(); - // print!("{}", a); + // Display + assert_eq!(String::from("Invalid argument: "), le_err.to_string()); } #[test] - fn test_try_from() -> Result<(), String> { + fn test_level_error_try_from() -> Result<(), String> { let rs = LevelError::try_from(1)?; assert!(&rs.is_not_found()); let rs: Result = 1.try_into(); -- Gitee From 0bc18d82911e30655ad2bd2c02545fa87066c89b Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 20:38:24 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=9C=80=E7=9F=AD=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/traits/comparator_trait.rs | 31 +++++++++++----- src/util/comparator.rs | 64 ++++++++++++++++++++++++---------- src/util/comparator_test.rs | 49 +++++++++++++++++++++++++- 3 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/traits/comparator_trait.rs b/src/traits/comparator_trait.rs index aaa0138..a78e054 100644 --- a/src/traits/comparator_trait.rs +++ b/src/traits/comparator_trait.rs @@ -33,29 +33,44 @@ pub trait ComparatorTrait { /// 函数:找到start、limit之间最短的字符串,如“helloworld”和”hellozoomer”之间最短的key可以是”hellox” /// - /// 作用是: - /// 作用是,如果start < limit,就把start修改为*start和limit的共同前缀后面多一个字符加1 + /// 作用是, + /// 如果start < limit,就把start修改为 start和limit的共同前缀, 后面多一个字符加1 + /// /// 例如: /// start: helloWorld /// limit: helloZookeeper - /// 由于 *start < limit, 所以调用 FindShortSuccessor(start, limit)之后,start变成: helloX (保留前缀,第一个不相同的字符+1) + /// 由于 start < limit, 所以调用 FindShortSuccessor(start, limit)之后, + /// start变成: helloX (保留前缀,第一个不相同的字符+1) /// /// # Arguments /// - /// * `start`: - /// * `limit`: + /// * `start`: String + /// * `limit`: Slice /// /// returns: String /// /// # Examples /// /// ``` - /// + /// let comp = BytewiseComparatorImpl::default(); + /// let find_shortest_separator_val = comp.find_shortest_separator( + /// &String::from("abcdefghijklimA"), + /// &Slice::from("abcdefghijklimNy")); + /// /// A < N + /// assert_eq!(find_shortest_separator_val, "abcdefghijklimB"); + /// + /// let comp = BytewiseComparatorImpl::default(); + /// let find_shortest_separator_val = comp.find_shortest_separator( + /// &String::from("abcdefghijklima"), + /// &Slice::from("abcdefghijklimNy")); + /// /// a > N + /// assert_eq!(find_shortest_separator_val, "abcdefghijklima"); /// ``` fn find_shortest_separator(&self, start: &String, limit:&Slice) -> String; - /// 找一个 >= key的短字符串, key变成一个比原*key大的短字符串,并返回。 - /// 简单的comparator实现可能不改变 key,这也是正确的 + /// 用于找到比key大的最短字符串,如传入“helloworld”,返回的key可能是“i”而已。 + /// + /// 找一个 >= key的短字符串, key变成一个比原key大的短字符串,并返回。 /// /// # Arguments /// diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 1e455bc..a5f4442 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -3,10 +3,18 @@ use std::cmp::{min, Ordering}; use crate::traits::comparator_trait::{ComparatorTrait}; use crate::util::slice::Slice; -/// BytewiseComparatorImpl是按字典逐字节序进行比较 -/// 也就是说 i>helloworld,因为先比较i和h,i>h,比较直接结束 pub struct BytewiseComparatorImpl {} +/// +/// compare: +/// 按字典逐字节序进行比较 +/// 也就是说 i>helloworld,因为先比较i和h,i>h,比较直接结束 +impl Default for BytewiseComparatorImpl { + fn default() -> Self { + Self{} + } +} + impl ComparatorTrait for BytewiseComparatorImpl { fn compare(&self, a: &Slice, b: &Slice) -> Option { @@ -19,29 +27,47 @@ impl ComparatorTrait for BytewiseComparatorImpl { fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { // 首先计算共同前缀字符串的长度 - let min_lengrh: usize = min(start.len(), limit.len()); + let min_length: usize = min(start.len(), limit.len()); - // let mut diff_index: usize = 0; + let mut diff_index: usize = 0; + let mut start_char_vec: Vec = start.as_bytes().to_vec(); + let limit_char_vec: &Vec = &limit.to_vec(); + // or use // let start_char_vec: Vec = start.chars().collect::>(); - // let limit_char_vec: Vec = limit.chars().collect::>(); - // while ( - // (diff_index < min_lengt) && - // (start_char_vec[diff_index] == limit_char_vec[diff_index]) - // ){ - // diff_index = diff_index + 1; - // } + // let limit_char_vec: Vec = limit.to_vec().iter().map(|b| *b as char).collect::>(); - String::from("") - } + while diff_index < min_length && + start_char_vec[diff_index] == limit_char_vec[diff_index] + { + // Increment counter + diff_index += 1; + } - fn find_short_successor(&self, key: &String) -> String { - todo!() + // 如果一个字符串是另个一字符串的前缀,无需做截短操作,否则进入 else。 + if diff_index >= min_length { + // 说明 start是limit的前缀,或者反之,此时不作修改,直接返回 + } else{ + // 尝试执行字符start[diff_index]++, 设置start长度为diff_index+1,并返回 + // ++条件:字符 < oxff 并且字符+1 < limit上该index的字符 + let diff_byte = start_char_vec[diff_index]; + // let diff_char = diff_byte as char; + + if diff_byte < 0xff && + // 且 start 中的差异字符的next 小于 limit中的diff_index的字符, + // 则将 start 差异字符位置+1的元素变更为 差异字符的next + (diff_byte + 1) < limit_char_vec[diff_index] { + start_char_vec[diff_index] = diff_byte + 1; + } + } + + let shortest_separator: &[u8] = &start_char_vec[0..diff_index+1]; + + let shortest_separator_val: String= Slice::from_buf(shortest_separator).into(); + shortest_separator_val } -} -impl Default for BytewiseComparatorImpl { - fn default() -> Self { - Self{} + fn find_short_successor(&self, key: &String) -> String { + String::from("a") } } diff --git a/src/util/comparator_test.rs b/src/util/comparator_test.rs index 420581f..b0688dc 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -8,7 +8,7 @@ mod test { #[test] fn test_bytewise_comparator_impl_get_name() { let name = BytewiseComparatorImpl::get_name(); - println!("{}", &name); + println!("get_name: {}", &name); assert_eq!("leveldb.BytewiseComparator", name); } @@ -18,6 +18,7 @@ mod test { let option_val = comp.compare(&Slice::from("a"), &Slice::from("ab")); assert_eq!(option_val.unwrap(), Ordering::Less); + // todo Slice 存在 bug 未修复 // let comp = BytewiseComparatorImpl::default(); // let option_val = comp.compare(&Slice::from("b"), &Slice::from("abcd")); // assert_eq!(option_val.unwrap(), Ordering::Greater); @@ -27,4 +28,50 @@ mod test { assert_eq!(option_val.unwrap(), Ordering::Equal); } + #[test] + fn test_bytewise_comparator_impl_find_shortest_separator() { + let comp = BytewiseComparatorImpl::default(); + let find_shortest_separator_val = comp.find_shortest_separator( + &String::from("helloWorld"), + &Slice::from("helloZookeeper")); + // W < Z + assert_eq!(find_shortest_separator_val, "helloX"); + + let comp = BytewiseComparatorImpl::default(); + let find_shortest_separator_val = comp.find_shortest_separator( + &String::from("abcdefghijklimx"), + &Slice::from("abcdefghijklimNy")); + // x(!X) > N + assert_eq!(find_shortest_separator_val, "abcdefghijklimx"); + + let comp = BytewiseComparatorImpl::default(); + let find_shortest_separator_val = comp.find_shortest_separator( + &String::from("abcdefghijklimA"), + &Slice::from("abcdefghijklimNy")); + // A < N + assert_eq!(find_shortest_separator_val, "abcdefghijklimB"); + + let comp = BytewiseComparatorImpl::default(); + let find_shortest_separator_val = comp.find_shortest_separator( + &String::from("abcdefghijklima"), + &Slice::from("abcdefghijklimNy")); + // a > N + assert_eq!(find_shortest_separator_val, "abcdefghijklima"); + + let comp = BytewiseComparatorImpl::default(); + let find_shortest_separator_val = comp.find_shortest_separator( + &String::from("abcdefghijklima"), + &Slice::from("abcdefghijklimny")); + // a < n + assert_eq!(find_shortest_separator_val, "abcdefghijklimb"); + } + + #[test] + fn test_bytewise_comparator_impl_find_short_successor() { + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&String::from("helloWorld")); + println!("find_short_successor_val: {}", &find_short_successor_val); + assert_eq!(find_short_successor_val, "a"); + } + } \ No newline at end of file -- Gitee From 970cc6949a5788e2a03f22917cb050ed3025c2ac Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 21:18:56 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=AF=94key=E5=A4=A7=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E7=9F=AD=E5=AD=97=E7=AC=A6=E4=B8=B2=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/traits/comparator_trait.rs | 2 +- src/util/comparator.rs | 25 ++++++++++++++-- src/util/comparator_test.rs | 52 ++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/traits/comparator_trait.rs b/src/traits/comparator_trait.rs index a78e054..47388a2 100644 --- a/src/traits/comparator_trait.rs +++ b/src/traits/comparator_trait.rs @@ -68,7 +68,7 @@ pub trait ComparatorTrait { /// ``` fn find_shortest_separator(&self, start: &String, limit:&Slice) -> String; - /// 用于找到比key大的最短字符串,如传入“helloworld”,返回的key可能是“i”而已。 + /// 用于找到比key大的最短字符串,如传入“helloworld”,返回的key可能是“i” /// /// 找一个 >= key的短字符串, key变成一个比原key大的短字符串,并返回。 /// diff --git a/src/util/comparator.rs b/src/util/comparator.rs index a5f4442..219539c 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -36,6 +36,7 @@ impl ComparatorTrait for BytewiseComparatorImpl { // let start_char_vec: Vec = start.chars().collect::>(); // let limit_char_vec: Vec = limit.to_vec().iter().map(|b| *b as char).collect::>(); + assert_eq!(u8::MAX, 255); while diff_index < min_length && start_char_vec[diff_index] == limit_char_vec[diff_index] { @@ -49,10 +50,10 @@ impl ComparatorTrait for BytewiseComparatorImpl { } else{ // 尝试执行字符start[diff_index]++, 设置start长度为diff_index+1,并返回 // ++条件:字符 < oxff 并且字符+1 < limit上该index的字符 - let diff_byte = start_char_vec[diff_index]; + let diff_byte: u8 = start_char_vec[diff_index]; // let diff_char = diff_byte as char; - if diff_byte < 0xff && + if diff_byte < u8::MAX && // 且 start 中的差异字符的next 小于 limit中的diff_index的字符, // 则将 start 差异字符位置+1的元素变更为 差异字符的next (diff_byte + 1) < limit_char_vec[diff_index] { @@ -67,7 +68,25 @@ impl ComparatorTrait for BytewiseComparatorImpl { } fn find_short_successor(&self, key: &String) -> String { - String::from("a") + /// 找到第一个可以++的字符,执行++后,截断字符串; + /// 如果找不到说明 key的字符都是 u8::MAX,直接返回 + let key_len = key.len(); + + let mut key_char_vec: Vec = key.as_bytes().to_vec(); + for i in 0..key_len { + let byte_val: u8 = key_char_vec[i]; + if byte_val != u8::MAX { + key_char_vec[i] = byte_val + 1; + + let short_successor: &[u8] = &key_char_vec[0..i+1]; + + let short_successor_val: String= Slice::from_buf(short_successor).into(); + return short_successor_val; + } + } + /// key is a run of u8::MAX. Leave it alone. + + Slice::from_buf(key.as_bytes()).into() } } diff --git a/src/util/comparator_test.rs b/src/util/comparator_test.rs index b0688dc..11b72ec 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -1,6 +1,7 @@ mod test { use std::cmp::Ordering; + use std::io::Write; use crate::traits::comparator_trait::ComparatorTrait; use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::slice::Slice; @@ -70,8 +71,55 @@ mod test { fn test_bytewise_comparator_impl_find_short_successor() { let comp = BytewiseComparatorImpl::default(); let find_short_successor_val = comp.find_short_successor(&String::from("helloWorld")); - println!("find_short_successor_val: {}", &find_short_successor_val); - assert_eq!(find_short_successor_val, "a"); + assert_eq!(find_short_successor_val, "i"); + + + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&String::from("a")); + assert_eq!(find_short_successor_val, "b"); + + + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&String::from("123")); + assert_eq!(find_short_successor_val, "2"); + + + // 只有 u8::MAX + let u8_max_vec: Vec = vec![u8::MAX]; + let u8_max_str = String::from(Slice::from_buf(u8_max_vec.as_slice())); + + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&u8_max_str); + assert_eq!(u8_max_str, find_short_successor_val); + + + // u8max 结尾 + let mut u8_vec: Vec = vec![]; + u8_vec.write(&String::from("helloWorld").as_bytes().to_vec()); + u8_vec.push(u8::MAX); + + let u8_array_str = String::from(Slice::from_buf(u8_vec.as_slice())); + + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&u8_array_str); + assert_eq!(find_short_successor_val, "i"); + + + // u8max 开头 + let mut u8_vec: Vec = vec![]; + u8_vec.push(u8::MAX); + u8_vec.write(&String::from("helloWorld").as_bytes().to_vec()); + let u8_max_str = String::from(Slice::from_buf(u8_vec.as_slice())); + + let comp = BytewiseComparatorImpl::default(); + let find_short_successor_val = comp.find_short_successor(&u8_max_str); + + // 只有 u8::MAX + let mut expect_u8_max_vec: Vec = vec![]; + expect_u8_max_vec.push(u8::MAX); + expect_u8_max_vec.write("i".as_bytes()).expect("panic message"); + assert_eq!(find_short_successor_val, + String::from(Slice::from_buf(expect_u8_max_vec.as_slice()))); } } \ No newline at end of file -- Gitee From 0782d1b555cc4178592e3a582bc8fed8ec3d4cfa Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 21:20:27 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=AF=94key=E5=A4=A7=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E7=9F=AD=E5=AD=97=E7=AC=A6=E4=B8=B2=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/comparator.rs | 60 ++++++++++++++++++------------------- src/util/comparator_test.rs | 8 ++++- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 219539c..3c8c01c 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -90,33 +90,33 @@ impl ComparatorTrait for BytewiseComparatorImpl { } } -// /// InternalKeyComparator -// pub struct InternalKeyComparator { -// // fn user_comparator(&self) -> Box { -// // todo!() -// // } -// -// // fn Compare(InternalKey, InternalKey) -// } -// -// /// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 -// /// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 -// impl ComparatorTrait for InternalKeyComparator { -// // todo InternalKeyComparator 的构造方法 -// -// fn compare(&self, a: &Slice, b: &Slice) -> Option { -// todo!() -// } -// -// fn get_name() -> String { -// String::from("leveldb.InternalKeyComparator") -// } -// -// fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { -// todo!() -// } -// -// fn find_short_successor(&self, key: &String) -> String { -// todo!() -// } -// } +/// InternalKeyComparator +pub struct InternalKeyComparator { + // fn user_comparator(&self) -> Box { + // todo!() + // } + + // fn Compare(InternalKey, InternalKey) +} + +/// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 +/// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 +impl ComparatorTrait for InternalKeyComparator { + // todo InternalKeyComparator 的构造方法 + + fn compare(&self, a: &Slice, b: &Slice) -> Option { + todo!() + } + + fn get_name() -> String { + String::from("leveldb.InternalKeyComparator") + } + + fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { + todo!() + } + + fn find_short_successor(&self, key: &String) -> String { + todo!() + } +} diff --git a/src/util/comparator_test.rs b/src/util/comparator_test.rs index 11b72ec..a9b2807 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -3,7 +3,7 @@ mod test { use std::cmp::Ordering; use std::io::Write; use crate::traits::comparator_trait::ComparatorTrait; - use crate::util::comparator::{BytewiseComparatorImpl}; + use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; use crate::util::slice::Slice; #[test] @@ -122,4 +122,10 @@ mod test { String::from(Slice::from_buf(expect_u8_max_vec.as_slice()))); } + #[test] + fn test_internal_key_comparator_get_name() { + let name = InternalKeyComparator::get_name(); + assert_eq!("leveldb.InternalKeyComparator", name); + } + } \ No newline at end of file -- Gitee From 7fdd44295f301e3eabe7dcfa8f613550ab25e780 Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 21:30:17 +0800 Subject: [PATCH 5/7] test --- src/util/comparator.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 3c8c01c..173c68a 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -68,8 +68,8 @@ impl ComparatorTrait for BytewiseComparatorImpl { } fn find_short_successor(&self, key: &String) -> String { - /// 找到第一个可以++的字符,执行++后,截断字符串; - /// 如果找不到说明 key的字符都是 u8::MAX,直接返回 + // 找到第一个可以++的字符,执行++后,截断字符串; + // 如果找不到说明 key的字符都是 u8::MAX,直接返回 let key_len = key.len(); let mut key_char_vec: Vec = key.as_bytes().to_vec(); @@ -84,7 +84,6 @@ impl ComparatorTrait for BytewiseComparatorImpl { return short_successor_val; } } - /// key is a run of u8::MAX. Leave it alone. Slice::from_buf(key.as_bytes()).into() } @@ -104,7 +103,7 @@ pub struct InternalKeyComparator { impl ComparatorTrait for InternalKeyComparator { // todo InternalKeyComparator 的构造方法 - fn compare(&self, a: &Slice, b: &Slice) -> Option { + fn compare(&self, _a: &Slice, _b: &Slice) -> Option { todo!() } @@ -112,11 +111,11 @@ impl ComparatorTrait for InternalKeyComparator { String::from("leveldb.InternalKeyComparator") } - fn find_shortest_separator(&self, start: &String, limit: &Slice) -> String { + fn find_shortest_separator(&self, _start: &String, _limit: &Slice) -> String { todo!() } - fn find_short_successor(&self, key: &String) -> String { + fn find_short_successor(&self, _key: &String) -> String { todo!() } } -- Gitee From 077cd5107584d9c22547e8c42a8e7de7fcfafd5c Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 22:22:28 +0800 Subject: [PATCH 6/7] readme.md --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 725b374..e323364 100644 --- a/README.md +++ b/README.md @@ -37,18 +37,18 @@ LevelDB for rust 1. 1.0.0 版本, 完成 util 相关的内容 -| 功能模块 | 完成人 | -|-------------------------------|-------------| -| Arena (Memory Management) | wangboo | -| Slice | wangboo | -| Random | colagy | -| Cache | colagy | -| Coding (Primitive Type SerDe) | colagy | -| Comparator | fengyang | -| Status | fengyang | -| BloomFilter | fengyang | -| CRC | lxd5866 | -| Env | lxd5866 | -| Hash | lxd5866 | -| MutexLock | kazeseiriou | -| Histgram | kazeseiriou | \ No newline at end of file +| 功能模块 | 完成人 | 进度 | +|-------------------------------|-----------------|------| +| Arena (Memory Management) | wangboo | | +| Slice | wangboo | | +| Random | colagy | | +| Cache | colagy | | +| Coding (Primitive Type SerDe) | colagy | | +| Comparator | fengyang | 85% | +| Status | fengyang | 100% | +| BloomFilter | fengyang | | +| CRC | wangboo、lxd5866 | | +| Env | lxd5866 | | +| Hash | lxd5866 | | +| MutexLock | kazeseiriou | | +| Histgram | kazeseiriou | | \ No newline at end of file -- Gitee From 159ac905c3d93349c2e881dfe70bb5f6133c9a0f Mon Sep 17 00:00:00 2001 From: fengyang Date: Thu, 15 Dec 2022 22:55:38 +0800 Subject: [PATCH 7/7] =?UTF-8?q?hash=20=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/util/hash.rs | 21 +++++++++++++++++++++ src/util/hash_test.rs | 6 ++++++ src/util/mod.rs | 7 ++++--- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/util/hash.rs create mode 100644 src/util/hash_test.rs diff --git a/README.md b/README.md index e323364..b7d8eb0 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,9 @@ LevelDB for rust | Coding (Primitive Type SerDe) | colagy | | | Comparator | fengyang | 85% | | Status | fengyang | 100% | -| BloomFilter | fengyang | | +| BloomFilter | fengyang | 0% | | CRC | wangboo、lxd5866 | | | Env | lxd5866 | | -| Hash | lxd5866 | | +| Hash | fengyang | 30% | | MutexLock | kazeseiriou | | | Histgram | kazeseiriou | | \ No newline at end of file diff --git a/src/util/hash.rs b/src/util/hash.rs new file mode 100644 index 0000000..d383f2b --- /dev/null +++ b/src/util/hash.rs @@ -0,0 +1,21 @@ + +pub trait AsHash { + /// + /// + /// # Arguments + /// + /// * `data`: + /// * `n`: data 的长度 + /// * `seed`: 随机数种子 + /// + /// returns: u32 + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn hash(data: String, n: usize, seed: u32) -> u32; +} + +pub struct Hash {} \ No newline at end of file diff --git a/src/util/hash_test.rs b/src/util/hash_test.rs new file mode 100644 index 0000000..0384579 --- /dev/null +++ b/src/util/hash_test.rs @@ -0,0 +1,6 @@ + +#[test] +fn test_hash() { + + +} \ No newline at end of file diff --git a/src/util/mod.rs b/src/util/mod.rs index b56627f..dab1d24 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,5 +1,6 @@ use crate::util::status::LevelError; use std::result; +pub use arena::Arena; /// 常量定义 pub mod r#const; @@ -11,13 +12,12 @@ mod coding_test; pub mod arena; mod arena_test; -pub use arena::Arena; - pub mod status; mod status_test; pub mod comparator; mod comparator_test; mod crc; +mod crc_test; pub mod bloom_filter; mod bloom_filter_test; pub mod filter_policy; @@ -27,4 +27,5 @@ pub type ResultT = result::Result; pub mod histogram; mod histogram_test; -mod crc_test; +mod hash; +mod hash_test; -- Gitee