From 56fda212bcd1ccf17c6ae57968322c44e90b7016 Mon Sep 17 00:00:00 2001 From: fengyang Date: Tue, 17 Jan 2023 11:39:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?BlockHandle=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/log_writer.rs | 2 +- src/table/format.rs | 120 +++++++++++++++++++++++++++++++++++++++++++ src/table/mod.rs | 1 + src/util/mod.rs | 4 +- 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 src/table/format.rs diff --git a/src/db/log_writer.rs b/src/db/log_writer.rs index 42406db..48e567c 100644 --- a/src/db/log_writer.rs +++ b/src/db/log_writer.rs @@ -79,7 +79,7 @@ impl LogWriter { header[6] = record_type; let mut crc = CRC::extend(self.type_crc[record_type as usize], data); crc = CRC::mask(crc); - Coding::encode_fixed32(crc, header.as_mut(), 0); + Coding::encode_fixed32(&mut crc, header.as_mut(), 0); self.file_writer.write(header.as_ref())?; self.block_offset += K_HEADER_SIZE; if !data.is_empty() { diff --git a/src/table/format.rs b/src/table/format.rs new file mode 100644 index 0000000..17c0f8f --- /dev/null +++ b/src/table/format.rs @@ -0,0 +1,120 @@ +use crate::traits::coding_trait::CodingTrait; +use crate::util::coding; +use crate::util::slice::Slice; +use crate::util::Result; + +/// Maximum encoding length of a BlockHandle +pub const k_max_encoded_length: u32 = 10 + 10; + +// // kTableMagicNumber was picked by running +// // echo http://code.google.com/p/leveldb/ | sha1sum +// // and taking the leading 64 bits. +// pub const k_table_magic_number: &str = 0xdb4775248b80fb57ull; + +pub struct BlockHandle { + // 偏移量 + offset_: u64, + // + size_: u64 +} + +/// Footer encapsulates the fixed information stored at the tail +/// end of every table file. +pub struct Footer { + metaindex_handle_: BlockHandle, + index_handle_: BlockHandle +} + +trait Block { + /// + /// The offset of the block in the file. + /// + fn offset(&self) -> u64; + + /// + /// set offset + /// # Arguments + /// + /// * `offset`: + /// + fn set_offset(&mut self, offset: u64); + + // The size of the stored block + fn size(&self) -> u64; + + /// + /// set size + /// # Arguments + /// + /// * `size`: + /// + fn set_size(&mut self, size: u64); + + /// + /// 将 Block 对象编码成 Slice + /// + /// # Arguments + /// + /// returns: Slice + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn encode_to(&self) -> Slice; + + /// + /// 将 Slice 对象解码后与BlockHandle比较,是否可以成功 + /// + /// # Arguments + /// * `input`: + /// + /// returns: Result + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn decode_from(&self, input: Slice) -> Result; +} + +trait Foot { + +} + +impl Block for BlockHandle { + fn offset(&self) -> u64 { + self.offset_ + } + + fn set_offset(&mut self, offset: u64) { + self.offset_ = offset; + } + + fn size(&self) -> u64 { + self.size_ + } + + fn set_size(&mut self, size: u64) { + self.size_ = size; + } + + fn encode_to(&self) -> Slice { + todo!() + + // // Sanity check that all fields have been set + // assert!(self.offset_ != 0); + // assert!(self.size_ != 0); + // + // let mut buf: [u8; 4] = [0, 0, 0, 0]; + // coding::Coding::put_varint64(&mut buf, 0, &self.offset_); + // + // Slice::default() + } + + fn decode_from(&self, input: Slice) -> Result { + todo!() + } +} \ No newline at end of file diff --git a/src/table/mod.rs b/src/table/mod.rs index e69de29..8da6115 100644 --- a/src/table/mod.rs +++ b/src/table/mod.rs @@ -0,0 +1 @@ +pub mod format; \ No newline at end of file diff --git a/src/util/mod.rs b/src/util/mod.rs index 2808228..26de74d 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -29,9 +29,9 @@ mod filter_policy_test; pub mod histogram; mod histogram_test; -mod hash; +pub mod hash; mod hash_test; -mod mutex_lock; +pub mod mutex_lock; mod mutex_lock_test; /// 定义别名 -- Gitee From 31ba785176120570be714b1d00d37b77e7145abb Mon Sep 17 00:00:00 2001 From: fengyang Date: Tue, 17 Jan 2023 15:18:31 +0800 Subject: [PATCH 2/4] =?UTF-8?q?BloomFilterPolicy=20=E6=89=A9=E5=B1=95=20As?= =?UTF-8?q?BloomHash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/table/format.rs | 2 +- src/table/format_test.rs | 7 ++++ src/table/mod.rs | 3 +- src/util/filter_policy.rs | 62 +++++++++++++++++++++++----------- src/util/filter_policy_test.rs | 6 ++-- 5 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 src/table/format_test.rs diff --git a/src/table/format.rs b/src/table/format.rs index 17c0f8f..26324c7 100644 --- a/src/table/format.rs +++ b/src/table/format.rs @@ -114,7 +114,7 @@ impl Block for BlockHandle { // Slice::default() } - fn decode_from(&self, input: Slice) -> Result { + fn decode_from(&self, input: Slice) -> Result { todo!() } } \ No newline at end of file diff --git a/src/table/format_test.rs b/src/table/format_test.rs new file mode 100644 index 0000000..c01c885 --- /dev/null +++ b/src/table/format_test.rs @@ -0,0 +1,7 @@ + + +// #################### BlockHandle test +#[test] +fn test_block_handle() { + +} \ No newline at end of file diff --git a/src/table/mod.rs b/src/table/mod.rs index 8da6115..149cdbe 100644 --- a/src/table/mod.rs +++ b/src/table/mod.rs @@ -1 +1,2 @@ -pub mod format; \ No newline at end of file +pub mod format; +mod format_test; \ No newline at end of file diff --git a/src/util/filter_policy.rs b/src/util/filter_policy.rs index 07b33b2..912dbaa 100644 --- a/src/util/filter_policy.rs +++ b/src/util/filter_policy.rs @@ -1,35 +1,26 @@ use std::ops::{BitOr, Mul, Shl}; use crate::traits::filter_policy_trait::{FilterPolicy}; use crate::util::hash::{Hash, ToHash}; +use crate::util::r#const::HASH_DEFAULT_SEED; use crate::util::slice::Slice; pub trait FromPolicy { fn from_bits_per_key(&self) -> usize; + fn from_k(&self) -> usize; } +/// 其他成员的语义扩展 +pub trait AsBloomHash { + #[inline] + fn bloom_hash(&self) -> u32; +} + pub struct BloomFilterPolicy { bits_per_key: usize, k: usize } -impl<'a> BloomFilterPolicy { - pub fn bloom_hash(key: &Slice) -> u32 { - key.to_hash_with_seed(0xbc9f1d34) - } -} - -/// get struct BloomFilterPolicy 属性 -impl FromPolicy for BloomFilterPolicy { - fn from_bits_per_key(&self) -> usize { - self.bits_per_key - } - - fn from_k(&self) -> usize { - self.k - } -} - impl BloomFilterPolicy { pub fn new(bits_per_key: usize) -> Self { // We intentionally round down to reduce probing cost a little bit @@ -51,6 +42,23 @@ impl BloomFilterPolicy { } } +impl<'a> BloomFilterPolicy { + pub fn bloom_hash(key: &Slice) -> u32 { + key.to_hash_with_seed(HASH_DEFAULT_SEED) + } +} + +/// get struct BloomFilterPolicy 属性 +impl FromPolicy for BloomFilterPolicy { + fn from_bits_per_key(&self) -> usize { + self.bits_per_key + } + + fn from_k(&self) -> usize { + self.k + } +} + // dyn FilterPolicy + FromPolicy impl FilterPolicy for BloomFilterPolicy { @@ -76,7 +84,9 @@ impl FilterPolicy for BloomFilterPolicy { dst_chars[bytes] = self.k as u8; for i in 0..n { - let mut h : u32 = BloomFilterPolicy::bloom_hash(keys.get(i).unwrap()); + let slice = keys.get(i).unwrap(); + + let mut h : u32 = slice.bloom_hash(); let delta : u32 = (h >> 17) | (h << 15); for j in 0..self.k { @@ -113,7 +123,7 @@ impl FilterPolicy for BloomFilterPolicy { return true; } - let mut h : u32 = BloomFilterPolicy::bloom_hash(key); + let mut h : u32 = key.bloom_hash(); // Rotate right 17 bits let delta = (h >> 17) | (h << 15); @@ -128,4 +138,18 @@ impl FilterPolicy for BloomFilterPolicy { return true; } +} + +/// 实现了 Slice 转 bloom_hash 的特质 +/// Sample: +/// ``` +/// let val = "aabbccd"; +/// let slice: Slice = Slice::from_buf(val.as_bytes()); +/// let hash_val = slice.bloom_hash(); +/// ``` +impl AsBloomHash for Slice { + #[inline] + fn bloom_hash(&self) -> u32 { + BloomFilterPolicy::bloom_hash(self) + } } \ No newline at end of file diff --git a/src/util/filter_policy_test.rs b/src/util/filter_policy_test.rs index 280f19e..e84ee12 100644 --- a/src/util/filter_policy_test.rs +++ b/src/util/filter_policy_test.rs @@ -1,7 +1,8 @@ use std::ptr::null; use crate::traits::filter_policy_trait::FilterPolicy; use crate::util::bloom_filter; -use crate::util::filter_policy::{BloomFilterPolicy, FromPolicy}; +use crate::util::filter_policy::{AsBloomHash, BloomFilterPolicy, FromPolicy}; +use crate::util::hash::ToHash; use crate::util::slice::Slice; // #################### BloomFilterPolicy test @@ -11,6 +12,8 @@ fn test_bloom_hash() { let slice: Slice = Slice::from_buf(val.as_bytes()); let hash_val = BloomFilterPolicy::bloom_hash(&slice); + let hash_val_1 = slice.bloom_hash(); + assert_eq!(hash_val, hash_val_1); assert_eq!(hash_val, 2085241752); } @@ -23,7 +26,6 @@ fn test_new() { let bloom_filter = BloomFilterPolicy::new(800); assert_eq!(bloom_filter.from_bits_per_key(), 800); assert_eq!(bloom_filter.from_k(), 30); - } // #################### FilterPolicy test -- Gitee From d9aa56d677cd0b71d70bb9867e5f79d18d2ae2f3 Mon Sep 17 00:00:00 2001 From: fengyang Date: Tue, 17 Jan 2023 16:13:35 +0800 Subject: [PATCH 3/4] =?UTF-8?q?db=5Fformat=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 | 115 +++++++++++++++++++++++++++++++++++++++ src/db/db_format_test.rs | 5 ++ src/db/mod.rs | 2 + src/table/format.rs | 110 ++++++++++++++++++++++++++++++++++++- src/table/format_test.rs | 2 +- src/util/status.rs | 33 +++++------ src/util/status_test.rs | 12 ++-- 7 files changed, 255 insertions(+), 24 deletions(-) create mode 100644 src/db/db_format.rs create mode 100644 src/db/db_format_test.rs diff --git a/src/db/db_format.rs b/src/db/db_format.rs new file mode 100644 index 0000000..cfc16d2 --- /dev/null +++ b/src/db/db_format.rs @@ -0,0 +1,115 @@ +use std::ops::Deref; +use crate::db::db_format::ValueType::{K_TYPE_DELETION, K_TYPE_VALUE}; +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, + + /// 0x1 + K_TYPE_VALUE, +} + +// typedef uint64_t SequenceNumber; + +pub struct ParsedInternalKey { + user_key: Slice, + // sequence: SequenceNumber, + value_type: ValueType +} + +impl ValueType { + pub fn get_value(&self) -> i32 { + let le = match self { + K_TYPE_DELETION => 0, + K_TYPE_VALUE => 1 + }; + + le + } +} + +impl TryFrom for ValueType { + type Error = String; + + /// i32 转 ValueType + /// + /// # Arguments + /// + /// * `value`: 值 + /// + /// returns: Result>::Error> + /// + /// # Examples + /// + /// ``` + /// let rs: ValueType = ValueType::try_from(1)?; + /// assert!(&rs == K_TYPE_DELETION); + /// ``` + #[inline] + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(K_TYPE_DELETION), + 1 => Ok(K_TYPE_VALUE), + // all other numbers + _ => Err(String::from(format!("Unknown code: {}", value))) + } + } +} + +impl Default for ParsedInternalKey { + #[inline] + fn default() -> Self { + ParsedInternalKey { + user_key: Default::default(), + value_type: K_TYPE_DELETION, + } + } +} + +impl ParsedInternalKey { + fn new(u: Slice, /* seq: SequenceNumber, */ t: ValueType) -> ParsedInternalKey { + ParsedInternalKey { + user_key: u, + value_type: t, + } + } + + fn debug_string() -> Slice { + Slice::default() + } +} + +// line 86 +//. \ No newline at end of file diff --git a/src/db/db_format_test.rs b/src/db/db_format_test.rs new file mode 100644 index 0000000..1f987ff --- /dev/null +++ b/src/db/db_format_test.rs @@ -0,0 +1,5 @@ + +#[test] +fn test_db_format() { + todo!() +} \ No newline at end of file diff --git a/src/db/mod.rs b/src/db/mod.rs index 5a34cf6..fa818b7 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -9,6 +9,8 @@ mod log_wr_test; pub mod skip_list; pub mod mem_table; pub mod db; +pub mod db_format; +mod db_format_test; /// 默认调表 pub type DefaultSkipList = SkipList; diff --git a/src/table/format.rs b/src/table/format.rs index 26324c7..9a64d4b 100644 --- a/src/table/format.rs +++ b/src/table/format.rs @@ -6,11 +6,19 @@ use crate::util::Result; /// Maximum encoding length of a BlockHandle pub const k_max_encoded_length: u32 = 10 + 10; +/// Encoded length of a Footer. Note that the serialization of a +/// Footer will always occupy exactly this many bytes. It consists +/// of two block handles and a magic number. +pub const k_encoded_length: u32 = 2 * k_max_encoded_length + 8; + // // kTableMagicNumber was picked by running // // echo http://code.google.com/p/leveldb/ | sha1sum // // and taking the leading 64 bits. // pub const k_table_magic_number: &str = 0xdb4775248b80fb57ull; +/// 1-byte type + 32-bit crc +pub const k_block_trailer_size: usize = 5; + pub struct BlockHandle { // 偏移量 offset_: u64, @@ -25,6 +33,17 @@ pub struct Footer { index_handle_: BlockHandle } +pub struct BlockContents { + // Actual contents of data + data: Slice, + + // True if data can be cached + cachable: bool, + + // True if caller should delete[] data.data() + heap_allocated:bool, +} + trait Block { /// /// The offset of the block in the file. @@ -81,6 +100,53 @@ trait Block { } trait Foot { + // The block handle for the metaindex block of the table + fn metaindex_handle() -> BlockHandle; + + fn set_metaindex_handle(h: BlockHandle); + + fn index_handle() -> BlockHandle; + + fn set_index_handle(h: BlockHandle); + + /// + /// 将 Foot 对象编码成 Slice + /// + /// # Arguments + /// + /// returns: Slice + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn encode_to(&self) -> Slice; + + /// + /// 将 Slice 对象解码后与 BlockHandle 比较,是否可以成功 + /// + /// # Arguments + /// * `input`: + /// + /// returns: Result + /// + /// # Examples + /// + /// ``` + /// + /// ``` + fn decode_from(&self, input: Slice) -> Result; +} + +trait BlockContent { + /// Read the block identified by "handle" from "file". On failure + /// return non-OK. On success fill *result and return OK. + fn read_block( + // todo RandomAccessFile, ReadOptions 未提供 + // file: RandomAccessFile, options: ReadOptions, + handle: BlockHandle + ) -> Result; } @@ -117,4 +183,46 @@ impl Block for BlockHandle { fn decode_from(&self, input: Slice) -> Result { todo!() } -} \ No newline at end of file +} + +impl Default for BlockHandle { + #[inline] + fn default() -> Self { + BlockHandle { + offset_: 0, + size_: 0, + } + } +} + +impl Foot for Footer { + fn metaindex_handle() -> BlockHandle { + todo!() + } + + fn set_metaindex_handle(h: BlockHandle) { + todo!() + } + + fn index_handle() -> BlockHandle { + todo!() + } + + fn set_index_handle(h: BlockHandle) { + todo!() + } + + fn encode_to(&self) -> Slice { + todo!() + } + + fn decode_from(&self, input: Slice) -> Result { + todo!() + } +} + +impl BlockContent for BlockContents { + fn read_block(handle: BlockHandle) -> Result { + todo!() + } +} diff --git a/src/table/format_test.rs b/src/table/format_test.rs index c01c885..e106bee 100644 --- a/src/table/format_test.rs +++ b/src/table/format_test.rs @@ -3,5 +3,5 @@ // #################### BlockHandle test #[test] fn test_block_handle() { - + todo!() } \ No newline at end of file diff --git a/src/util/status.rs b/src/util/status.rs index e7607f5..4af5597 100644 --- a/src/util/status.rs +++ b/src/util/status.rs @@ -1,5 +1,6 @@ use std::fmt::{Display, Formatter}; use std::io; +use std::ops::Deref; 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}; @@ -288,6 +289,20 @@ impl LevelError { msg } } + + pub fn get_value(&self) -> i32 { + let le = match self { + KOk => 0, + KNotFound => 1, + KCorruption => 2, + KNotSupported => 3, + KInvalidArgument => 4, + KIOError => 5, + KBadRecord => 6 + }; + + le + } } impl Default for LevelError { @@ -355,21 +370,3 @@ impl Display for LevelError { write!(f, "{}", print) } } - -// impl Deref for LevelError { -// type Target = i32; -// -// /// StatusTrait 解引用到 i32 -// fn deref(&self) -> &Self::Target { -// let le = match self { -// KOk => 0, -// KNotFound(_) => 1, -// KCorruption(_) => 2, -// KNotSupported(_) => 3, -// KInvalidArgument(_) => 4, -// KIOError(_) => 5, -// }; -// -// &*le -// } -// } \ No newline at end of file diff --git a/src/util/status_test.rs b/src/util/status_test.rs index 2ac1030..baad832 100644 --- a/src/util/status_test.rs +++ b/src/util/status_test.rs @@ -32,12 +32,10 @@ mod test { let err: Status = LevelError::invalid_argument(String::from(msg1).into(), String::from(msg2).into()); 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.is_corruption()); - // assert_eq!(err.into_code(), 2); let err: Status = LevelError::not_found(String::from(msg1).into(), String::from(msg2).into()); @@ -121,32 +119,38 @@ mod test { fn test_level_error_try_from() -> Result<(), String> { let rs = LevelError::try_from(1)?; assert!(&rs.is_not_found()); + assert_eq!(rs.get_value(), 1); let rs: Result = 1.try_into(); assert!(rs.ok().unwrap().is_not_found()); let rs = LevelError::try_from(0)?; assert!(&rs.is_ok()); + assert_eq!(rs.get_value(), 0); let rs: Result = 0.try_into(); assert!(rs.ok().unwrap().is_ok()); let rs = LevelError::try_from(2)?; assert!(&rs.is_corruption()); + assert_eq!(rs.get_value(), 2); let rs: LevelError = 2.try_into()?; assert!(rs.is_corruption()); let rs: LevelError = LevelError::try_from(3)?; assert!(&rs.is_not_supported_error()); + assert_eq!(rs.get_value(), 3); let rs: LevelError = 3.try_into()?; assert!(rs.is_not_supported_error()); let rs = LevelError::try_from(4)?; assert!(&rs.is_invalid_argument()); + assert_eq!(rs.get_value(), 4); let rs = LevelError::try_from(5)?; assert!(&rs.is_io_error()); + assert_eq!(rs.get_value(), 5); - let rs = LevelError::try_from(6); - assert_eq!("Unknown code: 6", rs.err().unwrap()); + let rs = LevelError::try_from(66); + assert_eq!("Unknown code: 66", rs.err().unwrap()); Ok(()) } -- Gitee From d71489b5a72ca33d451c28d5f425ce9d13db11be Mon Sep 17 00:00:00 2001 From: fengyang Date: Tue, 17 Jan 2023 16:32:46 +0800 Subject: [PATCH 4/4] =?UTF-8?q?ParsedInternalKey=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/db_format.rs | 24 +++++++++++++-- src/db/file_meta_data.rs | 11 +++++++ src/db/file_meta_data_test.rs | 5 ++++ src/db/mod.rs | 2 ++ src/table/mod.rs | 4 ++- src/table/ss_table.rs | 4 +++ src/table/ss_table_test.rs | 5 ++++ src/util/comparator.rs | 56 +++++++++++++++-------------------- src/util/comparator_test.rs | 8 +---- 9 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 src/db/file_meta_data.rs create mode 100644 src/db/file_meta_data_test.rs create mode 100644 src/table/ss_table.rs create mode 100644 src/table/ss_table_test.rs diff --git a/src/db/db_format.rs b/src/db/db_format.rs index cfc16d2..1af9eef 100644 --- a/src/db/db_format.rs +++ b/src/db/db_format.rs @@ -109,7 +109,25 @@ impl ParsedInternalKey { fn debug_string() -> Slice { Slice::default() } -} -// line 86 -//. \ No newline at end of file + /// Return the length of the encoding of "key". + fn internal_key_encoding_length(key: ParsedInternalKey) -> usize { + key.user_key.size() + 8 + } + + fn append_internal_key(key : ParsedInternalKey) -> Slice { + todo!() + } + + /// 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(internal_key : Slice, target: ParsedInternalKey) -> bool { + todo!() + } + + /// Returns the user key portion of an internal key. + fn extract_user_key(internal_key : Slice) -> Slice { + todo!() + } +} diff --git a/src/db/file_meta_data.rs b/src/db/file_meta_data.rs new file mode 100644 index 0000000..789c0bf --- /dev/null +++ b/src/db/file_meta_data.rs @@ -0,0 +1,11 @@ + +pub struct FileMetaData { + refs: u32, + // Seeks allowed until compaction + allowed_seeks: u32, + number: u64, + // File size in bytes + file_size: u64, + // smallest: InternalKey, + +} \ No newline at end of file diff --git a/src/db/file_meta_data_test.rs b/src/db/file_meta_data_test.rs new file mode 100644 index 0000000..b40ab66 --- /dev/null +++ b/src/db/file_meta_data_test.rs @@ -0,0 +1,5 @@ + +#[test] +fn test_file_meta_data() { + todo!() +} \ No newline at end of file diff --git a/src/db/mod.rs b/src/db/mod.rs index fa818b7..a673123 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -11,6 +11,8 @@ pub mod mem_table; pub mod db; pub mod db_format; mod db_format_test; +pub mod file_meta_data; +mod file_meta_data_test; /// 默认调表 pub type DefaultSkipList = SkipList; diff --git a/src/table/mod.rs b/src/table/mod.rs index 149cdbe..a4a1f72 100644 --- a/src/table/mod.rs +++ b/src/table/mod.rs @@ -1,2 +1,4 @@ pub mod format; -mod format_test; \ No newline at end of file +mod format_test; +pub mod ss_table; +mod ss_table_test; \ No newline at end of file diff --git a/src/table/ss_table.rs b/src/table/ss_table.rs new file mode 100644 index 0000000..869c7a7 --- /dev/null +++ b/src/table/ss_table.rs @@ -0,0 +1,4 @@ + +pub struct SSTable { + +} \ No newline at end of file diff --git a/src/table/ss_table_test.rs b/src/table/ss_table_test.rs new file mode 100644 index 0000000..bb5f800 --- /dev/null +++ b/src/table/ss_table_test.rs @@ -0,0 +1,5 @@ + +#[test] +fn test_ss_table() { + todo!() +} \ No newline at end of file diff --git a/src/util/comparator.rs b/src/util/comparator.rs index 71560fe..d28c48d 100644 --- a/src/util/comparator.rs +++ b/src/util/comparator.rs @@ -91,37 +91,29 @@ impl ComparatorTrait for BytewiseComparatorImpl { /// InternalKeyComparator pub struct InternalKeyComparator { - // fn user_comparator(&self) -> Box { - // todo!() - // } - - // fn Compare(InternalKey, InternalKey) -} - -impl Default for InternalKeyComparator { - fn default() -> Self { - Self {} - } + // user_comparator_: ComparatorTrait } -/// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 -/// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 -impl ComparatorTrait for InternalKeyComparator { - // todo InternalKeyComparator 的构造方法 - - 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!() - } -} +// /// InternalKeyComparator 比较器: 用来比较内部键(Internal Key)。 +// /// 内部键值是为了方便处理,将原普通键、序列号和值类型组成的新键。 +// impl ComparatorTrait for InternalKeyComparator { +// fn new(c: ComparatorTrait) -> 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 121c49a..8d5ec27 100644 --- a/src/util/comparator_test.rs +++ b/src/util/comparator_test.rs @@ -20,7 +20,7 @@ mod test { let option_val = comp.compare(&Slice::from("a"), &Slice::from("ab")); assert_eq!(option_val.unwrap(), Ordering::Less); - // todo Slice 存在 bug 未修复 + // // 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); @@ -123,10 +123,4 @@ mod test { String::from(Slice::from_buf(expect_u8_max_vec.as_slice()))); } - #[test] - fn test_internal_key_comparator_get_name() { - let name = InternalKeyComparator::default().get_name(); - assert_eq!("leveldb.InternalKeyComparator", name); - } - } \ No newline at end of file -- Gitee