Skip to content

Commit

Permalink
Use BytesMut for messages
Browse files Browse the repository at this point in the history
Benchmarks indicate that malloc accounts for a significant amount of the
runtime of queries. The message buffer accounts for ~half of that (the
other being channels), and this change should eliminate it.
  • Loading branch information
sfackler committed Oct 12, 2019
1 parent e99d65e commit ffd7245
Show file tree
Hide file tree
Showing 30 changed files with 390 additions and 414 deletions.
2 changes: 1 addition & 1 deletion postgres-derive/src/tosql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn expand_derive_tosql(input: DeriveInput) -> Result<TokenStream, Error> {
impl postgres_types::ToSql for #ident {
fn to_sql(&self,
_type: &postgres_types::Type,
buf: &mut std::vec::Vec<u8>)
buf: &mut postgres_types::private::BytesMut)
-> std::result::Result<postgres_types::IsNull,
std::boxed::Box<std::error::Error +
std::marker::Sync +
Expand Down
32 changes: 28 additions & 4 deletions postgres-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![warn(missing_docs, rust_2018_idioms, clippy::all)]

use byteorder::{BigEndian, ByteOrder};
use bytes::{BufMut, BytesMut};
use std::io;

pub mod authentication;
Expand All @@ -30,14 +31,37 @@ pub enum IsNull {
No,
}

#[inline]
fn write_nullable<F, E>(serializer: F, buf: &mut Vec<u8>) -> Result<(), E>
// https://github.com/tokio-rs/bytes/issues/170
struct B<'a>(&'a mut BytesMut);

impl<'a> BufMut for B<'a> {
#[inline]
fn remaining_mut(&self) -> usize {
usize::max_value() - self.0.len()
}

#[inline]
unsafe fn advance_mut(&mut self, cnt: usize) {
self.0.advance_mut(cnt);
}

#[inline]
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
if !self.0.has_remaining_mut() {
self.0.reserve(64);
}

self.0.bytes_mut()
}
}

fn write_nullable<F, E>(serializer: F, buf: &mut BytesMut) -> Result<(), E>
where
F: FnOnce(&mut Vec<u8>) -> Result<IsNull, E>,
F: FnOnce(&mut BytesMut) -> Result<IsNull, E>,
E: From<io::Error>,
{
let base = buf.len();
buf.extend_from_slice(&[0; 4]);
B(buf).put_i32_be(0);
let size = match serializer(buf)? {
IsNull::No => i32::from_usize(buf.len() - base - 4)?,
IsNull::Yes => -1,
Expand Down
Loading

0 comments on commit ffd7245

Please sign in to comment.