Skip to content

Commit 3307e10

Browse files
Allow containers to specify their own serialization (#604)
1 parent b411957 commit 3307e10

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

timely/src/dataflow/channels/mod.rs

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,78 @@ impl<T, C: Container> Message<T, C> {
6161
impl<T, C> crate::communication::Bytesable for Message<T, C>
6262
where
6363
T: Serialize + for<'a> Deserialize<'a>,
64-
C: Serialize + for<'a> Deserialize<'a>,
64+
C: ContainerBytes,
6565
{
66-
fn from_bytes(bytes: crate::bytes::arc::Bytes) -> Self {
67-
::bincode::deserialize(&bytes[..]).expect("bincode::deserialize() failed")
66+
fn from_bytes(mut bytes: crate::bytes::arc::Bytes) -> Self {
67+
let mut slice = &bytes[..];
68+
let from: usize = ::bincode::deserialize(&mut slice).expect("bincode::deserialize() failed");
69+
let seq: usize = ::bincode::deserialize(&mut slice).expect("bincode::deserialize() failed");
70+
let time: T = ::bincode::deserialize(&mut slice).expect("bincode::deserialize() failed");
71+
let bytes_read = bytes.len() - slice.len();
72+
bytes.extract_to(bytes_read);
73+
let data: C = ContainerBytes::from_bytes(bytes);
74+
Self { time, data, from, seq }
6875
}
6976

7077
fn length_in_bytes(&self) -> usize {
71-
::bincode::serialized_size(&self).expect("bincode::serialized_size() failed") as usize
78+
::bincode::serialized_size(&self.from).expect("bincode::serialized_size() failed") as usize +
79+
::bincode::serialized_size(&self.seq).expect("bincode::serialized_size() failed") as usize +
80+
::bincode::serialized_size(&self.time).expect("bincode::serialized_size() failed") as usize +
81+
self.data.length_in_bytes()
7282
}
7383

7484
fn into_bytes<W: ::std::io::Write>(&self, writer: &mut W) {
75-
::bincode::serialize_into(writer, &self).expect("bincode::serialize_into() failed");
85+
::bincode::serialize_into(&mut *writer, &self.from).expect("bincode::serialize_into() failed");
86+
::bincode::serialize_into(&mut *writer, &self.seq).expect("bincode::serialize_into() failed");
87+
::bincode::serialize_into(&mut *writer, &self.time).expect("bincode::serialize_into() failed");
88+
self.data.into_bytes(&mut *writer);
7689
}
77-
}
90+
}
91+
92+
93+
/// A container-oriented version of `Bytesable` that can be implemented here for `Vec<T>` and other containers.
94+
pub trait ContainerBytes {
95+
/// Wrap bytes as `Self`.
96+
fn from_bytes(bytes: crate::bytes::arc::Bytes) -> Self;
97+
98+
/// The number of bytes required to serialize the data.
99+
fn length_in_bytes(&self) -> usize;
100+
101+
/// Writes the binary representation into `writer`.
102+
fn into_bytes<W: ::std::io::Write>(&self, writer: &mut W);
103+
}
104+
105+
mod implementations {
106+
107+
use serde::{Serialize, Deserialize};
108+
use crate::dataflow::channels::ContainerBytes;
109+
110+
impl<T: Serialize + for<'a> Deserialize<'a>> ContainerBytes for Vec<T> {
111+
fn from_bytes(bytes: crate::bytes::arc::Bytes) -> Self {
112+
::bincode::deserialize(&bytes[..]).expect("bincode::deserialize() failed")
113+
}
114+
115+
fn length_in_bytes(&self) -> usize {
116+
::bincode::serialized_size(&self).expect("bincode::serialized_size() failed") as usize
117+
}
118+
119+
fn into_bytes<W: ::std::io::Write>(&self, writer: &mut W) {
120+
::bincode::serialize_into(writer, &self).expect("bincode::serialize_into() failed");
121+
}
122+
}
123+
124+
use crate::container::flatcontainer::FlatStack;
125+
impl<T: Serialize + for<'a> Deserialize<'a> + crate::container::flatcontainer::Region> ContainerBytes for FlatStack<T> {
126+
fn from_bytes(bytes: crate::bytes::arc::Bytes) -> Self {
127+
::bincode::deserialize(&bytes[..]).expect("bincode::deserialize() failed")
128+
}
129+
130+
fn length_in_bytes(&self) -> usize {
131+
::bincode::serialized_size(&self).expect("bincode::serialized_size() failed") as usize
132+
}
133+
134+
fn into_bytes<W: ::std::io::Write>(&self, writer: &mut W) {
135+
::bincode::serialize_into(writer, &self).expect("bincode::serialize_into() failed");
136+
}
137+
}
138+
}

timely/src/dataflow/channels/pact.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ where
6868
// Exchange uses a `Box<Pushable>` because it cannot know what type of pushable will return from the allocator.
6969
impl<T: Timestamp, C, H: 'static> ParallelizationContract<T, C> for ExchangeCore<C, H>
7070
where
71-
C: ExchangeData + PushPartitioned,
71+
C: ExchangeData + PushPartitioned + crate::dataflow::channels::ContainerBytes,
7272
for<'a> H: FnMut(&C::Item<'a>) -> u64
7373
{
7474
type Pusher = ExchangePusher<T, C, LogPusher<T, C, Box<dyn Push<Message<T, C>>>>, H>;

timely/src/dataflow/operators/core/exchange.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub trait Exchange<C: PushPartitioned> {
3030

3131
impl<G: Scope, C> Exchange<C> for StreamCore<G, C>
3232
where
33-
C: PushPartitioned + ExchangeData,
33+
C: PushPartitioned + ExchangeData + crate::dataflow::channels::ContainerBytes,
3434
{
3535
fn exchange<F>(&self, route: F) -> StreamCore<G, C>
3636
where

0 commit comments

Comments
 (0)