diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 11d3cd52a..b5431e2f2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,4 +16,3 @@ jobs: # clutter target/debug/deps with multiple copies of things. run: for file in $(find mdbook -name '*.md'); do rustdoc --test $file -L ./target/debug/deps; done - run: cargo test - - run: cargo test --features bincode diff --git a/communication/Cargo.toml b/communication/Cargo.toml index 45c797e08..9860f1ec3 100644 --- a/communication/Cargo.toml +++ b/communication/Cargo.toml @@ -18,12 +18,10 @@ default = ["getopts"] [dependencies] getopts = { version = "0.2.14", optional = true } -bincode = { version = "1.0", optional = true } +bincode = { version = "1.0" } byteorder = "1.5" serde_derive = "1.0" serde = "1.0" -abomonation = "0.7" -abomonation_derive = "0.5" timely_bytes = { path = "../bytes", version = "0.12" } timely_logging = { path = "../logging", version = "0.12" } crossbeam-channel = "0.5.0" diff --git a/communication/src/allocator/zero_copy/mod.rs b/communication/src/allocator/zero_copy/mod.rs index 81b90c01f..7d0de7c01 100644 --- a/communication/src/allocator/zero_copy/mod.rs +++ b/communication/src/allocator/zero_copy/mod.rs @@ -1,8 +1,12 @@ //! Allocators based on serialized data which avoid copies. //! -//! These allocators are based on `Abomonation` serialization, and its ability to deserialized -//! typed Rust data in-place. They surface references to data, often ultimately referencing the +//! These allocators were based on `Abomonation` serialization, and its ability to deserialized +//! typed Rust data in-place. They surfaced references to data, often ultimately referencing the //! raw binary data they initial received. +//! +//! For the moment, they no longer use Abomonation due to its unsafety, and instead rely on the +//! use of `Message::from_bytes` which .. could .. use Abomonation or something safer, but uses +//! `bincode` at of this writing. pub mod bytes_slab; pub mod bytes_exchange; diff --git a/communication/src/allocator/zero_copy/push_pull.rs b/communication/src/allocator/zero_copy/push_pull.rs index fe423c21a..c57f60a4b 100644 --- a/communication/src/allocator/zero_copy/push_pull.rs +++ b/communication/src/allocator/zero_copy/push_pull.rs @@ -90,7 +90,7 @@ impl Pull> for Puller { self.receiver .borrow_mut() .pop_front() - .map(|bytes| unsafe { Message::from_bytes(bytes) }); + .map(Message::from_bytes); &mut self.current } @@ -134,7 +134,7 @@ impl Pull> for PullerInner { self.receiver .borrow_mut() .pop_front() - .map(|bytes| unsafe { Message::from_bytes(bytes) }); + .map(Message::from_bytes); &mut self.current } diff --git a/communication/src/lib.rs b/communication/src/lib.rs index e3302cdb0..86853cec6 100644 --- a/communication/src/lib.rs +++ b/communication/src/lib.rs @@ -8,8 +8,7 @@ //! receive endpoint. Messages sent into a send endpoint will eventually be received by the corresponding worker, //! if it receives often enough. The point-to-point channels are each FIFO, but with no fairness guarantees. //! -//! To be communicated, a type must implement the [`Serialize`](serde::Serialize) trait when using the -//! `bincode` feature or the [`Abomonation`](abomonation::Abomonation) trait when not. +//! To be communicated, a type must implement the [`Serialize`](serde::Serialize) trait. //! //! Channel endpoints also implement a lower-level `push` and `pull` interface (through the [`Push`](Push) and [`Pull`](Pull) //! traits), which is used for more precise control of resources. @@ -77,14 +76,9 @@ #[cfg(feature = "getopts")] extern crate getopts; -#[cfg(feature = "bincode")] extern crate bincode; -#[cfg(feature = "bincode")] extern crate serde; -extern crate abomonation; -#[macro_use] extern crate abomonation_derive; - extern crate timely_bytes as bytes; extern crate timely_logging as logging_core; @@ -97,10 +91,7 @@ pub mod buzzer; use std::any::Any; -#[cfg(feature = "bincode")] use serde::{Serialize, Deserialize}; -#[cfg(not(feature = "bincode"))] -use abomonation::Abomonation; pub use allocator::Generic as Allocator; pub use allocator::Allocate; @@ -108,15 +99,7 @@ pub use initialize::{initialize, initialize_from, Config, WorkerGuards}; pub use message::Message; /// A composite trait for types that may be used with channels. -#[cfg(not(feature = "bincode"))] -pub trait Data : Send+Sync+Any+Abomonation+'static { } -#[cfg(not(feature = "bincode"))] -impl Data for T { } - -/// A composite trait for types that may be used with channels. -#[cfg(feature = "bincode")] pub trait Data : Send+Sync+Any+Serialize+for<'a>Deserialize<'a>+'static { } -#[cfg(feature = "bincode")] implDeserialize<'a>+'static> Data for T { } /// Pushing elements of type `T`. diff --git a/communication/src/logging.rs b/communication/src/logging.rs index 4556d6447..7b0113182 100644 --- a/communication/src/logging.rs +++ b/communication/src/logging.rs @@ -1,7 +1,9 @@ //! Configuration and events for communication logging. +use serde::{Serialize, Deserialize}; + /// Configuration information about a communication thread. -#[derive(Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] pub struct CommunicationSetup { /// True when this is a send thread (or the receive thread). pub sender: bool, @@ -12,7 +14,7 @@ pub struct CommunicationSetup { } /// Various communication events. -#[derive(Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] pub enum CommunicationEvent { /// An observed message. Message(MessageEvent), @@ -21,7 +23,7 @@ pub enum CommunicationEvent { } /// An observed message. -#[derive(Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] pub struct MessageEvent { /// true for send event, false for receive event pub is_send: bool, @@ -30,7 +32,7 @@ pub struct MessageEvent { } /// Starting or stopping communication threads. -#[derive(Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] pub struct StateEvent { /// Is the thread a send (vs a recv) thread. pub send: bool, diff --git a/communication/src/message.rs b/communication/src/message.rs index 1289498e8..8d3b325ba 100644 --- a/communication/src/message.rs +++ b/communication/src/message.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use bytes::arc::Bytes; -use abomonation; use crate::Data; /// Either an immutable or mutable reference. @@ -68,8 +67,6 @@ pub struct Message { /// Possible returned representations from a channel. enum MessageContents { - /// Binary representation. Only available as a reference. - Binary(abomonation::abomonated::Abomonated), /// Rust typed instance. Available for ownership. Owned(T), /// Atomic reference counted. Only available as a reference. @@ -88,7 +85,6 @@ impl Message { /// Destructures and returns any typed data. pub fn if_typed(self) -> Option { match self.payload { - MessageContents::Binary(_) => None, MessageContents::Owned(typed) => Some(typed), MessageContents::Arc(_) => None, } @@ -96,7 +92,6 @@ impl Message { /// Returns a mutable reference, if typed. pub fn if_mut(&mut self) -> Option<&mut T> { match &mut self.payload { - MessageContents::Binary(_) => None, MessageContents::Owned(typed) => Some(typed), MessageContents::Arc(_) => None, } @@ -108,54 +103,12 @@ impl Message { /// data are serialized binary data. pub fn as_ref_or_mut(&mut self) -> RefOrMut { match &mut self.payload { - MessageContents::Binary(bytes) => { RefOrMut::Ref(bytes) }, MessageContents::Owned(typed) => { RefOrMut::Mut(typed) }, MessageContents::Arc(typed) => { RefOrMut::Ref(typed) }, } } } -// These methods require `T` to implement `Abomonation`, for serialization functionality. -#[cfg(not(feature = "bincode"))] -impl Message { - /// Wrap bytes as a message. - /// - /// # Safety - /// - /// This method is unsafe, in that `Abomonated::new()` is unsafe: it presumes that - /// the binary data can be safely decoded, which is unsafe for e.g. UTF8 data and - /// enumerations (perhaps among many other types). - pub unsafe fn from_bytes(bytes: Bytes) -> Self { - let abomonated = abomonation::abomonated::Abomonated::new(bytes).expect("Abomonated::new() failed."); - Message { payload: MessageContents::Binary(abomonated) } - } - - /// The number of bytes required to serialize the data. - pub fn length_in_bytes(&self) -> usize { - match &self.payload { - MessageContents::Binary(bytes) => { bytes.as_bytes().len() }, - MessageContents::Owned(typed) => { abomonation::measure(typed) }, - MessageContents::Arc(typed) =>{ abomonation::measure::(&**typed) } , - } - } - - /// Writes the binary representation into `writer`. - pub fn into_bytes(&self, writer: &mut W) { - match &self.payload { - MessageContents::Binary(bytes) => { - writer.write_all(bytes.as_bytes()).expect("Message::into_bytes(): write_all failed."); - }, - MessageContents::Owned(typed) => { - unsafe { abomonation::encode(typed, writer).expect("Message::into_bytes(): Abomonation::encode failed"); } - }, - MessageContents::Arc(typed) => { - unsafe { abomonation::encode(&**typed, writer).expect("Message::into_bytes(): Abomonation::encode failed"); } - }, - } - } -} - -#[cfg(feature = "bincode")] impl Message { /// Wrap bytes as a message. pub fn from_bytes(bytes: Bytes) -> Self { @@ -166,7 +119,6 @@ impl Message { /// The number of bytes required to serialize the data. pub fn length_in_bytes(&self) -> usize { match &self.payload { - MessageContents::Binary(bytes) => { bytes.as_bytes().len() }, MessageContents::Owned(typed) => { ::bincode::serialized_size(&typed).expect("bincode::serialized_size() failed") as usize }, @@ -179,9 +131,6 @@ impl Message { /// Writes the binary representation into `writer`. pub fn into_bytes(&self, writer: &mut W) { match &self.payload { - MessageContents::Binary(bytes) => { - writer.write_all(bytes.as_bytes()).expect("Message::into_bytes(): write_all failed."); - }, MessageContents::Owned(typed) => { ::bincode::serialize_into(writer, &typed).expect("bincode::serialize_into() failed"); }, @@ -197,7 +146,6 @@ impl ::std::ops::Deref for Message { fn deref(&self) -> &Self::Target { // TODO: In principle we have aready decoded, but let's go again match &self.payload { - MessageContents::Binary(bytes) => { bytes }, MessageContents::Owned(typed) => { typed }, MessageContents::Arc(typed) => { typed }, } @@ -208,7 +156,6 @@ impl Message { /// Produces a typed instance of the wrapped element. pub fn into_typed(self) -> T { match self.payload { - MessageContents::Binary(bytes) => bytes.clone(), MessageContents::Owned(instance) => instance, // TODO: Could attempt `Arc::try_unwrap()` here. MessageContents::Arc(instance) => (*instance).clone(), @@ -218,7 +165,6 @@ impl Message { pub fn as_mut(&mut self) -> &mut T { let cloned: Option = match &self.payload { - MessageContents::Binary(bytes) => Some((*bytes).clone()), MessageContents::Owned(_) => None, // TODO: Could attempt `Arc::try_unwrap()` here. MessageContents::Arc(typed) => Some((**typed).clone()), diff --git a/communication/src/networking.rs b/communication/src/networking.rs index 9c3f7a953..433c2a911 100644 --- a/communication/src/networking.rs +++ b/communication/src/networking.rs @@ -9,6 +9,7 @@ use std::thread::sleep; use std::time::Duration; use byteorder::{ReadBytesExt, WriteBytesExt}; +use serde::{Deserialize, Serialize}; // This constant is sent along immediately after establishing a TCP stream, so // that it is easy to sniff out Timely traffic when it is multiplexed with @@ -21,7 +22,7 @@ type ByteOrder = byteorder::BigEndian; /// Framing data for each `Vec` transmission, indicating a typed channel, the source and /// destination workers, and the length in bytes. // *Warning*: Adding, removing and altering fields requires to adjust the implementation below! -#[derive(Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] pub struct MessageHeader { /// index of channel. pub channel: usize, diff --git a/mdbook/src/chapter_4/chapter_4_5.md b/mdbook/src/chapter_4/chapter_4_5.md index ea63e3c39..16eee37f9 100644 --- a/mdbook/src/chapter_4/chapter_4_5.md +++ b/mdbook/src/chapter_4/chapter_4_5.md @@ -17,33 +17,21 @@ struct YourStruct { .. } ## The `ExchangeData` trait -The `ExchangeData` trait is more complicated, and is established in the `communication/` module. There are two options for this trait, which are determined by whether you use the `--bincode` feature at compilation, or not. +The `ExchangeData` trait is more complicated, and is established in the `communication/` module. The trait is a synonym for -* If you use `--bincode` then the trait is a synonym for - - ```rust,ignore - Send+Sync+Any+serde::Serialize+for<'a>serde::Deserialize<'a>+'static - ``` - - where `serde` is Rust's most popular serialization and deserialization crate. A great many types implement these traits. If your types does not, you should add these decorators to their definition: - - ```rust,ignore - #[derive(Serialize, Deserialize)] - ``` - - You must include the `serde` crate, and if not on Rust 2018 the `serde_derive` crate. - - The downside to the `--bincode` flag is that deserialization will always involve a clone of the data, which has the potential to adversely impact performance. For example, if you have structures that contain lots of strings, timely dataflow will create allocations for each string even if you do not plan to use all of them. +```rust,ignore +Send+Sync+Any+serde::Serialize+for<'a>serde::Deserialize<'a>+'static +``` -* If you do not use the `--bincode` feature, then the `Serialize` and `Deserialize` requirements are replaced by `Abomonation`, from the `abomonation` crate. This trait allows in-place deserialization, but is implemented for fewer types, and has the potential to be a bit scarier (due to in-place pointer correction). +where `serde` is Rust's most popular serialization and deserialization crate. A great many types implement these traits. If your types does not, you should add these decorators to their definition: - Your types likely do not implement `Abomonation` by default, but you can similarly use +```rust,ignore +#[derive(Serialize, Deserialize)] +``` - ```rust,ignore - #[derive(Abomonation)] - ``` +You must include the `serde` crate, and if not on Rust 2018 the `serde_derive` crate. - You must include the `abomonation` and `abomonation_derive` crate for this to work correctly. +The downside to is that deserialization will always involve a clone of the data, which has the potential to adversely impact performance. For example, if you have structures that contain lots of strings, timely dataflow will create allocations for each string even if you do not plan to use all of them. ## An example @@ -140,7 +128,7 @@ impl TreeNode { We get a new error. A not especially helpful error. It says that it cannot find an `exchange` method, or more specifically that one exists but it doesn't apply to our type at hand. This is because the data need to satisfy the `ExchangeData` trait but do not. It would be better if this were clearer in the error messages, I agree. -We can fix the problem two ways. First, if you would like to use `bincode`, then we update the source like so: +The fix is to update the source like so: ```rust,ignore #[macro_use] @@ -154,10 +142,10 @@ struct TreeNode { } ``` -and make sure to include the `serde_derive` and `serde` crates. Now when we run things (notice the `--features` flag) we see: +and make sure to include the `serde_derive` and `serde` crates. ```ignore - Echidnatron% cargo run --example types --features bincode + Echidnatron% cargo run --example types Finished dev [unoptimized + debuginfo] target(s) in 0.07s Running `target/debug/examples/types` seen: TreeNode { data: 0, children: [] } diff --git a/timely/Cargo.toml b/timely/Cargo.toml index af629539d..7f6d5226d 100644 --- a/timely/Cargo.toml +++ b/timely/Cargo.toml @@ -17,15 +17,13 @@ license = "MIT" [features] default = ["getopts"] -bincode= ["timely_communication/bincode"] getopts = ["getopts-dep", "timely_communication/getopts"] [dependencies] getopts-dep = { package = "getopts", version = "0.2.14", optional = true } +bincode = { version = "1.0" } serde = "1.0" serde_derive = "1.0" -abomonation = "0.7.3" -abomonation_derive = "0.5" timely_bytes = { path = "../bytes", version = "0.12" } timely_logging = { path = "../logging", version = "0.12" } timely_communication = { path = "../communication", version = "0.12", default-features = false } diff --git a/timely/examples/flatcontainer.rs b/timely/examples/flatcontainer.rs index 3238138bf..1155d9c7a 100644 --- a/timely/examples/flatcontainer.rs +++ b/timely/examples/flatcontainer.rs @@ -1,6 +1,5 @@ //! Wordcount based on flatcontainer. -#[cfg(feature = "bincode")] use { std::collections::HashMap, timely::container::CapacityContainerBuilder, @@ -11,7 +10,6 @@ use { timely::dataflow::ProbeHandle, }; -#[cfg(feature = "bincode")] fn main() { type Container = FlatStack<<(String, i64) as RegionPreference>::Region>; @@ -97,8 +95,3 @@ fn main() { }) .unwrap(); } - -#[cfg(not(feature = "bincode"))] -fn main() { - eprintln!("Example requires feature bincode."); -} diff --git a/timely/examples/rc.rs b/timely/examples/rc.rs index f79ef7472..32278dfe5 100644 --- a/timely/examples/rc.rs +++ b/timely/examples/rc.rs @@ -1,21 +1,14 @@ -extern crate abomonation; extern crate timely; use std::rc::Rc; use timely::dataflow::{InputHandle, ProbeHandle}; use timely::dataflow::operators::{Input, Inspect, Probe}; -use abomonation::Abomonation; #[derive(Debug, Clone)] pub struct Test { _field: Rc, } -impl Abomonation for Test { - unsafe fn entomb(&self, _write: &mut W) -> ::std::io::Result<()> { panic!() } - unsafe fn exhume<'a,'b>(&'a mut self, _bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { panic!() } -} - fn main() { // initializes and runs a timely dataflow. timely::execute_from_args(std::env::args(), |worker| { diff --git a/timely/src/dataflow/channels/mod.rs b/timely/src/dataflow/channels/mod.rs index bf608b246..e38095a46 100644 --- a/timely/src/dataflow/channels/mod.rs +++ b/timely/src/dataflow/channels/mod.rs @@ -14,7 +14,7 @@ pub mod pact; pub type Bundle = crate::communication::Message>; /// A serializable representation of timestamped data. -#[derive(Clone, Abomonation, Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct Message { /// The timestamp associated with the message. pub time: T, diff --git a/timely/src/dataflow/operators/core/capture/event.rs b/timely/src/dataflow/operators/core/capture/event.rs index 3f7961e28..259d7ca4c 100644 --- a/timely/src/dataflow/operators/core/capture/event.rs +++ b/timely/src/dataflow/operators/core/capture/event.rs @@ -5,7 +5,7 @@ //! of timestamps. /// Data and progress events of the captured stream. -#[derive(Debug, Clone, Abomonation, Hash, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)] +#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)] pub enum Event { /// Progress received via `push_external_progress`. Progress(Vec<(T, i64)>), @@ -118,8 +118,8 @@ pub mod link { /// A binary event pusher and iterator. pub mod binary { - use std::io::Write; - use abomonation::Abomonation; + use serde::{de::DeserializeOwned, Serialize}; + use super::{Event, EventPusher, EventIterator}; /// A wrapper for `W: Write` implementing `EventPusher`. @@ -138,22 +138,17 @@ pub mod binary { } } - impl EventPusher for EventWriter { + impl EventPusher for EventWriter { fn push(&mut self, event: Event) { // TODO: `push` has no mechanism to report errors, so we `unwrap`. - unsafe { ::abomonation::encode(&event, &mut self.stream).expect("Event abomonation/write failed"); } + ::bincode::serialize_into(&mut self.stream, &event).expect("Event bincode/write failed"); } } /// A Wrapper for `R: Read` implementing `EventIterator`. pub struct EventReader { reader: R, - bytes: Vec, - buff1: Vec, - buff2: Vec, - consumed: usize, - valid: usize, - phant: ::std::marker::PhantomData<(T, C)>, + decoded: Option>, } impl EventReader { @@ -161,40 +156,15 @@ pub mod binary { pub fn new(r: R) -> Self { Self { reader: r, - bytes: vec![0u8; 1 << 20], - buff1: vec![], - buff2: vec![], - consumed: 0, - valid: 0, - phant: ::std::marker::PhantomData, + decoded: None, } } } - impl EventIterator for EventReader { + impl EventIterator for EventReader { fn next(&mut self) -> Option<&Event> { - - // if we can decode something, we should just return it! :D - if unsafe { ::abomonation::decode::>(&mut self.buff1[self.consumed..]) }.is_some() { - let (item, rest) = unsafe { ::abomonation::decode::>(&mut self.buff1[self.consumed..]) }.unwrap(); - self.consumed = self.valid - rest.len(); - return Some(item); - } - // if we exhaust data we should shift back (if any shifting to do) - if self.consumed > 0 { - self.buff2.clear(); - self.buff2.write_all(&self.buff1[self.consumed..]).unwrap(); - ::std::mem::swap(&mut self.buff1, &mut self.buff2); - self.valid = self.buff1.len(); - self.consumed = 0; - } - - if let Ok(len) = self.reader.read(&mut self.bytes[..]) { - self.buff1.write_all(&self.bytes[..len]).unwrap(); - self.valid = self.buff1.len(); - } - - None + self.decoded = ::bincode::deserialize_from(&mut self.reader).ok(); + self.decoded.as_ref() } } } diff --git a/timely/src/lib.rs b/timely/src/lib.rs index 96d7c7d99..d008c130d 100644 --- a/timely/src/lib.rs +++ b/timely/src/lib.rs @@ -2,8 +2,7 @@ //! //! The code is organized in crates and modules that are meant to depend as little as possible on each other. //! -//! **Serialization**: The [`abomonation`] crate contains simple and highly unsafe -//! serialization routines. +//! **Serialization**: Timely uses the `bincode` crate for serialization. Performance could be improved. //! //! **Communication**: The [`timely_communication`] crate defines several primitives for //! communicating between dataflow workers, and across machine boundaries. @@ -57,9 +56,7 @@ #![forbid(missing_docs)] -#[macro_use] -extern crate abomonation_derive; -extern crate abomonation; +extern crate bincode; extern crate serde; #[macro_use] extern crate serde_derive; diff --git a/timely/src/logging.rs b/timely/src/logging.rs index 39944ade0..655951d76 100644 --- a/timely/src/logging.rs +++ b/timely/src/logging.rs @@ -48,7 +48,7 @@ impl Drop for BatchLogger where P: EventPusher, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// External progress pushed onto an operator pub struct PushProgressEvent { /// Worker-unique operator identifier pub op_id: usize, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Message send or receive event pub struct MessagesEvent { /// `true` if send event, `false` if receive event. @@ -170,7 +170,7 @@ pub struct MessagesEvent { } /// Records the starting and stopping of an operator. -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] pub enum StartStop { /// Operator starts. Start, @@ -178,7 +178,7 @@ pub enum StartStop { Stop, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Operator start or stop. pub struct ScheduleEvent { /// Worker-unique identifier for the operator, linkable to the identifiers in `OperatesEvent`. @@ -196,14 +196,14 @@ impl ScheduleEvent { pub fn stop(id: usize) -> Self { ScheduleEvent { id, start_stop: StartStop::Stop } } } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Operator shutdown. pub struct ShutdownEvent { /// Worker-unique identifier for the operator, linkable to the identifiers in `OperatesEvent`. pub id: usize, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Application-defined code start or stop pub struct ApplicationEvent { /// Unique event type identifier @@ -212,28 +212,28 @@ pub struct ApplicationEvent { pub is_start: bool, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Application-defined code start or stop pub struct GuardedMessageEvent { /// True when activity begins, false when it stops pub is_start: bool, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Application-defined code start or stop pub struct GuardedProgressEvent { /// True when activity begins, false when it stops pub is_start: bool, } -#[derive(Serialize, Deserialize, Abomonation, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)] /// Identifier of the worker that generated a log line pub struct TimelySetup { /// Worker index pub index: usize, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Kind of communication channel pub enum CommChannelKind { /// Communication channel carrying progress information @@ -242,7 +242,7 @@ pub enum CommChannelKind { Data, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Event on a communication channel pub struct CommChannelsEvent { /// Communication channel identifier @@ -251,7 +251,7 @@ pub struct CommChannelsEvent { pub kind: CommChannelKind, } -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// Input logic start/stop pub struct InputEvent { /// True when activity begins, false when it stops @@ -259,7 +259,7 @@ pub struct InputEvent { } /// Records the starting and stopping of an operator. -#[derive(Serialize, Deserialize, Abomonation, Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] pub enum ParkEvent { /// Worker parks. Park(Option), @@ -274,7 +274,7 @@ impl ParkEvent { pub fn unpark() -> Self { ParkEvent::Unpark } } -#[derive(Serialize, Deserialize, Debug, Clone, Abomonation, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] /// An event in a timely worker pub enum TimelyEvent { /// Operator creation. diff --git a/timely/src/order.rs b/timely/src/order.rs index 982724255..4e891c755 100644 --- a/timely/src/order.rs +++ b/timely/src/order.rs @@ -72,7 +72,7 @@ mod product { /// /// We use `Product` rather than `(TOuter, TInner)` so that we can derive our own `PartialOrder`, /// because Rust just uses the lexicographic total order. - #[derive(Abomonation, Copy, Clone, Hash, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)] + #[derive(Copy, Clone, Hash, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)] pub struct Product { /// Outer timestamp. pub outer: TOuter, diff --git a/timely/src/progress/change_batch.rs b/timely/src/progress/change_batch.rs index b87ffdac6..77593e34c 100644 --- a/timely/src/progress/change_batch.rs +++ b/timely/src/progress/change_batch.rs @@ -11,7 +11,7 @@ use smallvec::SmallVec; /// until they are required. This means that several seemingly simple operations may be expensive, in /// that they may provoke a compaction. I've tried to prevent exposing methods that allow surprisingly /// expensive operations; all operations should take an amortized constant or logarithmic time. -#[derive(Clone, Debug, Eq, PartialEq, Abomonation, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct ChangeBatch { // A list of updates to which we append. updates: SmallVec<[(T, i64); X]>, diff --git a/timely/src/progress/frontier.rs b/timely/src/progress/frontier.rs index d49192583..6a1eaec1c 100644 --- a/timely/src/progress/frontier.rs +++ b/timely/src/progress/frontier.rs @@ -15,7 +15,7 @@ use crate::order::{PartialOrder, TotalOrder}; /// Two antichains are equal if they contain the same set of elements, even if in different orders. /// This can make equality testing quadratic, though linear in the common case that the sequences /// are identical. -#[derive(Debug, Abomonation, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct Antichain { elements: SmallVec<[T; 1]> } @@ -372,7 +372,7 @@ impl ::std::iter::IntoIterator for Antichain { /// The `MutableAntichain` implementation is done with the intent that updates to it are done in batches, /// and it is acceptable to rebuild the frontier from scratch when a batch of updates change it. This means /// that it can be expensive to maintain a large number of counts and change few elements near the frontier. -#[derive(Clone, Debug, Abomonation, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct MutableAntichain { updates: ChangeBatch, frontier: Vec, diff --git a/timely/src/progress/mod.rs b/timely/src/progress/mod.rs index 5d169c75d..038a6a50c 100644 --- a/timely/src/progress/mod.rs +++ b/timely/src/progress/mod.rs @@ -15,7 +15,7 @@ pub mod reachability; pub mod subgraph; /// A timely dataflow location. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Abomonation, Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)] pub struct Location { /// A scope-local operator identifier. pub node: usize, @@ -57,7 +57,7 @@ impl From for Location { } /// An operator port. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Abomonation, Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)] pub enum Port { /// An operator input. Target(usize),