From 2ffa127800e25a975b1c94b290490f77e29767e5 Mon Sep 17 00:00:00 2001 From: wangboo <5417808+wangboa@user.noreply.gitee.com> Date: Fri, 17 Mar 2023 16:17:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0skiplist/memtable=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/db_format.rs | 79 +++++++++++++++++++++------------- src/db/log_wr_test.rs | 14 +++--- src/db/mem_table.rs | 61 +++++++++++++++++--------- src/db/mod.rs | 8 +--- src/db/skip_list.rs | 23 +++++----- src/db/skip_list_test.rs | 20 ++++----- src/traits/coding_trait.rs | 2 +- src/util/arena_test.rs | 2 +- src/util/coding.rs | 55 +++-------------------- src/util/coding_test.rs | 8 +--- src/util/comparator_test.rs | 8 ---- src/util/crc_test.rs | 4 +- src/util/filter_policy.rs | 20 +++------ src/util/filter_policy_test.rs | 15 ------- src/util/hash_test.rs | 7 ++- src/util/histogram_test.rs | 2 +- src/util/mutex_lock_test.rs | 5 +-- src/util/slice.rs | 7 +++ src/util/slice_test.rs | 2 +- src/util/status.rs | 7 +++ src/util/status_test.rs | 6 +-- 21 files changed, 159 insertions(+), 196 deletions(-) diff --git a/src/db/db_format.rs b/src/db/db_format.rs index 891b906..49e7194 100644 --- a/src/db/db_format.rs +++ b/src/db/db_format.rs @@ -1,16 +1,18 @@ use std::cmp::Ordering; -use std::ops::Deref; -use crate::db::db_format::ValueType::{K_TYPE_DELETION, K_TYPE_VALUE}; +use std::io::Write; +use crate::db::db_format::ValueType::{KTypeDeletion, KTypeValue}; use crate::db::file_meta_data::FileMetaData; +use crate::traits::coding_trait::CodingTrait; use crate::traits::comparator_trait::Comparator; +use crate::util::coding::Coding; use crate::util::slice::Slice; pub enum ValueType { /// 0x0 - K_TYPE_DELETION, + KTypeDeletion, /// 0x1 - K_TYPE_VALUE, + KTypeValue, } pub struct ParsedInternalKey { @@ -32,27 +34,17 @@ pub struct InternalKeyComparator { /// 查找键 // todo add clone trait pub struct LookupKey { - // We construct a char array of the form: - // klength varint32 <-- start_ - // userkey char[klength] <-- kstart_ - // tag uint64 - // <-- end_ - // The array is a suitable MemTable key. - // The suffix starting with "userkey" can be used as an InternalKey. - - start_: Slice, - kstart_: Slice, - end_: Slice, - - // Avoid allocation for short keys - space_: [u8; 200], + /// |klength(varint32)|user key(string)|sequence number(7 bytes)|value type(1 byte)| + data: Slice, + /// start index at user key + user_key_start: usize, } impl ValueType { - pub fn get_value(&self) -> i32 { + pub fn get_value(&self) -> usize { let le = match self { - K_TYPE_DELETION => 0, - K_TYPE_VALUE => 1 + KTypeDeletion => 0, + KTypeValue => 1 }; le @@ -79,8 +71,8 @@ impl TryFrom for ValueType { #[inline] fn try_from(value: i32) -> Result { match value { - 0 => Ok(K_TYPE_DELETION), - 1 => Ok(K_TYPE_VALUE), + 0 => Ok(KTypeDeletion), + 1 => Ok(KTypeValue), // all other numbers _ => Err(String::from(format!("Unknown code: {}", value))) } @@ -93,7 +85,7 @@ impl Default for ParsedInternalKey { ParsedInternalKey { user_key: Default::default(), sequence: 0, - value_type: K_TYPE_DELETION, + value_type: KTypeDeletion, } } } @@ -251,20 +243,39 @@ impl Comparator for InternalKeyComparator { impl LookupKey { /// Initialize *this for looking up user_key at a snapshot with /// the specified sequence number. - fn new(user_key: Slice, sequence: u64) -> Self { - // todo - todo!() + fn new(user_key: Slice, sequence: usize) -> Self { + let user_key_size = user_key.size(); + let need = user_key_size + 13; // A conservative estimate + let mut data = Vec::with_capacity(need); + let buf = data.as_mut_slice(); + let klength = Coding::varint_length(user_key_size + 8); + let mut offset = 0; + // write key size + offset = Coding::encode_varint32(klength as u32, buf, offset); + // write key slice + offset += (&mut buf[offset..]).write(user_key.as_ref()).expect("write user_key"); + // write sequence number and value type + Coding::encode_fixed64( + pack_sequence_and_type(sequence, ValueType::KTypeValue), + buf, offset); + + LookupKey { + data: Slice::from_vec(data), + user_key_start: klength + } } /// Return a key suitable for lookup in a MemTable. fn mem_table_key(&self) -> Slice { - todo!() + self.data.clone() } /// Return an internal key (suitable for passing to an internal iterator) fn internal_key(&self) -> Slice { // line 204 - todo!() + let buf = self.data.as_ref(); + let internal_key_buf = &buf[self.user_key_start..]; + Slice::from_buf(internal_key_buf.clone()) } /// Return the user key @@ -293,6 +304,14 @@ impl LookupKey { // } // } +const K_MAX_SEQUENCE_NUMBER: usize = (1 << 56) - 1; + +#[inline] +pub fn pack_sequence_and_type(seq_no: usize, v_type: ValueType) -> u64 { + debug_assert!(seq_no <= K_MAX_SEQUENCE_NUMBER); + debug_assert!(v_type.get_value() <= 1); + ((seq_no << 8) | v_type.get_value()) as u64 +} pub struct Config {} impl Config { @@ -325,5 +344,5 @@ impl Config { // and the value type is embedded as the low 8 bits in the sequence // number in internal keys, we need to use the highest-numbered // ValueType, not the lowest). - pub const K_VALUE_TYPE_FOR_SEEK: ValueType = ValueType::K_TYPE_VALUE; + pub const K_VALUE_TYPE_FOR_SEEK: ValueType = ValueType::KTypeValue; } \ No newline at end of file diff --git a/src/db/log_wr_test.rs b/src/db/log_wr_test.rs index d333556..a5ad510 100644 --- a/src/db/log_wr_test.rs +++ b/src/db/log_wr_test.rs @@ -1,13 +1,13 @@ mod test { - - - - - - - + use std::fs::File; + use crate::db::log_reader::LogReader; + use crate::db::log_writer::LogWriter; + use crate::traits::coding_trait::CodingTrait; + use crate::util::coding::Coding; + use crate::util::crc::{AsCrc, ToMask}; use crate::util::slice::Slice; + use crate::util::Result; #[test] fn write() -> Result<()> { diff --git a/src/db/mem_table.rs b/src/db/mem_table.rs index be88ba7..aff4c60 100644 --- a/src/db/mem_table.rs +++ b/src/db/mem_table.rs @@ -1,27 +1,22 @@ -use std::rc::Rc; +use std::io::Write; +use std::sync::{Arc, Mutex}; +use crate::db::db_format::{LookupKey, ValueType}; +use crate::db::skip_list::SkipList; +use crate::traits::coding_trait::CodingTrait; use crate::traits::comparator_trait::Comparator; use crate::traits::DataIterator; -<<<<<<< HEAD -======= - ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb +use crate::util::arena::ArenaRef; use crate::util::slice::Slice; - -use crate::util::Result; - -pub enum ValueType { - Insert, - Deletion, -} +use crate::util::{Arena, Result}; +use crate::util::coding::Coding; /// 内存表 pub struct MemTable { - cmp: Rc, + cmp: Arc, + list: SkipList, + arena: ArenaRef, } -/// 临时, 查找键 -pub struct LookupKey {} - impl MemTable { /// 创建内存表 @@ -37,15 +32,20 @@ impl MemTable { /// ``` /// let mt = MemTable::create(cmp); /// ``` - pub fn create(cmp: Rc) -> Self { + pub fn create(cmp: Arc) -> Self { + let arena = Arc::new(Mutex::new(Arena::default())); + let list = SkipList::create(cmp.clone(), arena.clone()); Self { cmp, + list, + arena } } /// 返回该表使用的内存近似值 + #[inline] pub fn approximate_memory_usage(&self) -> usize { - todo!() + self.arena.lock().unwrap().memory_usage() } /// 创建内存表迭代器 @@ -58,15 +58,34 @@ impl MemTable { /// /// ``` /// let mem = MemTable::create(comp); - /// let it = mem::new_new_iterator()?; + /// let it = mem.new_new_iterator()?; /// ``` pub fn new_iterator(&self) -> Result> { todo!() } /// 像内存表中写入或删除一个元素 - pub fn add(&mut self, _seq_no: usize, _v_type: ValueType, _key: &Slice, _value: Slice) -> Result<()> { - todo!() + pub fn add(&mut self, seq_no: usize, v_type: ValueType, key: &Slice, value: Slice) -> Result<()> { + let key_size = key.size(); + let value_size = value.size(); + let internal_key_size = key_size + 8; + let encoded_len = Coding::varint_length(key_size) + + internal_key_size + + Coding::varint_length(value_size) + + value_size; + let mut lock = self.arena.lock()?; + let buf = lock.allocate(encoded_len); + let mut offset = 0; + // write key size + offset = Coding::encode_varint32(internal_key_size as u32, buf, offset); + // write key slice + offset += (&mut buf[offset..]).write(key.as_ref())?; + // write seq_no and type + offset = Coding::encode_fixed64((seq_no << 8 | v_type.get_value()) as u64, buf, offset); + // write value slice + (&mut buf[offset..]).write(value.as_ref())?; + let slice = Slice::from_buf(buf); + self.list.insert(slice) } /// 通过 key 查找结果 diff --git a/src/db/mod.rs b/src/db/mod.rs index eb55254..b82f563 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,13 +1,7 @@ use crate::db::db_format::InternalKeyComparator; use crate::db::skip_list::SkipList; -<<<<<<< HEAD use crate::db::mem_table::MemTable; -use crate::util::comparator::{BytewiseComparatorImpl}; -use crate::util::slice::Slice; -======= -use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; - ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb +use crate::util::comparator::BytewiseComparatorImpl; pub mod log_writer; pub mod log_reader; diff --git a/src/db/skip_list.rs b/src/db/skip_list.rs index 55eeaed..449712f 100644 --- a/src/db/skip_list.rs +++ b/src/db/skip_list.rs @@ -2,14 +2,14 @@ use std::cmp::Ordering; use std::mem; use std::mem::size_of; use std::ptr::null_mut; -use std::sync::Arc; +use std::sync::{Arc, RwLock}; use rand::prelude::*; use crate::debug; use crate::traits::comparator_trait::Comparator; -use crate::util::arena::{ArenaAllocLike, ArenaRef}; -use crate::util::Result; +use crate::util::arena::ArenaRef; +use crate::util::{Arena, Result}; use crate::util::slice::Slice; use crate::util::status::{LevelError, Status}; @@ -77,7 +77,7 @@ impl SkipList { fn insert_ele0(&mut self, key: Slice) -> Result<()> { let level = rand_level(); debug!("insert {}, level: {}", &key, level); - let node = unsafe { Node::create(key, level, self.arena.clone()) }; + let node = Node::create(key, level, self.arena.clone()); // head bind node // TODO, use macro to expand for-loop unsafe { @@ -98,9 +98,7 @@ impl SkipList { let node_height = rand_level(); let node_top_level = node_height - 1; debug!("insert {}, level: {}", &key, node_height); - let node_ptr = unsafe { - Node::create(key, node_height, self.arena.clone()) - }; + let node_ptr = Node::create(key, node_height, self.arena.clone()); let node = unsafe { &mut *node_ptr }; // loop from highest level to 0 for l in (0..self.height).rev() { @@ -166,7 +164,6 @@ impl SkipList { Ok(()) } - #[macro_use] pub fn contains(&self, key: &Slice) -> bool { debug!("================== begin contains, key: {} ==================", key); if self.num == 0 { @@ -232,6 +229,13 @@ impl SkipList { Iter::create(&self) } + #[inline] + pub fn memory_usage(&self) -> usize { + let a = Arc::new(RwLock::new(Arena::default())); + a.read().unwrap().memory_usage(); + self.arena.lock().unwrap().memory_usage() + } + fn rnd_level(&self) -> usize { let mut level = 1; for _ in 1..MAX_LEVEL { @@ -274,9 +278,8 @@ impl ToString for SkipList { impl Node { #[inline] fn create(src: Slice, level: usize, arena: ArenaRef) -> RawNode { - let key = src.copy_with_arena(arena.clone()); let node = box Self { - key: Some(key), + key: Some(src), next_elems: allocate_next_elems(arena), level, }; diff --git a/src/db/skip_list_test.rs b/src/db/skip_list_test.rs index 287d18c..7ac6f6f 100644 --- a/src/db/skip_list_test.rs +++ b/src/db/skip_list_test.rs @@ -1,15 +1,13 @@ mod test { - - - - - - - - - - - + use std::collections::HashSet; + use std::sync::{Arc, Mutex}; + use rand::Rng; + use crate::db::DefaultSkipList; + use crate::debug; + use crate::util::Arena; + use crate::util::comparator::BytewiseComparatorImpl; + use crate::util::Result; + use crate::util::slice::Slice; #[test] fn test_add() -> Result<()> { diff --git a/src/traits/coding_trait.rs b/src/traits/coding_trait.rs index 3a0a49e..157d1f7 100644 --- a/src/traits/coding_trait.rs +++ b/src/traits/coding_trait.rs @@ -172,7 +172,7 @@ pub trait CodingTrait { /// /// ``` /// 从slice的开头解码一个32位的变长整数, 并将slice的索引置于解码后的位置 - fn varint_length(value: u64) -> i32; + fn varint_length(value: usize) -> usize; /// 32位定长正整数编码 /// /// # Arguments diff --git a/src/util/arena_test.rs b/src/util/arena_test.rs index fc800e1..dbc8cf1 100644 --- a/src/util/arena_test.rs +++ b/src/util/arena_test.rs @@ -1,4 +1,4 @@ - +use crate::util::Arena; #[test] fn test_memory_usage() { diff --git a/src/util/coding.rs b/src/util/coding.rs index d05abf7..220148e 100644 --- a/src/util/coding.rs +++ b/src/util/coding.rs @@ -1,3 +1,4 @@ +use std::io::Write; use crate::traits::coding_trait::CodingTrait; use crate::traits::coding_trait::Coding32; use crate::traits::coding_trait::Coding64; @@ -25,11 +26,7 @@ macro_rules! varint { pub struct Coding {} impl CodingTrait for Coding { -<<<<<<< HEAD fn put_fixed32(dst: &mut [u8], mut offset: usize, value: u32) -> usize { -======= - fn put_fixed32(dst: &mut String, value: u32) { ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb let mut buf: [u8; 4] = [0, 0, 0, 0]; Self::encode_fixed32(value, &mut buf, 0); dst[offset] = buf[0]; @@ -42,11 +39,7 @@ impl CodingTrait for Coding { offset } -<<<<<<< HEAD fn put_fixed64(dst: &mut [u8], mut offset: usize, value: u64) -> usize { -======= - fn put_fixed64(dst: &mut String, value: u64) { ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; Self::encode_fixed64(value, &mut buf, 0); dst[offset] = buf[0]; @@ -71,11 +64,7 @@ impl CodingTrait for Coding { varint!(u64,encode_varint64); -<<<<<<< HEAD fn put_varint32(dst: &mut [u8], mut offset: usize, value: u32) -> usize { -======= - fn put_varint32(dst: &mut String, value: u32) { ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb let mut buf: [u8; 4] = [0, 0, 0, 0]; let var_offset = Self::encode_varint32(value, &mut buf, 0); for i in 0..var_offset { @@ -85,11 +74,7 @@ impl CodingTrait for Coding { offset } -<<<<<<< HEAD fn put_varint64(dst: &mut [u8], mut offset: usize, value: u64) -> usize { -======= - fn put_varint64(dst: &mut String, value: u64) { ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; let var_offset = Self::encode_varint64(value, &mut buf, 0); for i in 0..var_offset { @@ -149,7 +134,7 @@ impl CodingTrait for Coding { Slice::from_buf(decode.to_le_bytes().as_mut_slice()) } - fn varint_length(mut value: u64) -> i32 { + fn varint_length(mut value: usize) -> usize { let mut len = 1; while value >= 128 { value >>= 7; @@ -159,35 +144,13 @@ impl CodingTrait for Coding { } fn encode_fixed32(value: u32, buf: &mut [u8], mut offset: usize) -> usize { - buf[offset] = value as u8; - offset += 1; - buf[offset] = (value >> 8) as u8; - offset += 1; - buf[offset] = (value >> 16) as u8; - offset += 1; - buf[offset] = (value >> 24) as u8; - offset += 1; - offset + (&mut buf[offset..]).write(&value.to_le_bytes()).unwrap(); + offset+4 } fn encode_fixed64(value: u64, buf: &mut [u8], mut offset: usize) -> usize { - buf[offset] = value as u8; - offset += 1; - buf[offset] = (value >> 8) as u8; - offset += 1; - buf[offset] = (value >> 16) as u8; - offset += 1; - buf[offset] = (value >> 24) as u8; - offset += 1; - buf[offset] = (value >> 32) as u8; - offset += 1; - buf[offset] = (value >> 40) as u8; - offset += 1; - buf[offset] = (value >> 48) as u8; - offset += 1; - buf[offset] = (value >> 56) as u8; - offset += 1; - offset + (&mut buf[offset..]).write(&value.to_le_bytes()).unwrap(); + offset+8 } @@ -213,11 +176,6 @@ impl CodingTrait for Coding { macro_rules! coding_impl { {$TRAIT: ident, $TYPE: ty, $VAR_NAME: ident, $FIXED_NAME: ident} => { impl $TRAIT for $TYPE { -<<<<<<< HEAD - fn varint(self, buf: &mut [u8], offset: usize) -> usize { - Coding::$VAR_NAME (self, buf, offset) - } -======= /// 变长正整数编码 /// /// # Arguments @@ -253,7 +211,6 @@ macro_rules! coding_impl { /// let value: u32 = 65534; /// let offset = value.fixedint(&mut buf, 0); /// ``` ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb fn fixedint(self, buf: &mut [u8], offset: usize) -> usize { Coding::$FIXED_NAME (self, buf, offset) } diff --git a/src/util/coding_test.rs b/src/util/coding_test.rs index 96ea2f7..1531ad0 100644 --- a/src/util/coding_test.rs +++ b/src/util/coding_test.rs @@ -1,12 +1,6 @@ mod test { -<<<<<<< HEAD use crate::traits::coding_trait::{Coding32, Coding64, CodingTrait}; use crate::util::coding::{Coding}; -======= - - - ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb #[test] fn test_put_fixed32() { @@ -133,7 +127,7 @@ mod test { #[test] fn test_varint_length() { - let len = Coding::varint_length( 65535 as u64); + let len = Coding::varint_length(65535 as u64 as usize); println!("len: {:?}", len); assert_eq!(len, 3); } diff --git a/src/util/comparator_test.rs b/src/util/comparator_test.rs index 87bc67d..d6d311b 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -1,18 +1,10 @@ mod test { -<<<<<<< HEAD use std::cmp::Ordering; use std::io::Write; use crate::traits::comparator_trait::Comparator; use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::slice::Slice; -======= - - - - - ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb // ##################### BytewiseComparatorImpl test #[test] diff --git a/src/util/crc_test.rs b/src/util/crc_test.rs index e304450..c67c0db 100644 --- a/src/util/crc_test.rs +++ b/src/util/crc_test.rs @@ -1,5 +1,5 @@ - - +use crate::util::crc::{AsCrc, CRC, ToMask}; +use crate::util::slice::Slice; #[test] fn test_crc() { diff --git a/src/util/filter_policy.rs b/src/util/filter_policy.rs index 56f048c..f493364 100644 --- a/src/util/filter_policy.rs +++ b/src/util/filter_policy.rs @@ -1,11 +1,7 @@ use std::ops::{BitOr, Mul, Shl}; use crate::traits::filter_policy_trait::{FilterPolicy}; -<<<<<<< HEAD use crate::util::hash::{Hash, ToHash}; use crate::util::r#const::HASH_DEFAULT_SEED; -======= -use crate::util::hash::{ToHash}; ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb use crate::util::slice::Slice; pub trait FromPolicy { @@ -23,8 +19,9 @@ pub trait AsBloomHash { /// 实现了 Slice 转 bloom_hash 的特质 /// Sample: /// ``` -/// let val = "aabbccd"; -/// let slice: Slice = Slice::from_buf(val.as_bytes()); +/// use rand::distributions::Slice; +/// let val = "aabbccd"; +/// let slice = Slice::from_buf(val.as_bytes()); /// let hash_val = slice.bloom_hash(); /// ``` impl AsBloomHash for Slice { @@ -85,7 +82,6 @@ impl FilterPolicy for BloomFilterPolicy { String::from("leveldb.BuiltinBloomFilter2") } -<<<<<<< HEAD fn create_filter(&self, keys: Vec) -> Slice { let n: usize = keys.len(); @@ -178,12 +174,6 @@ impl FilterPolicy for InternalFilterPolicy { } fn create_filter(&self, keys: Vec) -> Slice { - todo!() - } - - fn key_may_match(&self, key: &Slice, bloom_filter: &Slice) -> bool { -======= - fn create_filter(&self, _keys: Slice, _n: u32, _dst: String) -> String { // 根据指定的参数创建过滤器,并返回结果, 结果为dst的原始内容 + append结果。 // 参数keys[0,n-1]包含依据用户提供的comparator排序的key列表--可重复, // 并把根据这些key创建的filter追加到 dst中。 @@ -191,8 +181,8 @@ impl FilterPolicy for InternalFilterPolicy { todo!() } - fn key_may_match(_key: &Slice, _filter: &Slice) -> bool { ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb + fn key_may_match(&self, key: &Slice, bloom_filter: &Slice) -> bool { todo!() } + } \ No newline at end of file diff --git a/src/util/filter_policy_test.rs b/src/util/filter_policy_test.rs index dd94fe4..e84ee12 100644 --- a/src/util/filter_policy_test.rs +++ b/src/util/filter_policy_test.rs @@ -1,4 +1,3 @@ -<<<<<<< HEAD use std::ptr::null; use crate::traits::filter_policy_trait::FilterPolicy; use crate::util::bloom_filter; @@ -28,20 +27,6 @@ fn test_new() { assert_eq!(bloom_filter.from_bits_per_key(), 800); assert_eq!(bloom_filter.from_k(), 30); } -======= - - - - -#[test] -fn test_new() { - let _bloom_filter = BloomFilterPolicy::new(8); - println!("hash:{}", "a"); - // assert_eq!(bloom_filter, null()); - - let _bloom_filter = BloomFilterPolicy::new(800); - println!("hash:{}", "a"); ->>>>>>> 7ab46579f8abd8c45c40227dfb601ec7468625eb // #################### FilterPolicy test #[test] diff --git a/src/util/hash_test.rs b/src/util/hash_test.rs index e0961d0..28bf95d 100644 --- a/src/util/hash_test.rs +++ b/src/util/hash_test.rs @@ -1,7 +1,6 @@ - - - - +use crate::util::hash::{Hash, ToHash}; +use crate::util::r#const::HASH_DEFAULT_SEED; +use crate::util::slice::Slice; #[test] fn test_hash() { diff --git a/src/util/histogram_test.rs b/src/util/histogram_test.rs index 74e9033..a4f01e7 100644 --- a/src/util/histogram_test.rs +++ b/src/util/histogram_test.rs @@ -1,6 +1,6 @@ mod test{ - + use crate::util::histogram::Histogram; #[test] fn test_add() { diff --git a/src/util/mutex_lock_test.rs b/src/util/mutex_lock_test.rs index 548871f..f442b37 100644 --- a/src/util/mutex_lock_test.rs +++ b/src/util/mutex_lock_test.rs @@ -1,7 +1,6 @@ mod test { - - - + use std::thread; + use crate::util::mutex_lock::MutexLock; #[test] fn test() { diff --git a/src/util/slice.rs b/src/util/slice.rs index 64b45d7..f172c83 100644 --- a/src/util/slice.rs +++ b/src/util/slice.rs @@ -121,6 +121,13 @@ impl<'a> Slice { } } +impl Clone for Slice { + fn clone(&self) -> Self { + let data = self.data.clone(); + Slice::from_vec(data) + } +} + impl From for String { /// 将 Slice 内数据的所有权移交给 String #[inline] diff --git a/src/util/slice_test.rs b/src/util/slice_test.rs index 75ae7a7..9baf1d1 100644 --- a/src/util/slice_test.rs +++ b/src/util/slice_test.rs @@ -1,5 +1,5 @@ mod test { - + use std::cmp::Ordering; use crate::util::slice::Slice; #[test] diff --git a/src/util/status.rs b/src/util/status.rs index 8c51782..9a25887 100644 --- a/src/util/status.rs +++ b/src/util/status.rs @@ -1,6 +1,7 @@ use std::fmt::{Display, Formatter}; use std::io; use std::ops::Deref; +use std::sync::PoisonError; use crate::util::r#const::COLON_WHITE_SPACE; use crate::util::slice::Slice; use crate::util::status::LevelError::{KCorruption, KIOError, KInvalidArgument, KNotSupported, KNotFound, KOk, KBadRecord, KRepeatedRecord}; @@ -389,6 +390,12 @@ impl From for Status { } } +impl From> for Status { + fn from(_value: PoisonError) -> Self { + Status::wrapper(KCorruption, "PoisonError".into()) + } +} + impl Display for LevelError { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/src/util/status_test.rs b/src/util/status_test.rs index 7cf0698..baad832 100644 --- a/src/util/status_test.rs +++ b/src/util/status_test.rs @@ -1,8 +1,8 @@ mod test { - - - + use crate::util::r#const::COLON_WHITE_SPACE; + use crate::util::slice::Slice; + use crate::util::status::{LevelError, Status}; #[test] fn test_wraper() { -- Gitee