Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.

Commit 24d8b36

Browse files
authored
perf(breaking): improve serialization performance with serde_bytes (#16)
1 parent c9f9083 commit 24d8b36

3 files changed

Lines changed: 86 additions & 20 deletions

File tree

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ openmls = { git = "https://github.com/openmls/openmls.git", rev = "e19efc810cf6c
1515
openmls_rust_crypto = { git = "https://github.com/openmls/openmls.git", rev = "e19efc810cf6c703b2ec8cc4fd7661a3c17e42d1" }
1616
thiserror = "2.0"
1717
chrono = { version = "0.4", features = ["serde"] }
18+
serde_bytes = "0.11.17"

src/memory_provider.rs

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use openmls_traits::{
1717
},
1818
};
1919
use serde::{Deserialize, Serialize, de::DeserializeOwned};
20+
use serde_bytes::{ByteBuf, Bytes};
2021

2122
use crate::{
2223
group::errors::StorageError,
@@ -25,10 +26,18 @@ use crate::{
2526

2627
#[derive(Serialize, Deserialize, Default)]
2728
struct PublicGroupState {
29+
#[serde(with = "serde_bytes")]
2830
treesync: Vec<u8>,
31+
#[serde(with = "serde_bytes")]
2932
interim_transcript_hash: Vec<u8>,
33+
#[serde(with = "serde_bytes")]
3034
context: Vec<u8>,
35+
#[serde(with = "serde_bytes")]
3136
confirmation_tag: Vec<u8>,
37+
#[serde(
38+
serialize_with = "serde_btreemap_bytes::serialize",
39+
deserialize_with = "serde_btreemap_bytes::deserialize"
40+
)]
3241
proposal_queue: BTreeMap<Vec<u8>, Vec<u8>>,
3342
}
3443

@@ -368,39 +377,45 @@ impl<C: Codec> PublicStorageProvider<CURRENT_VERSION> for MlsAssistMemoryStorage
368377
}
369378
}
370379

371-
#[derive(Default, Serialize, Deserialize)]
380+
#[derive(Default, Deserialize)]
372381
struct SerializableMlsAssistMemoryStorage {
373-
storage_bytes: Vec<(Vec<u8>, Vec<u8>)>,
374-
past_group_states_bytes: Vec<(Vec<u8>, Vec<u8>)>,
375-
group_infos_bytes: Vec<(Vec<u8>, Vec<u8>)>,
382+
storage_bytes: Vec<(ByteBuf, ByteBuf)>,
383+
past_group_states_bytes: Vec<(ByteBuf, ByteBuf)>,
384+
group_infos_bytes: Vec<(ByteBuf, ByteBuf)>,
385+
}
386+
387+
#[derive(Default, Serialize)]
388+
struct SerializableMlsAssistMemoryStorageRef<'a> {
389+
storage_bytes: Vec<(&'a Bytes, ByteBuf)>,
390+
past_group_states_bytes: Vec<(&'a Bytes, &'a Bytes)>,
391+
group_infos_bytes: Vec<(&'a Bytes, &'a Bytes)>,
376392
}
377393

378394
impl<C: Codec> MlsAssistMemoryStorage<C> {
379395
pub fn serialize(&self) -> Result<Vec<u8>, C::Error> {
380396
let storage = self.group_states.read().unwrap();
381397
let storage_bytes = storage
382398
.iter()
383-
.map(|(key, value)| Ok((key.clone(), C::to_vec(value)?)))
399+
.map(|(key, value)| Ok((Bytes::new(key), C::to_vec(value)?.into())))
384400
.collect::<Result<Vec<_>, _>>()?;
385-
let past_group_states_bytes = self
386-
.past_group_states
387-
.read()
388-
.unwrap()
401+
let past_group_states = self.past_group_states.read().unwrap();
402+
let past_group_states_bytes = past_group_states
389403
.iter()
390404
.map(|(group_id_bytes, past_group_states_bytes)| {
391-
(group_id_bytes.clone(), past_group_states_bytes.clone())
405+
(
406+
Bytes::new(group_id_bytes),
407+
Bytes::new(past_group_states_bytes),
408+
)
392409
})
393410
.collect();
394-
let group_infos_bytes = self
395-
.group_infos
396-
.read()
397-
.unwrap()
411+
let group_infos = self.group_infos.read().unwrap();
412+
let group_infos_bytes = group_infos
398413
.iter()
399414
.map(|(group_id_bytes, group_info_bytes)| {
400-
(group_id_bytes.clone(), group_info_bytes.clone())
415+
(Bytes::new(group_id_bytes), Bytes::new(group_info_bytes))
401416
})
402417
.collect();
403-
let serialized = SerializableMlsAssistMemoryStorage {
418+
let serialized = SerializableMlsAssistMemoryStorageRef {
404419
storage_bytes,
405420
past_group_states_bytes,
406421
group_infos_bytes,
@@ -410,15 +425,26 @@ impl<C: Codec> MlsAssistMemoryStorage<C> {
410425

411426
pub fn deserialize(serialized: &[u8]) -> Result<Self, C::Error> {
412427
let deserialized: SerializableMlsAssistMemoryStorage = C::from_slice(serialized)?;
413-
let past_group_states =
414-
RwLock::new(deserialized.past_group_states_bytes.into_iter().collect());
415-
let group_infos = RwLock::new(deserialized.group_infos_bytes.into_iter().collect());
428+
let past_group_states = RwLock::new(
429+
deserialized
430+
.past_group_states_bytes
431+
.into_iter()
432+
.map(|(k, v)| (k.into_vec(), v.into_vec()))
433+
.collect(),
434+
);
435+
let group_infos = RwLock::new(
436+
deserialized
437+
.group_infos_bytes
438+
.into_iter()
439+
.map(|(k, v)| (k.into_vec(), v.into_vec()))
440+
.collect(),
441+
);
416442
let storage = Self {
417443
group_states: RwLock::new(
418444
deserialized
419445
.storage_bytes
420446
.into_iter()
421-
.map(|(k, v)| Ok((k, C::from_slice(&v)?)))
447+
.map(|(k, v)| Ok((k.into_vec(), C::from_slice(&v)?)))
422448
.collect::<Result<HashMap<_, _>, _>>()?,
423449
),
424450
past_group_states,
@@ -533,3 +559,32 @@ impl<C: Codec> MlsAssistProvider for MlsAssistRustCrypto<C> {
533559
&self.crypto
534560
}
535561
}
562+
563+
mod serde_btreemap_bytes {
564+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
565+
use serde_bytes::{ByteBuf, Bytes};
566+
use std::collections::BTreeMap;
567+
568+
pub fn serialize<S>(map: &BTreeMap<Vec<u8>, Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
569+
where
570+
S: Serializer,
571+
{
572+
let vec: Vec<(&Bytes, &Bytes)> = map
573+
.iter()
574+
.map(|(k, v)| (Bytes::new(k.as_slice()), Bytes::new(v.as_slice())))
575+
.collect();
576+
vec.serialize(serializer)
577+
}
578+
579+
pub fn deserialize<'de, D>(deserializer: D) -> Result<BTreeMap<Vec<u8>, Vec<u8>>, D::Error>
580+
where
581+
D: Deserializer<'de>,
582+
{
583+
let vec: Vec<(ByteBuf, ByteBuf)> = Vec::deserialize(deserializer)?;
584+
let map: BTreeMap<Vec<u8>, Vec<u8>> = vec
585+
.into_iter()
586+
.map(|(k, v)| (k.to_vec(), v.to_vec()))
587+
.collect();
588+
Ok(map)
589+
}
590+
}

0 commit comments

Comments
 (0)