Change internal bytes representation to Bytes object from bytes crate

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/38/head
trivernis 2 years ago
parent ca264abae8
commit ac471d296e
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

3
Cargo.lock generated

@ -93,11 +93,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bromine"
version = "0.19.0"
version = "0.20.0"
dependencies = [
"async-trait",
"bincode",
"byteorder",
"bytes",
"criterion",
"crossbeam-utils",
"futures",

@ -1,6 +1,6 @@
[package]
name = "bromine"
version = "0.19.0"
version = "0.20.0"
authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018"
readme = "README.md"
@ -31,6 +31,7 @@ trait-bound-typemap = "0.3.3"
rmp-serde = { version = "1.0.0", optional = true }
bincode = { version = "1.3.3", optional = true }
serde_json = { version = "1.0.79", optional = true }
bytes = "1.1.0"
[dependencies.serde]
optional = true

@ -1,3 +1,4 @@
use bytes::Bytes;
use criterion::{black_box, BenchmarkId, Throughput};
use criterion::{criterion_group, criterion_main};
use criterion::{BatchSize, Criterion};
@ -9,17 +10,21 @@ use tokio::runtime::Runtime;
pub const EVENT_NAME: &str = "bench_event";
fn create_event_bytes_reader(data_size: usize) -> Cursor<Vec<u8>> {
let bytes = Event::initiator(None, EVENT_NAME.to_string(), vec![0u8; data_size])
.into_bytes()
.unwrap();
Cursor::new(bytes)
let bytes = Event::initiator(
None,
EVENT_NAME.to_string(),
Bytes::from(vec![0u8; data_size]),
)
.into_bytes()
.unwrap();
Cursor::new(bytes.to_vec())
}
fn event_deserialization(c: &mut Criterion) {
let runtime = Runtime::new().unwrap();
let mut group = c.benchmark_group("event_deserialization");
for size in (0..10)
for size in (0..16)
.step_by(2)
.map(|i| 1024 * 2u32.pow(i as u32) as usize)
{

@ -1,4 +1,5 @@
use bromine::event::Event;
use bytes::Bytes;
use criterion::{
black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput,
};
@ -6,13 +7,17 @@ use criterion::{
pub const EVENT_NAME: &str = "bench_event";
fn create_event(data_size: usize) -> Event {
Event::initiator(None, EVENT_NAME.to_string(), vec![0u8; data_size])
Event::initiator(
None,
EVENT_NAME.to_string(),
Bytes::from(vec![0u8; data_size]),
)
}
fn event_serialization(c: &mut Criterion) {
let mut group = c.benchmark_group("event_serialization");
for size in (0..10)
for size in (0..16)
.step_by(2)
.map(|i| 1024 * 2u32.pow(i as u32) as usize)
{

@ -3,6 +3,7 @@ use crate::error::Result;
use crate::payload::{FromPayload, IntoPayload};
use crate::prelude::{IPCError, IPCResult};
use byteorder::{BigEndian, ReadBytesExt};
use bytes::{BufMut, Bytes, BytesMut};
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::io::Read;
@ -29,14 +30,13 @@ impl Display for ErrorEventData {
}
impl IntoPayload for ErrorEventData {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new();
buf.append(&mut self.code.to_be_bytes().to_vec());
let message_len = self.message.len() as u32;
buf.append(&mut message_len.to_be_bytes().to_vec());
buf.append(&mut self.message.into_bytes());
Ok(buf)
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
let mut buf = BytesMut::new();
buf.put_u16(self.code);
buf.put_u32(self.message.len() as u32);
buf.put(Bytes::from(self.message));
Ok(buf.freeze())
}
}

@ -2,6 +2,7 @@ use crate::error::{Error, Result};
use crate::events::generate_event_id;
use crate::events::payload::FromPayload;
use byteorder::{BigEndian, ReadBytesExt};
use bytes::{BufMut, Bytes, BytesMut};
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::convert::TryFrom;
use std::fmt::Debug;
@ -16,7 +17,7 @@ pub const FORMAT_VERSION: [u8; 3] = [0, 9, 0];
#[derive(Debug)]
pub struct Event {
header: EventHeader,
data: Vec<u8>,
data: Bytes,
}
#[derive(Debug)]
@ -41,21 +42,21 @@ impl Event {
/// Creates a new event that acts as an initiator for further response events
#[tracing::instrument(level = "trace", skip(data))]
#[inline]
pub fn initiator(namespace: Option<String>, name: String, data: Vec<u8>) -> Self {
pub fn initiator(namespace: Option<String>, name: String, data: Bytes) -> Self {
Self::new(namespace, name, data, None, EventType::Initiator)
}
/// Creates a new event that is a response to a previous event
#[tracing::instrument(level = "trace", skip(data))]
#[inline]
pub fn response(namespace: Option<String>, name: String, data: Vec<u8>, ref_id: u64) -> Self {
pub fn response(namespace: Option<String>, name: String, data: Bytes, ref_id: u64) -> Self {
Self::new(namespace, name, data, Some(ref_id), EventType::Response)
}
/// Creates a new error event as a response to a previous event
#[tracing::instrument(level = "trace", skip(data))]
#[inline]
pub fn error(namespace: Option<String>, name: String, data: Vec<u8>, ref_id: u64) -> Self {
pub fn error(namespace: Option<String>, name: String, data: Bytes, ref_id: u64) -> Self {
Self::new(namespace, name, data, Some(ref_id), EventType::Error)
}
@ -63,7 +64,7 @@ impl Event {
/// and might contain a final response payload
#[tracing::instrument(level = "trace", skip(data))]
#[inline]
pub fn end(namespace: Option<String>, name: String, data: Vec<u8>, ref_id: u64) -> Self {
pub fn end(namespace: Option<String>, name: String, data: Bytes, ref_id: u64) -> Self {
Self::new(namespace, name, data, Some(ref_id), EventType::Response)
}
@ -72,7 +73,7 @@ impl Event {
pub(crate) fn new(
namespace: Option<String>,
name: String,
data: Vec<u8>,
data: Bytes,
ref_id: Option<u64>,
event_type: EventType,
) -> Self {
@ -145,57 +146,59 @@ impl Event {
// additional header fields can be added a the end because when reading they will just be ignored
let header: EventHeader = EventHeader::from_read(&mut Cursor::new(header_bytes))?;
let mut data = vec![0u8; data_length as usize];
reader.read_exact(&mut data).await?;
let event = Event { header, data };
let mut buf = vec![0u8; data_length as usize];
reader.read_exact(&mut buf).await?;
let event = Event {
header,
data: Bytes::from(buf),
};
Ok(event)
}
/// Encodes the event into bytes
#[tracing::instrument(level = "trace", skip(self))]
pub fn into_bytes(mut self) -> Result<Vec<u8>> {
let mut header_bytes = self.header.into_bytes();
pub fn into_bytes(self) -> Result<Bytes> {
let header_bytes = self.header.into_bytes();
let header_length = header_bytes.len() as u16;
let data_length = self.data.len();
let total_length = header_length as u64 + data_length as u64;
tracing::trace!(total_length, header_length, data_length);
let mut buf = Vec::with_capacity(total_length as usize);
buf.append(&mut total_length.to_be_bytes().to_vec());
buf.append(&mut header_length.to_be_bytes().to_vec());
buf.append(&mut header_bytes);
buf.append(&mut self.data);
let mut buf = BytesMut::with_capacity(total_length as usize);
buf.put_u64(total_length);
buf.put_u16(header_length);
buf.put(header_bytes);
buf.put(self.data);
Ok(buf)
Ok(buf.freeze())
}
}
impl EventHeader {
/// Serializes the event header into bytes
pub fn into_bytes(self) -> Vec<u8> {
let mut buf = FORMAT_VERSION.to_vec();
buf.append(&mut self.id.to_be_bytes().to_vec());
buf.push(self.event_type.into());
pub fn into_bytes(self) -> Bytes {
let mut buf = BytesMut::with_capacity(256);
buf.put_slice(&FORMAT_VERSION);
buf.put_u64(self.id);
buf.put_u8(u8::from(self.event_type));
if let Some(ref_id) = self.ref_id {
buf.push(0xFF);
buf.append(&mut ref_id.to_be_bytes().to_vec());
buf.put_u8(0xFF);
buf.put_u64(ref_id);
} else {
buf.push(0x00);
buf.put_u8(0x00);
}
if let Some(namespace) = self.namespace {
let namespace_len = namespace.len() as u16;
buf.append(&mut namespace_len.to_be_bytes().to_vec());
buf.append(&mut namespace.into_bytes());
buf.put_u16(namespace.len() as u16);
buf.put(Bytes::from(namespace));
} else {
buf.append(&mut 0u16.to_be_bytes().to_vec());
buf.put_u16(0);
}
let name_len = self.name.len() as u16;
buf.append(&mut name_len.to_be_bytes().to_vec());
buf.append(&mut self.name.into_bytes());
buf.put_u16(self.name.len() as u16);
buf.put(Bytes::from(self.name));
buf
buf.freeze()
}
/// Parses an event header from an async reader

@ -2,13 +2,14 @@ use crate::error::Result;
use crate::events::event::Event;
use crate::ipc::context::Context;
use crate::payload::{BytePayload, IntoPayload};
use bytes::Bytes;
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
pub struct Response(Vec<u8>);
pub struct Response(Bytes);
impl Response {
/// Creates a new response with a given payload
@ -20,11 +21,11 @@ impl Response {
/// Creates an empty response
pub fn empty() -> Self {
Self(vec![])
Self(Bytes::new())
}
pub(crate) fn into_byte_payload(self) -> BytePayload {
BytePayload::new(self.0)
BytePayload::from(self.0)
}
}

@ -1,5 +1,6 @@
use crate::prelude::IPCResult;
use byteorder::{BigEndian, ReadBytesExt};
use bytes::{BufMut, Bytes, BytesMut};
use std::io::Read;
#[cfg(feature = "serialize")]
@ -7,18 +8,13 @@ pub use super::payload_serializer::*;
/// Trait that serializes a type into bytes and can fail
pub trait TryIntoBytes {
fn try_into_bytes(self) -> IPCResult<Vec<u8>>;
}
/// Trait that serializes a type into bytes and never fails
pub trait IntoBytes {
fn into_bytes(self) -> Vec<u8>;
fn try_into_bytes(self) -> IPCResult<Bytes>;
}
/// Trait to convert event data into sending bytes
/// It is implemented for all types that implement Serialize
pub trait IntoPayload {
fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>>;
fn into_payload(self, ctx: &Context) -> IPCResult<Bytes>;
}
/// Trait to get the event data from receiving bytes.
@ -31,25 +27,39 @@ pub trait FromPayload: Sized {
/// serializing them
#[derive(Clone)]
pub struct BytePayload {
bytes: Vec<u8>,
bytes: Bytes,
}
impl BytePayload {
#[inline]
pub fn new(bytes: Vec<u8>) -> Self {
Self { bytes }
Self {
bytes: Bytes::from(bytes),
}
}
/// Returns the bytes of the payload
/// Returns the bytes as a `Vec<u8>` of the payload
#[inline]
pub fn into_inner(self) -> Vec<u8> {
self.bytes.to_vec()
}
/// Returns the bytes struct of the payload
#[inline]
pub fn into_bytes(self) -> Bytes {
self.bytes
}
}
impl From<Bytes> for BytePayload {
fn from(bytes: Bytes) -> Self {
Self { bytes }
}
}
impl IntoPayload for BytePayload {
#[inline]
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
Ok(self.bytes)
}
}
@ -87,20 +97,18 @@ impl<P1, P2> TandemPayload<P1, P2> {
}
impl<P1: IntoPayload, P2: IntoPayload> IntoPayload for TandemPayload<P1, P2> {
fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>> {
let mut p1_bytes = self.load1.into_payload(&ctx)?;
let mut p2_bytes = self.load2.into_payload(&ctx)?;
fn into_payload(self, ctx: &Context) -> IPCResult<Bytes> {
let p1_bytes = self.load1.into_payload(&ctx)?;
let p2_bytes = self.load2.into_payload(&ctx)?;
let mut p1_length_bytes = (p1_bytes.len() as u64).to_be_bytes().to_vec();
let mut p2_length_bytes = (p2_bytes.len() as u64).to_be_bytes().to_vec();
let mut bytes = BytesMut::with_capacity(p1_bytes.len() + p2_bytes.len() + 16);
let mut bytes = Vec::new();
bytes.append(&mut p1_length_bytes);
bytes.append(&mut p1_bytes);
bytes.append(&mut p2_length_bytes);
bytes.append(&mut p2_bytes);
bytes.put_u64(p1_bytes.len() as u64);
bytes.put(p1_bytes);
bytes.put_u64(p2_bytes.len() as u64);
bytes.put(p2_bytes);
Ok(bytes)
Ok(bytes.freeze())
}
}
@ -123,8 +131,8 @@ impl<P1: FromPayload, P2: FromPayload> FromPayload for TandemPayload<P1, P2> {
#[cfg(not(feature = "serialize"))]
impl IntoPayload for () {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![])
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
Ok(Bytes::new())
}
}
@ -135,6 +143,7 @@ mod serde_payload {
use crate::payload::{FromPayload, TryIntoBytes};
use crate::prelude::{IPCResult, IntoPayload};
use byteorder::ReadBytesExt;
use bytes::{BufMut, Bytes, BytesMut};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
@ -168,20 +177,20 @@ mod serde_payload {
}
impl<T: Serialize> TryIntoBytes for SerdePayload<T> {
fn try_into_bytes(self) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new();
let mut data_bytes = self.serializer.serialize(self.data)?;
fn try_into_bytes(self) -> IPCResult<Bytes> {
let mut buf = BytesMut::new();
let data_bytes = self.serializer.serialize(self.data)?;
let format_id = self.serializer as u8;
buf.push(format_id);
buf.append(&mut data_bytes);
buf.put_u8(format_id);
buf.put(data_bytes);
Ok(buf)
Ok(buf.freeze())
}
}
impl<T: Serialize> IntoPayload for SerdePayload<T> {
#[inline]
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
self.try_into_bytes()
}
}
@ -198,7 +207,7 @@ mod serde_payload {
impl<T: Serialize> IntoPayload for T {
#[inline]
fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>> {
fn into_payload(self, ctx: &Context) -> IPCResult<Bytes> {
ctx.create_serde_payload(self).into_payload(&ctx)
}
}

@ -1,3 +1,4 @@
use bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
@ -49,7 +50,7 @@ pub enum SerializationError {
UnknownFormat(usize),
}
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum DynamicSerializer {
Messagepack,
Bincode,
@ -109,7 +110,7 @@ impl DynamicSerializer {
}
}
pub fn serialize<T: Serialize>(&self, data: T) -> SerializationResult<Vec<u8>> {
pub fn serialize<T: Serialize>(&self, data: T) -> SerializationResult<Bytes> {
match self {
#[cfg(feature = "serialize_rmp")]
DynamicSerializer::Messagepack => serialize_rmp::serialize(data),

@ -1,13 +1,14 @@
use crate::payload::SerializationResult;
use bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
#[inline]
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Vec<u8>> {
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Bytes> {
let bytes = bincode::serialize(&data)?;
Ok(bytes)
Ok(Bytes::from(bytes))
}
#[inline]

@ -1,13 +1,14 @@
use crate::payload::SerializationResult;
use bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
#[inline]
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Vec<u8>> {
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Bytes> {
let bytes = serde_json::to_vec(&data)?;
Ok(bytes)
Ok(Bytes::from(bytes))
}
#[inline]

@ -1,13 +1,14 @@
use crate::payload::SerializationResult;
use bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
#[inline]
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Vec<u8>> {
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Bytes> {
let bytes = postcard::to_allocvec(&data)?.to_vec();
Ok(bytes)
Ok(Bytes::from(bytes))
}
#[inline]

@ -1,13 +1,14 @@
use crate::payload::SerializationResult;
use bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
#[inline]
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Vec<u8>> {
pub fn serialize<T: Serialize>(data: T) -> SerializationResult<Bytes> {
let bytes = rmp_serde::to_vec(&data)?;
Ok(bytes)
Ok(Bytes::from(bytes))
}
#[inline]

@ -37,7 +37,7 @@ impl<P: IntoPayload> EventMetadata<P> {
let payload = self.payload.take().ok_or(Error::InvalidState)?;
let res_id = self.res_id.take().ok_or(Error::InvalidState)?;
let event_type = self.event_type.take().ok_or(Error::InvalidState)?;
let payload_bytes = payload.into_payload(&ctx)?;
let payload_bytes = payload.into_payload(&ctx)?.into();
let event = Event::new(
namespace,

@ -119,6 +119,12 @@ mod macros;
mod namespaces;
pub mod protocol;
/// Reexported for usage in payload implementations
pub use bytes;
/// Reexported for sharing data in context
pub use trait_bound_typemap;
pub use events::error_event;
pub use events::event;
pub use events::event_handler;
@ -146,4 +152,5 @@ pub mod prelude {
pub use crate::payload::*;
pub use crate::protocol::*;
pub use crate::*;
pub use trait_bound_typemap::TypeMap;
}

@ -3,6 +3,7 @@ use crate::utils::protocol::TestProtocolListener;
use crate::utils::{get_free_port, start_server_and_client};
use bromine::prelude::*;
use byteorder::ReadBytesExt;
use bytes::Bytes;
use futures::StreamExt;
use std::io::Read;
use std::time::Duration;
@ -66,16 +67,16 @@ async fn handle_stream_event(ctx: &Context, event: Event) -> IPCResult<Response>
pub struct EmptyPayload;
impl IntoPayload for EmptyPayload {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![])
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
Ok(Bytes::new())
}
}
pub struct NumberPayload(u8);
impl IntoPayload for NumberPayload {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![self.0])
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
Ok(Bytes::from(vec![self.0]))
}
}

@ -91,6 +91,7 @@ mod payload_impl {
use bromine::payload::{FromPayload, IntoPayload};
use bromine::prelude::IPCResult;
use byteorder::{BigEndian, ReadBytesExt};
use bytes::{BufMut, Bytes, BytesMut};
use std::io::Read;
pub struct SimplePayload {
@ -99,17 +100,13 @@ mod payload_impl {
}
impl IntoPayload for SimplePayload {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new();
let string_length = self.string.len() as u16;
let string_length_bytes = string_length.to_be_bytes();
buf.append(&mut string_length_bytes.to_vec());
let mut string_bytes = self.string.into_bytes();
buf.append(&mut string_bytes);
let num_bytes = self.number.to_be_bytes();
buf.append(&mut num_bytes.to_vec());
Ok(buf)
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
let mut buf = BytesMut::new();
buf.put_u16(self.string.len() as u16);
buf.put(Bytes::from(self.string));
buf.put_u32(self.number);
Ok(buf.freeze())
}
}

@ -2,6 +2,7 @@ mod utils;
use crate::utils::start_server_and_client;
use bromine::prelude::*;
use bytes::Bytes;
use std::time::Duration;
use utils::call_counter::*;
use utils::get_free_port;
@ -132,7 +133,7 @@ async fn handle_error_event(ctx: &Context, event: Event) -> IPCResult<Response>
pub struct EmptyPayload;
impl IntoPayload for EmptyPayload {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![])
fn into_payload(self, _: &Context) -> IPCResult<Bytes> {
Ok(Bytes::new())
}
}

Loading…
Cancel
Save