Files
mini_lsm/mini-lsm-starter/src/lsm_iterator.rs
ECROF88 8fb4176e71
Some checks failed
CI (main) / build (push) Has been cancelled
CI (main) / deploy (push) Has been cancelled
First Commit
2025-10-20 20:12:40 +08:00

125 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2022-2025 Alex Chi Z
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![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 crate::{
iterators::{StorageIterator, merge_iterator::MergeIterator},
mem_table::MemTableIterator,
};
/// Represents the internal type for an LSM iterator. This type will be changed across the course for multiple times.
type LsmIteratorInner = MergeIterator<MemTableIterator>;
pub struct LsmIterator {
inner: LsmIteratorInner,
}
impl LsmIterator {
pub(crate) fn new(iter: LsmIteratorInner) -> Result<Self> {
Ok(Self { inner: iter })
}
}
impl StorageIterator for LsmIterator {
type KeyType<'a> = &'a [u8];
fn is_valid(&self) -> bool {
self.inner.is_valid()
}
fn key(&self) -> &[u8] {
self.inner.key().into_inner()
}
fn value(&self) -> &[u8] {
self.inner.value()
}
fn next(&mut self) -> Result<()> {
// TODO: I dont know if I need use ? to return the Error or not
self.inner.next()?;
// 跳过已经删除的key
while self.inner.is_valid() && self.inner.value().is_empty() {
self.inner.next()?;
}
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,
has_errored: bool,
}
impl<I: StorageIterator> FusedIterator<I> {
pub fn new(iter: I) -> Self {
Self {
iter,
has_errored: false,
}
}
}
impl<I: StorageIterator> StorageIterator for FusedIterator<I> {
type KeyType<'a>
= I::KeyType<'a>
where
Self: 'a;
fn is_valid(&self) -> bool {
// self.iter.is_valid() && !self.has_errored
if self.has_errored {
false
} else {
self.iter.is_valid()
}
}
fn key(&self) -> Self::KeyType<'_> {
self.iter.key()
}
fn value(&self) -> &[u8] {
self.iter.value()
}
fn next(&mut self) -> Result<()> {
// 按照测试用例出现错误就要返回err
if self.has_errored {
return Err(anyhow::anyhow!("iterator has errored previously"));
}
// 但是对于迭代器已经失效,不应该报错
if !self.iter.is_valid() {
return Ok(());
}
//
match self.iter.next() {
Ok(()) => Ok(()),
Err(e) => {
self.has_errored = true;
Err(e)
}
}
}
}