Skip to content

Commit

Permalink
Use fixed integer encoding for ticks for server events (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shatur authored Dec 1, 2024
1 parent c99bfca commit 7e6c077
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
37 changes: 14 additions & 23 deletions src/core/event_registry/server_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ unsafe fn receive<E: Event>(
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!(
Expand Down Expand Up @@ -671,7 +671,7 @@ unsafe fn serialize_with_padding<E: Event>(
event: &E,
) -> bincode::Result<SerializedMessage> {
let mut cursor = Cursor::new(Vec::new());
let padding = [0u8; RepliconTick::MAX_SERIALIZED_SIZE];
let padding = [0; mem::size_of::<RepliconTick>()];
cursor.write_all(&padding)?;
event_data.serialize(ctx, event, &mut cursor)?;
let message = SerializedMessage::Raw(cursor.into_inner());
Expand All @@ -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<u8>),
/// A message with serialized tick.
///
/// `tick | messsage`
Resolved {
tick: RepliconTick,
tick_size: usize,
bytes: Bytes,
},
Resolved { tick: RepliconTick, bytes: Bytes },
}

impl SerializedMessage {
Expand All @@ -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::<RepliconTick>()],
&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::<RepliconTick>()..]);
Ok(new_bytes.into())
}
}
Expand Down
13 changes: 0 additions & 13 deletions src/core/replicon_tick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -82,18 +79,8 @@ impl SubAssign<u32> 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));
Expand Down

0 comments on commit 7e6c077

Please sign in to comment.