fast-cache 0.1.0

Embedded-first thread-per-core in-memory cache with optional Redis-compatible server
Documentation
use crate::protocol::{FastCommand, FastRequest, FastResponse, Frame};
use crate::storage::{EngineCommandContext, EngineFastFuture, ShardOperation, ShardReply};
use crate::{FastCacheError, Result};

use super::Get;
use crate::commands::EngineCommandDispatch;

impl EngineCommandDispatch for Get {
    fn execute_engine_fast<'a>(
        &'static self,
        ctx: EngineCommandContext<'a>,
        request: FastRequest<'a>,
    ) -> EngineFastFuture<'a> {
        Box::pin(async move {
            let key_hash = request.key_hash;
            match request.command {
                FastCommand::Get { key } => {
                    Get::execute_engine_fast_response(ctx, key_hash, key).await
                }
                _ => Ok(FastResponse::Error(b"ERR unsupported command".to_vec())),
            }
        })
    }
}

impl Get {
    pub(super) async fn execute_engine_frame(
        ctx: EngineCommandContext<'_>,
        key: &[u8],
    ) -> Result<Frame> {
        match Self::load_value(ctx, None, key).await? {
            Some(value) => Ok(Frame::BlobString(value)),
            None => Ok(Frame::Null),
        }
    }

    async fn execute_engine_fast_response(
        ctx: EngineCommandContext<'_>,
        key_hash: Option<u64>,
        key: &[u8],
    ) -> Result<FastResponse> {
        match Self::load_value(ctx, key_hash, key).await? {
            Some(value) => Ok(FastResponse::Value(value)),
            None => Ok(FastResponse::Null),
        }
    }

    async fn load_value(
        ctx: EngineCommandContext<'_>,
        key_hash: Option<u64>,
        key: &[u8],
    ) -> Result<Option<Vec<u8>>> {
        let shard = key_hash
            .map(|hash| ctx.route_key_hash(hash))
            .unwrap_or_else(|| ctx.route_key(key));
        match ctx
            .request(shard, ShardOperation::Get(key.to_vec()))
            .await?
        {
            ShardReply::Value(value) => Ok(value),
            _ => Err(FastCacheError::Command(
                "GET received unexpected shard reply".into(),
            )),
        }
    }
}