Skip to content

Commit

Permalink
[week1] 1.2 finished
Browse files Browse the repository at this point in the history
  • Loading branch information
HeartLinked committed Sep 13, 2024
1 parent 6d40e78 commit 67290f3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 17 deletions.
50 changes: 35 additions & 15 deletions mini-lsm-starter/src/lsm_iterator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![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 anyhow::Result;
use anyhow::{anyhow, Result};

use crate::{
iterators::{merge_iterator::MergeIterator, StorageIterator},
Expand All @@ -12,40 +12,49 @@ use crate::{
type LsmIteratorInner = MergeIterator<MemTableIterator>;

pub struct LsmIterator {
inner: LsmIteratorInner,
inner: LsmIteratorInner, // MergeIterator<MemTableIterator>
}

impl LsmIterator {
pub(crate) fn new(iter: LsmIteratorInner) -> Result<Self> {
Ok(Self { inner: iter })
}

pub fn skip_delete_key(&mut self) -> Result<()> {
while self.is_valid() && !self.inner.key().is_empty() && self.inner.value().is_empty() {
self.inner.next()?;
}
Ok(())
}
}

impl StorageIterator for LsmIterator {
type KeyType<'a> = &'a [u8];

fn is_valid(&self) -> bool {
unimplemented!()
fn value(&self) -> &[u8] {
self.inner.value()
}

fn key(&self) -> &[u8] {
unimplemented!()
self.inner.key().raw_ref()
}

fn value(&self) -> &[u8] {
unimplemented!()
fn is_valid(&self) -> bool {
return self.inner.is_valid();
}

fn next(&mut self) -> Result<()> {
unimplemented!()
self.inner.next()?;
self.skip_delete_key()?;
Ok(())
}
}

/// A wrapper around existing iterator, will prevent users from calling `next` when the iterator is
/// invalid. If an iterator is already invalid, `next` does not do anything. If `next` returns an error,
/// `is_valid` should return false, and `next` should always return an error.
pub struct FusedIterator<I: StorageIterator> {
iter: I,
iter: I, // 一个迭代器,可以自身错误(无法获得 key),也可以自身仍有效,但无法执行 next,这是两种不同的情况
has_errored: bool,
}

Expand All @@ -61,19 +70,30 @@ impl<I: StorageIterator> FusedIterator<I> {
impl<I: StorageIterator> StorageIterator for FusedIterator<I> {
type KeyType<'a> = I::KeyType<'a> where Self: 'a;

fn is_valid(&self) -> bool {
unimplemented!()
fn value(&self) -> &[u8] {
self.iter.value()
}

fn key(&self) -> Self::KeyType<'_> {
unimplemented!()
self.iter.key()
}

fn value(&self) -> &[u8] {
unimplemented!()
fn is_valid(&self) -> bool {
// 这里二者的顺序不能调换,如果在迭代器包含错误的情况下调用is_valid,可能会直接 panic
(!self.has_errored) && self.iter.is_valid()
}

fn next(&mut self) -> Result<()> {
unimplemented!()
if self.has_errored {
// 有错误一定不能next
return Err(anyhow!("The iterator is invalid!"));
}
if let Ok(res) = self.iter.next() {
self.has_errored = false;
Ok(res)
} else {
self.has_errored = true;
Err(anyhow!("The iterator is invalid after next operation!"))
}
}
}
21 changes: 19 additions & 2 deletions mini-lsm-starter/src/lsm_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ use crate::compact::{
CompactionController, CompactionOptions, LeveledCompactionController, LeveledCompactionOptions,
SimpleLeveledCompactionController, SimpleLeveledCompactionOptions, TieredCompactionController,
};
use crate::iterators::merge_iterator::MergeIterator;
use crate::iterators::StorageIterator;
use crate::lsm_iterator::{FusedIterator, LsmIterator};
use crate::manifest::Manifest;
use crate::mem_table::MemTable;
use crate::mem_table::{MemTable, MemTableIterator};
use crate::mvcc::LsmMvccInner;
use crate::table::SsTable;

Expand Down Expand Up @@ -424,6 +426,21 @@ impl LsmStorageInner {
_lower: Bound<&[u8]>,
_upper: Bound<&[u8]>,
) -> Result<FusedIterator<LsmIterator>> {
unimplemented!()
let state = self.state.read();

let memtable = state.as_ref().memtable.as_ref();
let memtable_iter = memtable.scan(_lower, _upper);
let mut iters = vec![Box::new(memtable_iter)];

for imm_memtable in &state.imm_memtables {
let imm_memtable = Arc::as_ref(imm_memtable);
let imm_memtable_iter = imm_memtable.scan(_lower, _upper);
iters.push(Box::new(imm_memtable_iter));
// 这里可以使用 imm_memtable_ref
}
let lsm_iterator_inner = MergeIterator::create(iters);
let mut iter = LsmIterator::new(lsm_iterator_inner)?;
iter.skip_delete_key().unwrap();
Ok(FusedIterator::new(iter))
}
}

0 comments on commit 67290f3

Please sign in to comment.