From ec1d3c4b48aa8bc774d98e74362891d68974649d Mon Sep 17 00:00:00 2001 From: fengyang Date: Tue, 17 Jan 2023 18:35:19 +0800 Subject: [PATCH] =?UTF-8?q?LookupKey=20=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/db_format.rs | 262 ++++++++++++++++++++++++++++++------ src/db/db_format_test.rs | 3 +- src/db/mem_table.rs | 1 - src/db/mod.rs | 3 +- src/util/comparator.rs | 43 ------ src/util/comparator_test.rs | 2 +- src/util/mod.rs | 2 +- 7 files changed, 226 insertions(+), 90 deletions(-) diff --git a/src/db/db_format.rs b/src/db/db_format.rs index d69d626..87c7701 100644 --- a/src/db/db_format.rs +++ b/src/db/db_format.rs @@ -1,38 +1,9 @@ +use std::cmp::Ordering; use std::ops::Deref; use crate::db::db_format::ValueType::{K_TYPE_DELETION, K_TYPE_VALUE}; +use crate::traits::comparator_trait::Comparator; use crate::util::slice::Slice; -/// Maximum encoding length of a BlockHandle -pub const k_num_levels: usize = 7; - -// Level-0 compaction is started when we hit this many files. -pub const kl0_compaction_trigger: usize = 4; - -// Soft limit on number of level-0 files. We slow down writes at this point. -pub const kl0_slowdown_writes_trigger: usize = 8; - -// Maximum number of level-0 files. We stop writes at this point. -pub const kL0_stop_writes_trigger: usize = 12; - -// Maximum level to which a new compacted memtable is pushed if it -// does not create overlap. We try to push to level 2 to avoid the -// relatively expensive level 0=>1 compactions and to avoid some -// expensive manifest file operations. We do not push all the way to -// the largest level since that can generate a lot of wasted disk -// space if the same key space is being repeatedly overwritten. -pub const k_max_mem_compact_level: usize = 2; - -// Approximate gap in bytes between samples of data read during iteration. -pub const k_read_bytes_period: usize = 1048576; - -// kValueTypeForSeek defines the ValueType that should be passed when -// constructing a ParsedInternalKey object for seeking to a particular -// sequence number (since we sort sequence numbers in decreasing order -// 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 enum ValueType { /// 0x0 K_TYPE_DELETION, @@ -51,6 +22,30 @@ pub struct InternalKey { rep_: Slice } +/// InternalKeyComparator +pub struct InternalKeyComparator { + user_comparator_: dyn Comparator +} + +/// 查找键 +// 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], +} + impl ValueType { pub fn get_value(&self) -> i32 { let le = match self { @@ -102,13 +97,6 @@ impl Default for ParsedInternalKey { } impl ParsedInternalKey { - fn new(u: Slice, seq: u64, t: ValueType) -> Self { - Self { - user_key: u, - sequence: seq, - value_type: t, - } - } fn debug_string(&self) -> Slice { Slice::default() @@ -119,23 +107,213 @@ impl ParsedInternalKey { key.user_key.size() + 8 } - fn append_internal_key(&self, key : ParsedInternalKey) -> Slice { + // 将 self 的数据追加到 result 中 + fn append_internal_key(&self, result: Slice) { todo!() } + fn new(user_key: Slice, sequence: u64, value_type: ValueType) -> Self { + Self { + user_key, + sequence, + value_type, + } + } + /// Attempt to parse an internal key from "internal_key". On success, /// stores the parsed data in "*result", and returns true. /// On error, returns false, leaves "*result" in an undefined state. - fn parse_internal_key(&self, internal_key : Slice, target: ParsedInternalKey) -> bool { + fn parse_internal_key(internal_key : Slice, target: ParsedInternalKey) -> bool { + // line 173 todo!() } /// Returns the user key portion of an internal key. - fn extract_user_key(&self, internal_key : Slice) -> Slice { + fn extract_user_key(internal_key : Slice) -> Slice { todo!() } } +impl Default for InternalKey { + #[inline] + fn default() -> Self { + Self { + rep_: Slice::default() + } + } +} + impl InternalKey { - // line139 + fn new(user_key: Slice, sequence: u64, value_type: ValueType) -> Self { + // line 145 + let result: Slice = Slice::default(); + ParsedInternalKey::new(user_key, sequence, value_type) + .append_internal_key(result); + + Self{ + // rep_: result + // todo result值如何赋值 + rep_: Slice::default() + } + } + + /// + /// xxx + /// + /// # Arguments + /// * `input`: + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn decode_from(&self, input: Slice) { + todo!() + + // wangbo + // self.rep_.assign(input.borrow_data().bytes()); + } + + /// 输出 InternalKey 调试信息 + fn debug_string(&self) -> Slice { + // line 164 + todo!() + } + + fn encode(self) -> Slice { + self.rep_ + } + + fn user_key(self) -> Slice { + ParsedInternalKey::extract_user_key(self.rep_) + } + + fn set_from(self, p: ParsedInternalKey) { + // self.rep_.clear(); + p.append_internal_key(self.rep_); + } + + fn clear(self) { + // self.rep_.clear(); + } +} + +impl InternalKeyComparator { + fn new(c: Box) -> Box { + todo!() + } + + fn user_comparator(&self) -> Box { + todo!() + } + + fn compare(&self, a: InternalKey, b: InternalKey) -> u32 { + // line 122, 167 + todo!() + } +} + +/// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 +/// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 +impl Comparator for InternalKeyComparator { + // fn new(c: Box) -> InternalKeyComparator { + // todo!() + // } + + fn compare(&self, _a: &Slice, _b: &Slice) -> Option { + todo!() + } + + fn get_name(&self) -> 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!() + } +} + +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!() + } + + /// Return a key suitable for lookup in a MemTable. + fn mem_table_key(&self) -> Slice { + todo!() + } + + /// Return an internal key (suitable for passing to an internal iterator) + fn internal_key(&self) -> Slice { + // line 204 + todo!() + } + + /// Return the user key + fn user_key(&self) -> Slice { + // line 207 + todo!() + } +} + +// like ~LookupKey() +// impl Drop for LookupKey { +// fn drop(&mut self) { +// todo!() +// } +// } +// +// impl Default for LookupKey { +// #[inline] +// fn default() -> Self { +// Self { +// start_: Default::default(), +// kstart_: Default::default(), +// end_: Default::default(), +// space_: [u8; 200], +// } +// } +// } + + +pub struct Config {} +impl Config { + /// Maximum encoding length of a BlockHandle + pub const K_NUM_LEVELS: usize = 7; + + // Level-0 compaction is started when we hit this many files. + pub const KL0_COMPACTION_TRIGGER: usize = 4; + + // Soft limit on number of level-0 files. We slow down writes at this point. + pub const KL0_SLOWDOWN_WRITES_TRIGGER: usize = 8; + + // Maximum number of level-0 files. We stop writes at this point. + pub const K_L0_STOP_WRITES_TRIGGER: usize = 12; + + // Maximum level to which a new compacted memtable is pushed if it +// does not create overlap. We try to push to level 2 to avoid the +// relatively expensive level 0=>1 compactions and to avoid some +// expensive manifest file operations. We do not push all the way to +// the largest level since that can generate a lot of wasted disk +// space if the same key space is being repeatedly overwritten. + pub const K_MAX_MEM_COMPACT_LEVEL: usize = 2; + + // Approximate gap in bytes between samples of data read during iteration. + pub const K_READ_BYTES_PERIOD: usize = 1048576; + + // kValueTypeForSeek defines the ValueType that should be passed when +// constructing a ParsedInternalKey object for seeking to a particular +// sequence number (since we sort sequence numbers in decreasing order +// 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; } \ No newline at end of file diff --git a/src/db/db_format_test.rs b/src/db/db_format_test.rs index 1f987ff..da87a75 100644 --- a/src/db/db_format_test.rs +++ b/src/db/db_format_test.rs @@ -1,5 +1,6 @@ +use crate::db::db_format::Config; #[test] fn test_db_format() { - todo!() + Config::K_NUM_LEVELS; } \ No newline at end of file diff --git a/src/db/mem_table.rs b/src/db/mem_table.rs index b9720c2..e0d99ce 100644 --- a/src/db/mem_table.rs +++ b/src/db/mem_table.rs @@ -1,7 +1,6 @@ use std::rc::Rc; use crate::traits::comparator_trait::Comparator; use crate::traits::DataIterator; -use crate::util::comparator::InternalKeyComparator; use crate::util::slice::Slice; use crate::util::Result; diff --git a/src/db/mod.rs b/src/db/mod.rs index e07b93e..d9f915b 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,6 +1,7 @@ +use crate::db::db_format::InternalKeyComparator; use crate::db::skip_list::SkipList; use crate::db::mem_table::MemTable; -use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; +use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::slice::Slice; pub mod log_writer; diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 1f9bbf7..5159a95 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -88,46 +88,3 @@ impl Comparator for BytewiseComparatorImpl { Slice::from_buf(key.as_bytes()).into() } } - -/// InternalKeyComparator -pub struct InternalKeyComparator { - user_comparator_: dyn Comparator -} - -impl InternalKeyComparator { - fn new(c: Box) -> Box { - todo!() - } - - fn user_comparator() -> Box { - todo!() - } - - // fn compare(a: InternalKey, b: InternalKey) -> u32 { - // todo!() - // } -} - -/// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 -/// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 -impl Comparator for InternalKeyComparator { - // fn new(c: Box) -> InternalKeyComparator { - // todo!() - // } - - fn compare(&self, _a: &Slice, _b: &Slice) -> Option { - todo!() - } - - fn get_name(&self) -> 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 12d570f..e1ad1b6 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::Comparator; - use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; + use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::slice::Slice; // ##################### BytewiseComparatorImpl test diff --git a/src/util/mod.rs b/src/util/mod.rs index 384d687..bd12ce0 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -3,7 +3,7 @@ use std::result; pub use arena::Arena; -use crate::util::comparator::{BytewiseComparatorImpl, InternalKeyComparator}; +use crate::util::comparator::{BytewiseComparatorImpl}; use crate::util::status::Status; /// 常量定义 -- Gitee