From 7e6c0774c428d2d2188c949cc3183a0376f3bc1e Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Mon, 2 Dec 2024 01:13:55 +0300 Subject: [PATCH] Use fixed integer encoding for ticks for server events (#371) --- CHANGELOG.md | 1 + src/core/event_registry/server_event.rs | 37 ++++++++++--------------- src/core/replicon_tick.rs | 13 --------- 3 files changed, 15 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a120f778..0f7e8b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Split the `ctx` module and move event-related contexts under `core::events_registry::ctx` and replication-related contexts under `core::replication_registry::ctx`. - Separate paths from `diagnostics` module by `/` and their parent path now `client/replication` instead of `replication/client`. - Provide replication statistics by sum instead of per second and use `usize` for it. +- Use fixed integer encoding for ticks for server events. - Rename `ServerPlugin::change_timeout` into `ServerPlugin::mutations_timeout`. - Rename `ServerInitTick` into `ServerChangeTick`. - Rename `ReplicatedClient::init_tick` into `ReplicatedClient::change_tick`. diff --git a/src/core/event_registry/server_event.rs b/src/core/event_registry/server_event.rs index d47774d8..5686c246 100644 --- a/src/core/event_registry/server_event.rs +++ b/src/core/event_registry/server_event.rs @@ -519,7 +519,7 @@ unsafe fn receive( for message in client.receive(event_data.channel_id) { let mut cursor = Cursor::new(&*message); if !event_data.is_independent() { - let tick = match DefaultOptions::new().deserialize_from(&mut cursor) { + let tick = match bincode::deserialize_from(&mut cursor) { Ok(tick) => tick, Err(e) => { error!( @@ -671,7 +671,7 @@ unsafe fn serialize_with_padding( event: &E, ) -> bincode::Result { let mut cursor = Cursor::new(Vec::new()); - let padding = [0u8; RepliconTick::MAX_SERIALIZED_SIZE]; + let padding = [0; mem::size_of::()]; cursor.write_all(&padding)?; event_data.serialize(ctx, event, &mut cursor)?; let message = SerializedMessage::Raw(cursor.into_inner()); @@ -685,17 +685,13 @@ enum SerializedMessage { /// /// `padding | message` /// - /// The padding length equals max serialized bytes of [`RepliconTick`]. It should be overwritten before sending + /// The padding length equals to serialized bytes of [`RepliconTick`]. It should be overwritten before sending /// to clients. Raw(Vec), /// A message with serialized tick. /// /// `tick | messsage` - Resolved { - tick: RepliconTick, - tick_size: usize, - bytes: Bytes, - }, + Resolved { tick: RepliconTick, bytes: Bytes }, } impl SerializedMessage { @@ -705,32 +701,27 @@ impl SerializedMessage { match self { // Resolve the raw value into a message with serialized tick. Self::Raw(raw) => { - let mut bytes = std::mem::take(raw); - let tick_size = DefaultOptions::new().serialized_size(&change_tick)? as usize; - let padding = RepliconTick::MAX_SERIALIZED_SIZE - tick_size; - DefaultOptions::new().serialize_into(&mut bytes[padding..], &change_tick)?; - let bytes = Bytes::from(bytes).slice(padding..); + let mut bytes = mem::take(raw); + bincode::serialize_into( + &mut bytes[..mem::size_of::()], + &change_tick, + )?; + let bytes = Bytes::from(bytes); *self = Self::Resolved { tick: change_tick, - tick_size, bytes: bytes.clone(), }; Ok(bytes) } // Get the already-resolved value or reserialize with a different tick. - Self::Resolved { - tick, - tick_size, - bytes, - } => { + Self::Resolved { tick, bytes } => { if *tick == change_tick { return Ok(bytes.clone()); } - let new_tick_size = DefaultOptions::new().serialized_size(&change_tick)? as usize; - let mut new_bytes = Vec::with_capacity(new_tick_size + bytes.len() - *tick_size); - DefaultOptions::new().serialize_into(&mut new_bytes, &change_tick)?; - new_bytes.extend_from_slice(&bytes[*tick_size..]); + let mut new_bytes = Vec::with_capacity(bytes.len()); + bincode::serialize_into(&mut new_bytes, &change_tick)?; + new_bytes.extend_from_slice(&bytes[mem::size_of::()..]); Ok(new_bytes.into()) } } diff --git a/src/core/replicon_tick.rs b/src/core/replicon_tick.rs index 446e2612..aeb4996b 100644 --- a/src/core/replicon_tick.rs +++ b/src/core/replicon_tick.rs @@ -15,9 +15,6 @@ use serde::{Deserialize, Serialize}; pub struct RepliconTick(u32); impl RepliconTick { - /// Maximum number of bytes required to serialize [`Self`] using default [`bincode::DefaultOptions`]. - pub const MAX_SERIALIZED_SIZE: usize = 5; - /// Creates a new instance wrapping the given value. #[inline] pub fn new(value: u32) -> Self { @@ -82,18 +79,8 @@ impl SubAssign for RepliconTick { #[cfg(test)] mod tests { - use bincode::{DefaultOptions, Options}; - use super::*; - #[test] - fn max_serialized_size() { - let max = DefaultOptions::new() - .serialized_size(&RepliconTick(u32::MAX)) - .unwrap(); - assert_eq!(max as usize, RepliconTick::MAX_SERIALIZED_SIZE); - } - #[test] fn tick_comparsion() { assert_eq!(RepliconTick::new(0), RepliconTick::new(0));