Skip to content

Commit

Permalink
refactor(network): replace handwritten diagrams with diagrams in asci…
Browse files Browse the repository at this point in the history
…iflow
  • Loading branch information
nerodono committed Jan 21, 2025
1 parent d146625 commit 198be9d
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 114 deletions.
124 changes: 62 additions & 62 deletions elfo-network/src/socket/capabilities/compression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,39 @@ use std::fmt;

use crate::config::Preference;

bitflags::bitflags! {
/// Set of algorithms. 24 bits.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Algorithms: u32 {
const LZ4 = 1;
// NB: Shift by 2: `const ZSTD = 1 << 2;`.
}
}

/// Compression capabilities.
///
/// Layout:
/// ```text
/// Bits
/// 6 2
/// +---+-----+
/// | R | Lz4 |
/// +---+-----+
/// 22 2
/// ┌────────────┬─────┐
/// │ Reserved │ Lz4 │
/// └────────────┴─────┘
/// ```
///
/// `R` - reserved, any other mean specific compression algorithm. Layout
/// for specific compression algorithm:
/// Each mentioned algorithm here occupies two bits for a reason, here's the
/// layout of those bits:
/// ```text
/// Bits
/// 1 1
/// +---+---+
/// | S | P |
/// +---+---+
/// 1 1
/// ┌───────────┬───────────┐
/// │ Preferred │ Supported │
/// └───────────┴───────────┘
/// ```
///
/// 1. `S` - the compression algorithm is supported.
/// 2. `P` - the compression algorithm is preferred, implies `S`.
/// 1. Preferred - the compression algorithm is preferred, implies `Supported`.
/// 2. Supported - the compression algorithm is supported.
#[derive(Debug, Clone, Copy)]
pub(crate) struct Compression(u32);

fn write_array(
hide: Option<Algorithms>,
algos: Algorithms,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
write!(f, "[")?;
let mut need_comma = false;
for (name, _) in algos
.iter_names()
.filter(|(_, algo)| hide.map_or(true, |hide| hide.contains(*algo)))
{
if need_comma {
write!(f, ", ")?;
}

f.write_str(name)?;
need_comma = true;
}

write!(f, "]")
}

impl fmt::Display for Compression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let preferred = self.preferred();
let supported = self.supported();

write!(f, "(preferred: ")?;
write_array(None, preferred, f)?;
write!(f, ", supported: ")?;
// Don't show preferred in supported, more compact
// output.
write_array(Some(preferred), supported, f)?;
write!(f, ")")
}
}

impl Compression {
pub(crate) const fn empty() -> Self {
Self::new(Algorithms::empty(), Algorithms::empty())
Expand All @@ -75,8 +47,8 @@ impl Compression {
}

pub(crate) const fn from_bits_truncate(v: u32) -> Self {
let supported = Algorithms::from_bits_truncate(v >> 1);
let preferred = Algorithms::from_bits_truncate(v);
let supported = Algorithms::from_bits_truncate(v);
let preferred = Algorithms::from_bits_truncate(v >> 1);

Self::new(supported, preferred)
}
Expand All @@ -90,7 +62,7 @@ impl Compression {
// 1 0 1 0 | Supported
// -------
// 1 1 1 1
let joined = (supported << 1) | preferred;
let joined = supported | (preferred << 1);

Self(joined)
}
Expand Down Expand Up @@ -138,20 +110,48 @@ impl Compression {

pub(crate) const fn supported(self) -> Algorithms {
// `preferred` bits would be discarded.
Algorithms::from_bits_truncate(self.0 >> 1)
Algorithms::from_bits_truncate(self.0)
}

pub(crate) const fn preferred(self) -> Algorithms {
// `supported` bits would be discarded.
Algorithms::from_bits_truncate(self.0)
Algorithms::from_bits_truncate(self.0 >> 1)
}
}

bitflags::bitflags! {
// Actually, 24 bits.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Algorithms: u32 {
const LZ4 = 1;
// NB: Shift by 2: `const ZSTD = 1 << 2;`.
impl fmt::Display for Compression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn write_array(
hide: Option<Algorithms>,
algos: Algorithms,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
write!(f, "[")?;
let mut need_comma = false;
for (name, _) in algos
.iter_names()
.filter(|(_, algo)| hide.map_or(true, |hide| hide.contains(*algo)))
{
if need_comma {
write!(f, ", ")?;
}

f.write_str(name)?;
need_comma = true;
}

write!(f, "]")
}

let preferred = self.preferred();
let supported = self.supported();

write!(f, "(preferred: ")?;
write_array(None, preferred, f)?;
write!(f, ", supported: ")?;
// Don't show preferred in supported, more compact
// output.
write_array(Some(preferred), supported, f)?;
write!(f, ")")
}
}
78 changes: 71 additions & 7 deletions elfo-network/src/socket/capabilities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@ use self::compression::Compression;

pub(crate) mod compression;

/// Things supported by the node.
///
/// ### Layout
///
/// ```text
/// 24 bits 8 bits
/// ┌─────────────────────┬──────────────────┐
/// │ Compression │ Reserved │
/// └─────────────────────┴──────────────────┘
/// ```
///
/// 1. [`Compression`] - compression capabilities.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Capabilities(u32);

impl fmt::Display for Capabilities {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(compression: {})", self.compression())
}
}

impl Capabilities {
pub(crate) const fn new(compression: Compression) -> Self {
let compression = compression.bits() as u32;
let compression = compression.bits();
let joined = compression << 8;

Self(joined)
Expand All @@ -41,3 +47,61 @@ impl Capabilities {
self.0
}
}

impl fmt::Display for Capabilities {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(compression: {})", self.compression())
}
}

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

use self::compression::Algorithms;

#[test]
fn capabilities_format_is_compatible_with_020alpha17() {
let caps = Capabilities::new(Compression::new(Algorithms::LZ4, Algorithms::empty()));
let lz4_bit = caps.bits() & (1 << 8);

assert_eq!(lz4_bit, 1 << 8);
}

#[test]
fn compression_capabilities_encoded_right_way() {
#[track_caller]
fn case(create: (Algorithms, Algorithms), expect: (Algorithms, Algorithms)) {
let caps = Capabilities::new(Compression::new(create.0, create.1));
let compr = caps.compression();

assert_eq!(compr.supported(), expect.0);
assert_eq!(compr.preferred(), expect.1);

// Just in case we should decode same caps.

let bits = caps.bits();
let same_caps = Capabilities::from_bits_truncate(bits);

assert_eq!(caps, same_caps);
}

// Supported does not implies preferred.
case(
(Algorithms::LZ4, Algorithms::empty()),
(Algorithms::LZ4, Algorithms::empty()),
);

// Preferred implies supported.
case(
(Algorithms::empty(), Algorithms::LZ4),
(Algorithms::LZ4, Algorithms::LZ4),
);

// Nothing ever happens.
case(
(Algorithms::empty(), Algorithms::empty()),
(Algorithms::empty(), Algorithms::empty()),
);
}
}
45 changes: 0 additions & 45 deletions elfo-network/src/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,51 +309,6 @@ mod tests {
#[derive(PartialEq)]
struct TestSocketMessage(String);

#[test]
fn capabilities_format_is_compatible_with_020alpha17() {
let caps = Capabilities::new(Compression::new(Algorithms::LZ4, Algorithms::empty()));
let lz4_bit = caps.bits() & (1 << 8);

assert_eq!(lz4_bit, 1 << 8);
}

#[test]
fn compression_capabilities_encoded_right_way() {
#[track_caller]
fn case(create: (Algorithms, Algorithms), expect: (Algorithms, Algorithms)) {
let caps = Capabilities::new(Compression::new(create.0, create.1));
let compr = caps.compression();

assert_eq!(compr.supported(), expect.0);
assert_eq!(compr.preferred(), expect.1);

// Just in case we should decode same caps.

let bits = caps.bits();
let same_caps = Capabilities::from_bits_truncate(bits);

assert_eq!(caps, same_caps);
}

// Supported does not implies preferred.
case(
(Algorithms::LZ4, Algorithms::empty()),
(Algorithms::LZ4, Algorithms::empty()),
);

// Preferred implies supported.
case(
(Algorithms::empty(), Algorithms::LZ4),
(Algorithms::LZ4, Algorithms::LZ4),
);

// Nothing ever happens.
case(
(Algorithms::empty(), Algorithms::empty()),
(Algorithms::empty(), Algorithms::empty()),
);
}

fn feed_frame(client_socket: &mut Socket, envelope: &NetworkEnvelope) {
for _ in 0..100 {
client_socket
Expand Down

0 comments on commit 198be9d

Please sign in to comment.