Skip to content

Commit

Permalink
[week1] 1.3 task1
Browse files Browse the repository at this point in the history
  • Loading branch information
HeartLinked committed Sep 14, 2024
1 parent 34b024b commit 3978ca8
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 9 deletions.
36 changes: 33 additions & 3 deletions mini-lsm-starter/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ mod builder;
mod iterator;

pub use builder::BlockBuilder;
use bytes::Bytes;
use bytes::{BufMut, Bytes, BytesMut};
pub use iterator::BlockIterator;
use nom::ExtendInto;

/// A block is the smallest unit of read and caching in LSM tree. It is a collection of sorted key-value pairs.
pub struct Block {
Expand All @@ -18,11 +19,40 @@ impl Block {
/// Encode the internal data to the data layout illustrated in the tutorial
/// Note: You may want to recheck if any of the expected field is missing from your output
pub fn encode(&self) -> Bytes {
unimplemented!()
let mut bytes = BytesMut::with_capacity(self.data.len() + self.offsets.len() * 2 + 2);
bytes.extend_from_slice(&self.data);
for &offset in &self.offsets {
bytes.extend_from_slice(&offset.to_le_bytes());
}
bytes.put_u16(self.offsets.len() as u16);
return bytes.freeze();
}

/// Decode from the data layout, transform the input `data` to a single `Block`
pub fn decode(data: &[u8]) -> Self {
unimplemented!()
// num_of_elements
let num_of_elements_offset = data.len() - 2; // 偏移量是倒数第二个字节开始
let num_of_elements = u16::from_le_bytes([
data[num_of_elements_offset],
data[num_of_elements_offset + 1],
]) as usize;

let offsets_start = num_of_elements_offset - num_of_elements * 2;
let mut offsets = Vec::with_capacity(num_of_elements);

// offsets
for i in 0..num_of_elements {
let offset_pos = offsets_start + i * 2;
let offset = u16::from_le_bytes([data[offset_pos], data[offset_pos + 1]]);
offsets.push(offset);
}

// data
let data_part = &data[..offsets_start]; // 数据部分到偏移开始为止

Block {
data: data_part.to_vec(),
offsets,
}
}
}
45 changes: 39 additions & 6 deletions mini-lsm-starter/src/block/builder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![allow(unused_variables)] // TODO(you): remove this lint after implementing this mod
#![allow(dead_code)] // TODO(you): remove this lint after implementing this mod

use crate::key::{KeySlice, KeyVec};

use super::Block;
use crate::key::{KeySlice, KeyVec};
use bytes::{Buf, BufMut, Bytes, BytesMut};

/// Builds a block.
pub struct BlockBuilder {
Expand All @@ -20,22 +20,55 @@ pub struct BlockBuilder {
impl BlockBuilder {
/// Creates a new block builder.
pub fn new(block_size: usize) -> Self {
unimplemented!()
BlockBuilder {
offsets: Vec::new(),
data: Vec::new(),
block_size,
first_key: KeyVec::new(),
}
}

/// Adds a key-value pair to the block. Returns false when the block is full.
#[must_use]
pub fn add(&mut self, key: KeySlice, value: &[u8]) -> bool {
unimplemented!()
if self.data.is_empty() {
self.first_key = KeyVec::from_vec(key.raw_ref().to_vec());
} else {
const KEY_VAL_LEN: usize = 4;
const NUM_OF_ELEMENTS_LEN: usize = 2;
const OFFSET_LEN: usize = 2;
let size_add = KEY_VAL_LEN + key.len() + value.len() + OFFSET_LEN; // entry + offset
if self.offsets.len() * 2 + self.data.len() + size_add + NUM_OF_ELEMENTS_LEN
> self.block_size
{
println!("---------OVERFLOW!--------------");
return false;
}
}
// 获取 key 和 value 的字节切片
let key_bytes = key.raw_ref();
let value_bytes = value;
// 获取 key 和 value 的长度
let key_len = (key_bytes.len() as u16); // 包含 2 个元素为 u8 的数组, [u8, 2]
let value_len = (value_bytes.len() as u16); // 包含 2 个元素为 u8 的数组, [u8, 2]
self.data.extend_from_slice(&key_len.to_le_bytes());
self.data.extend_from_slice(key_bytes);

self.data.extend_from_slice(&value_len.to_le_bytes());
self.data.extend_from_slice(value_bytes);
true
}

/// Check if there is no key-value pair in the block.
pub fn is_empty(&self) -> bool {
unimplemented!()
self.data.is_empty() || self.offsets.is_empty()
}

/// Finalize the block.
pub fn build(self) -> Block {
unimplemented!()
Block {
data: self.data,
offsets: self.offsets,
}
}
}
1 change: 1 addition & 0 deletions mini-lsm-starter/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
mod harness;
mod week1_day1;
mod week1_day2;
mod week1_day3;

0 comments on commit 3978ca8

Please sign in to comment.