shardmap 0.3.0

Sharded embedded in-memory map with optional cache, protocol, and server internals
Documentation
use crate::storage::RedisZSetStore;
#[cfg(feature = "server")]
use bytes::BytesMut;

use crate::commands::redis::{
    define_redis_command, reserve_resp_bulk_array_hint, scan_array, write_frame,
    write_resp_array_header, wrong_arity, wrongtype, zentries_flat,
};
use crate::commands::zset_shared::write_resp_score;
use crate::protocol::Frame;
#[cfg(feature = "server")]
use crate::server::wire::ServerWire;
use crate::storage::{
    EmbeddedStore, RedisObjectError, RedisObjectReadOutcome, RedisObjectZSetRangeItem,
};

define_redis_command!(ZScan, "ZSCAN", false);

impl crate::commands::redis::RedisCommand for ZScan {
    fn execute(store: &EmbeddedStore, args: &[&[u8]]) -> Frame {
        if args.len() < 2 {
            return wrong_arity("ZSCAN");
        }
        match store.zentries(args[0]) {
            Ok(entries) => scan_array(zentries_flat(entries)),
            Err(RedisObjectError::WrongType) => wrongtype(),
            Err(RedisObjectError::MissingKey) => scan_array(Vec::new()),
        }
    }

    #[cfg(feature = "server")]
    fn write_resp(store: &EmbeddedStore, args: &[&[u8]], out: &mut BytesMut) {
        if args.len() < 2 {
            write_frame(out, &wrong_arity("ZSCAN"));
            return;
        }
        match store.zrange_entries_visit(args[0], 0, -1, false, |item| match item {
            RedisObjectZSetRangeItem::Begin(count) => {
                reserve_resp_bulk_array_hint(out, count.saturating_mul(2));
                write_resp_array_header(out, 2);
                ServerWire::write_resp_blob_string(out, b"0");
                write_resp_array_header(out, count.saturating_mul(2));
            }
            RedisObjectZSetRangeItem::Entry { member, score } => {
                ServerWire::write_resp_blob_string(out, member);
                write_resp_score(out, score);
            }
        }) {
            RedisObjectReadOutcome::Written => {}
            RedisObjectReadOutcome::Missing => {
                write_resp_array_header(out, 2);
                ServerWire::write_resp_blob_string(out, b"0");
                write_resp_array_header(out, 0);
            }
            RedisObjectReadOutcome::WrongType => write_frame(out, &wrongtype()),
        }
    }
}