wedb_standalone 0.1.1

单机网络服务底座:RESP 协议帧、AOF 逻辑层与节点服务编排(对标 Garnet libs/server 单机半区)
//! 有序集合条目比较器(对标 libs/server/Objects/SortedSetComparer.cs)
//!
//! 排序键为 (score, member):先按分值,分值相同再按成员字节序。
//! 排序视图(BTreeSet/BTreeMap range 查询)的正确性依赖本比较器。

use std::cmp::Ordering;

pub struct SortedSetComparer;

impl SortedSetComparer {
  /// 比较 (score, member) 二元组
  ///
  /// libs/server/Objects/SortedSetComparer.cs:Compare
  ///
  /// 刻意差异(对照 C#):C# `double.CompareTo` 把 NaN 排在所有数值之前;
  /// Rust `f64::total_cmp` 把 NaN 排在所有数值之后(且 -NaN < +NaN)。
  /// Garnet 命令层禁止 NaN 分值入库(ZADD/ZINCRBY 的 NaN 直接报错),
  /// 故该差异不可观测。
  #[inline]
  pub fn compare(
    (x_score, x_member): (&f64, &[u8]),
    (y_score, y_member): (&f64, &[u8]),
  ) -> Ordering {
    x_score
      .total_cmp(y_score)
      .then_with(|| x_member.cmp(y_member))
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn orders_by_score_then_member() {
    assert_eq!(
      SortedSetComparer::compare((&1.0, b"a"), (&2.0, b"z")),
      Ordering::Less
    );
    // 同分按成员字节序
    assert_eq!(
      SortedSetComparer::compare((&1.0, b"a"), (&1.0, b"b")),
      Ordering::Less
    );
    assert_eq!(
      SortedSetComparer::compare((&1.0, b"b"), (&1.0, b"a")),
      Ordering::Greater
    );
    assert_eq!(
      SortedSetComparer::compare((&1.0, b"a"), (&1.0, b"a")),
      Ordering::Equal
    );
    // -0.0 与 0.0 依 total_cmp 区分符号(成员兜底不触发)
    assert_eq!(
      SortedSetComparer::compare((&-0.0, b"a"), (&0.0, b"a")),
      Ordering::Less
    );
  }
}