tycho-core 0.3.7

Basic functionality of peer.
Documentation
use std::sync::Arc;

use anyhow::Result;
use tycho_block_util::block::BlockStuff;
use tycho_storage::StorageContext;
use tycho_storage::kv::ApplyMigrations;

pub use self::block::{
    ArchiveId, BlockGcStats, BlockStorage, BlockStorageConfig, MaybeExistingHandle, OpenStats,
    PackageEntryKey, PartialBlockId, StoreBlockResult,
};
pub use self::block_connection::{BlockConnection, BlockConnectionStorage};
pub use self::block_handle::{
    BlockFlags, BlockHandle, BlockHandleStorage, BlockMeta, HandleCreationStatus,
    KeyBlocksDirection, LoadedBlockMeta, NewBlockMeta, WeakBlockHandle,
};
pub use self::config::{
    ArchivesGcConfig, BlocksCacheConfig, BlocksGcConfig, BlocksGcType, CoreStorageConfig,
    StatesGcConfig,
};
pub use self::db::{CellsDb, CoreDb, CoreDbExt, CoreTables};
use self::gc::CoreStorageGc;
pub use self::gc::ManualGcTrigger;
pub use self::node_state::{NodeStateStorage, NodeSyncState};
pub use self::persistent_state::{
    BriefBocHeader, PersistentState, PersistentStateInfo, PersistentStateKind,
    PersistentStateStorage, QueueDiffReader, QueueStateReader, QueueStateWriter, ShardStateReader,
    ShardStateWriter,
};
pub use self::shard_state::{
    CachedStateUpdate, ShardStateStorage, ShardStateStorageError, ShardStateStorageMetrics,
    StoreStateHint, StoreStateStatus, split_shard_accounts,
};

pub mod tables;

pub(crate) mod block;
mod block_connection;
mod block_handle;
mod config;
mod db;
mod gc;
mod node_state;
mod persistent_state;
mod shard_state;
mod util;

pub const CORE_DB_SUBDIR: &str = "core";
pub const CELLS_DB_SUBDIR: &str = "cells";

#[derive(Clone)]
#[repr(transparent)]
pub struct CoreStorage {
    inner: Arc<Inner>,
}

impl CoreStorage {
    pub async fn open(ctx: StorageContext, config: CoreStorageConfig) -> Result<Self> {
        let db: CoreDb = ctx.open_preconfigured(CORE_DB_SUBDIR)?;
        db.normalize_version()?;
        db.apply_migrations().await?;

        let cells_db: CellsDb = ctx.open_preconfigured(CELLS_DB_SUBDIR)?;
        cells_db.normalize_version()?;
        cells_db.apply_migrations().await?;

        let node_state_storage = Arc::new(NodeStateStorage::new(db.clone()));

        let blocks_storage_config = BlockStorageConfig {
            blocks_cache: config.blocks_cache,
            blobs_root: ctx.root_dir().path().join("blobs"),
            blob_db_config: config.blob_db.clone(),
        };
        let block_handle_storage = Arc::new(BlockHandleStorage::new(db.clone()));
        let block_connection_storage = Arc::new(BlockConnectionStorage::new(db.clone()));
        let block_storage = BlockStorage::new(
            db.clone(),
            blocks_storage_config,
            block_handle_storage.clone(),
            block_connection_storage.clone(),
        )
        .await?;
        let block_storage = Arc::new(block_storage);

        let shard_state_storage = ShardStateStorage::new(
            cells_db.clone(),
            block_handle_storage.clone(),
            block_storage.clone(),
            ctx.temp_files().clone(),
            &config,
        )?;
        let persistent_state_storage = PersistentStateStorage::new(
            cells_db.clone(),
            ctx.files_dir(),
            node_state_storage.clone(),
            block_handle_storage.clone(),
            block_storage.clone(),
            shard_state_storage.clone(),
        )?;

        persistent_state_storage.preload().await?;

        let gc = CoreStorageGc::new(
            &node_state_storage,
            block_handle_storage.clone(),
            block_storage.clone(),
            shard_state_storage.clone(),
            persistent_state_storage.clone(),
            &config,
        );

        Ok(Self {
            inner: Arc::new(Inner {
                ctx,
                db,
                config,
                gc,
                block_handle_storage,
                block_storage,
                shard_state_storage,
                persistent_state_storage,
                block_connection_storage,
                node_state_storage,
            }),
        })
    }

    pub fn context(&self) -> &StorageContext {
        &self.inner.ctx
    }

    pub fn db(&self) -> &CoreDb {
        &self.inner.db
    }

    pub fn config(&self) -> &CoreStorageConfig {
        &self.inner.config
    }

    pub fn persistent_state_storage(&self) -> &PersistentStateStorage {
        &self.inner.persistent_state_storage
    }

    pub fn block_handle_storage(&self) -> &BlockHandleStorage {
        &self.inner.block_handle_storage
    }

    pub fn block_storage(&self) -> &BlockStorage {
        &self.inner.block_storage
    }

    pub fn block_connection_storage(&self) -> &BlockConnectionStorage {
        &self.inner.block_connection_storage
    }

    pub fn shard_state_storage(&self) -> &ShardStateStorage {
        &self.inner.shard_state_storage
    }

    pub fn node_state(&self) -> &NodeStateStorage {
        &self.inner.node_state_storage
    }

    pub fn open_stats(&self) -> &OpenStats {
        self.inner.block_storage.open_stats()
    }

    pub fn trigger_archives_gc(&self, trigger: ManualGcTrigger) {
        self.inner.gc.trigger_archives_gc(trigger);
    }

    pub fn trigger_blocks_gc(&self, trigger: ManualGcTrigger) {
        self.inner.gc.trigger_blocks_gc(trigger);
    }

    pub fn trigger_states_gc(&self, trigger: ManualGcTrigger) {
        self.inner.gc.trigger_states_gc(trigger);
    }

    pub(crate) fn update_gc_state(&self, is_key_block: bool, block: &BlockStuff) {
        self.inner.gc.handle_block(is_key_block, block);
    }
}

struct Inner {
    ctx: StorageContext,
    db: CoreDb,
    config: CoreStorageConfig,
    gc: CoreStorageGc,

    block_handle_storage: Arc<BlockHandleStorage>,
    block_connection_storage: Arc<BlockConnectionStorage>,
    block_storage: Arc<BlockStorage>,
    shard_state_storage: Arc<ShardStateStorage>,
    node_state_storage: Arc<NodeStateStorage>,
    persistent_state_storage: PersistentStateStorage,
}