From 2077e3fd21bce183648fed83047987a2a3edfb61 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sat, 16 Mar 2019 00:58:01 -0700 Subject: [PATCH] use varbincode for mux protocol; results in ~3x smaller packets Reduces the size of the full screen serialized size from 40k -> 13k. Note that the `zlo` crate (which doesn't appear to have a repo on github any longer; sources are only found in the crates.io documentation source view), employes zigzag encoding of all integers and floating point values and takes the size down to just under 10k. A todo is to follow up on that and see if we could adopt the same scheme in varbincode. --- Cargo.toml | 3 +-- src/main.rs | 2 +- src/server/codec.rs | 58 ++++++++++++++++++++---------------------- varbincode/src/test.rs | 4 +-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e58f4e9a4..9454e4a44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,9 +31,8 @@ rayon = "1.0" promise = { path = "promise" } base91 = { path = "base91" } varbincode = { path = "varbincode" } -varu64 = "0.6" -bincode = "1.1" lazy_static = "1.3" +leb128 = "0.2" [target.'cfg(unix)'.dependencies] harfbuzz-sys = { git = "https://github.com/wez/rust-harfbuzz", branch="coretext" } diff --git a/src/main.rs b/src/main.rs index 3b3a81d78..e4c7b5c8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,7 +162,7 @@ fn main() -> Result<(), Error> { let data = client.get_coarse_tab_renderable_data(GetCoarseTabRenderableData { tab_id: *tab_id, })?; - eprintln!("coarse: {:?}", data); + // eprintln!("coarse: {:?}", data); } Ok(()) } diff --git a/src/server/codec.rs b/src/server/codec.rs index d372a7392..007c22ed3 100644 --- a/src/server/codec.rs +++ b/src/server/codec.rs @@ -11,14 +11,29 @@ #![allow(dead_code)] use crate::mux::tab::TabId; -use bincode; use failure::Error; +use leb128; use serde_derive::*; use std::collections::HashMap; use std::sync::Arc; use term::{CursorPosition, Line}; use termwiz::hyperlink::Hyperlink; -use varu64; +use varbincode; + +/// Returns the encoded length of the leb128 representation of value +fn encoded_length(value: u64) -> usize { + struct NullWrite {}; + impl std::io::Write for NullWrite { + fn write(&mut self, buf: &[u8]) -> std::result::Result { + Ok(buf.len()) + } + fn flush(&mut self) -> std::result::Result<(), std::io::Error> { + Ok(()) + } + }; + + leb128::write::unsigned(&mut NullWrite {}, value).unwrap() +} fn encode_raw( ident: u64, @@ -26,34 +41,16 @@ fn encode_raw( data: &[u8], mut w: W, ) -> Result<(), std::io::Error> { - let len = data.len() + varu64::encoding_length(ident) + varu64::encoding_length(serial); - varu64::encode_write(len as u64, w.by_ref())?; - varu64::encode_write(serial, w.by_ref())?; - varu64::encode_write(ident, w.by_ref())?; + let len = data.len() + encoded_length(ident) + encoded_length(serial); + leb128::write::unsigned(w.by_ref(), len as u64)?; + leb128::write::unsigned(w.by_ref(), serial)?; + leb128::write::unsigned(w.by_ref(), ident)?; w.write_all(data) } fn read_u64(mut r: R) -> Result { - let mut intbuf = [0u8; 9]; - r.read_exact(&mut intbuf[0..1])?; - let len = match intbuf[0] { - 0...247 => 0, - 248 => 1, - 249 => 2, - 250 => 3, - 251 => 4, - 252 => 5, - 253 => 6, - 254 => 7, - 255 => 8, - _ => unreachable!(), - }; - if len > 0 { - r.read_exact(&mut intbuf[1..=len])?; - } - let (value, _) = varu64::decode(&intbuf[0..=len]) - .map_err(|(err, _)| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", err)))?; - Ok(value) + leb128::read::unsigned(&mut r) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", err))) } #[derive(Debug)] @@ -65,9 +62,10 @@ struct Decoded { fn decode_raw(mut r: R) -> Result { let len = read_u64(r.by_ref())? as usize; + eprintln!("decode_raw: {} bytes", len); let serial = read_u64(r.by_ref())?; let ident = read_u64(r.by_ref())?; - let data_len = len - (varu64::encoding_length(ident) + varu64::encoding_length(serial)); + let data_len = len - (encoded_length(ident) + encoded_length(serial)); let mut data = vec![0u8; data_len]; r.read_exact(&mut data)?; Ok(Decoded { @@ -99,7 +97,7 @@ macro_rules! pdu { Pdu::Invalid{..} => bail!("attempted to serialize Pdu::Invalid"), $( Pdu::$name(s) => { - let data = bincode::serialize(s)?; + let data = varbincode::serialize(s)?; encode_raw($vers, serial, &data, w)?; Ok(()) } @@ -114,7 +112,7 @@ macro_rules! pdu { $vers => { Ok(DecodedPdu { serial: decoded.serial, - pdu: Pdu::$name(bincode::deserialize(&decoded.data)?) + pdu: Pdu::$name(varbincode::deserialize(decoded.data.as_slice())?) }) } ,)* @@ -188,7 +186,7 @@ mod test { fn test_frame() { let mut encoded = Vec::new(); encode_raw(0x81, 0x42, b"hello", &mut encoded).unwrap(); - assert_eq!(&encoded, b"\x07\x42\x81hello"); + assert_eq!(&encoded, b"\x08\x42\x81\x01hello"); let decoded = decode_raw(encoded.as_slice()).unwrap(); assert_eq!(decoded.ident, 0x81); assert_eq!(decoded.serial, 0x42); diff --git a/varbincode/src/test.rs b/varbincode/src/test.rs index 7e59d86fa..4885825e6 100644 --- a/varbincode/src/test.rs +++ b/varbincode/src/test.rs @@ -1,5 +1,5 @@ -use super::{deserialize, error::Error, serialize}; -use serde::{Deserialize, Serialize}; +use super::{deserialize, serialize}; +use serde::Serialize; use serde_derive::*; use std::collections::HashMap;