tempest-core 0.0.2

Core utilities and primitives for TempestDB
Documentation
use std::path::PathBuf;

use serde::{Deserialize, Serialize};
use tempest_io::VirtualIo;
use tempest_rt::block_on;

use crate::test_utils::setup_tracing;

use super::*;

#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
struct ReplayableCounter(i64);

#[derive(Serialize, Deserialize)]
enum ReplayableCounterEdit {
    Add(i64),
    Set(i64),
}

impl ReplayableCounter {
    fn count(&self) -> i64 {
        self.0
    }
}

impl Replayable for ReplayableCounter {
    type Edit = ReplayableCounterEdit;

    fn apply(&mut self, edit: Self::Edit) {
        match edit {
            ReplayableCounterEdit::Add(v) => self.0 += v,
            ReplayableCounterEdit::Set(v) => self.0 = v,
        }
    }

    fn snapshot(&self) -> Self::Edit {
        ReplayableCounterEdit::Set(self.0)
    }

    fn filename_prefix() -> &'static str {
        "replayable-counter"
    }

    fn initial() -> Self {
        Self(0)
    }
}

#[test]
fn test_journal() {
    setup_tracing();

    let io = VirtualIo::default();
    let dir = PathBuf::from("/journal-dir");
    let config = JournalConfig::default();

    block_on(io, async {
        {
            info!("opening journal");
            // open first journal
            let (journal, join) =
                Journal::<ReplayableCounter, VirtualIo>::new(dir.clone(), config.clone())
                    .await
                    .unwrap();
            assert_eq!(journal.data().count(), ReplayableCounter::initial().count());

            // first edit
            journal.append(ReplayableCounterEdit::Add(1)).await.unwrap();
            assert_eq!(journal.data().count(), 1);

            // second edit
            journal
                .append(ReplayableCounterEdit::Add(-6))
                .await
                .unwrap();
            assert_eq!(journal.data().count(), -5);

            // set to final value
            journal
                .append(ReplayableCounterEdit::Set(42))
                .await
                .unwrap();
            assert_eq!(journal.data().count(), 42);

            drop(journal);
            join.await.unwrap();
        }

        {
            info!("reopening journal");
            // reopen journal — verify replay
            let (journal, join) =
                Journal::<ReplayableCounter, VirtualIo>::new(dir.clone(), config.clone())
                    .await
                    .unwrap();
            assert_eq!(journal.data().count(), 42);

            drop(journal);
            join.await.unwrap();
        }
    });
}