Skip to content

Commit

Permalink
add way more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
marvin-j97 committed Dec 4, 2023
1 parent c0a55eb commit 2c43673
Show file tree
Hide file tree
Showing 16 changed files with 455 additions and 92 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
test_stable:
strategy:
matrix:
rust_version:
- stable
- "1.68.2"
os:
- ubuntu-latest
# - windows-latest
Expand All @@ -24,6 +27,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust_version }}
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
with:
Expand Down
10 changes: 10 additions & 0 deletions src/compaction/fifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ pub struct Strategy {

impl Strategy {
/// Configures a new `Fifo` compaction strategy
///
/// # Examples
///
/// ```
/// use lsm_tree::{Config, compaction::Fifo};
///
/// let one_gb = 1 * 1_024 * 1_024 * 1_024;
///
/// let config = Config::default().compaction_strategy(Fifo::new(one_gb));
/// ```
#[must_use]
pub fn new(limit: u64) -> Arc<Self> {
Arc::new(Self { limit })
Expand Down
4 changes: 2 additions & 2 deletions src/compaction/major.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Choice, CompactionStrategy, Options};
use super::{Choice, CompactionStrategy, CompactionInput};
use crate::levels::Levels;
use std::sync::Arc;

Expand Down Expand Up @@ -36,7 +36,7 @@ impl CompactionStrategy for Strategy {
let segments = levels.get_segments();
let segment_ids = segments.values().map(|s| s.metadata.id.clone()).collect();

Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
segment_ids,
dest_level: levels.depth() as u8 - 1,
target_size: self.target_size,
Expand Down
20 changes: 13 additions & 7 deletions src/compaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ pub(crate) mod worker;

use crate::levels::Levels;

/// Configuration for compaction
/// Input for compactor.
///
/// The compaction strategy chooses which segments to compact and how.
/// That information is given to the compactor.
#[derive(Debug, Eq, PartialEq)]
pub struct Options {
pub struct CompactionInput {
/// Segments to compact
pub segment_ids: Vec<String>,

Expand All @@ -26,20 +29,23 @@ pub struct Options {
/// Describes what to do (compact or not)
#[derive(Debug, Eq, PartialEq)]
pub enum Choice {
/// Just do nothing
/// Just do nothing.
DoNothing,

/// Compacts some segments into a new level
DoCompact(Options),
/// Compacts some segments into a new level.
DoCompact(CompactionInput),

/// Delete segments without doing compaction
/// Delete segments without doing compaction.
///
/// This may be used by a compaction strategy that wants to delete old data
/// without having to compact it away, like [`fifo::Strategy`].
DeleteSegments(Vec<String>),
}

/// Trait for a compaction strategy
///
/// The strategy receives the levels of the LSM-tree as argument
/// and emits a choice on what to do
/// and emits a choice on what to do.
pub trait CompactionStrategy {
/// Decides on what to do based on the current state of the LSM-tree's levels
fn choose(&self, _: &Levels) -> Choice;
Expand Down
24 changes: 16 additions & 8 deletions src/compaction/tiered.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Choice, CompactionStrategy, Options};
use super::{Choice, CompactionInput, CompactionStrategy};
use crate::levels::Levels;
use std::sync::Arc;

Expand All @@ -17,6 +17,14 @@ pub struct Strategy {
impl Strategy {
/// Configures a new `SizeTiered` compaction strategy
///
/// # Examples
///
/// ```
/// use lsm_tree::{Config, compaction::SizeTiered};
///
/// let config = Config::default().compaction_strategy(SizeTiered::new(4, 8));
/// ```
///
/// # Panics
///
/// Panics, if `min_threshold` is equal to 0 or larger than `max_threshold`
Expand Down Expand Up @@ -60,7 +68,7 @@ impl CompactionStrategy for Strategy {
#[allow(clippy::cast_possible_truncation)]
let next_level_index = (level_index + 1) as u8;

return Choice::DoCompact(Options {
return Choice::DoCompact(CompactionInput {
segment_ids: level
.iter()
.take(self.max_threshold)
Expand All @@ -82,7 +90,7 @@ mod tests {
use super::Strategy;
use crate::{
block_cache::BlockCache,
compaction::{Choice, CompactionStrategy, Options},
compaction::{Choice, CompactionInput, CompactionStrategy},
levels::Levels,
segment::{index::MetaIndex, meta::Metadata, Segment},
};
Expand Down Expand Up @@ -153,7 +161,7 @@ mod tests {
levels.add(fixture_segment("4".into()));
assert_eq!(
compactor.choose(&levels),
Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
dest_level: 1,
segment_ids: vec!["1".into(), "2".into(), "3".into(), "4".into()],
target_size: u64::MAX,
Expand Down Expand Up @@ -181,7 +189,7 @@ mod tests {

assert_eq!(
compactor.choose(&levels),
Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
dest_level: 1,
segment_ids: vec!["1".into(), "2".into(), "3".into(), "4".into()],
target_size: u64::MAX,
Expand All @@ -204,7 +212,7 @@ mod tests {

assert_eq!(
compactor.choose(&levels),
Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
dest_level: 1,
segment_ids: vec!["1".into(), "2".into()],
target_size: u64::MAX,
Expand All @@ -227,7 +235,7 @@ mod tests {

assert_eq!(
compactor.choose(&levels),
Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
dest_level: 2,
segment_ids: vec!["2".into(), "3".into()],
target_size: u64::MAX,
Expand All @@ -242,7 +250,7 @@ mod tests {

assert_eq!(
compactor.choose(&levels),
Choice::DoCompact(Options {
Choice::DoCompact(CompactionInput {
dest_level: 3,
segment_ids: vec!["2".into(), "3".into()],
target_size: u64::MAX,
Expand Down
8 changes: 4 additions & 4 deletions src/compaction/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::{

pub fn do_compaction(
tree: &Tree,
payload: &crate::compaction::Options,
payload: &crate::compaction::CompactionInput,
mut segments_lock: RwLockWriteGuard<'_, Levels>,
) -> crate::Result<()> {
if tree.is_stopped() {
Expand Down Expand Up @@ -65,7 +65,7 @@ pub fn do_compaction(
crate::segment::writer::Options {
block_size: tree.config.block_size,
evict_tombstones: should_evict_tombstones,
path: tree.path().join("segments"),
path: tree.config().path.join("segments"),
},
)?;

Expand Down Expand Up @@ -130,7 +130,7 @@ pub fn do_compaction(

for key in &payload.segment_ids {
log::trace!("rm -rf segment folder {}", key);
std::fs::remove_dir_all(tree.path().join("segments").join(key))?;
std::fs::remove_dir_all(tree.config().path.join("segments").join(key))?;
}

segments_lock.show_segments(&payload.segment_ids);
Expand Down Expand Up @@ -173,7 +173,7 @@ pub fn compaction_worker(tree: &Tree) -> crate::Result<()> {

for key in &payload {
log::trace!("rm -rf segment folder {}", key);
std::fs::remove_dir_all(tree.path().join("segments").join(key))?;
std::fs::remove_dir_all(tree.config().path.join("segments").join(key))?;
}

log::trace!("Deleted {} segments", payload.len());
Expand Down
15 changes: 8 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,40 @@ use std::{
};
pub use tiered::Strategy as SizeTiered;

#[derive(Clone)]
/// Tree configuration
pub struct Config {
/// Folder path
///
/// Defaults to `./.lsm.data`
pub(crate) path: PathBuf,
pub path: PathBuf,

/// Block size of data and index blocks
///
/// Defaults to 4 KiB (4096 bytes)
pub(crate) block_size: u32,
pub block_size: u32,

/// Block cache size in # blocks
///
/// Defaults to 1,024
pub(crate) block_cache_capacity: u32,
pub block_cache_capacity: u32,

/// [`MemTable`] maximum size in bytes
/// Maximum size in bytes of the write buffer
///
/// Defaults to 64 MiB, like RocksDB
pub(crate) max_memtable_size: u32,
pub max_memtable_size: u32,

/// Amount of levels of the LSM tree (depth of tree)
///
/// Defaults to 7, like RocksDB
pub(crate) levels: u8,
pub levels: u8,

/// Maximum amount of concurrent flush threads
///
/// You may want to increase this the more CPU cores you have
///
/// Defaults to 4
pub(crate) flush_threads: u8,
pub flush_threads: u8,

/// Compaction strategy to use
///
Expand Down
73 changes: 73 additions & 0 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ use Entry::{Occupied, Vacant};

impl Entry {
/// Returns a reference to this entry's key
///
/// # Examples
///
/// ```
/// # let folder = tempfile::tempdir()?;
/// use lsm_tree::{Config, Tree};
///
/// let tree = Tree::open(Config::new(folder))?;
///
/// let entry = tree.entry("a")?;
/// assert_eq!("a".as_bytes(), entry.key());
/// #
/// # Ok::<(), lsm_tree::Error>(())
/// ```
#[must_use]
pub fn key(&self) -> &Vec<u8> {
match self {
Expand All @@ -70,6 +84,23 @@ impl Entry {

/// Updates the value if it exists before any potential inserts.
///
/// # Examples
///
/// ```
/// # let folder = tempfile::tempdir()?;
/// use lsm_tree::{Config, Tree};
///
/// let tree = Tree::open(Config::new(folder))?;
///
/// let value = tree.entry("a")?.or_insert("abc")?;
/// assert_eq!("abc".as_bytes(), &value);
///
/// let value = tree.entry("a")?.and_update(|_| "def")?.or_insert("abc")?;
/// assert_eq!("def".as_bytes(), &value);
/// #
/// # Ok::<(), lsm_tree::Error>(())
/// ```
///
/// # Errors
///
/// Will return `Err` if an IO error occurs.
Expand All @@ -86,6 +117,20 @@ impl Entry {

/// Ensures a value is in the entry by inserting the default if empty, and returns that value.
///
/// # Examples
///
/// ```
/// # let folder = tempfile::tempdir()?;
/// use lsm_tree::{Config, Tree};
///
/// let tree = Tree::open(Config::new(folder))?;
///
/// let value = tree.entry("a")?.or_insert("abc")?;
/// assert_eq!("abc".as_bytes(), &value);
/// #
/// # Ok::<(), lsm_tree::Error>(())
/// ```
///
/// # Errors
///
/// Will return `Err` if an IO error occurs.
Expand All @@ -98,6 +143,20 @@ impl Entry {

/// Ensures a value is in the entry by inserting the result of the default function if empty, and returns that value.
///
/// # Examples
///
/// ```
/// # let folder = tempfile::tempdir()?;
/// use lsm_tree::{Config, Tree};
///
/// let tree = Tree::open(Config::new(folder))?;
///
/// let value = tree.entry("a")?.or_insert_with(|| "abc")?;
/// assert_eq!("abc".as_bytes(), &value);
/// #
/// # Ok::<(), lsm_tree::Error>(())
/// ```
///
/// # Errors
///
/// Will return `Err` if an IO error occurs.
Expand All @@ -113,6 +172,20 @@ impl Entry {

/// Ensures a value is in the entry by inserting the result of the default function if empty, and returns that value.
///
/// # Examples
///
/// ```
/// # let folder = tempfile::tempdir()?;
/// use lsm_tree::{Config, Tree};
///
/// let tree = Tree::open(Config::new(folder))?;
///
/// let value = tree.entry("a")?.or_insert_with_key(|k| k.clone())?;
/// assert_eq!("a".as_bytes(), &value);
/// #
/// # Ok::<(), lsm_tree::Error>(())
/// ```
///
/// # Errors
///
/// Will return `Err` if an IO error occurs.
Expand Down
2 changes: 1 addition & 1 deletion src/levels/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl Levels {
write_segment_history_entry("remove".into(), self); */
}

/// Returns true if there are no segments
/// Returns `true` if there are no segments
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
Expand Down
Loading

0 comments on commit 2c43673

Please sign in to comment.